@@ -961,7 +961,6 @@ function M.sections.terminal(opts)
961961local height ,width = opts .height or 10 ,opts .width or (self .opts .width - (opts .indent or 0 ))
962962local hl = opts .hl and hl_groups [opts .hl ]or opts .hl or " SnacksDashboardTerminal"
963963local cache_buf ,term_buf ,win --- @type integer ?, integer ?, integer ?
964- local term_ready = false
965964
966965local cache_parts = {
967966table.concat (type (cmd )== " table" and cmd or {cmd }," " ),
@@ -974,7 +973,7 @@ function M.sections.terminal(opts)
974973local has_cache = stat and stat .type == " file" and stat .size > 0
975974local is_expired = has_cache and stat and os.time ()- stat .mtime .sec >= ttl
976975
977- if has_cache and not cache_buf and stat then
976+ if has_cache and stat then -- show cached output
978977cache_buf = vim .api .nvim_create_buf (false ,true )
979978vim .bo [cache_buf ].buftype = " nofile"
980979local fin = assert (uv .fs_open (cache_file ," r" ,438 ))
@@ -985,13 +984,9 @@ function M.sections.terminal(opts)
985984vim .bo [cache_buf ].scrollback = 9998
986985end
987986
988- local function get_buf ()
989- return assert (term_ready and term_buf or cache_buf ," No terminal or cache buffer available" )
990- end
991-
992- local function set_buf ()
987+ --- @param buf integer
988+ local function show (buf )
993989if win and vim .api .nvim_win_is_valid (win )then
994- local buf = assert (term_ready and term_buf or cache_buf ," No terminal or cache buffer available" )
995990vim .api .nvim_win_set_buf (win ,buf )
996991Snacks .util .wo (win , {winhighlight = " TermCursorNC:" .. hl .. " ,NormalFloat:" .. hl })
997992Snacks .util .bo (buf , {filetype = Snacks .config .styles .dashboard .bo .filetype })
@@ -1000,54 +995,43 @@ function M.sections.terminal(opts)
1000995
1001996local job --- @type snacks.Job ?
1002997if not has_cache or is_expired then
1003- term_ready ,term_buf = not has_cache ,vim .api .nvim_create_buf (false ,true )
998+ term_buf = vim .api .nvim_create_buf (false ,true )
999+ local term_ready = false
10041000local output = {}--- @type string[]
1005- local timer = assert (uv .new_timer ())
1006-
1007- --- @param force boolean ?
1008- local function show (force )
1009- if
1010- not force
1011- and vim .api .nvim_buf_is_valid (term_buf )
1012- and # vim .tbl_filter (function (line )
1013- return line :match (" %S" )
1014- end ,vim .api .nvim_buf_get_lines (term_buf ,0 ,- 1 ,false ))
1015- < 3
1016- then
1017- return
1018- end
1019- if timer :is_active ()then
1020- timer :stop ()
1021- timer :close ()
1022- end
1023- term_ready = true
1024- set_buf ()
1025- end
1026- timer :start (30 ,30 ,vim .schedule_wrap (show ))
10271001
10281002local recording = vim .defer_fn (function ()
10291003output = {}
1030- show (true )
1004+ show (term_buf )
10311005end ,5000 )--[[ @as uv.uv_timer_t]]
10321006
10331007local Job = require (" snacks.util.job" )
10341008job = Job .new (
10351009term_buf ,
10361010cmd ,
10371011Snacks .config .merge ({}, {
1012+ start = false ,
10381013term = true ,
10391014width = width ,
10401015height = height ,
10411016on_stdout = function (_ ,data )
10421017if recording :is_active ()then
10431018table.insert (output ,table.concat (data ," \n " ))
10441019end
1020+ if not term_ready and job then
1021+ local non_empty = # vim .tbl_filter (function (line )
1022+ return line :match (" %S" )
1023+ end ,job .lines )
1024+ if non_empty >= 3 then
1025+ term_ready = true
1026+ show (term_buf )
1027+ end
1028+ end
10451029end ,
10461030on_exit = function (_ ,code )
10471031if job and job .killed then
10481032return
10491033end
1050- show (true )
1034+ show (term_buf )
10511035if recording :is_active ()and code == 0 and ttl > 0 then -- save the output
10521036vim .fn .mkdir (cache_dir ," p" )
10531037local fout = assert (uv .fs_open (cache_file ," w" ,438 ))
@@ -1065,7 +1049,9 @@ function M.sections.terminal(opts)
10651049label = not opts .title and opts .label or nil ,
10661050render = function (_ ,pos )
10671051self :trace (" terminal.render" )
1068- win = vim .api .nvim_open_win (get_buf (),false , {
1052+ -- open the window with the terminal buffer if available.
1053+ -- This is to ensure it starts with the correct window size.
1054+ win = vim .api .nvim_open_win (assert (term_buf or cache_buf ),false , {
10691055bufpos = {pos [1 ]- 1 ,pos [2 ]+ 1 },
10701056col = opts .indent or 0 ,
10711057focusable = false ,
@@ -1079,7 +1065,10 @@ function M.sections.terminal(opts)
10791065win = self .win ,
10801066border = " none" ,
10811067 })
1082- set_buf ()
1068+ if job then -- start the job if needed
1069+ job :start ()
1070+ end
1071+ show (assert (cache_buf or term_buf ))-- set the correct buffer
10831072local close = vim .schedule_wrap (function ()
10841073if job then
10851074job :stop ()