5

How can I use a variable when mapping keys in vim? The specific problem that I am trying to solve is the following. I need these key mappings:

nnoremap <C-1> 1gt
nnoremap <C-2> 2gt
nnoremap <C-3> 3gt

... and so on.

Can I specify one mapping; something like

nnoremap <C-x> xgt

where x takes the value of the key pressed (which can be from 1..9)

Thank you.

Edit 1: Towards the solution (not yet complete) thanks to Peter Rincker

I can use the function

function gotoTab(num)
   execute "normal" a:num."gt"
endfunction

If I :call goToTab(3), it goes to tab 3.

How do I map Command-x (D-x) to goToTab(x) where x is between 1..9. How do I read the number from a Command-x press?

Curious2learn
  • 31,692
  • 43
  • 108
  • 125

1 Answers1

6

I got bad news. You can not map <c-1>, etc. You can only bind <c-6> which I wouldn't do as it is very handy.

It also seems like you are doing a heavily tab centric workflow. I know it might sound weird but maybe use less tab panes and more buffers. Here are some nice posts about it:

... Ok, but I really want to do this variable mapping thing. You have options:

  • Use a for loop and use :execute to create mappings
  • The more Vim Way is to use a count so 7gt. The 7 is the count.

Example of using :for and :execute:

for i in range(1, 9)
  execute "nnoremap \<d-" . i . "> " . i . "gt"
endfor

Note: this uses <d-...> syntax for Command which is only available on MacVim and no terminal support (See :h <D-). You can use <a-...> for Alt. However I must warn you using Alt on the terminal can be tricky.

For more help see:

:h keycodes
:h map-which-keys
:h :for
:h :exe
:h count
:h v:count
:h range(
Community
  • 1
  • 1
Peter Rincker
  • 43,539
  • 9
  • 74
  • 101
  • Thanks for the information about buffers. I am new to vim and was not even aware of them. While I will read and look up on buffers, just for the purpose of learning Vim I want to try and implement the above (say with the command key instead of the control key). Please see my edited message above. I am one step closer to the solution due to your other pointers. Can you or someone help me with the next step (or the solution). Thanks! – Curious2learn Nov 11 '14 at 00:31
  • Maybe try using alt-mappings instead of ctrl-mappings, then. I'd go with the for loop. – Ben Nov 11 '14 at 01:12
  • @Ben How do I read the number (whether Alt or Command) as an input to the loop or to a function call? Would love an example. I think for-loop will not work since it will start counting from the current tab. That is not what say 2gt does. Thank you. – Curious2learn Nov 11 '14 at 01:30
  • Looks like an example got added. It will *not* start counting from the current tab, and that is *not* what `2gt` will do anyway. `2gt` will always go to the 2nd tab page, starting from the leftmost tab, regardless of what tab you're on. – Ben Nov 11 '14 at 12:12
  • If you want this to count from the current tab you can use the expression register. Change your `:execute` line look like so: `execute "nnoremap \ " . i . "@='gt'\"`. For more information see `:h @`, `:h @=`, and this [Vimcast](http://vimcasts.org/) episode: [Creating mappings that accept a count](http://vimcasts.org/episodes/creating-mappings-that-accept-a-count/) – Peter Rincker Nov 11 '14 at 14:10
  • @Ben I had misunderstood the for-loop. I knew what `2gt` does, but thought that for-loop counts from the current tab. – Curious2learn Nov 12 '14 at 02:10
  • @PeterRincker Thanks again for the example. BTW, I am liking the buffer way. Thanks for pointing that out. However, it was still useful to learn how to write a command like this. – Curious2learn Nov 12 '14 at 02:12