Disable tmux resizing using shift (only) + hjkl - resize

I added tmux binding for resizing pane like this
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
but ended up can't type HJKL (uppercase), since it's already resizing the panel. what I want to expect is using ctrl-a (prefix) then HJKL.

You can use tmux list-keys to verify if those keys are actually sit in prefix key table. You may need to explicitly reset the prefix key via set -g prefix C-a.

Related

Copy to client clipboard after mouse selection with tmux in a remote session

This is my .tmux.conf
setw -g mouse on
set-option -s set-clipboard off
bind-key -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -selection clipboard -i"
Works well on a linux machine locally. Mouse selection is copied to system clipboard automatically.
However, in a remote session (iTerm + Mac), it doesn't work. Text isn't copied to the client's system clipboard. Apparently I have to use OSC 52. Here is a helper script.
You can use the script like so:
echo "whatever text" | osc52.sh
Now "whatever text" is copied to the client's system clipboard.
However I can't get the script to work with tmux mouse selection:
setw -g mouse on
set-option -s set-clipboard off
osc52="~/osc52.sh"
bind-key -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "$osc52"
Any help is appreciated. Thanks!
This is not the way to use OSC 52. You can't send it from a script - all output from commands run from copy-pipe is ignored.
Instead, you need to configure tmux itself to do it. Try the following:
1) Remove the bind-key command and just leave MouseDragEnd1Pane as the default which is copy-selection.
2) Change set-clipboard off to set-clipboard on. Remember to restart tmux entirely after changing .tmux.conf.
3) Make sure TERM outside tmux is xterm or xterm-256color so that tmux adds the Ms capability from the default terminal-overrides. This should be the default in iTerm2. Make sure you are not removing it from terminal-overrides in .tmux.conf.
4) In iTerm2, I think you need to turn on this option, "Applications in terminal may access clipboard":

Bind "up arrow" key to fzf command

I want to use the fzf fuzzyfinder command history instead of the typical command history when I press the up arrow.
In my fzf shell keybindings file I'm able to edit which key brings up the fuzzy finder by editing the following snippet:
bindkey '{command such as ^R}' fzf-history-widget
How can I represent the up arrow key so that it calls this function when pressed? Do I have to disable other functionality somewhere else as well?
Binding <Up> key in zsh
Use
bindkey "${key[Up]}" fzf-history-widget
or
bindkey '^[[A' fzf-history-widget
or
bindkey "${terminfo[kcuu1]}" up-line-or-history
to bind <Up> key in zsh to fzf-history-widget function.
Binding <Up> key in bash
You can set the <Up> arrow key to show the commands from history beginning with the characters before the cursor on the command line
bind '"\e[A": history-search-backward'
fzf bindings for bash
There is an issue #1492:
[bash] Fire command directly with CTRL-X in CTRL-R
Accordingly, history-exec.bash plugin created for the purpose of history expansion using fzf
macOS Specific Binding
bindkey "${terminfo[kcuu1]}" fzf-history-widget
In bash version 4 or more, none of these works for me:
bind -m emacs-standard -x '"\C-p": __fzf_history__'
bind -m vi-command -x '"\C-p": __fzf_history__'
bind -m vi-insert -x '"\C-p": __fzf_history__'
This also doesn't work:
bind '"\C-p": __fzf_history__'
But this one does the trick for me:
bind -x '"\C-p": __fzf_history__'
By the way, you can use bind -X to see the current binding.

Use env variable to represent SSH options

These two ssh options:
ssh -o StrictHostKeyChecking=no -o NumberOfPasswordPrompts=0
I am interested in setting those using env variables, is there a way to do that?
export StrictHostKeyChecking=no
export NumberOfPasswordPrompts=0
but that's of course not quite right
The "proper" way to do this is within your ~/.ssh/config file, where you can make those global for all connections or you can restrict it by host (or a few more advanced things). I'm going to assume you can't do that but that you do still have the ability to alter your ~/.bashrc or whatever.
You can solve this by putting this in your ~/.bashrc or ~/.zshrc (or by running these lines before ssh):
SSH_ARGS=( -o StrictHostKeyChecking=no -o NumberOfPasswordPrompts=0 )
alias ssh='ssh "${SSH_ARGS[#]}"'
If you want explicit environment variables like what you're proposing in your question (e.g. $StrictHostKeyChecking) then you'll have to make a really ugly alias or function to convert them all to the final ssh call. Here's a solution that should work in bash but won't work in POSIX shell:
ssh() {
local SSH_VAR SSH_VAR_VALUE
for SSH_VAR in StrictHostKeyChecking NumberOfPasswordPrompts; do # expand this
SSH_VAR_VALUE="${!SSH_VAR}" # bash indirect expansion
if [ -n "$SSH_VAR_VALUE" ]; then
set -- -o "$SSH_VAR=$SSH_VAR_VALUE" "$#"
fi
done
command ssh "$#"
}
The above example only supports the two SSH variables named in the question. That line will likely have to get really long as it must explicitly name every option before the semicolon on the line with the # expand this comment.
This loops over every supported SSH variable and uses bash's indirect expansion to check whether it is in the environment (and not an empty value). If it is, a -o and the option name and its value are prepended to the start of the argument list ($#).
If you use zsh, you'll need zsh's parameter expansion flag P, replacing bash's ${!SSH_VAR} with zsh's ${(P)SSH_VAR}. Other shells may need to replace that whole "bash indirect expansion" line with eval "SSH_VAR_VALUE=\"\${$SSH_VAR}\"" (watch your quoting there, or that line can be dangerous).
Invoking command ssh prevents the recursion we'd get from calling ssh from within a function of the same name. command ssh ignores the function and actually runs the true ssh command.

How can I bind a key to "exit copy-mode" in tmux?

I was trying to find a command for "leaving copy-mode" from this page, but it seems only the key binding prefix+q exists for this function; i.e., I can't find the associated :command-style command.
Does this mean it is impossible to bind another key to "leave copy-mode"? I'd like to bind the Esc key.
Copy mode uses its own set of commands, separate from tmux itself. Use send-keys -X to "type" commands in copy mode, as demonstrated by the default binding for exiting copy mode:
bind-key -T copy-mode q send-keys -X cancel
Note that Escape is already bound to the same command, at least in tmux 2.7.
% tmux list-keys | grep "send-keys -X cancel"
bind-key -T copy-mode C-c send-keys -X cancel
bind-key -T copy-mode Escape send-keys -X cancel
bind-key -T copy-mode q send-keys -X cancel
bind-key -T copy-mode-vi C-c send-keys -X cancel
bind-key -T copy-mode-vi q send-keys -X cancel
The page you were referring to is not a comprehensive list of tmux commands, but rather a comparison of how to accomplish some common tasks in different terminal multiplexers.

How do you get the size of a non-interactive tmux pane?

I have several tmux panes running in a window that have been started with syntax like:
tmux split-window -h -l {dynamic value} tail -f somefile.txt
tmux split-window -v -l {dynamic value} tail -f someotherfile.txt
tmux split-window -h -l {dynamic value} nc -l -p {random port}
As I use this script to create new panes and I need to update an array in my script with the sizes of each "window" (pane).
If the tmux panes contained interactive shells, I could just run tput cols and tput rows in them to get the size. I checked the tmux man page, but didn't see the commands I'm looking for.
If you know a pane’s id (e.g. %24) or its name (e.g. session_name:win_idx.pane_idx; see target-pane in the man page), then you can use display-message -p to query the dimensions:
tmux display-message -pt "$pane" -F '#{pane_width}x#{pane_height}'
If you do not already have a way to name to panes, then you can collect the pane ids as you split them off by using the -P option along with the -F option:
pane_a=$(tmux split-window -PF '#{pane_id}' -hl "$dynamic_value" 'tail -f somefile.txt')
⋮ # create other panes
pane_a_width=$(tmux display-message -pt "$pane_a" -F '#{pane_width}')
If you want to know about all the panes in a window, then you can use list-panes with the window’s id (e.g. #5) or name (e.g. session_name.win_idx; see target-window in the man page):
tmux list-panes -t "$window" -F '#{pane_id} #{pane_width}x#{pane_height} #{session_name}:#{window_index}.#{pane_index}'
Some of these options and format specifiers are not available on old versions of tmux, but there are usually workarounds (depending on just how old your version is).