Adding a keybinding to enter vi copy mode in tmux - tmux

Pressing C-b and [ puts tmux in copy mode, this lets you select and copy text in a manner similar to vi.
Could you please show me how to add a new key binding like C-j to do this?
I guess it would look like - bind -n C-j function-to-enter-copy-mode
But, I don't know what the function to enter vi copy mode is called. I think I just need the function name.

bind -n C-j copy-mode
Add this to the tmux configuration file and reload tmux config

Related

How do you switch from a tmux pane that you've scrolled up in to another tmux pane?

If I have two tmux panes open and I go to one and scroll back to the history using CTRL-B [, then for some reason I can't switch to the other pane without making the current pane scroll back to the bottom. Does anyone know how to work around this? Note that I use some custom tmux configuration, as described here, to make it easier to navigate between vim windows and tmux panes. Is this somehow messing up how tmux scrolling works?
Is it possible you're running into a conflicting default keybinding for tmux when it's in copy mode?
When tmux is running, you can check the currently active keybindings by doing prefix+?. When I do this on a bare tmux config, I can see that C-k is bound to send-keys -X copy-end-of-line, and it will move a buffer that's in copy mode to the end of the buffer, like you're describing. Alternatively, if you're using tmux's copy-mode-vi, then it looks like C-j is bound by default to send-keys -X copy-selection-and-cancel.
Try adding the following to your .tmux.conf:
unbind-key -Tcopy-mode C-k
unbind-key -Tcopy-mode-vi C-j
After this configuration update, I'm able to use C-j and C-k to navigate panes like described in the article you linked.

Configure tmux copy mode to also dump a copy into the system clipboard

When working with multiple panes, it's convenient to use the tmux copy mode (ctrl+b [) to be able to use pane-aware copying. However, copy mode copies into a tmux copy buffer, rather than into the system clipboard. Ideally, I would like a copy to automatically copy into the system clipboard too.
A basic starting point was to add this alias to my bashrc:
alias tmux2clip='tmux save-buffer - | xsel -i -b' (on linux, requires xsel to be installed)
alias tmux2clip='tmux save-buffer - | pbcopy' (on macos)
After I copy using copy mode, I run the alias and the text gets copied into my clipboard! Works like a charm, but always requires that one extra manual step.
It would be ideal, if that alias can trigger as a kind of "post tmux copy hook" that I configure in tmux.
The best thing I could come up with is this line in my ~/.tmux.conf:
bind-key -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xsel -i -b"
# similarly, I believe only needed for keyboard based copies:
bind-key -T copy-mode C-w send-keys -X copy-pipe-and-cancel "xsel -i -b"
bind-key -T copy-mode M-w send-keys -X copy-pipe-and-cancel "xsel -i -b"
This causes any mouse based selection (note: I prefer mouse selection over keyboard based selections) to trigger a copy of that selection into my system clipboard. The annoying thing is though, that it will always happen, i.e. not only in copy mode, just anytime I select something it happens. This turns out to be quite sensitive in practice, just clicking the window with my mouse to give it focus often already accidentally triggers a small selection (often accidentally overwriting existing content in my clipboard, causing me to sometimes paste completely different stuff than intended).
I searched many similar questions but haven't been able to find any satisfying answers. I would really hope to find a way to get a kind of "post tmux copy hook" where I can insert my copy-to-clipboard command.
I use Ubuntu 18.04, with tmux 2.6. Please also be aware that I use mouse mode in my ~/.tmux.conf:
set -g mouse on
Any help would be highly appreciated. I've been wanting this for many months now already, and all of my revived efforts have only led to lost time :(
If you don't want tmux to enter copy mode when you drag on the pane, then unbind MouseDrag1Pane in the root table (unbind -n MouseDrag1Pane).

Different starting directory per window?

I daily use tmux (2.5) on my laptop to work, and my tmux sessions have a starting directory which is the working directory I started the tmux session from. Every pane/window I open start with this starting directory as working directory.
I can change this starting directory, and this change would apply to the whole session.
But if I want to work on a different project with several panes, I could start a new window, but every pane I would open in it would start with the session's starting directory : I would have to cd to the new location for each pane which isn't practical.
If I need to work on several project/directories simultaneously, I can start a new terminal session, then cd to the relevant directory/project and start a new tmux session. That's not complicated.
But if I want to do the same thing on a server through ssh, I'd need to either :
open a new ssh session.
either embed my remote tmux sessions in an other tmux session.
Neither sounds practical to me, I'd prefer a single tmux session on the remote machine.
I think it would be more convenient to being able to start new window with its own starting directory location that would apply to any new pane opened in it. Is there a way to achieve this?
Edit :
I already tried the -c parameter of tmux new-window command.
But it doesn't assign its starting directory to the window created this way, it only applies this custom starting directory to the first pane created.
Any new pane opened in this window then uses the session's starting directory as default working dir (and not the path passed to tmux new-window).
This question is very similar to: https://unix.stackexchange.com/questions/12032/create-new-window-with-current-directory-in-tmux
It depends on your tmux version but the -c parameter does do the trick but it does not remember the setting. There used to be a default-path setting but that has been removed in version 1.9 unfortunately.
For newer versions you will need to pass along the -c in all cases (you can use an alias if you manually execute that command) or if you use key bindings you need to rebind the split/new window keys.
bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"
To use a custom path instead of the current pane path, execute this command:
tmux setenv custom_path /home/whatever/some/path
Put this in your config:
bind '"' split-window -c "#{custom_path}"
bind % split-window -h -c "#{custom_path}"
bind c new-window -c "#{custom_path}"
Yes, it turns out the -c option to the new-window command is what you are looking for: https://unix.stackexchange.com/questions/12032/create-new-window-with-current-directory-in-tmux Also, this: https://unix.stackexchange.com/questions/101949/new-tmux-panes-go-to-the-same-directory-as-the-current-pane-new-tmux-windows-go
So either of tmux new-window -c $(pwd) or tmux new-window -c /path/to/dir inside your tmux session should do it.

tmux - Environment variables don't show up in session

I'm trying to move from screen to tmux (to eventually using tmux from within byobu). However, I have a severe problem with environment variables not being applied, especially PS1. None of them get copied to the session (or window) environments. I found this thread that seemed relevant:
How do I start tmux with my current environment?
However, I actually can see all my right variables when I do
:show-environment -g
But none of them get carried over to the session environment, so I don't see anything when I do
:show-environment
I do have the right update-environment statement in my ~/.tmuxrc file:
# start a non-login shell by default for each new window
set -g default-command 'bash'
# Prefix is C-a like in screen
unbind C-b
set -g prefix C-a
# Carry over the PS1
set-option -ga update-environment "PS1"
Frankly this all seems like a mess to me. I can see the benefit of starting from a clean session for each screen, but for the most part this seems like a pain. I export the variable I intend to use in sub-processes, such as as the Python virtualenvwrapper functions, and expect them to be available.
Is there a way to disable this behavior? If not, what should I try to carry over my PS1 variable to tmux?
EDIT 11/13/2013
I realized that removing the first line (default-command bash) does carry over all of the environment variables. However, I really don't want each new screen of tmux to launch as a login shell. For instance, I specifically declared my PS1 variable in a login shell, so that it wouldn't be overwritten whenever I open a new screen.
Based on the following post, every new screen in tmux should launch as a non-login shell:
https://superuser.com/questions/614277/profile-and-bash-profile-ignored-when-starting-tmux-from-bashrc
Why is this not happening by default for me?
Tmux cannot update running processes (e.g. bash), it can only update its own environment. If you were to start a new window/pane it would pick up the new environment. My suggestion would be to use a utility function like this:
#!/bin/bash
tmup ()
{
echo -n "Updating to latest tmux environment...";
export IFS=",";
for line in $(tmux showenv -t $(tmux display -p "#S") | tr "\n" ",");
do
if [[ $line == -* ]]; then
unset $(echo $line | cut -c2-);
else
export $line;
fi;
done;
unset IFS;
echo "Done"
}
This goes through all the updated environment that tmux has learned about and updates your shell.

tmux - split-window with custom environment variables

I want to split the current tmux window and have it inherit my current environment.
I need to do this programmatically so I can't do it through some predefined config file.
Simply put, I want to do something like,
tmux split-window my-binary
my-binary is in my current PATH but not the usual one (it seems tmux just goes through my bash_profile).
Is it possible? Or do I have to start bash and setup the env before starting my-binary?
To split a window that will run an instance of your default shell, use the env command that runs whatever is configured as default-command in your ~/.tmux.conf:
tmux split-window "env FOO=bar $(tmux show-options -vg default-command)"

Resources