how to move Tmux panes - tmux

I like to work with 3 tmux panes. one horizontal pane at the upper half of the screen and two more panes at the bottom half. These panes are split vertically.
There are cases where I would like to take the last pane and make it go from top to bottom. like this:
How can I achieve this? using [ctrl+b ctrl+o] and [ctrl+b space] did not reach the desired position and is cumbersome.

There is probably an easier way, but what you can do is arrange the panes manually in each of the two configurations, noting each layout in a variable with e.g.:
layout1=$(tmux list-windows -F '#{window_layout}')
This holds a string something like:
5f2f,80x23,0,0[80x11,0,0,0,80x11,0,12{39x11,0,12,1,40x11,40,12,2}]
which you must not alter in any way as the first number is a checksum of the rest of the string.
Once you have the two strings you can set a binding to set that layout using select-layout, or by giving the command from the shell where you have the variables:
tmux select-layout "$layout1"
You might find it easier to write a small helper script, say mtmux to toggle between the layouts:
#!/usr/bin/bash
# https://stackoverflow.com/q/56343223/5008284
# toggle between 2 layouts, previously saved
layout1='5f2f,80x23,0,0[80x11,0,0,0,80x11,0,12{39x11,0,12,1,40x11,40,12,2}]'
layout2='093c,80x23,0,0{39x23,0,0[39x11,0,0,0,39x11,0,12,4],40x23,40,0,3}'
layout="$(tmux list-windows -F '#{window_layout}')"
case "$layout" in
*80x11*) new=$layout2 ;;
*) new=$layout1 ;;
esac
tmux select-layout "$new"
tmux display-panes
exit 0
and have a binding, say control-L, to run this shell:
bind-key -n C-l run-shell 'mtmux'

Related

How to resize a pane to occupy a certain percentage of a whole tmux window?

I recently started to use tmux and likes it a lot. I'd like to know how to set the size of my panes using percentage. For example, there are 3 panels in a row, and I'd like to set the 1 pane to occupy 20% of the window width, and the other 2 panes each occupy 40% of the window width. But so far, I could only find commands below.
Ctrl+B Alt+Arrow
- Resize the active pane
resize-pane -R 20
- Resizes the pane right by 20 cells
Any better ways to do it?
There is no -p flag for resize-pane, which is what you are really after, although it has been on the todo list for a while. Instead you will need to use -x or -y and work out the sizes yourself, for example a shell script like:
W=$(tmux display -p '#{window_width}')
L=$(expr $W \* 2 / 10)
R=$(expr $W \* 4 / 10)
tmux resizep -t{left} -x $L
tmux resizep -t{right} -x $R
Another alternative would be to set up a layout like you want then get the layout string (you can see it in "tmux lsw"), then you can reapply it to a different window with the same number of panes using "tmux selectl ...").

tmux split-window without changing focus

Is there any way to split a window in tmux without changing the current focus?
I'm running a script inside one of my tmux panes that occasionally runs "tmux split-window ..." with some command that takes a minute to complete and MAY request input.
I can end up trying to type input into one of the tmux panes but in the middle of my typing, the original pane executes "tmux split-window ..." and (mid word) my cursor shifts to the new pane, and I end up typing part of the input into the wrong pane.
Note: this answer is correct, but obsolete. The right way is to use -d flag for split-window command. I'm leaving this answer as a demonstration how to do some yak shaving with tmux.
A split-window command flag provided by tmux would be the right solution for this. Unfortunately tmux does not provide such command flag. Update: there is a -d split-window flag that does this.
The simple solution is to immediately switch to previous pane after split-window:
tmux split-window
tmux last-pane
This can be also written as a one liner:
tmux split-window\; last-pane
The downside of this solution is that *theoretically* you might end up writing a character in the wrong window if you type it in time interval between split-window and last-pane command execution.
Here another approach with the downside that it's more complex.
Create a new window in the background and get the pane_id of this window (note how this command is wrapped in $(...) because we want it executed in a subprocess:
pane_id=$(tmux new-window -d -P -F "#{pane_id}")
Now join the window we just created with the window where your cursor is located (will not change cursor focus):
tmux join-pane -b -t "$pane_id"
Add -h to the join-pane above if you want a horizontal split.
I recommend taking the first approach for it's simplicity. It's highly unlikely you'll have any practical issues with it.

how to do quick pane cycling in Tmux

there, recently I decide to hug with Tmux and to configure the .tmux.conf by myself. I am trying to get the command of quick pane cycling now. Here I have a short configure lines referenced from others:
# quick pane cycling
unbind ^A
bind ^A select-pane -t :.+
Does anyone know what's the meaning of these three lines? I tried several times with my Tmux, but still cannot find the shortcut command related to these three lines.
As pointed out in the comments, I'll explain and post the relevant sections of man page
unbind ^A
Disassociates any command previously bound to C-b C-a, freeing ^A for the following
bind ^A select-pane -t :.+
Cycles to the next pane in the current window. From man page
select-pane [-lDLRU] [-t target-pane]
(alias: selectp)
Make pane target-pane the active pane in window target-window.
For specification of 'target-pane'
target-pane takes a similar form to target-window but with the optional addition of a period followed by a pane index, for example: mysession:mywindow.1. If the pane index is omitted, the currently active pane in the specified window is used. If neither a colon nor period appears, tmux first attempts to use the argument as a pane index; if that fails, it is looked up as for target-window. A ‘+’ or ‘-’ indicate the next or previous pane index, respectively.
^A means Control+A.
If you add this to your config file, and then tmux source-file .tmux.conf, you can cycle between your panes by hitting Control+A.

Narrow centered single frame in tmux

Writing prose in a console environment I like to have my editor in a narrow centered pane. I can achieve this with this .screenrc:
focusminsize 75 25
split -v
focus
only
split -v
split -v
focus
caption string "%{= dd} "
sorendition "="
Then $screen emacs gives me the desired layout.
How do I achieve something similar in tmux 1.8?
Bonus: how to I bind toggling 'default layout' / 'narrow centered single pane' to a key?

Split pane switching in tmux: switch once per command

I've been a happy tmux user for a while now but there's one behaviour that's bugging me. When I switch panes using ^b-arrow, and then immediately press arrow-up (to get a command from history, for example), the window pane switches again. I understand this can be useful if you want to move through multiple panes quickly, but for me it's a pain in the backside since I keep ending up in panes I never meant to be in.
So, is there a way to set tmux so that the ^b-arrow command only switches pane once and ignores any following arrow key presses?
That happens because the default bindings for the arrow keys are setup with bind-key -r, specifying that they may be repeated. There are two ways that you can disable this.
First, you can use set-option repeat-time 0 to disable repeating entirely. This will affect all bindings. I find that to be very annoying when resizing panes.
Secondly, you can change the bindings for the arrow keys to use bind-key without the -r option:
bind-key Up select-pane -U
bind-key Down select-pane -D
bind-key Left select-pane -L
bind-key Right select-pane -R
If you spend a lot of times navigating panes, why not set up global mappings so you don't have to use prefixes at all, e.g. bind -n C-h select-pane -L to map ctrl-h to switching left, same as Vim.
See http://robots.thoughtbot.com/seamlessly-navigate-vim-and-tmux-splits for an even better solution that also navigates across Vim windows.
Another option is to make a binding to jump to the previous pane, if you are flicking back and forth between the same two panes.
bind-key C-a last-pane

Resources