ritchie
ritchie

Reputation: 455

How do I pass a visual range to a function without numbers or using :command in vim?

How do I pass a visual selection to a function from a script and NOT command line / mapping. I was wondering if something like this was possible? Or if there is a function that gets a range ?

What I want:

:call LowerToUpper('<,'>)
:call LowerToUpper(GetVisualRange())

NOT THIS

:call LowerToUpper(1,5)
command! -range Edit call LowerToUpper(<line1>,<line2>)
:'<,'>LowerToUpper

Here is the function example:

function! LowerToUpper(first,last) abort
for lineno in range(a:first,a:last)
    let line = getline(lineno) 
    let newLine= substitute(line, '\v(\w)','\U\1','g')
    call setline(lineno,newLine)
endfor
endfunction

The solution might be a hack to make a function that returns the visual selection GetVisualSelection().

Upvotes: 3

Views: 381

Answers (2)

Matt
Matt

Reputation: 15186

You can have your function with range modifier.

function! LowerToUpper() abort range
    for lineno in range(a:firstline, a:lastline)
        let line = getline(lineno)
        let newLine = substitute(line, '\v(\w)','\U\1','g')
        call setline(lineno, newLine)
    endfor
endfunction

'<,'>call LowerToUpper()

This mostly serves as a shortcut for passing line("'<") and line("'>") implicitly. The argument names a:firstline and a:lastline are fixed.

Upvotes: 1

phd
phd

Reputation: 94676

:call LowerToUpper('<,'>)

You're very very close. Use line() to get lines of the marks:

:call LowerToUpper(line("'<"), line("'>"))

Upvotes: 2

Related Questions