I'd like to call a function declared with script-scope (s:
) in a sourced Vim script, without hard-coding the %d
in call <SNR>%d_function()
or exposing the function to the global namespace by modifying the plugin file itself. How can I retrieve its parent script's<SNR>
, or script number, programmatically?
You can retrieve a script's <SNR>
by parsing the output of :scriptnames
. The following function will do just that for either the script's full filename, or a fragment of it (as long as it uniquely identifies the one you want).
func! GetScriptNumber(script_name)
" Return the <SNR> of a script.
"
" Args:
" script_name : (str) The name of a sourced script.
"
" Return:
" (int) The <SNR> of the script; if the script isn't found, -1.
redir => scriptnames
silent! scriptnames
redir END
for script in split(l:scriptnames, "\n")
if l:script =~ a:script_name
return str2nr(split(l:script, ":")[0])
endif
endfor
return -1
endfunc
If you need to, for instance, call a function foo
defined with s:
in a script named bar.vim
, you can use:
call eval(printf("<SNR>%d_foo()", GetScriptNumber("bar.vim")))
There is also a Vim plugin scriptease which provides a command :Scriptnames
to show all the loaded script in their order of loading in a quickfix window. The script number is the integer behind the script path. It is easy to find the script you want then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With