@@ -3,11 +3,12 @@ vim9script
33# Language: Vim9 script
44# Contributers: @l acygoill
55# Shane- XB- Qian
6- # Last Change: 2025 Aug 13
6+ # Andrew Radev
7+ # Last Change: 2025 Sep 02
78#
8- # Vim Script to handle
9- # :import , :packadd and :colorscheme
10- # lines and allows to easily jump to it using gf
9+ # Vim Script to handle jumping to the targets of several types of Vim commands
10+ # ( :import , :packadd , : runtime , :colorscheme ), and to autoloaded functions of
11+ # the style <path> # <function_name> .
1112#
1213# see runtime /ftplugin/ vim .vim
1314
@@ -20,6 +21,11 @@ export def Find(editcmd: string) #{{{2
2021 return
2122 endif
2223
24+ if curline = ~ ' ^\s*\%(:\s*\)\=ru\%[ntime]!\='
25+ HandleRuntimeLine (editcmd, curline, expand (' <cfile>' ))
26+ return
27+ endif
28+
2329 if curline = ~ ' ^\s*\%(:\s*\)\=colo\%[rscheme]\s'
2430 HandleColoLine (editcmd, curline)
2531 return
@@ -30,6 +36,20 @@ export def Find(editcmd: string) #{{{2
3036 return
3137 endif
3238
39+ var curfunc = FindCurfunc ()
40+
41+ if stridx (curfunc, ' #' ) >= 0
42+ var parts = split (curfunc, ' #' )
43+ var path = $ " autoload/{join(parts[0 : -2], '/')}.vim"
44+ var resolved_path = globpath (&runtimepath , path )
45+
46+ if resolved_path != ' '
47+ var function_pattern: string = $ ' ^\s*\%(:\s*\)\=fun\%[ction]!\=\s\+\zs{curfunc}('
48+ resolved_path- >Open (editcmd, function_pattern)
49+ endif
50+ return
51+ endif
52+
3353 try
3454 execute ' normal! ' .. editcmd
3555 catch
@@ -45,22 +65,42 @@ def HandlePackaddLine(editcmd: string, curline: string) #{{{2
4565 - >substitute (' ^vim-\|\.vim$' , ' ' , ' g' )
4666
4767 if plugin == ' '
48- try
49- execute ' normal! ' .. editcmd .. ' zv'
50- catch
51- Error (v: exception )
52- return
53- endtry
68+ Fallback (editcmd)
5469 else
55- var split : string = editcmd[0 ] == ' g' ? ' edit' : editcmd[1 ] == ' g' ? ' tabedit' : ' split'
5670 var files : list <string> = getcompletion ($ ' plugin/{plugin}' , ' runtime' )
5771 - >map ((_, fname: string ) = > fname- >findfile (&rtp )- >fnamemodify (' :p' ))
5872 - >filter ((_, path : string ): bool = > filereadable (path ))
5973 if empty (files )
6074 echo ' Could not find any plugin file for ' .. string (plugin )
6175 return
6276 endif
63- files - >Open (split )
77+ files - >Open (editcmd)
78+ endif
79+ enddef
80+
81+ def HandleRuntimeLine (editcmd: string , curline: string , cfile : string ) #{{{2
82+ var fname: string
83+ var where_pat: string = ' \%(START\|OPT\|PACK\|ALL\)'
84+
85+ if cfile == ' runtime' || cfile = ~# $ ' ^{where_pat}$'
86+ # then the cursor was not on one of the filenames, jump to the first file :
87+ var fname_pat: string = $ ' \s*\%(:\s*\)\=ru\%[ntime]\%(!\s*\|\s\+\)\%({where_pat}\s\+\)\=\zs\S\+\>\ze'
88+ fname = curline- >matchstr (fname_pat)
89+ else
90+ fname = cfile
91+ endif
92+
93+ if fname == ' '
94+ Fallback (editcmd)
95+ else
96+ var file : string = fname
97+ - >findfile (&rtp )
98+ - >fnamemodify (' :p' )
99+ if file == ' ' || ! filereadable (file )
100+ echo ' Could not be found in the runtimepath: ' .. string (fname)
101+ return
102+ endif
103+ file - >Open (editcmd)
64104 endif
65105enddef
66106
@@ -69,22 +109,16 @@ def HandleColoLine(editcmd: string, curline: string) #{{{2
69109 var colo : string = curline- >matchstr (pat)
70110
71111 if colo == ' '
72- try
73- execute ' normal! ' .. editcmd .. ' zv'
74- catch
75- Error (v: exception )
76- return
77- endtry
112+ Fallback (editcmd)
78113 else
79- var split : string = editcmd[0 ] == ' g' ? ' edit' : editcmd[1 ] == ' g' ? ' tabedit' : ' split'
80114 var files : list <string> = getcompletion ($ ' colors/{colo}' , ' runtime' )
81115 - >map ((_, fname: string ) = > fname- >findfile (&rtp )- >fnamemodify (' :p' ))
82116 - >filter ((_, path : string ): bool = > filereadable (path ))
83117 if empty (files )
84118 echo ' Could not find any colorscheme file for ' .. string (colo )
85119 return
86120 endif
87- files - >Open (split )
121+ files - >Open (editcmd )
88122 endif
89123enddef
90124
@@ -136,27 +170,34 @@ def HandleImportLine(editcmd: string, curline: string) #{{{2
136170 execute how_to_split .. ' ' .. filepath
137171enddef
138172
139- def Open (what: any, how: string ) #{{{2
173+ def Open (target: any, editcmd: string , search_pattern: string = ' ' ) #{{{2
174+ var split : string = editcmd[0 ] == ' g' ? ' edit' : editcmd[1 ] == ' g' ? ' tabedit' : ' split'
140175 var fname: string
141- if what- >typename () == ' list<string>'
142- if what- >empty ()
176+ var cmd: string
177+
178+ if target- >typename () == ' list<string>'
179+ if target- >empty ()
143180 return
144181 endif
145- fname = what [0 ]
182+ fname = target [0 ]
146183 else
147- if what - >typename () != ' string'
184+ if target - >typename () != ' string'
148185 return
149186 endif
150- fname = what
187+ fname = target
151188 endif
152189
153- execute $ ' {how} {fname}'
154- cursor (1 , 1 )
190+ if search_pattern != ' '
191+ var escaped_pattern = escape (search_pattern, ' \#'' ' )
192+ cmd = $ ' +silent\ call\ search('' {escaped_pattern}'' )'
193+ endif
194+
195+ execute $ ' {split} {cmd} {fname}'
155196
156197 # If there are several files to open , put them into an arglist.
157- if what - >typename () == ' list<string>'
158- && what - >len () > 1
159- var arglist: list <string> = what
198+ if target - >typename () == ' list<string>'
199+ && target - >len () > 1
200+ var arglist: list <string> = target
160201 - >copy ()
161202 - >map ((_, f : string ) = > f - >fnameescape ())
162203 execute $ ' arglocal {arglist->join()}'
@@ -170,4 +211,26 @@ def Error(msg: string) #{{{2
170211 echohl NONE
171212enddef
172213
214+ def Fallback (editcmd: string ) #{{{2
215+ try
216+ execute ' normal! ' .. editcmd .. ' zv'
217+ catch
218+ Error (v: exception )
219+ endtry
220+ enddef
221+
222+ def FindCurfunc (): string #{{{2
223+ var curfunc = ' '
224+ var saved_iskeyword = &iskeyword
225+
226+ try
227+ set iskeyword += #
228+ curfunc = expand (' <cword>' )
229+ finally
230+ &iskeyword = saved_iskeyword
231+ endtry
232+
233+ return curfunc
234+ enddef
235+
173236# vim: sw = 4 et
0 commit comments