2

I've looked around in :help V but haven't found anything of this sort, but was wondering if there's a function I can call from vimscript that would visually select a region based on (row, column) coordinate pairs.

For example, I could call it with (1,1),(2,3) to visually select the rectangle with the top left corner at row 1, column 1, and bottom right corner at row 2, column 3.

Does such a function exist?

4
  • 2
    You first need to set the visual type manually using e.g. exe "norm! \<c-v>\<esc>" for visual block mode. Then you can set the marks '<, '> manually using setpos(). Then use gv May 23, 2019 at 5:51
  • 1
    Following @ChristianBrabandt idea you could write it like this it seems to be working very well!
    – statox
    May 23, 2019 at 9:50
  • @statox, I am using this technique for my NrrwRgn plugin. May 23, 2019 at 12:03
  • @ChristianBrabandt So that's an already tested code, great :) You could write an answer, I think it matches pretty well OP's question.
    – statox
    May 23, 2019 at 12:05

3 Answers 3

3

You can do this similarly to how you would do it manually, by using the :normal command:

:normal! 1G1|^V2G3|

The ^V is a CTRL-V character. You can enter this literally by pressing Ctrl-VCtrl-V, but as you’re most likely going to need to build the command as a string anyway so you can use variables for the line/column numbers, using a string escape sequence is cleaner:

:execute "normal! 1G1|\<C-V>2G3|"

In an actual script, I'd probably break it up over a few lines to make it a bit clearer what you're doing:

let select_command = line1 . 'G' . column1 . '|'
let select_command .= "\<C-V>"
let select_command .= line2 . 'G' . column2 . '|'
execute 'normal!' select_command
2

There is no direct function available to create a new block-wise selection. However you can work around it the following way:

1) First you need to set the visual selection type, so that when using gv the selection will be set correctly. You can simply abort it right afterwards, so e.g. use :exe ":norm! \<c-v>\<esc>. This sets block-wise selection and aborts it right afterwards.

2) Since patch 7.3.590 the visual marks '< and '> that define the start and end position of the visual selection are directly settable using setpos().

3) After the marks have been set, you can then use gv to "reselect" the last visual selected area. I have been using this technique in my NrrwRgn plugin ever since that patch has been included (commit) and is has been working well.

0

Based on the answer from @Rich

function MyVertBlock(line1, line2, column1, column2)
let select_command = a:line1 . 'G' . a:column1 . '|'
let select_command .= "\<C-V>"
let select_command .= a:line2 . 'G' . a:column2 . '|'
execute 'normal!' select_command
endfunction

call MyVertBlock(1, 10, 2, 4)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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