How to start multi panel with one command - tmux

I'm new to tmux and lately I'm thinking about how to start multi panels with just one command.
For example, 4 panels with one command. And I can do this by typing [Ctrl-b + "] and [Ctrl-b + %]. I wonder is there any less typing way?
Any answers are appreciated.

If you often need a new 2x2 panes tmux session, you could make a shell alias to the following command:
tmux new -s '2x2 panes' \; split-window -h \; split-window -v \; select-pane -t 0 \; split-window -v \; attach

Related

TMUX: no space for new pane

Consider the TMUX
tmux new-session -d -s theSession
for p in {1..30}
do
echo "Welcome to Pane number #$p"
tmux split-window -v -p 140 -t theSession
tmux send-keys -t theSession "./run-exp-scr.sh" Enter
done
tmux attach -t theSession
When I run script I get :
no space for new pane
Any idea how to solve this ?
Googling your error I came across this mailing list link which seems to imply you need to tell tmux to relayout things with e.g. selectl tiled to ensure there's enough space. Add a select-layout call in your loop:
tmux split-window -v -p 140 -t theSession
tmux select-layout -t theSession tiled

On tmux 2.4 how to enter copy-mode and start a search all in one go?

I am trying to bind F1 key to:
Enter copy-mode
Start a reverse search
The only thing I found online was:
bind-key F1 copy-mode \; send-key ?
However, that doesnt seem to work on tmux 2.4.
Is there a way to have it work on all tmux versions?
This worked:
bind -n F1 copy-mode \; command-prompt -p "(search up)" "send -X search-backward \"%%%\""
bind -T copy-mode-vi F1 copy-mode \; command-prompt -p "(search up)" "send -X search-backward \"%%%\""

Tmux loading multiple enviroments from different files

Hello I would like to load multiple environments from different files. For example:
First File builds a session with 1 window and 3 panes.
Second File builds a session with 2 windows first window with 2 panes and second window with one pane.
Like:
tmux -f /path/to/file/basic.conf a
and then after detaching from the first session, i would like to load the same way the other enviroment.
tmux -f /path/to/file/scripting.conf a
but when i fire the second command i will attach to the first session (basic.conf).
But i would expect that when I fire the second script I would attach to the second session.
And tmux ls list only one session.
(The conf files by itself are running with no problem)
How is it possible to have multiple session build trough differnt conf files with tmux, and only with tmux no tmuxinator no tmuxp or anything else?
Or should i have one big conf file which builds everything that now is in muliply conf files?
basic.conf
SESSION_NAME="basic"
FIRST_WINDOW="shells"
SECOND_WINDOW="console"
source ~/.tmux.conf
new-session -s $SESSION_NAME -n $FIRST_WINDOW -d
split-window -h -t $SESSION_NAME
split-window -v -t $SESSION_NAME
new-window -n $SECOND_WINDOW -t $SESSION_NAME
select-window -t $SESSION_NAME:0.0
scripting.conf
SESSION_NAME="script"
FIRST_WINDOW="editor"
SECOND_WINDOW="console"
source ~/.tmux.conf
new-session -s $SESSION_NAME -n $FIRST_WINDOW -d
split-window -v -p 5 -t $SESSION_NAME
send-keys -t $SESSION_NAME:0.0 'cd ~/Code' C-m
send-keys -t $SESSION_NAME:0.0 'vim' C-m
send-keys -t $SESSION_NAME:0.1 'cd ~/Code' C-m
send-keys -t $SESSION_NAME:0.1 C-l C-m
new-window -n $SECOND_WINDOW -t $SESSION_NAME
send-keys -t $SESSION_NAME:1 'cd ~/Code' C-m
select-window -t $SESSION_NAME:0
I think I found a solution by myself.
The command:
tmux -f /path/to/file.conf a
should only be used when you would like to load another tmux config file instead of the default one.
If you like to start multiple sessions , which are preconfigured in files, then you have to do something like this:
tmux source-file -q .dotfiles/tmux/enviroments/basic.conf && tmux attach -t basic
Perhaps there is a better solution, but for now this solves my problem.
P.S. i made a little function to load the files less complicated.
function muxload(){
if [ -f ~/.dotfiles/tmux/enviroments/$1 ]; then
tmux source-file -q ~/.dotfiles/tmux/enviroments/$1 && tmux attach -t $1
fi
if [ -f ~/.dotfiles/tmux/enviroments/$1.conf ]; then
tmux source-file -q ~/.dotfiles/tmux/enviroments/$1.conf && tmux attach -t $1
fi
}
run it like this:
muxload {name_of_conf_file}

Tmux: disallow switching into a particular pane

I would like to remove a pane from being selected using ctrl+b arrow-keys. This is because I have a pane displaying the time using tmux clock-mode -t 2 and I do not ever want to switch into that pane.
This solution is similar to a problem I answered on sister site unix.stackexchange, and is not perfect.
tmux has a flag for each pane saying whether it is in a mode. For example, display -p #{pane_in_mode} for a pane in clock-mode prints 1.
Unfortunately, you cannot distinguish between, say, copy-mode and clock-mode. However, if you are unlikely to have many panes in a mode at a time, you can write a small shell script to intercept the appropriate bindings, and test if the resulting movement ended up in a pane in a mode. If so, the script repeats the movement, probably to the next window.
Create the following file mytmux in your PATH and make it executable (chmod +x mytmux):
#!/bin/bash
# https://stackoverflow.com/a/51232832/5008284
noclock(){
tmux "$#"
inmode=$(tmux display -p '#{pane_in_mode}')
[ "$inmode" = 1 ] && tmux "$#"
exit 0
}
case $1 in
-noclock)shift
: ${1?select-pane cmd and args}
noclock "$#" ;;
esac
then setup the following bindings in your ~/.tmux.conf:
bind-key -T prefix o run-shell 'mytmux -noclock select-pane -t :.+'
bind-key -T prefix l run-shell 'mytmux -noclock select-pane -l'
bind-key -r -T prefix Up run-shell 'mytmux -noclock select-pane -U'
bind-key -r -T prefix Down run-shell 'mytmux -noclock select-pane -D'
bind-key -r -T prefix Left run-shell 'mytmux -noclock select-pane -L'
bind-key -r -T prefix Right run-shell 'mytmux -noclock select-pane -R'
You will need to extend this if you want to handle multiple sessions, for example. I put select-pane -l in the bindings, but this is not useful, as if it repeats it will just go back to where you started from.

How to send a command to all panes in tmux?

I like to call :clear-history on panes with a huge scrollback. However, I want to script a way to send this command to all the panes in the various windows.
I know how to send a command to all the windows, courtesy of this question, but how do I send a command to all the panes of which window as well?
send-keys and synchronize-panes from the tmux manpage come to mind, but I'm not sure how to marry them together. But maybe there is a simpler way to do this.
Extra Observations:
Thinking about this a little bit, tmux list-panes -a seems to list all the panes in the current session. Pretty useful to start off with. Where do I go from here?
Have you tried following in tmux window with multiple panes
Ctrl-B :
setw synchronize-panes on
clear history
A bit late to the party but I didn't want to set and unset synchronize-panes just to send one command so I created a wrapper function around tmux and added a custom function called send-keys-all-panes.
_tmux_send_keys_all_panes_ () {
for _pane in $(tmux list-panes -F '#P'); do
tmux send-keys -t ${_pane} "$#"
done
}
I also create a wrapper around the tmux command to simplify calling this function (for convenience). The wrapper and the above code are all here.
This allows me to run tmux send-keys-all-panes <command> or tmux skap <command to send <command> to all panes.
Note that tmux is aliased to my wrapper function tmux_pp.
Update June 2019
Quick illustration on how to configure your own binding for synchronize panes.
Added the following into my tmux.conf (the comments certainly apply to my overall configuration):
# synchronize all panes in a window
# don't use control S, too easily confused
# with navigation key sequences in tmux (show sessions)
unbind C-S
bind C-Y set-window-option synchronize-panes
Now, I can toggle the ability to synchronize commands across multiple panes with <C-a><C-y>.
(Yes, I remapped the bind key to Ctrl a).
my tmux version is 1.9a, and this works for me, one key is enough for both on and off
bind-key X set-window-option synchronize-panes\; display-message "synchronize-panes is now #{?pane_synchronized,on,off}"
None of the above answers worked for me (tmux v2.3), but this did, from the bash command line:
for _pane in $(tmux list-panes -a -F '#{pane_id}'); do \
tmux clear-history -t ${_pane} ; done
A more generalized script, for tmux commands other than 'clear-history' would just replace that element with a parameter, eg. $1. Do be careful if you intend to write a script to handle a series of tmux commands, as "-t ${_pane}" will need to be applied to each.
Note that the -a parameter to tmux list-panes is required to cover all panes in all windows in all sessions. Without that, only panes in your current tmux window will be affected. If you have more than one tmux session open and only want to apply the command to panes within the current session, replace -a with -s (It's all in the tmux man page).
I haven't the mod points to comment directly on each of the above answers, so here's why they weren't working for me:
The problem that I had with #shailesh-garg 's answer was that the sync affected only commands issued within the panes, not tmux commands issued using Ctrl-B : which are outside the panes.
The three problems that I had with #kshenoy 's answer were that:
it sends keystrokes to within a pane, not to the tmux operation
of that pane, so for instance, if one had a bash shell running in
the pane and one used the script to send "clear-history", those
would be the keystrokes that would appear in the bash command-line.
A work-around would be to send "tmux clear-history" or to pre-pend
"tmux " to "$#", but I haven't edited the answer because of my other
problems with the answer;
I couldn't figure out how to send a
new-line character without literally breaking the line;
Even when I did that, sending "tmux clear-history" had no effect.
If you want to send your command to every pane in every window in every session, add this to your .bashrc:
send_command_to_every_pane() {
for session in `tmux list-sessions -F '#S'`; do
for window in `tmux list-windows -t $session -F '#P' | sort`; do
for pane in `tmux list-panes -t $session:$window -F '#P' | sort`; do
tmux send-keys -t "$session:$window.$pane" "$*" C-m
done
done
done
}
You can then use it like this:
send_command_to_every_pane source ~/.bash_profile
Change "$*" to "$#" if you want that behavior, but in my experience this is what you want.
tmux send-keys -t <session id> <command> C-m
Replace the "session id" and "command" accordingly.
This is my utility function to do it, only executing the command when there there is nothing running in the pane.
#!/bin/bash
_send_bash_command_to_session() {
if [[ $# -eq 0 || "$1" = "--help" ]] ; then
echo 'Usage: _send_bash_command_to_session $session_name what ever command you want: '
return
fi
input_session="$1"
input_command="${#:2}"
for _pane in $(tmux list-panes -s -t ${input_session} -F '#{window_index}.#{pane_index}'); do
# only apply the command in bash or zsh panes.
_current_command=$(tmux display-message -p -t ${input_session}:${_pane} '#{pane_current_command}')
if [ ${_current_command} = zsh ] || [ ${_current_command} = bash ] ; then
tmux send-keys -t ${_pane} "${input_command}" Enter
fi
done
}
tmux_set_venv() {
_current_session=$(tmux display-message -p '#{session_name}')
_send_bash_command_to_session ${_current_session} workon $1
}
Example targeting a session called dev, enabling a python virtualenv in all panes that are in bash or zsh, avoiding executing the command in panes with vim or any other executable:
_send_bash_command_to_session dev workon myvirtualenv
or easier to remember: to do it in the current session:
tmux_set_venv myvirtualenv
Find my configuration file with this function.
You can combine synchronize-panes and send-keys in a single shortcut to send commands to all the panes:
Predefined tmux command clear-history:
bind-key C set-option -w synchronize-panes on\; clear-history \; set-option -w synchronize-panes off
Prompt an arbitrary tmux command:
bind-key p command-prompt -p "Panes command: " "set-option -w synchronize-panes on; %% ; set-option -w -u synchronize-panes"
Prompt an arbitrary shell command:
bind-key p command-prompt -p "Panes command: " "set-option -w synchronize-panes on; send-keys %%\\n ; set-option -w -u synchronize-panes"
By default, byobu uses tmux as backend. It's a wrapper that make things much easier:
Shift+F9:
Ctrl+F9:
Shift+F1
Admittedly only semi-related, I found I could make the status background red when I toggle synchronize-panes so it's obvious when I switch back to a window with an unknown synchronize-panes state:
bind-key C-x setw synchronize-panes on \; set-window-option status-bg red \; display-message "pane sync on"
bind-key M-x setw synchronize-panes off \; set-window-option status-bg default \; display-message "pane sync off"

Resources