diff --git a/Filelist b/Filelist index 4067df5081..c5b3c4fdd8 100644 --- a/Filelist +++ b/Filelist @@ -863,6 +863,7 @@ RT_SCRIPTS = \ runtime/indent/testdir/*.vim \ runtime/indent/testdir/*.in \ runtime/indent/testdir/*.ok \ + runtime/indent/testdir/tools/* \ runtime/ftplugin/*.vim \ runtime/ftplugin/logtalk.dict \ runtime/ftplugin/README.txt \ diff --git a/runtime/indent/testdir/tools/tracer.vim b/runtime/indent/testdir/tools/tracer.vim new file mode 100644 index 0000000000..d87315401c --- /dev/null +++ b/runtime/indent/testdir/tools/tracer.vim @@ -0,0 +1,166 @@ +vim9script + +# Whenever indent plugins contain "search*()" lines explicitly annotated with +# "VIM_INDENT_TEST_TRACE_(START|END)" comment markers; this script can then be +# used as shown to measure and record elapsed time for such decorated calls. +# +# Usage: +# cd runtime/indent +# vim -u NONE -S testdir/tools/tracer.vim \ +# html.vim javascript.vim \ +# ../autoload/python.vim ../autoload/dist/vimindent.vim +# git diff +# make clean test +# vim testdir/00-TRACE_LOG.fail + +def GenerateTempletForTracing(fname: string, vname: string): list + #### ONLY INSTRUMENT "search*()"es FOR INDENT TESTS. + + const templet: list =<< trim eval END + + if getcwd() =~# '\, result: any): any + const end: list = reltime(start) + + if !has_key(g:indent_test_trace_times, id) + g:indent_test_trace_times[id] = [] + endif + + g:indent_test_trace_times[id] + ->add(reltimefloat(end)) + return result + enddef + + def! g:IndentTestInitTracing() + # Possibly use a later "{fname}", cf. ":runtime indent/foo.vim". + autocmd_add([{{ + replace: true, + group: 'tracing', + event: 'QuitPre', + bufnr: bufnr(), + cmd: 'g:IndentTestWriteTraceTimes()', + }}]) + g:indent_test_trace_times = {{}} + enddef + + def! g:IndentTestWriteTraceTimes() + # Anticipate usage by multiple languages. + const token: string = printf('%02x', (rand() % 26)) + writefile(['" {fname}:', + "let {vname}_" .. token .. " = " .. string(g:indent_test_trace_times), + "let {vname}_" .. token .. "_summary = " .. string(g:indent_test_trace_times + ->items() + ->reduce((outer: dict>, times: list) => + extend({{[times[0]]: times[1] + ->copy() + ->reduce((inner: dict, v: float) => + extend({{ + min: inner.min < v ? inner.min : v, + max: inner.max > v ? inner.max : v, + sum: (inner.sum + v), + avg: ((inner.sum + v) / inner.count), + }}, + inner, + "keep"), + {{ + min: v:numbermax - 0.0, + max: v:numbermin + 0.0, + sum: 0.0, + avg: 0.0, + count: len(times[1]), + }})}}, + outer), + {{}}))], + (!empty($VIM_INDENT_TEST_LOG) && filewritable($VIM_INDENT_TEST_LOG)) + ? $VIM_INDENT_TEST_LOG + : "testdir/00-TRACE_LOG.fail", + "a") + enddef + + call g:IndentTestInitTracing() + + else + + def! g:IndentTestTrace(_: string, _: list, result: any): any + return result + enddef + + endif + + END + return templet +enddef + +def InstrumentMarkedEntry(): bool + const marker_start: string = 'VIM_INDENT_TEST_TRACE_START' + const start: number = search('\C\<' .. marker_start .. '\>', 'ceW') + + if start == 0 + return false + endif + + const marker_end: string = 'VIM_INDENT_TEST_TRACE_END' + const end: number = search('\C\<' .. marker_end .. '\>', 'ceW') + + if end == 0 + return false + endif + + const tracee: list = matchlist( + getline(start + 1), + '\(^.\+\)\(\ 1 + setline((start + 1), tracer) + setline((end - 1), getline(end - 1) .. ')') + else + setline((start + 1), tracer .. ')') + endif + + return true +enddef + +def ProcessIndentPluginCmdlineArgs() + const names: list = range(char2nr('a'), char2nr('z')) + ->map((_: number, n: number) => nr2char(n, true)) + var entries: number = 0 + var next: number = 0 + + for fname: string in argv(-1) + if filereadable(fname) && filewritable(fname) + execute 'new ' .. fname + call cursor(1, 1) + + while InstrumentMarkedEntry() + entries += 1 + endwhile + + if entries > 0 + append(1, GenerateTempletForTracing(fname, get(names, next, names[-1]))) + wq + endif + + entries = 0 + next += 1 + endif + endfor +enddef + +if empty(system('git status --porcelain=v1')) + ProcessIndentPluginCmdlineArgs() +endif + +quitall + +# vim:fdm=syntax:sw=2:ts=8:noet:nosta: