When I run Vim inside Tmux, I have to press the tab key two times to get the keypress registered. I googled around for a while, to no avail, and I don't h ave this problem when I use Vim outside of Tmux. Is the tab key reserved for something I'm not aware of?
How do I fix this?
I haven't really configured anything in tmux besides remapping C-b to C-i.
set -g prefix C-i
unbind C-b
bind C-i send-prefix
While Tab and the Control-i are usually distinguished in GUI environment, they generate the same character in tty-based environments like terminal emulators. That character is U+0009, which is the Tab control character. It is represented as the single byte 0x09 in ASCII, UTF-8 and many other encodings. All of the “C0 control codes” (ASCII 0-31) have keyboard equivalents that combine the Control key with another key (mostly letters, but also some symbols). The Tab control character is generated by Control-i.
You can verify that (at least) tmux considers C-i and Tab to be the same by looking at the output of tmux show-options -g | grep prefix. You will see it has set your prefix to the key named Tab, even though you specified it as C-i in your configuration. You can also notice the same canonicalization in the output of tmux list-keys | grep prefix.
You may want to pick a different prefix if you do not want to type Tab twice when you want to send one to programs running inside tmux.
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 trying to "ease" into VIM as my primary coding editor. I find that I'm still making plenty of "mistrokes" as I learn the many modes/features of VIM. While I'm in insert mode, I notice that combinations of keystrokes will produce special characters - mostly characters in non-latin alphabets.) I would like to disable this for now. Is it possible? In order words, to prevent multi-byte characters from being displayed in insert mode?
EDIT: (added example)
One example of this is when I delete a character (delete key on mac keyboard) and follow this quickly with another character. For example, delete+d produces " ﺽ " .
Thanks!
Steve
This sounds suspiciously like keys not timing out as controlled by 'timeout', 'timeoutlen', 'ttimeout' and 'ttimeoutlen'. You might try
:set timeout timeoutlen=5000 ttimeoutlen=50
which should cut the time vim will wait between keystrokes to see if they're the "same" (pseudo-)key down to 50ms.
The exact numbers you want would vary depending on your connection. If you're editing over a low-bandwidth connection, you might have to bump up the 50ms to something higher if you use function keys, 6-pack, or arrow keys (anything that transmits as a sequence of characters).
In vim, typing the two characters with a backspace between them will produce a digraph if the digraph option is set. If you want to disable this, see if there is a set digraph in your vimrc and remove it.
Your terminal settings probably map the delete key to backspace.
If you don't want that, you have to change that in the settings.
I'm trying to a get a ctrl+tab and ctrl+shift+tab binding to work inside of a tmux session (I'm also using PuTTY).
I already went through the pains of having to recompile PuTTY so it would send ctrl and shift correctly. After using ctrl+v, and I'm able to see that ^[[27;5;9~ and ^[[27;6;9~ are being sent for ctrl+tab and ctrl+shift+tab, respectively. Is there any way I can get these bound to next-window and previous-window inside of tmux?
Edit:
After some research, I'm thinking I might have to configure xterm to include those keycodes. Any idea how I would go about doing that?
Edit2:
So I found out I can retrieve infocmp and recompile it. I added
kctab=\E[27;5;9~, kcstab=\E[27;6;9~,
to the end of it, except now it's giving me an error. "entry does not start with terminal names in column one"
Recent “unreleased” versions of tmux do automatically recognize those xterm-style key sequences once you have your terminal sending them (no need to change your terminfo entry). The next release version (1.8?) should also have this support. With an appropriate build of tmux1, all you have to do is bind the keys in your tmux configuration:
bind-key C-Tab next-window
bind-key C-S-Tab previous-window
You will still need to type your prefix key before these keys.
(Note: ~/.tmux.conf is only processed when the server starts. If you make changes to it, you will either need to exit all your sessions and restart the server, or use (e.g.) tmux source ~/.tmux.conf to have your existing server re-process the file.)
Also, if you want tmux to pass along these (and other) xterm-style key sequences to programs running inside tmux, then you will need to enable the xterm-keys window option.
set-option -gw xterm-keys on
(If you prefer, you can do this on a per-window basis by using -w instead of -gw.)
If you want to be able to use those keys without typing the prefix, then you can use “no prefix” bindings instead:
bind-key -n C-Tab next-window
bind-key -n C-S-Tab previous-window
This will more or less “dedicate” the keys to tmux, though. It will be difficult to type these keys to any program running inside tmux (e.g. you would have to use the tmux command send-keys C-Tab—as normal, xterm-keys must be enabled to send these xterm-style key sequences).
The problem with your terminfo entry editing is probably because each line after the one that names the terminal type needs to start with a Tab. Lines that do not start with a tab are the beginning of a new terminal entry. Technically, the NL TAB sequence is basically a line continuation in this file format; each entry is a single logical line.
Also, if you are redefining terminfo entries, be sure to use -x with infocmp and tic to preserve the user-defined capabilities (some of which are fairly standard).
1 I.e. built from recent code in the tmux Git repository at sf.net (at the clone-able URL git://git.code.sf.net/p/tmux/tmux-code).
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.
In a terminal, one cannot distinguish Ctrl+A and Ctrl+Shift+A as they both emit the same key code, so I can see why Vim can't do it. But gVim, being an X application, can differentiate Ctrl+A and Ctrl+Shift+A. Is there any way to map those two things differently?
For starters, I'd like to do something like the following: Make "paste from clipboard" work like Gnome terminal, while keeping Ctrl+V to the visual mode.
:nmap <C-S-V> "+gP
Gvim doesn't do it because vim cannot do it (under normal circumstances). Sorry, but that's just how it is.
However...
Some terminals (e.g., xterm and iterm2) can be configured to send an arbitrary escape sequence for any combination of keys.
For example, add the following to .Xresources for xterm to send <Esc>[65;5u for CtrlShiftA. You can then map that in Vim to <C-S-a>. (65 is the decimal Unicode value for shift-a and 5 is the bit for the ctrl modifier. The u in this case stands for "unicode".)
! .Xresources
XTerm*vt100.translations: #override Ctrl ~Meta Shift <Key>a: string(0x1b) string("[65;5u")
iTerm and [u]rxvt can also be configured to do this (examples not provided).
More info: http://www.leonerd.org.uk/hacks/fixterms/
As already pointed out, there are no ways to map <C-S-A> differently from <C-A>.
However, using tools like autokey (for linux & windows) or autohotkey (for windows), you can remap <C-S-A> to send a different key-stroke(s) for specific applications.
e.g. On my system, I have this setting in autokey:
$ cat ~/.config/autokey/data/gnome-terminal/ctrlshifta-gnome-terminal.py
#ctrl+shift+a sends '<S-F1>a'
keyboard.send_keys("<shift>+<f1>a") # Note that `f` in `f1` needs to be in lower case.
Assign it these properties:
keyboard-shortcut as ctrl+shift+a
window class: gnome-terminal-server.Gnome-terminal
Then your ~/.vimrc can create mapping for <S-F1>a to do whatever you want.
Notes:
I have used <S-F1> as kind of leader key for detecting <C-S>. This was because my terminal did not accept <F13>-<F37> etc keys. If your application supports it, (gvim does I think) using those keys is recommended.
I mainly vim in gnome-terminal. So I used window class = gnome-terminal-server.Gnome-terminal as filter. Modify it to use gvim if you want. autokey supports a button for capturing any other window's properties like class/title.
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 release.
If what bothers you is loosing existing C-V functionality, you can use C-Q instead. See, :help CTRL-V-alternative.
NeoVim now offers this functionality for both its terminal and gui clients. See :h nvim-features-new
As you've noted, you get the same keycode. So the only way to distinguish them is to check the state of the Shift key in your event handling function. Of course, if you have more than 0.5 second delay between keypress and processing, you'll miss some hits.
Most terminal emulators treat control plus shift simply as control by default. Instead, you usually map those key combinations to an escape sequence and listen to that inside the terminal application.
Step 1: Configure your terminal emulator to bind Ctrl+Shift+A to the sequence Esc,A.
Your terminal emulator is the program that shows the actual window of the terminal. When accessing a server via SSH, the terminal emulator is a program on your local machine. Binding keys works differently in different terminal emulators. For example:
For urxvt, add URxvt.keysym.Control-Shift-A: \033A to the ~/.Xresources configuration file and reload it with xrdb ~/.Xresources.
For iTerm2, open Preferences -> Keys, add an entry, and bind Ctrl+Shift+A to the action "Send Escape Sequence" and type A into the field below.
Step 2: Bind Esc,A to a command in Vim.
Add the key mapping to your ~/.vimrc configuration and reload it with :source ~/.vimrc:
nnoremap <esc>a your command here