Reply to message «Re: How to mimic vim assignment in vimscript?», 
sent 14:26:41 10 January 2011, Monday
by Marc Weber:

> or the like. However be careful: eval can run arbitrary code. I don't
> know about a "safe" way to do this without writing a parser or looking
> for an existing one.
If you are going to look onto a parser, I can suggest my own jsonvim and 
yamlvim 
parsers: first is used to parse json (which is much similar to vimscript), 
second parses yaml (which is superset of json). In the first case the code will 
look like this:

    function! ParseVars()
        let s:j=load#LoadFuncdict("json")
        let lastline=line('$')
        let curline=1
        let toparse=[]
        let prevwasmatch=0
        while curline<=lastline
            let linestr=getline(curline)
            let match=matchlist(linestr, '\([a-zA-Z]\w*\)\s*=\s*\(.*\)$')
            if !empty(match)
                call add(toparse, [match[1], match[2]])
                let prevwasmatch=1
            elseif linestr=~'^\s*\\' && prevwasmatch
                let toparse[-1][1].=matchstr(linestr, '\\\zs.*')
            else
                let prevwasmatch=0
            endif
            let curline+=1
        endwhile
        for [varname, varstr] in toparse
            let b:{varname}=s:j.loads(varstr)
        endfor
    endfunction

Replacing "json" with "yaml" here is enough to switch to yaml parser, which 
have 
the following advantage: it will parse the incorrect vim variable assignment
    a = [[1:"foo"], [2:"bar"]]
as
    a=[[{'1': 'foo'}], [{'2': 'bar'}]]
(complaining about converting number to string, you may ignore these messages 
or 
even add `silent' before ``let b:{varname}''), while json parser will fail 
(because this code is incorrect). Using these parsers should be safe enough.

Original message:
> Excerpts from Yue Wu's message of Mon Jan 10 12:21:30 +0100 2011:
> > Hi, list,
> > 
> > I'm writing a vim script, in which I want to support buffer defined
> > vars in two patterns, say, user can put the following lines into a
> > 
> > file:
> >     a = [[1:"foo"],[2:"bar"]]
> 
> The most simple way is:
> 
> call map(filter(getlines(0,line('$')), 'match your var assignment here
> v:val =~ 'regex'"), 'eval(v:val)') (untested)
> 
> or the like. However be careful: eval can run arbitrary code. I don't
> know about a "safe" way to do this without writing a parser or looking
> for an existing one.
> 
> Marc Weber

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to