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).
Related
I connect my server(centos 7) with putty, and run vim in byobu.
Now I have 2 windows in byobu, and two files, a.py in window-1 and b.py in window-2.
I tried copy some text from a.py to b.py, but ran into some problems.
If I follow steps below, it works fine:
STEP1: In window-1, open a.py, press yy, then quit with :wq
STEP2: In window-2, open b.py, press p.
But if I keep a.py, and b.py open at first , or doest quit a.py after yy, paste fails.
It seems quite odd, did missed anything?
I have set clipboard=unnamedplus in .vimrc, and have +clipboard in vim --version, my vim version is 8.2.1438.
You are able to paste across Vim sessions because of the [viminfo] file. By default, Vim stores the contents of non-empty registers (including the default register) into the viminfo file. That's why when you put (with p) right after you start Vim, you get the contents you last yanked (with yy) before you quit Vim last time.
The viminfo file is written right before Vim quits, and it's read during Vim initialization. That's why this won't work automatically if you start the second instance of Vim before you quit the first instance. Then the viminfo file will be read too early by the second instance (or written too late by the first instance) to allow you to put the yanked text across instances.
You can explicitly write the viminfo file with the :wviminfo or wv command. And you can explicitly read it with the :rviminfo or :rv command. So you could use these two commands in the two separate instances to transfer the register information through the viminfo file without having to quit them.
I have set clipboard=unnamedplus in .vimrc, and have +clipboard in vim --version.
If you're using the X11 clipboard integration, you could use that to share copied contents between Vim instances. Note that setting the 'clipboard' option only affects yanks, so to put from the clipboard register you'd have to use "+p.
But this assumes you have a valid X11 server to connect to, which is quite unlikely in your situation. First, since you're connecting through SSH using PuTTY, you would need to use SSH forwarding to export an X11 server from your client. Since you're using PuTTY, I'm assuming you're on a Windows box, which doesn't really run X11 by default, so you'd have to install one and run it (easier said than done.) Also, since you're running Byobu, you will also have trouble reconnecting to an existing Byobu session, which will quite likely be pointing at an invalid X11 server, using the connection information at the time the Byobu session was created, which may no longer match the new X11 forwarding connection information of the new SSH session... It'spossible to make this all work, but if you want my opinion, it's probably too much trouble, especially for this particular use case of two Vim instances in the same remote box.
Have been enjoying tmux + vim these days, except one problem I cannot resolve every time.
It's a clipboard failure easy to reproduce. Vim's "+y "+p, copy to or paste from clipboard, work well if I create a new tmux session and keep using it either on Linux machine or via ssh (I use MobaXterm which supports X11 forwarding) from Windows. But copy and paste will surely stop working after I switch from one side to the other.
I tried to search but cannot find an answer but maybe I used wrong keywords. Any tip would be appreciated.
This is most likely related to your DISPLAY environment variable.
When you run tmux locally on your Linux machine, it's going to set DISPLAY to the default, most likely :0. This tells X11 programs to use your local X server. The Vim clipboard integration uses that X server for clipboard storage with the + register (in your config, based on your question; it could also use the * register, based on what Vim's clipboard option is set to).
When you SSH in with X11 forwarding, DISPLAY will be set to a virtual server, representing the forwarded connection--most likely :10.0 or localhost:10.0.
When you start tmux, it will use whatever DISPLAY is set to when it's initially started. If you detach and later reattach from the other machine, tmux won't automatically change DISPLAY. So if you initially start your tmux session from Linux, and then later SSH in from Windows and reattach the session, tmux (and the Vim running inside it) will still be using the Linux display.
One option is to quit Vim, do export DISPLAY=:0 (or DISPLAY=:10.0 as appropriate), and restart Vim. Note that you'll have to do this in each shell you have open, and if you open a new window/pane, it will still inherit the parent tmux session's DISPLAY setting.
Another option is to change the environment variable inside Vim, so that you don't have to restart Vim. You can do this via :let $DISPLAY="whatever".
There may be a way to change the tmux session's DISPLAY value at runtime, but I don't know how to do that. If you could figure a way out, you could probably automate it via a wrapper around tmux attach. This answer to a tmux question might help, but I just do one of the above.
I'm still looking for a better solution to this as well, but I found a bit of a workaround.
Save your vim session with :mksession
Exit with :qall
Reload the vim session with vim -S
When vim starts back up the clipboard integration works again.
Just like bydsky says. After your reattach Tmux session with an old running vim. Just run :xrestore Ex command in vim to restore X11 connection.
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.
Say for example that I have 3 terminals open (i.e. gnome-terminal or xterm) and would like to group them together to send commands to all of them at the same time while typing on 1 single terminal.
I want the option to disperse those terminals if I need to issue 1 command in a particular terminal. Is there any terminal application that could provide this capability? I've tried keyboardcast and is not exactly what i am looking for, since you have to type your command in a popup window.
There is a program called terminator, It does exactly what you want :)
http://www.tenshu.net/p/terminator.html
[EDIT] https://github.com/software-jessies-org/jessies/wiki/Terminator
If you want a non-GUI based approach you can also use tmux to send to multiple sessions as explained here - basically it works by using the following tmux command in a loop (if necessary):
tmux send-keys -t session_id your_command C-m
There's also an enhancement of tmux, called wemux, that supports paired, mirrored, and rogue modes.
If you use panes in tmux instead of separate terminals, you can use 'synchronize-panes' to send the same input to multiple panes. Plus you can bind the command to a key in .tmux.conf to easily turn it on and off.
# sends input to all panes in a given window.
bind e setw synchronize-panes on
bind E setw synchronize-panes off
see https://linux.die.net/man/1/tmux
There is an add-on: https://github.com/chabou/hyper-broadcast for Hyper terminal https://hyper.is/ . You can target individual tabs and/or other options of targeting which terminals. I use this on windows although there is no reason you could not also use this on linux.
If you open several tabs/windows in konsole, you can direct the keyboard input from one of them into the others. Simply select menu Edit -> Copy Input To ... -> All Tabs/Select .../None.
Is there a command which shows what was the last command in normal mode?
Suppose I accidently hit random key and got some unexpected result.
Sure I can undo it, but could I reveal what key was pressed and how it was interpreted?
Hit the colon (:) and then use the up arrow to start going back through previous commands. You can use the up/down arrows too to move around the list.
q: will show you command history in Vim.
q/ will show you history of searches.
And must importantly, :q will quit the mode.
The text from the last command is stored in the . register. You can see all registers by :display. Unfortunately it doesn't say what the started the normal command.
To see commands from : (command mode) you can use :hist or q: which is limited to the last 20 (by default).
Another ability is to save the undo buffer :wundo undo.bin -- but the undo buffer is binary.
But none of these actually answer your question. I'm curious if it can be done.
Entering colon : then ctrl+p shows your previous command, i.e., moving backward through your vim command history. ctrl+n moves forward.
This is very convenient if you're used to using the command line and prefer not to change your keyboard hand positioning to use arrow keys.
It is difficult to know it. You can play with the variables:
v:operator
v:count (and v:prevcount)
v:register
But you cannot fully get the last normal mode command issued.
However if you want to systematically record everything you type while in Vim, you can launch vim -W ~/.vim-last-scriptout (a Windows version: vim -W "%HOMEPATH%\Vim\.last-scriptout) You can alias it in your shell on a UNIX machine. Every single key, or control-key, will be recorded into that file. Note that if you happen to use gvim or vim -g (the GUI) you might encounter this bug.
If you want to replay this file you can use :source! (with the exclamation mark) or the -s option from the command line.
On Windows I have set gvimportable.exe -W gvim_directory\last_scriptout as my default editor in my Commander program (FreeCommander). This way I can always remember what I have typed to do something and repeat a sequence of commands on another file. Of course I have another shortcut for opening Vim and playing the scriptout.
Note that the file might be written only when Vim exits, so you have to lose your session to know what you've done.