0

I used a certain editor for many years and got used to selecting words with Alt+Return. I can't lose that habit and still try to do that in Vim too often, always without success.

So I try these:

noremap     <M-Return>  viw
noremap     <C-Return>  viw

You see, I am trying both, Alt+Return and Ctrl+Return. But neither works.

This works:

noremap     <C-M>   viw

I press Ctrl+m and the word is selected. But it comes with a strange side effect: Return/Enter alone also selects words! And I don't want that.

So it's a double question:

1) How can I make Alt+Enter select the current word (under cursor)?

2) Why does Return/Enter act like Ctrl+m?

3 Answers 3

2

Due to the way that the keyboard input is handled internally, this unfortunately isn't generally possible today, even in GVIM. Some key combinations, like Ctrl + non-alphabetic cannot be mapped, and Ctrl + letter vs. Ctrl + Shift + letter cannot be distinguished. (Unless your terminal sends a distinct termcap code for it, which most don't.) In insert or command-line mode, try typing the key combination. If nothing happens / is inserted, you cannot use that key combination. This also applies to <Tab> / <C-I>, <CR> / <C-M> / <Esc> / <C-[> etc. (Only exception is <BS> / <C-H>.) This is a known pain point, and the subject of various discussions on vim_dev and the #vim IRC channel.

Some people (foremost Paul LeoNerd Evans) want to fix that (even for console Vim in terminals that support this), and have floated various proposals, cp. http://groups.google.com/group/vim_dev/browse_thread/thread/626e83fa4588b32a/bfbcb22f37a8a1f8

But as of today, no patches or volunteers have yet come forward, though many have expressed a desire to have this in a future Vim 8 major release.

3

The solution would depend on your terminal and how it's set up. Unix terminals generally send a meta character or sequence when you hold Alt and press another key. There are two traditional ways of sending meta characters to terminal programs:

  1. Take the ASCII value of the other key pressed (i.e. the one that's not Alt) and OR it with 128 (setting bit 7 high). This is discouraged these days because the resulting 8-bit character code isn't compatible with UTF-8 or even 8-bit encodings like Latin-1.

  2. Send an escape character, ASCII 27, and then the ASCII code for the other key. This works well with a variety of encodings, but it can complicate the handling of cases where you actually meant to send an explicit escape character, e.g. when you hit Esc in Vim.

If your terminal is set to use #2, you might be tempted to do noremap <Esc><CR> viw. However, this will make Vim pause any time it receives an escape. To avoid this, you can set an <A-CR> key code and use that in the map; this makes it so that Vim can treat the sequence as different from an escape+character sequence (in particular, the sequence can have a timeout that's much shorter than the one used by other mappings; since terminals send the escape character and the following character almost simultaneously, this can guard against accidentally triggering a key code when you're not trying to).

The set command itself interprets strings like <Esc> literally (i.e. doesn't convert that into ASCII 27), so you have to wrap it in an exec:

exec "set <A-CR>=\<Esc>\<CR>"

After that, you can finally do a mapping:

noremap <A-CR> viw

You probably also want to set a very short ttimeoutlen so you don't accidentally trigger this new mapping with EscReturn, e.g.

:set timeout timeoutlen=3000 ttimeoutlen=100

would make "normal" mappings wait a full 3 seconds between keys but key code mappings only a tenth of a second.

References:

  1. :h :set-termcap
  2. :h :map-alt-keys
  3. :h 'ttimeout'
1

Open a terminal or put yourself in insert mode in vim and then press <c-v>Return and you will see why your <C-M> binding has that effect.

That should also explain to you why you can't bind <C-Return> or <M-Return> in console vim (you might be able to in gvim but I'm not sure).

6
  • Ok, Ctrl+m is the same as Enter. That part of the mystery is solved.
    – user223557
    Jul 10, 2013 at 18:01
  • That solves both parts if you think about it. If <Enter> is <C-M> then what would <C-Enter> be? Or <M-Enter>? Like I said, gvim might be able to bind these because it has additional keypress/etc. detection capabilities (though whether this key falls into the set that gvim can handle but vim can't I'm not sure). Jul 10, 2013 at 18:03
  • I don't use gvim, ever.
    – user223557
    Jul 10, 2013 at 18:18
  • So you're saying it's not possible?
    – user223557
    Jul 10, 2013 at 18:27
  • In console vim? I don't believe it is possible. I don't believe that is a generally representable key sequence. Current versions of xterm can represent it I believe but vim cannot use that representation format. Jul 10, 2013 at 18:28

You must log in to answer this question.