I've got a problem that I've already solved on the X-server level (BTW: I'm running Ubuntu 12.04) but not in GVim.
I have a German keyboard layout with the letters ö and ä where [ and ] are on a qwerty keyboard. But now I want to change vim's normal mode mappings so I can type ö and Ctrl+ö as if it were [ and CTRL+[, respectively. So I created an xmodmap file and mapped Ctrl+ö to CTRL+[. Now the xserver exhibits the right response (e.g. when I map Ctrl+ö to Ctrl+u I can erase the current line in xterm).
But somehow this doesn't work in gVim, and as far as I understand the gVim help it handles escape sequences like Ctrl+something in a special way (e.g. Ctrl+ö in insert mode yields a plain ö in contrast to the behavior in xterm). But I don't understand how to solve this. Can anyone help me?
EDIT:
I've noticed that it does work when I run Vim in my terminal emulator (which is guake), but not in GVim (which I want to get working).
If I understand you correctly try to use the langmap option like this:
:set langmap=ö[,ä]
Related
Is it possible for the terminal to detect ⇧ Shift+Enter↵ or Ctrl+Enter↵ keypresses?
I am trying to configure vim to do key mappings that use these sequences, and while they work fine in gvim, they don't seem to work in any terminal console.
The curious thing is that although Ctrl+Enter↵ is not detected in vim, mapping Enter↵ to Esc maps properly, but then pressing Ctrl+Enter↵ behaves like Enter↵!
Some terminals send <NL> when <C-Enter> is pressed. This is equivalent to sending <C-J>.
To find out what your terminal does with <Shift-Enter>, <Ctrl-Enter> and <Enter>, go to your terminal, type <Ctrl-V> (similar to sykora's suggestion for vim), and type in the sequence you're interested in.
Using gnome-terminal, I get the following:
<Enter> : ^M
<S-Enter> : ^M
<C-Enter> : <NL>
Looking at man ascii indicates that ^M gives the <CR> sequence.
The answer is that it depends on the terminal, and there's an easy way to check.
Gvim runs its own manager for keystroke handling and so can pick up all the various key combinations. Vim is reliant on the specific terminal for passing on the particular keypress, so keyhandling is only as good or varied as the terminal is.
One way you can find out whether you can do what you want to do is to use the key to find out what is inserted. eg Type:
:<C-V><C-Enter>
ie actually type in the combination you want to press after having typed the combination Control-V. After that do the same thing for enter, ie
:<C-V><Enter>
If they yield the same code, then the terminal interprets both key combinations as the same keycode, and you can't bind them without messing with the terminal.
In my terminal (urxvt), Control-Enter, Shift-Enter and Enter (by itself) all produce the ^M character, meaning I can't map one without mapping the other. The same goes for Control-Tab and Control-I, and Control-Space and Control-#
EDIT: Use C-Q instead of C-V for Windows.
I'm running Vim on a gnome terminal. But the alt key mappings are not working. For example:
:imap <A-i> <Esc>
It works fine in GVim. But when I run the same command with Vim in the gnome terminal it does nothing.
I'm using Windows 7, The problem is with the terminal, right?
The problem
There are two ways for a terminal emulator to send an Alt key (usually called a Meta key as actual terminals didn't have Alt). It can either send 8 bit characters and set the high bit when Alt is used, or it can use escape sequences, sending Alt-a as <Esc>a. Vim expects to see the 8 bit encoding rather than the escape sequence.
Some terminal emulators such as xterm can be set to use either mode, but Gnome terminal doesn't offer any such setting. To be honest in these days of Unicode editing, the 8-bit encoding is not such a good idea anyway. But escape sequences are not problem free either; they offer no way of distinguishing between <Esc>j meaning Alt-j vs pressing Esc followed by j.
In earlier terminal use, typing Escj was another way to send a Meta on a keyboard without a Meta key, but this doesn't fit well with vi's use of Esc to leave insert mode.
The solution
It is possible to work around this by configuring vim to map the escape sequences to their Alt combinations.
Add this to your .vimrc:
let c='a'
while c <= 'z'
exec "set <A-".c.">=\e".c
exec "imap \e".c." <A-".c.">"
let c = nr2char(1+char2nr(c))
endw
set timeout ttimeoutlen=50
Alt-letter will now be recognised by vi in a terminal as well as by gvim. The timeout settings are used to work around the ambiguity with escape sequences. Esc and j sent within 50ms will be mapped to <A-j>, greater than 50ms will count as separate keys. That should be enough time to distinguish between Meta encoding and hitting two keys.
If you don't like having timout set, which times out for other mapped key sequences (after a second by default), then you can use ttimeout instead. ttimeout applies only to key codes and not other mappings.
set ttimeout ttimeoutlen=50
For Gnome-terminal, use the following instead:
imap ^[i <Esc>
^[i should be typed by pressing Ctrl-v Alt-i
Attention: You need to yank and put in Vim when you want to copy it elsewhere. If you just copy the mapping in an editor like gedit, the mapping will probably be broken.
EDIT here is an example which makes Alt-k add an empty line above the cursor, and Alt-j add an empty line after the current line.
" Alt-j/k to add a blank line
if has('gui_running')
" the following two lines do not work in vim, but work in Gvim
nnoremap <silent><A-j> :set paste<CR>m`o<Esc>``:set nopaste<CR>
nnoremap <silent><A-k> :set paste<CR>m`O<Esc>``:set nopaste<CR>
else
" these two work in vim
" shrtcut with alt key: press Ctrl-v then Alt-k
" ATTENTION: the following two lines should not be
" edited under other editors like gedit. ^[k and ^[j will be broken!
nnoremap ^[k :set paste<CR>m`O<Esc>``:set nopaste<CR>
nnoremap ^[j :set paste<CR>m`o<Esc>``:set nopaste<CR>
endif
Try
<m-i>
Or, if typing alti inserts a character (like in my case, it inserts a carret: ˆ) just map to that character:
:inoremap ˆ <esc>
Be careful, because this one wouldn't work (at least in my system, MacOS 10.6). The caret waits for a letter, because it's not exactly a caret, it is a circumflex.
It may be that the shortcuts are actually from the Gnome Desktop. Try looking at the Gnome Keyboard Shortcuts tool (System menu, Preferences, Keyboard Shortcuts), which lets you view and modify the shortcuts defined on Gnome Desktop. If the key combination is assigned to a function on Gnome Desktop, then remove it and then that key combo should filter down to Vim properly.
Or you may be right that it is a problem of the terminal. Not all terminals support all key combos. Your problem may be the one described in the Vim help docs at :h map-alt-keys. The docs provide a workaround, but not a very good one.
The same thing happens to me. I searched on Google with "gnome terminal alt key", and found that someone asked almost the same question: "How to disable the alt-hotkey behavior on gnome terminal?" in the first link found. (The second link is just this question)
So, maybe you can try that:
Edit > Keyboard Shortcuts, and uncheck "Enable menu access keys"
Take a look at section 1.10 of http://vimdoc.sourceforge.net/htmldoc/map.html. It seems to indicate that gnome-terminal automatically escapes the Alt modifier, so that it doesn't switch the byte sent in the way that Vim is expecting. The document seems to indicate that there isn't really a way around this except for using a different terminal (such as xterm).
This is certainly frustrating because so far as I can tell Linux machines are also incapable of using the D (Mac's Command or Linux's Super) bindings, so at least as far as the terminal goes, we are limited to Shift and Ctrl modifiers, which is frustrating if we want to ensure that we can use all the commands we use in Gvim on terminal Vim (at least without switching terminals, towards which I'm perhaps overly stubborn - gnome-terminal is just so much prettier). I've been looking for a way around this but have been unable to find anything.
Okay, so I've been trying out Vim (the standard console version; my OS is Linux Mint 13) and I'd like to get rid of having to use the Escape key to change modes. Preferably, I'd like to swap the Capslock and Escape keys, but as far as I've heard, that's not possible within Vim itself. Most "solutions" I've found involve changing the key on a global level (using xmodmap or whatever), but I don't really want that. If there's an easy way to swap Capslock and Escape only in Vim, please let me know.
Another common thing I've heard of is using "Ctrl-[" as an equivalent to Escape. However, because I'm using a German keyboard with a different layout, that's not an option. So, I thought I'd use noremap <C-ü> <Esc> in Vim (the "ü" key on a German keyboard is in the same place as the "[" key on US keyboards), but that didn't work, either. I'm assuming that's because "ü" isn't an ASCII character. Is there any way to get either of these options working?
UPDATE: Well, this is strange. After experimenting some more, it seems that "Ctrl-ü" does work after all. I'm not sure what happened – maybe I messed up some encoding-related settings while trying different things? If there is no good solution for remapping capslock, I guess I will stick with "Ctrl-ü".
So, yeah, eventually I decided to go with <C-ü> because it doesn't conflict with anything else and because it's the same as <C-[> on US keyboards.
However, because I'm getting tired of using the German keyboard layout for programming (for example, to get "{" you need to type "Alt Gr-7"), I'm switching my keyboard to US-International, which essentially has a similar effect as far as Vim is concerned. It also helps if you want to want to get into the habit of touch-typing; you actually can't look at the keyboard because the keys aren't labeled "correctly" ;-)
A lot of people use jk:
inoremap jk <Esc>
You can also simply do <C-c>.
Here is another alternative that may be useful to you! It involves changing the keyboard file related to VIM. I found this suggestion on this youtube video
$ cd /usr/share/X11/xkb/symbols/
sudo vim pc
to edit the capslock key to escape, change the capslock line to read as follows:
key <CAPS> { [ Escape ] };
:wq # to write and close the file
Log out and log back into the machine and it should be updated!
I'm running Vim on a gnome terminal. But the alt key mappings are not working. For example:
:imap <A-i> <Esc>
It works fine in GVim. But when I run the same command with Vim in the gnome terminal it does nothing.
I'm using Windows 7, The problem is with the terminal, right?
The problem
There are two ways for a terminal emulator to send an Alt key (usually called a Meta key as actual terminals didn't have Alt). It can either send 8 bit characters and set the high bit when Alt is used, or it can use escape sequences, sending Alt-a as <Esc>a. Vim expects to see the 8 bit encoding rather than the escape sequence.
Some terminal emulators such as xterm can be set to use either mode, but Gnome terminal doesn't offer any such setting. To be honest in these days of Unicode editing, the 8-bit encoding is not such a good idea anyway. But escape sequences are not problem free either; they offer no way of distinguishing between <Esc>j meaning Alt-j vs pressing Esc followed by j.
In earlier terminal use, typing Escj was another way to send a Meta on a keyboard without a Meta key, but this doesn't fit well with vi's use of Esc to leave insert mode.
The solution
It is possible to work around this by configuring vim to map the escape sequences to their Alt combinations.
Add this to your .vimrc:
let c='a'
while c <= 'z'
exec "set <A-".c.">=\e".c
exec "imap \e".c." <A-".c.">"
let c = nr2char(1+char2nr(c))
endw
set timeout ttimeoutlen=50
Alt-letter will now be recognised by vi in a terminal as well as by gvim. The timeout settings are used to work around the ambiguity with escape sequences. Esc and j sent within 50ms will be mapped to <A-j>, greater than 50ms will count as separate keys. That should be enough time to distinguish between Meta encoding and hitting two keys.
If you don't like having timout set, which times out for other mapped key sequences (after a second by default), then you can use ttimeout instead. ttimeout applies only to key codes and not other mappings.
set ttimeout ttimeoutlen=50
For Gnome-terminal, use the following instead:
imap ^[i <Esc>
^[i should be typed by pressing Ctrl-v Alt-i
Attention: You need to yank and put in Vim when you want to copy it elsewhere. If you just copy the mapping in an editor like gedit, the mapping will probably be broken.
EDIT here is an example which makes Alt-k add an empty line above the cursor, and Alt-j add an empty line after the current line.
" Alt-j/k to add a blank line
if has('gui_running')
" the following two lines do not work in vim, but work in Gvim
nnoremap <silent><A-j> :set paste<CR>m`o<Esc>``:set nopaste<CR>
nnoremap <silent><A-k> :set paste<CR>m`O<Esc>``:set nopaste<CR>
else
" these two work in vim
" shrtcut with alt key: press Ctrl-v then Alt-k
" ATTENTION: the following two lines should not be
" edited under other editors like gedit. ^[k and ^[j will be broken!
nnoremap ^[k :set paste<CR>m`O<Esc>``:set nopaste<CR>
nnoremap ^[j :set paste<CR>m`o<Esc>``:set nopaste<CR>
endif
Try
<m-i>
Or, if typing alti inserts a character (like in my case, it inserts a carret: ˆ) just map to that character:
:inoremap ˆ <esc>
Be careful, because this one wouldn't work (at least in my system, MacOS 10.6). The caret waits for a letter, because it's not exactly a caret, it is a circumflex.
It may be that the shortcuts are actually from the Gnome Desktop. Try looking at the Gnome Keyboard Shortcuts tool (System menu, Preferences, Keyboard Shortcuts), which lets you view and modify the shortcuts defined on Gnome Desktop. If the key combination is assigned to a function on Gnome Desktop, then remove it and then that key combo should filter down to Vim properly.
Or you may be right that it is a problem of the terminal. Not all terminals support all key combos. Your problem may be the one described in the Vim help docs at :h map-alt-keys. The docs provide a workaround, but not a very good one.
The same thing happens to me. I searched on Google with "gnome terminal alt key", and found that someone asked almost the same question: "How to disable the alt-hotkey behavior on gnome terminal?" in the first link found. (The second link is just this question)
So, maybe you can try that:
Edit > Keyboard Shortcuts, and uncheck "Enable menu access keys"
Take a look at section 1.10 of http://vimdoc.sourceforge.net/htmldoc/map.html. It seems to indicate that gnome-terminal automatically escapes the Alt modifier, so that it doesn't switch the byte sent in the way that Vim is expecting. The document seems to indicate that there isn't really a way around this except for using a different terminal (such as xterm).
This is certainly frustrating because so far as I can tell Linux machines are also incapable of using the D (Mac's Command or Linux's Super) bindings, so at least as far as the terminal goes, we are limited to Shift and Ctrl modifiers, which is frustrating if we want to ensure that we can use all the commands we use in Gvim on terminal Vim (at least without switching terminals, towards which I'm perhaps overly stubborn - gnome-terminal is just so much prettier). I've been looking for a way around this but have been unable to find anything.
Is it possible for the terminal to detect ⇧ Shift+Enter↵ or Ctrl+Enter↵ keypresses?
I am trying to configure vim to do key mappings that use these sequences, and while they work fine in gvim, they don't seem to work in any terminal console.
The curious thing is that although Ctrl+Enter↵ is not detected in vim, mapping Enter↵ to Esc maps properly, but then pressing Ctrl+Enter↵ behaves like Enter↵!
Some terminals send <NL> when <C-Enter> is pressed. This is equivalent to sending <C-J>.
To find out what your terminal does with <Shift-Enter>, <Ctrl-Enter> and <Enter>, go to your terminal, type <Ctrl-V> (similar to sykora's suggestion for vim), and type in the sequence you're interested in.
Using gnome-terminal, I get the following:
<Enter> : ^M
<S-Enter> : ^M
<C-Enter> : <NL>
Looking at man ascii indicates that ^M gives the <CR> sequence.
The answer is that it depends on the terminal, and there's an easy way to check.
Gvim runs its own manager for keystroke handling and so can pick up all the various key combinations. Vim is reliant on the specific terminal for passing on the particular keypress, so keyhandling is only as good or varied as the terminal is.
One way you can find out whether you can do what you want to do is to use the key to find out what is inserted. eg Type:
:<C-V><C-Enter>
ie actually type in the combination you want to press after having typed the combination Control-V. After that do the same thing for enter, ie
:<C-V><Enter>
If they yield the same code, then the terminal interprets both key combinations as the same keycode, and you can't bind them without messing with the terminal.
In my terminal (urxvt), Control-Enter, Shift-Enter and Enter (by itself) all produce the ^M character, meaning I can't map one without mapping the other. The same goes for Control-Tab and Control-I, and Control-Space and Control-#
EDIT: Use C-Q instead of C-V for Windows.