Get a Vim script's <SNR>
vim
Solution
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")))
Problem
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?