1

For example, I have the following code

command! -range Test call TestFunc()
function! TestFunc() abort
  " if run with range
  "   get selected content
  " else
  "   get current word under the cursor
  " endif
endfunction

I want to differentiate whether users run :Test or :'<,'>Test.

I've tested mode() function doesn't work here. Also <line1>,<line2> do not help because they always give me the same result(current line number) when I run it with range(select the current line) or not.

I wonder if there are any solutions for this?

  • 1
    Since you mentioned word under the cursor, consider implementing an operator that takes a motion/text object rather than a command that takes a range. The latter is limited to lines only when passed a range. See Grep Operator from "Learn Vimscript the Hard Way" for an example operator. (You might want to consider reading the whole material, it's an excellent resource if you want to master Vimscript.) – filbranden Apr 23 at 5:26
  • 1
    @filbranden Thanks, I'll read it. – voldikss Apr 24 at 1:15
3

A range with commands is always about lines. It seems you want to work with line/column positions.

Whether a range was given can be checked by using <range>:

command! -range Test call TestFunc(<range>,<line1>,<line2>)
function! TestFunc(r,l1,l2) abort
    if a:r == 0
        echo "No range"
    elseif a:r == 1
        echo "Single Line given (like :22Test)"
    else
        echo "Line range given (like 1,23Test, '<,'>Test or %Test)"
    endif
endfunction

Note: You might need to set cmdheight=2 to see the echo in all cases.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.