diff --git a/autoload/startuptime.vim b/autoload/startuptime.vim index b4fc88c..61eeb90 100644 --- a/autoload/startuptime.vim +++ b/autoload/startuptime.vim @@ -283,7 +283,7 @@ function! s:Profile(onfinish, onprogress, options, tries, file, items) abort if a:options.input_file !=# v:null || a:tries <# a:options.tries while 1 try - let l:items = s:Extract(a:file, a:options) + let l:items = s:Extract(a:file) break catch /^Vim:Interrupt$/ " Ignore interrupts. The loop will result in re-attempting to extract. @@ -295,16 +295,11 @@ function! s:Profile(onfinish, onprogress, options, tries, file, items) abort endif if a:tries ==# 0 || a:options.input_file !=# v:null if has('nvim-0.9') - if a:options.input_file !=# v:null || a:options.tries * 2 ==# len(a:items) - " Add a workaround for Neovim #23036. When the number of results is double - " what's expected, use every other result. - let l:items = [] - for l:idx in range(0, len(a:items) - 1, 2) - call add(l:items, a:items[l:idx]) - endfor - call remove(a:items, 0, -1) - call extend(a:items, l:items) + let l:filtered = luaeval('require("startuptime").remove_tui_sessions(_A)', a:items) + if !empty(a:items) + call remove(a:items, 0, len(a:items) - 1) endif + call extend(a:items, l:filtered) endif if len(a:items) ==# 0 throw 'vim-startuptime: unable to obtain startup times' @@ -344,10 +339,9 @@ function! s:Profile(onfinish, onprogress, options, tries, file, items) abort endif endfunction -function! s:ExtractLua(file, options) abort +function! s:ExtractLua(file) abort let l:args = [ \ a:file, - \ a:options, \ s:event_types, \ ] let l:result = luaeval('require("startuptime").extract(unpack(_A))', l:args) @@ -364,11 +358,11 @@ function! s:ExtractLua(file, options) abort return l:result endfunction -function! s:ExtractVim9(file, options) abort - return startuptime9#Extract(a:file, a:options, s:event_types) +function! s:ExtractVim9(file) abort + return startuptime9#Extract(a:file, s:event_types) endfunction -function! s:ExtractVimScript(file, options) abort +function! s:ExtractVimScript(file) abort let l:result = [] let l:lines = readfile(a:file) for l:line in l:lines @@ -407,16 +401,7 @@ function! s:ExtractVimScript(file, options) abort let l:item.elapsed = str2float(l:times[1]) let l:item.start = l:item.finish - l:item.elapsed endif - let l:types = [] - if a:options.sourcing_events - call add(l:types, s:event_types['sourcing']) - endif - if a:options.other_events - call add(l:types, s:event_types['other']) - endif - if s:Contains(l:types, l:item.type) - call add(l:result[-1], l:item) - endif + call add(l:result[-1], l:item) endfor return l:result endfunction @@ -424,15 +409,15 @@ endfunction " Returns a nested list. The top-level list entries correspond to different " profiling sessions. The next level lists contain the parsed lines for each " profiling session. Each line is represented with a dict. -function! s:Extract(file, options) abort +function! s:Extract(file) abort " For improved speed, a Lua function is used for Neovim and a Vim9 function " for Vim, when available. if s:nvim_lua - return s:ExtractLua(a:file, a:options) + return s:ExtractLua(a:file) elseif s:vim9script - return s:ExtractVim9(a:file, a:options) + return s:ExtractVim9(a:file) else - return s:ExtractVimScript(a:file, a:options) + return s:ExtractVimScript(a:file) endif endfunction @@ -558,6 +543,25 @@ function! s:Augment(items, options) abort return l:result endfunction +" Filter items based on whether --no-sourcing-events or --no-other-events were +" used. +function! s:Filter(items, options) abort + let l:result = [] + let l:types = [] + if a:options.sourcing_events + call add(l:types, s:event_types['sourcing']) + endif + if a:options.other_events + call add(l:types, s:event_types['other']) + endif + for l:item in a:items + if s:Contains(l:types, l:item.type) + call add(l:result, l:item) + endif + endfor + return l:result +endfunction + function! startuptime#ShowMoreInfo() abort let l:cmdheight = &cmdheight let l:laststatus = &laststatus @@ -1073,9 +1077,13 @@ endfunction function! s:Process(options, items) abort let l:items = a:items + " Total startup time is determined prior to filtering. The reported + " startuptime above the table is independent of whether --no-sourcing-events + " or --no-other-events were used. let l:startup = s:Startup(l:items) let l:items = s:Consolidate(l:items) let l:items = s:Augment(l:items, a:options) + let l:items = s:Filter(l:items, a:options) if a:options.sort let l:Compare = {i1, i2 -> \ i1.time ==# i2.time ? 0 : (i1.time <# i2.time ? 1 : -1)} diff --git a/autoload/startuptime9.vim b/autoload/startuptime9.vim index 924b5cf..5bdf89e 100644 --- a/autoload/startuptime9.vim +++ b/autoload/startuptime9.vim @@ -3,7 +3,6 @@ vim9script # (documented in autoload/startuptime.vim) export def Extract( file: string, - options: dict, event_types: dict ): list>> const other_event_type = event_types['other'] @@ -47,16 +46,7 @@ export def Extract( item.elapsed = str2float(times[1]) item.start = item.finish - item.elapsed endif - final types = [] - if options.sourcing_events - add(types, sourcing_event_type) - endif - if options.other_events - add(types, other_event_type) - endif - if index(types, item.type) !=# -1 - add(result[-1], item) - endif + add(result[-1], item) endfor return result enddef diff --git a/lua/startuptime.lua b/lua/startuptime.lua index be817f5..f9dc8f9 100644 --- a/lua/startuptime.lua +++ b/lua/startuptime.lua @@ -10,7 +10,7 @@ local to_bool = function(x) end -- (documented in autoload/startuptime.vim) -local extract = function(file, options, event_types) +local extract = function(file, event_types) local other_event_type = event_types['other'] local sourcing_event_type = event_types['sourcing'] local result = {} @@ -53,15 +53,7 @@ local extract = function(file, options, event_types) item.start = item.finish - item.elapsed end local types = {} - if to_bool(options.sourcing_events) then - table.insert(types, sourcing_event_type) - end - if to_bool(options.other_events) then - table.insert(types, other_event_type) - end - if vim.tbl_contains(types, item.type) then - table.insert(result[#result], item) - end + table.insert(result[#result], item) end end return result @@ -146,7 +138,30 @@ local consolidate = function(items, tfields) return result end +-- Given extraction results (from startuptime::Extract), drop the entries that +-- correspond to the TUI Neovim process. Neovim #23036, #26790. +-- In Neovim 0.9, the TUI data comes after the main process data. In Neovim +-- 0.10, the startup times are labeled for the different processes +-- (Primary/TUI or Embedded). The main process data can be in either section +-- (for example, it would ordinarily be under "Embedded", but it's under +-- "Primary/TUI" when nvim is called from :!). Here we determine TUI sessions +-- by their lack of an event that occurs for main processes but not the TUI +-- process. +local remove_tui_sessions = function(sessions) + local result = {} + for _, session in ipairs(sessions) do + for _, item in ipairs(session) do + if item.event == 'opening buffers' then + table.insert(result, session) + break + end + end + end + return result +end + return { extract = extract, - consolidate = consolidate + consolidate = consolidate, + remove_tui_sessions = remove_tui_sessions, } diff --git a/tests/test_consistency.vim b/tests/test_consistency.vim index a277198..966efea 100644 --- a/tests/test_consistency.vim +++ b/tests/test_consistency.vim @@ -43,10 +43,10 @@ try for s:options in s:optionss " Test Lua/VimScript consistency with default options. - let s:extracted_vimscript = s:ExtractVimScript(s:file, s:options) + let s:extracted_vimscript = s:ExtractVimScript(s:file) call assert_equal(1, len(s:extracted_vimscript)) call assert_true(!empty(s:extracted_vimscript[0])) - let s:extracted_opt = s:ExtractOpt(s:file, s:options) + let s:extracted_opt = s:ExtractOpt(s:file) call assert_equal(s:extracted_vimscript, s:extracted_opt) let s:consolidated_vimscript = \ s:ConsolidateVimScript(s:extracted_vimscript) @@ -74,10 +74,10 @@ try call s:Execute(s:file) endfor for s:options in s:optionss - let s:extracted_vimscript = s:ExtractVimScript(s:file, s:options) + let s:extracted_vimscript = s:ExtractVimScript(s:file) call assert_equal(6, len(s:extracted_vimscript)) call assert_true(!empty(s:extracted_vimscript[0])) - let s:extracted_opt = s:ExtractOpt(s:file, s:options) + let s:extracted_opt = s:ExtractOpt(s:file) call assert_equal(s:extracted_vimscript, s:extracted_opt) let s:consolidated_vimscript = \ s:ConsolidateVimScript(s:extracted_vimscript)