Show pane in all windows in tmux - tmux

I wonder if I can configure a pane in tmux to appear in all windows.
Any hints how to do that?

Of course this is possible, but you would need to run tmux inside a tmux pane.
+-------------+-------------+
| tmux pane 1 | tmux pane 2 |
| | |
| |+-----------+|
| || new tmux ||
| || session ||
| |+-----------+|
+-------------+-------------+
How to do it:
start new tmux session
split pane
unset TMUX in pane 2 # this allows tmux in tmux
start new tmux session in pane
repeat 1-3
run tmux attach -t <target-session> # this is opens the shared session
This does not work as easily if you are running wrappers for tmux, such as come with oh-my-zsh or tmuxinator. And there are probably many reasons you shouldn't do it, I just don't know any of them.

Here's a way to do this, but the mirrored panes will be read-only. There's the pipe-pane command which sends the pane's output to a command. You can have that command write the output to a file and then from the panes you want to mirror from, you can tail -f that file. Example:
# In source pane
tmux pipe-pane 'cat > /tmp/asdf'
# In the target pane (or another tmux session or terminal window)
tail -f /tmp/asdf

no you can't configure a pane to be linked to every window in a traditional sense but you can use tmux's link-window functionality to achieve much of this effect. wrap it in a script or tmux session file to link it to many windows at once.
**edit
you will also want to use the join-pane feature.

Related

Can the number of sleeping task in the current window be shown in Tmux statusbar?

I often use ^Z to make sleep a process, possibly open a new one, make this one sleep too, and so on, also moving between different Tmux windows.
So what I would like, is that the Tmux status bar update relevantly to indicate me how many processes are sleeping in the currently focused window.
Is that possible?
This is a common question - how to pass information from a shell inside tmux to tmux. The easiest way to do this is to have your shell do it as part of PS1 or some other variable that is evaluated when the prompt is printed.
There are two things you can do:
1) Set a user option with tmux set -w #myoption xyz, then you can use it in the status line with #{#myoption}. This has the disadvantage that it cannot work over ssh.
2) Set the pane title using the escape sequence, for example: printf "\033]2;xyz\033\\". It is then available in #{pane_title}. This works over ssh but had the disadvantage that there is no way to prevent applications also changing the title if they want.
In either case you will only want to run this when TMUX is set, so something like:
[ -n "$TMUX" ] && tmux set -w #myoption $(jobs|wc -l)

tmux: list all the tmux windows with last 5 lines of output

I am running a lot of tmux session like
Each tmux session is started as:
today=`date +%Y-%m-%d-%H_%M_%S_%N`
tmux new-session -d -s "$today" zsh /home/path/to/script.sh "with_params"
If i want to only view the list of tmux sessions. I can do by
tmux ls | awk '{print $1}';
Now what i want is to monitor their output using the while loop to show the session name and the recent output:
while true;
do;
echo "##########################################"
??? For list of tmux session; do
sleep 1;
??? session name
??? recent last 5 lines of output
done
echo "##########################################"
done;
??? : What commands should i use
You can use capture-pane to show the last five lines of output:
tmux capture-pane -p -S- -E-|sed '/^$/d'|tail -5
Add -t to specify the pane you want to see - if you just give a session it will use the active pane in the current window.
Add -e if you want colour sequences included.

Start tmux with specific layout

I have a question and searched on the web but didn't find a specific solution, or solutions didn't work for me.
In order to start tmux with a specific layout of panes, I'd like to setup my tmux.conf accordingly.
Now, I found something like this:
new -s my_sess # create new session
neww -n shell # create new window
splitw -v
Which has no effect, since I see only one window, not split into panes. Another trial was like this:
# Automatically set window title
set-window-option -g automatic-rename on
set-option -g set-titles on
# Split the pane horizontally
splitw -h
Which results in an error no current target.
It's probably a stupid mistake of mine caused by poor understanding. But I hope that people here might be able to help.
I'd say that this very basic task is covered abominably in the available tmux resources.
It cost me six hours of perusing material to come to a solution. The biggest help came from https://gist.github.com/sdondley/b01cc5bb1169c8c83401e438a652b84e
Your minimal .tmux.conf file shall be (you got there 99%):
new -s my_sess # create new session
neww -n shell # create new window
split-window -t shell # split vertically the window just created
and you have to launch it with tmux attach instead of a plain tmux.
I have created a gist to sum up my experiences. It covers also topics like launching different commands in each new pane.
If you create new sessions in .tmux.conf, you probably want to start tmux with tmux attach not tmux new. If you don't, you will be creating both your session in .tmux.conf and a new session, which is probably not what you want. Your first attempt looks OK, so I guess this is what you are doing.
Also remember .tmux.conf is only loaded on server startup, so only the first time you run tmux. If you want to create a new session like this later, put it in a separate config file and load it with source-file.

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.

tmux resize on focus

I'd like to be able to specify a secondary size parameter for a particular pane so that it assigns the new size upon focusing the pane, and returns it upon exiting. So e.g.
(Note [] represents focused terminal cursor)
________________
|$ ls | |
|a's | |
|dir | |
|$ |$ [] |
|______|_______|
Swap pane focus
_______________
| | |
|$ ls | |
|a's dir | |
|$ [] |$ |
|________|____|
And so on. Especially gonna be cool since resizing panes in recent tmux versions has it do a great job re-flowing the content rather than slicing it off.
In the example, the left pane has its width set to automatically switch to being 8 columns when it is focused, and it got squished thinner when it lost focus. Notice how the content is still visible (this is afterall why we love tmux) but we can still eat our cake too by letting the currently focused pane expand itself automatically so it's always big enough to do work in!
I can probably come up with some elaborate binds to automate the application of resize-pane commands to do this, and make it just the right amount of elaborate to suit my wishes. But I was hoping there was some kind of built-in feature for this.
It would be practical to track and allow the modification of an auxiliary 4-tuple of integers for each pane. These specify the amount of resize-pane -L/D/U/R operations to do upon that pane's focusing, and the reverse direction upon that pane's defocusing.
There may be other, more reasonable formulations of this.
Found a partial solution...
Ive got my pane switching synced with vim, so whenever I switch switch panes, I also resize tmux.
This is not optimal because tmux is not verifying the current pane size and resizing it accordingly. Anyway, it works pretty well since you can do ctr-h or ctrl-k twice to resize the panes size.
The relevant config is the following:
# Sync panes with vi
bind -n C-h run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim(diff)?$' && tmux send-keys C-h) || tmux select-pane -L && tmux resize-pane -R 30"
bind -n C-l run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim(diff)?$' && tmux send-keys C-l) || tmux select-pane -R && tmux resize-pane -L 30"
bind -n C-j run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim(diff)?$' && tmux send-keys C-j) || tmux select-pane -D"
# Move panes up and down, wont resize
bind -n C-k run "(tmux display-message -p '#{pane_current_command}' | grep -iqE '(^|\/)vim(diff)?$' && tmux send-keys C-k) || tmux select-pane -U"
Sorry, this only amounts to speculation so far, but I thought about it some, and I think there is functionality that is built in to tmux that can support this but it'll require some/a lot of scripting.
See this question I posted.
http://sourceforge.net/p/tmux/mailman/message/31221459/
Essentially it looks like the select-layout command can (possibly!??!) be used to apply an arbitrary mutation to the layout. I've not tested if it works, though.
Thomas Adam suggested to look in the layout-custom.c source to find out more about what's going on. That's about as far as I got. But if indeed it is possible to programmatically mutate the layout and generate working strings to pass to select-layout, then this would be a very good approach.
Update: Now I have asked this directly (whether just generating a suitable string can indeed achieve resizing to arbitrary layouts), but not yet received a response, from Mr. Adam himself, but the reason why I suspect that this can work if we can generate a string that passes the checksum is that I am able to resize my panes any which way, and change them away once I record the string (yielded by the list-windows command), and then afterwards restore to the recorded layout with the string. This means that there is not some sort of explicit action that must be taken to like "save" the layout or anything, it seems like the checksum is just some kind of clever way to help prevent garbage/pathological strings from wreaking havoc with the string interpreter that does the pane layout rearrangement.
You definitely need to pass a string that is nontrivial to construct in order for this to work. However, the code for computing the checksum and the rest is plain to see in layout-custom.c. One day I'll probably be back with a shell script (or just a C program, if it's possible to lift out the code) that implements suitable transformations. Should be fun.
Yes it would be awesome for me to crank this out and pick up that nice little bounty, but I have Real WorkTM waiting for me tonight unfortunately.

Resources