Reply to message «How to script a function, which reacts on visual blocks», 
sent 19:50:39 17 January 2011, Monday
by [email protected]:

>  any hint how to script a function, which also evaluate the
>  limits of a visual block.
> 
>  How can I do this?
You may find example under `:h g@' useful to accomplish this task. Here is how 
I 
may have written function that reverses order of characters in selection:

    function! OperatorFunc(type)
        let savedselection=&selection
        try
            let [startline, endline]=[line("'["), line("']")]
            if startline>endline
                let [endline, startline]=[startline, endline]
            endif
            if a:type==#'line'
                call setline(startline, map(range(startline, endline),
                           \'join(reverse(split(getline(v:val), "\\zs")), "")'))
            elseif a:type==#'block'
                let savedureg=@"
                try
                    let [startvcol, endvcol]=[virtcol("'["), virtcol("']")]
                    for line in range(startline, endline)
                        execute line
                        execute "normal! ".startvcol."|v".endvcol."|d"
                        execute "normal! i".join(reverse(split(@", '\zs')), "")
                    endfor
                finally
                    let @"=savedureg
                endtry
            else " if a:type==#"char"
                let savedureg=@"
                try
                    execute "normal! `[v`]d"
                    execute "normal! i".join(reverse(split(@", '\zs')), "")
                finally
                    let @"=savedureg
                endtry
            endif
        finally
            let &selection=savedselection
        endtry
    endfunction
    function! SetOpfunc()
        set operatorfunc=OperatorFunc
        return "g@"
    endfunction
    nnoremap <expr> ,i SetOpfunc()
    vnoremap <expr> ,i SetOpfunc()
List of differencies between this function and example (excluding the fact that 
they do different things):
1. Using <expr> mapping made me able not to write different mapping for visual 
mode: the main problem is that entering command mode to set operatorfunction 
like in example disables visual mode, but using SetOpfunc does not.
2. `nnoremap' and `vnoremap': you must use it when possible. Prevents problems 
which may occur if you have tons of mappings.
3. Using `try ... finally' to restore saved values: it handles case when user 
interrupts your function before it proceed to the code that restores them.

Note that `exe "normal! i".text' is a quick and dirty solution which will break 
if text contains special characters.

Original message:
> WARNING! VIM_SCRIPTING_NEWBIE AHEAD!
> 
> Hi,
> 
>  A few day before I have started to learn to script vim.
>  I think, I understand to write "func! fun() range"-functions,
>  which react on ranges, but I didnt find ( =! "there is no" ;)
>  any hint how to script a function, which also evaluate the
>  limits of a visual block.
> 
>  How can I do this?
> 
>  Thank you very much for any help in advance!
>  Best regards,
>  mcc

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

Reply via email to