runtime(indent-tests): Instrument timed "search*()" calls

Commit: 
https://github.com/vim/vim/commit/fe8508eda002196bd9095c35ea7892bce06bb6d2
Author: Aliaksei Budavei <0x000...@gmail.com>
Date:   Sat Apr 19 11:35:02 2025 +0200

    runtime(indent-tests): Instrument timed "search*()" calls
    
    The offered "tracer.vim" script can be used to measure and
    record elapsed time for explicitly annotated "search*()"es,
    set off with "VIM_INDENT_TEST_TRACE_(START|END)" comment
    markers, in indent plugins.
    
    related: #17116
    
    Signed-off-by: Aliaksei Budavei <0x000...@gmail.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/Filelist b/Filelist
index 4067df508..c5b3c4fdd 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 000000000..d87315401
--- /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<string>
+  #### ONLY INSTRUMENT "search*()"es FOR INDENT TESTS.
+
+  const templet: list<string> =<< trim eval END
+
+  if getcwd() =~# '\<runtime/indent$'
+
+  def! g:IndentTestTrace(id: string, start: list<number>, result: any): any
+    const end: list<number> = 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<dict<any>>, times: list<any>) =>
+                   extend({{[times[0]]: times[1]
+                             ->copy()
+                             ->reduce((inner: dict<any>, 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<number>, 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<string> = matchlist(
+    getline(start + 1),
+    '\(^.\+\)\(\<search\%(pair\)\=\%(pos\)\=\s*(.*$\)')
+
+  if empty(get(tracee, 1, '')) || empty(get(tracee, 2, ''))
+    return false
+  endif
+
+  const end_line: string = getline(end)
+  const tracer: string = printf('%sg:IndentTestTrace("%s", reltime(), %s',
+      tracee[1],
+      strpart(end_line, (stridx(end_line, marker_end) + strlen(marker_end) + 
1)),
+      tracee[2])
+
+  if (end - start) > 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<string> = 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:

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1u64kz-00CJkT-E2%40256bit.org.

Raspunde prin e-mail lui