I have this command in my ~/.tmux.conf file:
setw -at weechat window-style 'bg=colour235,fg=colour223'
I expect the command to tell tmux to set the custom background & foreground for any window created with the name weechat irrespective of session (i.e. in any session).
But when run the command:
tmux -2u new -s myapps -n weechat
I get the following error:
/home/theone/.tmux.conf:17: no current [0/0]
/home/theone/.tmux.conf:17: couldn't set 'window-style'
And the window-style I set in the tmux config. file isn't applied to the window weechat.
So I have to press Ctrl + c to clear the error message from the screen, and then press Ctrl + b and type :source-file ~/.tmux.conf for the style to be applied to the Window. (To make the process less cumbersome, I configured a key binding so that when I press Ctrl + b, then r, the config. file is reloaded.)
But I'd like to avoid having to reload the config. file at all for the style(s) to apply, i.e. when I run the command tmux -2u new -s myapps -n weechat, I want tmux to create the window weechat with the colors automatically applied.
Can this be done? If so, how?
I don't think this is possible, because global styles applied on config initialization. I would suggest you create key binding that creates named window and applies desired styles to it
bind-key C new-window -n weechat \; setw -at weechat window-style 'bg=colour235,fg=colour223'
You cannot initialize a color style for specific window before the window created in any session. You can add -vvvv to your command and check the tmux-server log. I think Sardorbek's answer is good and convenient.
Related
For example, if I want to know the value of textwidth in vim, I can dereference it by appending a ?. Thus, I will simply type :set textwidth?.
How can you do the equivalent in tmux?
To dereference the value of a tmux setting or variable, you can run the following terminal command:
tmux display-pane -p #{<setting-or-variable-name>}
Or, to be more verbose
tmux display-pane -p "The value of your setting or variable is #{<setting-or-variable-name>}"
Example of a working command:
tmux display-message -p "You have #{display-panes-time}ms to press a number key after running 'display-pane'"
Note: The corresponding command-prompt commands, surprisingly, will fail:
:display-pane #{display-panes-time}
:display-pane #{display-panes-colour}
However, when you add quotes, they act as expected:
:display-pane "#{display-panes-time}"
:display-pane "#{display-panes-colour}"
What...?
Using tmux, I'd like to run a command from one pane against another pane, and capture the output of the command.
For example, say in pane 7 I have an SSH session running, and I'd like to run a bash script in pane 2 to capture the host name from pane 7.
Is this possible?
I know I can do the send keys like so
$ tmux send-keys -t 7 "hostname" Enter
but I'm not sure how to capture the output from pane 7 into a bash variable.
I don't mind if it displays on the screen either (doesnt have to happen in the background).
EDIT: Note that hostname is just an example - I would like to run other scripts against each pane as well
As an alternative to capture-pane you can similarly use pipe-pane. It is often used for logging. You give it a command to pipe all output into, or no command at all to stop piping. So you end up with something like
tmux pipe-pane -t 7 'cat >/tmp/capture'
tmux send-keys -t 7 'hostname' Enter
sleep 1
tmux pipe-pane -t 7 # stops piping
IT=$(</tmp/capture)
Beware, this capture includes carriage-return characters. You will need to remove the first and last lines of the capture to get just the wanted output. Eg:
IT=$(sed '1d;$d;s/\r//' </tmp/capture)
While not exactly what I was looking for, the tmux capture-pane command seems to capture the displayed output of a pane, which I can run of course after running my command.
example.sh
#/bin/bash
# run the command in another pane
tmux send-keys -t 7 "hostname" Enter
# capture it's output
IT=$(tmux capture-pane -p -t 7)
echo "$IT"
What it comes down to is, I would like to
print a variable unique to the window ,or
run a script unique to the window
and use the output in the status bar such that each window status is unique. I've tried to make it more clear through 2 scenarios:
Scenario 1
I'm trying to print a unique per window variable in the status bar. I've opened a shell inside tmux and have stored the tmux environment variable locally (per session) and globally (for all sessions) with the following commands, respectively:
bash> tmux set-environment TMUX_STATUS_1 localvalue1
bash> tmux set-environment -g TMUX_STATUS_1 globalvalue1
I can verify these values for instance by going the another shell (in the same session) and typing:
bash> tmux show-environment TMUX_STATUS_1
TMUX_STATUS_1=localvalue1
bash> tmux show-environment -g TMUX_STATUS_1
TMUX_STATUS_1=globalvalue1
I've tried to print the above value in the statusbar (both the local and global value) and have configured the window format as follows:
WINDOW='[#(tmux show-environment -g TMUX_STATUS_#I 2>&1)]'
setw -g window-status-current-format $WINDOW
setw -g window-status-format $WINDOW
Initially it only showed windows as '[]', after this I added the redirection of stderr to stdout and got the status bar showing the following:
[unknown variable: TMUX_STATUS_1] [unknown variable: TMUX_STATUS_2] [...
What needs to be changed to make the statusbar show (according to previous commands):
[globalvalue1] [unknown variable: TMUX_STATUS_2] [...
PS: it's not a status bar refresh issues, as i've used the following command after setting the variable to manually force a refresh of the statusbar:
tmux refresh-client -S
Scenario 2
I've written a small bash script called 'tmuxscript' containing only:
echo "$(date '+%S') window:$(tmux display -p '#I') args:$#"
I updated my PATH variable and I have changed the window format to '[#(tmuxscript arg1 #I)]'. The output looks like:
[47 window:1 args:arg1] [47 window:1 args:arg1] [...
The time updates nicely. Printing the window index inside the script doesn't seem to work. The number 1 represents the window index of the currently focused window. This value is set for all windows, which is not what I want. I would at least expect to see (note the window index number) :
[47 window:1 args:arg1] [47 window:2 args:arg1] [...
Also, #I isn't getting past to the script, but the text 'arg1' is. How can I pas tmux variables to the script?
EDIT: I have now also tried setting the window status to:
'[#(tmux show-environment -g TMUX_STATUS_$\(tmux display -p "#I"\) 2>&1 | sed "s:^.*=::" )]'
Which gives me the following when the active (focused) window index is 1:
[globalvalue1] [globalvalue1] [...
Any help is appreciated!
Ok, I figured it out.
The problem lies in the fact that you are obligated to use the -g (global) flag when specifying a window-status in .tmux.conf.
.tmux.conf:
WINDOW="[#I #20W]"
set-window -g window-status-current-format $WINDOW
set-window -g window-status-format $WINDOW
The key is to make the status local after creating a window. Also, each window needs to be uniquely identifiable. Luckily this can be done by tmux variable 'window_id'. A small script, shown below, will output a variable unique to the window with this id as its first argument:
~/tmuxstatus:
#!/bin/bash
VARIABLE="W_$1"
VALUE=$(tmux show-environment -g $VARIABLE 2>&1)
VALUE=${VALUE#*=}
echo $VALUE
There is probably a TMUX only solution to make the status local, but I don't currently have the time. I'm using bash to do it with the aid of the environment variable PROMPT_COMMAND, which is evaluated just before the prompt is shown.
.bashrc:
function __prompt_command (){
if [ -n "$TMUX" ] && [ ! -n "$TMUX_INIT" ]; then
W=$(tmux display -p '#{window_id}')
VARIABLE="W_$W"
VALUE="value_$W"
STATUS="[#I #(~/tmuxstatus $W)]"
tmux set-option quiet on;
tmux set-environment -g $VARIABLE $VALUE;
tmux set-window window-status-current-format "$STATUS";
tmux set-window window-status-format "$STATUS";
export TMUX_INIT="done";
fi;
}
export PROMPT_COMMAND=__prompt_command
When changing the value of W_id, the window status changes also. It looks like:
[1 value_#0] [2 value_#1] [3 value_#2] [4 value_#3]
enjoy!
Perhaps using the echo command you can manually set the title using this syntax:
echo -ne "\033]0;$(tmux show-environment TMUX_STATUS_1)\007"
Try running that in different TMUX windows and see if it changes the title.
I am scripting the display of the output of a script (well, it is just the program git diff) with tmux: Once a filesystem change is detected the shell script executes tmux send-keys q enter C-l "git diff" enter which has it effectively refresh the git diff view.
You might consider this similar to functionality provided by iTerm's coprocesses.
Problem is, I want it on refresh to scroll back to the same position that it was in.
One of the reasons for using tmux is that the window is actually a totally normal and interactive terminal session that can be interacted with as normal to scroll around to look at the full output.
But I want to obtain the scroll position somehow.
Suppose I want to actually do computation on the text content of the terminal window itself, exactly like iTerm2's coprocess does, but so that I can use it on Linux (over ssh). Does tmux provide this ability?
I'm unsure about capturing this with a script, but less -N will show line numbers.
And -jn or --jump-target=n can jump to a location.
About iTerm's coprocesses,
tmux has a command pipe-pane that can be used to pipe the input and output of a shell command to the output and input of a target pane specified by -t.
So if I have a shell program, ~/script.sh for example:
#!/usr/bin/env bash
while read line; do
if [[ "$line" = "are you there?"* ]]; then
echo "echo yes"
fi
done
Note that read line will read every line printed to the pane, i.e. the prompt as well.
I can connect its stdin and stdout to pane 0 in my-session:my-window like so:
tmux pipe-pane -IO -t my-session:my-window.0 "~/script.sh"
and then at the prompt, type echo are you there?, and it responds:
$ echo are you there?
are you there?
$ echo yes
yes
Be careful using -IO together as it can easily cause a feedback loop (I had to kill the tmux server a few times while experimenting with this feature, lol).
i know tmux display-message -p '#S' will display the current tmux session name, but i donno how to set the current tmux session name to the iterm2 tab title?
This would really help me to distinguish the various tmux sessions that i am running concurrently and jump to the correct tab rightaway.
add these to your ~/.tmux.conf:
set-option -g set-titles on
set-option -g set-titles-string "#{session_name} - #{host}"
My workflow is usually centered around panes, and I don't use tmux, so I used a slight variation of #mislav answer:
set_terminal_tab_title() {
print -Pn "\e]1;$TABTITLE:q\a"
}
precmd_functions=($precmd_functions set_terminal_tab_title)
I threw that into my zshrc; then, in each pane, I export TABTITLE='FOO'. That way, when I switch panes, I get the title I want on the tab.
Stick this in your ~/.zshrc:
set_terminal_tab_title() {
print -Pn "\e]1;$1:q\a"
}
indicate_tmux_session_in_terminal() {
set_terminal_tab_title "$(tmux display-message -p '#S')"
}
precmd_functions=($precmd_functions indicate_tmux_session_in_terminal)
precmd_functions is an array that in zsh contains the list of functions to call prior to showing the prompt. If you add your own function to the list, it will get called whenever the prompt is shown, making it a good place to periodically update the terminal tab title.
Bash Version to display Hello World as a title:
echo -ne "\033]0; Hello World \007"
And if you want title refreshed each time bash print your prompt:
export PROMPT_COMMAND='echo -ne "\033]0;${USER}#${HOSTNAME%%.*}: ${PWD/#$HOME/~}\007"'
Found it on http://hints.macworld.com/article.php?story=20031015173932306