Skip to content

Commit 1acbcbc

Browse files
AndrewRadevdkearns
authored andcommitted
runtime(vimgoto): Implement jumping to autoloaded functions
Also refactor the script slightly. closes: #18193 Co-authored-by: dkearns <dougkearns@gmail.com> Signed-off-by: Andrew Radev <andrey.radev@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent 9a6cafd commit 1acbcbc

1 file changed

Lines changed: 94 additions & 31 deletions

File tree

runtime/autoload/vimgoto.vim

Lines changed: 94 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ vim9script
33
# Language: Vim9 script
44
# Contributers: @lacygoill
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
65105
enddef
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
89123
enddef
90124

@@ -136,27 +170,34 @@ def HandleImportLine(editcmd: string, curline: string) #{{{2
136170
execute how_to_split .. ' ' .. filepath
137171
enddef
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
171212
enddef
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

Comments
 (0)