Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to understand these vim scripts

Tags:

vim

I have two question about understand those vim script. please give some help,

Question 1: I download a.vim plugin, and i try to read this plugin, how to understand the below variable definition? the first line I can understand, but the second line, I don't know exactly "g:alternateExtensions_{'aspx.cs'}" means.

" E.g. let g:alternateExtensions_CPP = "inc,h,H,HPP,hpp" 
"      let g:alternateExtensions_{'aspx.cs'} = "aspx"

Question 2: how to understand "SID" before the function name, using like below function definition and function call.

function! <SID>AddAlternateExtensionMapping(extension, alternates)
//omit define body

call <SID>AddAlternateExtensionMapping('h',"c,cpp,cxx,cc,CC")
call <SID>AddAlternateExtensionMapping('H',"C,CPP,CXX,CC")

thanks for you kindly help.

like image 954
gladman Avatar asked May 27 '13 07:05

gladman


2 Answers

let g:alternateExtensions_{'aspx.cs'} = "aspx"

That is an inline expansion of a Vimscript expression into a variable name, a rather obscure feature that is rarely used since Vim version 7. See :help curly-braces-names for details. It is usually used to interpolate a variable, not a string literal like here ('aspx.cs'). Furthermore, this here yields an error, because periods are forbidden in variable names. Newer plugins would use a List or Dictionary variable, but those data types weren't available when a.vim was written.


To avoid polluting the function namespace, plugin-internal functions should be script-local, i.e. have the prefix s:. To invoke these from a mapping, the special <SID> prefix has to be used instead of s:, because <SID> internally gets translated into something that keeps the script's ID, whereas the pure s:, when executed as part of the mapping, has lost its association to the script that defined it.

Some plugin authors don't fully understand this unfortunate and accidental complexity of Vim's scoping implementation either, and they put the <SID> prefix also in front of the function name (which works, too). Though it's slightly more correct and recommended to write it like this:

" Define and invoke script-local function.
function! s:AddAlternateExtensionMapping(extension, alternates)
...
call s:AddAlternateExtensionMapping('h',"c,cpp,cxx,cc,CC")

" Only in a mapping, the special <SID> prefix is actually necessary.
nmap <Leader>a :call <SID>AddAlternateExtensionMapping('h',"c,cpp,cxx,cc,CC")
like image 107
Ingo Karkat Avatar answered Sep 21 '22 13:09

Ingo Karkat


<SID> is explained in :help <SID>:

When defining a function in a script, "s:" can be prepended to the name to
make it local to the script.  But when a mapping is executed from outside of
the script, it doesn't know in which script the function was defined.  To
avoid this problem, use "<SID>" instead of "s:".  The same translation is done
as for mappings.  This makes it possible to define a call to the function in
a mapping.

When a local function is executed, it runs in the context of the script it was
defined in.  This means that new functions and mappings it defines can also
use "s:" or "<SID>" and it will use the same unique number as when the
function itself was defined.  Also, the "s:var" local script variables can be
used.

That number is the one you see on the left when you do :scriptnames, IIRC.

like image 22
romainl Avatar answered Sep 22 '22 13:09

romainl