I know it's not a bug, since the help page explains it cleary, but is there any reason why gt is still kept different from the majority of commands that accept a {count} prepended? I mean, isn't it in contrast with vi(m) phylosophy?

What annoys me the most is that gt and gT are not the opposite of each other when a {count} is prepended (unlike many others, e.g. n and N, w and W, and so on), so, for instance, I can't "undo" a 2gT by typing 2gt.


I can't really explain why it works like this, my best guess is that you more often need to go a tab by its index rather than going 3 tabs forwards.

However, if you really don't like how Vim works and want to be able to "undo" a 2gT with 2gt you can add the following to your vimrc:

function! Mygt(forward, count)
    let loop = a:count
    while loop > 0
        if a:forward
            normal! gt
            normal! gT
        let loop = loop -1

nnoremap <silent> gt :<C-U>execute "call Mygt(1, " . v:count1 . ")"<CR>
nnoremap <silent> gT :<C-U>execute "call Mygt(0, " . v:count1 . ")"<CR>

The function Mygt() is pretty straightforward: it takes 2 arguments, the first one is used to define if you want to go forward or backward in the list of tabs and the second one is how many tabs you want to skip. So it loops on the given count and repeats gt or gT according to the first parameter.

You can try it with :call Mygt(1, 2) or :call Mygt(0, 4)

To make it easier to use, we also remap gt and gT:

  • <silent> is used to avoid prompting the function called by the mapping. (see :h :map-<silent>)
  • <C-u> is used to remove characters on the command line, it is used to allow a count to the mapping (see :h c_CTRL-U)
  • We build the string which will contain the command to execute (e.g. call Mygt(1, 3) and execute it with execute (see :h execute())
  • And finally, we use the count given to the mapping with v:count1 which will default to 1 if no count is given. (see :h v:count and :h v:count1)

All of this allows us to use gt, gT, 3gt and 5gT and get a "consistent" behavior.

| improve this answer | |
  • Very nice solution! There's one thing I can't get: why have you written a function that overrides gT as well? It works like that already, it is gt the "misbehaving" one (at least imho). – Enrico Jul 25 '18 at 18:47
  • 2
    It has been discussed previously. It is probably an oversight. Now Bram does not feel like changing it to not break compatibility. So we would need a new command. It never bothered me to create a new command. – Christian Brabandt Jul 25 '18 at 20:08
  • 1
    I don't think this extreme and no-matter-what care about backward compatibility will take us to the promised keyboard... Anyway, accepted answer, @statox! – Enrico Jul 26 '18 at 6:30
  • 1
    that is your opinion. Other people might feel differently, if we change the semantics of a well-known command now. So he certainly has a point there. – Christian Brabandt Jul 26 '18 at 8:54
  • 1
    I would certainly hate it. I use a customized tab string that displays the tab number in the tab title and it's much easier to glance up and see the tab number than it is to look up and count how many tabs I want to jump forwards or backwards. To my mind, this works very similar to {count}G jumping to a specific line number. tabline is here: vim.wikia.com/wiki/Show_tab_number_in_your_tab_line – Dan J. Jul 26 '18 at 11:46

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.