1

Commands in VIM can be prefixed with numbers, but the numbering scheme is not consistent for some operations.

Prefixing the movement commands left, down, up, and right (H, J, K, L) with a number results in the cursor jumping to the expected location, e.g. 1L will move one character to the right.

The current line can be moved up or down using :m+N or :m-N, however, you have have to use :m-2 to get the opposite effect of :m+1.

I'm also using VSVim in Visual Studio 2019 and I'm using the gt and gT commands to switch between tabs. If I have three tabs open and I'm currently on the first tab (the left most) using 3gt will switch to the third tab. If I'm on the third tab (the right-most), then 2gT will switch back to the first tab whereas 3gT results in staying on the same tab.

Why do different numbers have to be used to achieve opposite effects? Is this possibly a design flaw that was just never changed?

1 Answer 1

1

Your observation that there are inconsistencies there is accurate.

While the {count} is used most often to repeat an action, that's not always the case. Sometimes it is taken as an absolute number, for example, 47G to go to line 47, 35| to go to column 35 on the current line, or 90% to go to a line 90% into the file.

Sometimes, it is just used to flag different flavors of the same command. For example, CTRL-G will print information about the file opened in the current buffer. 1 CTRL-G will print that information, but show the full path to the file. 2 CTRL-G (or any larger count number) will print the same, and also include the number of the buffer in the output. (See :help CTRL-G for details.)

Addressing your specific examples:

Prefixing the movement commands left, down, up, and right (hjkl) with a number results in the cursor jumping to the expected location, e.g. 1l will move one character to the right.

This is the typical use of {count}, as a repeat of the command.

The current line can be moved up or down using :m +N or :m -N, however, you have have to use :m -2 to get the opposite effect of :m +1.

First, this is not really a {count}, but an {address}. This one is actually consistent (even if you might find odd at a first look.) The :m command will move the current line below the line specified by the address.

If you're on line 47, you would use :m 48 to have it moved below the following line. Since the current line is moved, the one that used to be 48 is now 47, and the current line is 48. If you now want it back to the original location, you need :m 46, since it goes below the line with the address. +1 is simply a shortcut to 48 (starting at line 47), and -2 is just a shorthand for 46 (while now on line 48.) Makes sense, right?

If Vim had decided to move the line above the address if the address precedes it, then the behavior a command such as :m 46 would depend on whether the current line was above or below it and that wouldn't be great. So Vim decided consistency on this factor was more important.

I'm using the gt and gT commands to switch between tabs. If I have three tabs open and I'm currently on the first tab (the left most) using 3gt will switch to the third tab. If I'm on the third tab (the right-most), then 2gT will switch back to the first tab whereas 3gT results in staying on the same tab.

Yes, this one is indeed inconsistent, but there's a reason for it.

While implementing tabs, Vim authors decided it was more important to have a quick way to switch to tab "N" rather than skipping "N" tabs. It's rare that you'd need to do the latter. So they decided to use the {count} as an absolute tab number for the gt command.

On the other hand, there's not much need for the gT command to implement the same behavior (you already had an easier keystroke for that), so the repeat meaning of {count} was left there, so if anyone would like to skip "N" tabs, that command might help...

Note that, this way, it's possible to have the three commands (next tab, previous tab, go to tab "N") while only taking two commands, gt and gT, and having fewer commands is somewhat important, since Vim already has too many of them for us to remember! 😁

Note also that this behavior is fully documented in :help gt and :help gT:

{count}gt: Go to tab page {count}. The first tab page has number one.

{count}gT: Go {count} tab pages back. Wraps around from the first one to the last one. Note that the use of {count} is different from :tabnext, where it is used as the tab page number.

Note also that you can use :tabnext +2 to skip two tabs forward, and that if you prefer that kind of behavior in gt, you could write a mapping to make it behave that way (at least in Vim, not sure about VS Code.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .