63

I'm using tmux with vi keys, and copy/paste works fine as long as you're selecting one line of text, or if you have only one window. When I want to select a block of text (multiple lines, but not full width), then I run into trouble. If I have multiple vim windows opened, then it would select text from all of them, and what I need is to select text only from one window. That is, just like a visual select in vim.

Is this possible to do?

6
  • How do you activate Vi keybindings in tmux?
    – romainl
    Feb 29, 2012 at 6:40
  • add "set-window-option -g mode-keys vi" to your ~/.tmux.conf Apr 29, 2013 at 20:45
  • 1
    It looks like the answers aren't getting to your question of using visual block mode - "multiple lines, but not full width" is also what I'm looking for. Did you find your own solution?
    – dmonopoly
    Apr 23, 2014 at 14:38
  • Nope, still no solution. Jul 14, 2015 at 18:37
  • 1
    bind-key -t vi-copy 'C-v' rectangle-toggle Jul 14, 2015 at 18:41

8 Answers 8

71

Make sure to check the bottom of this post for necessary bindings that need to go into your .tmux.conf file.

I am assuming your prefix key is C-a:

  • C-a means: press Ctrl + A
  • C-a [ means: press Ctrl + A then press [

To do a rectangle selection of text from (1,1) to (2,2) in tmux:

  • Go to the copy mode: C-a [
  • Move the middle of a line
  • Press C-v
  • Press Space
  • Move the selection with jkhl
  • Once you are happy with your selection press Enter (or y if you have the binding in your conf file).
  • You can paste the latest copy buffer by: C-a ]

Notice that pressing space is necessary for rectangle selection.

To select lines like you would normally do, go the copy mode, and press v, select with jkhl keys and press y.

I have these bindings in my .tmux.conf:

Prior to version 2.4 (20 April 2017):

setw -g mode-keys vi
bind-key -t vi-copy 'v' begin-selection     # Begin selection in copy mode.
bind-key -t vi-copy 'C-v' rectangle-toggle  # Begin selection in copy mode.
bind-key -t vi-copy 'y' copy-selection      # Yank selection in copy mode.

After version 2.4:

setw -g mode-keys vi
bind-key -T copy-mode-vi 'v' send -X begin-selection     # Begin selection in copy mode.
bind-key -T copy-mode-vi 'C-v' send -X rectangle-toggle  # Begin selection in copy mode.
bind-key -T copy-mode-vi 'y' send -X copy-selection      # Yank selection in copy mode.

It is important to unbind default rectangle-toggle binding:

unbind-key -t vi-copy v  # Prior to version 2.4
unbind-key -T copy-mode-vi v

Otherwise new 'C-v' binding doesn't work.

Note: to have a single .tmux.conf which works across versions, see this question.

6
  • 1
    Thank you so much. The emphasis is on your tmux.conf - you could edit the answer to include bind-key -t vi-copy 'C-v' rectangle-toggle at the beginning. Jul 14, 2015 at 18:42
  • The original question asks how to get rectangular selection working with "mode-keys vi". There is no need to re-bind keys to answer this question. See the other answers; it's just "v" and "space" from selection mode.
    – Lqueryvg
    Oct 15, 2015 at 8:54
  • this works other than the fact that jkhl do not work, I have to use the arrow keys to move around, is there any way to change this?
    – Max
    Apr 2, 2019 at 22:53
  • What is the difference between send and send-keys. I see in superuser.com/questions/196060/selecting-text-in-tmux-copy-mode send-key is used. Also are the quotation marks important? Oct 18, 2019 at 16:54
  • @user2442366 send is an alias for send-keys. Jul 14, 2022 at 23:52
20

You can select a visual block just like in vi -- type v before starting the selection. In the manpage, this is called "Rectangle toggle".

2
  • 2
    That exactly what I'm using. But that has a problem which I described above. The rectangle is always full width. I need a VIM-like rectangle (x1, y1) - (x2, y2) :) Apr 29, 2013 at 20:44
  • 1
    @Srećko Toroman what do you mean exactly with full width?
    – gitaarik
    Jan 2, 2014 at 16:24
12

As Lars points out, v actually does what you are asking for by toggling between rectangle mode and full-line selection mode. space and enter are used respectively to start a new selection and copy it. Enter copy mode using your prefix followed by [ and paste your copied selection into any tmux window using ]

This confused me also since v functions in vim as space does in tmux , to begin the selection.

Issuing :list-keys -T copy-mode-vi in tmux will show the full table of commands in copy mode.

bind-key -t vi-copy    C-b page-up                                                      
bind-key -t vi-copy    C-c cancel
bind-key -t vi-copy    C-e scroll-down
bind-key -t vi-copy    C-f page-down
bind-key -t vi-copy    C-h cursor-left
bind-key -t vi-copy  Enter copy-selection
bind-key -t vi-copy    C-y scroll-up
bind-key -t vi-copy Escape clear-selection
bind-key -t vi-copy  Space begin-selection
bind-key -t vi-copy      $ end-of-line
bind-key -t vi-copy      , jump-reverse
bind-key -t vi-copy      / search-forward
bind-key -t vi-copy      0 start-of-line
bind-key -t vi-copy      1 start-number-prefix
bind-key -t vi-copy      2 start-number-prefix
bind-key -t vi-copy      3 start-number-prefix
bind-key -t vi-copy      4 start-number-prefix
bind-key -t vi-copy      5 start-number-prefix
bind-key -t vi-copy      6 start-number-prefix
bind-key -t vi-copy      7 start-number-prefix
bind-key -t vi-copy      8 start-number-prefix
bind-key -t vi-copy      9 start-number-prefix
bind-key -t vi-copy      : goto-line
bind-key -t vi-copy      ; jump-again
bind-key -t vi-copy      ? search-backward
bind-key -t vi-copy      B previous-space
bind-key -t vi-copy      D copy-end-of-line
bind-key -t vi-copy      E next-space-end
bind-key -t vi-copy      F jump-backward
bind-key -t vi-copy      G history-bottom
bind-key -t vi-copy      H top-line
bind-key -t vi-copy      J scroll-down
bind-key -t vi-copy      K scroll-up
bind-key -t vi-copy      L bottom-line
bind-key -t vi-copy      M middle-line
bind-key -t vi-copy      N search-reverse
bind-key -t vi-copy      T jump-to-backward
bind-key -t vi-copy      W next-space
bind-key -t vi-copy      ^ back-to-indentation
bind-key -t vi-copy      b previous-word
bind-key -t vi-copy      e next-word-end
bind-key -t vi-copy      f jump-forward
bind-key -t vi-copy      g history-top
bind-key -t vi-copy      h cursor-left
bind-key -t vi-copy      j cursor-down
bind-key -t vi-copy      k cursor-up
bind-key -t vi-copy      l cursor-right
bind-key -t vi-copy      n search-again
bind-key -t vi-copy      q cancel
bind-key -t vi-copy      t jump-to-forward
bind-key -t vi-copy      v rectangle-toggle
bind-key -t vi-copy      w next-word
bind-key -t vi-copy BSpace cursor-left
bind-key -t vi-copy  NPage page-down
bind-key -t vi-copy  PPage page-up
bind-key -t vi-copy     Up cursor-up
bind-key -t vi-copy   Down cursor-down
bind-key -t vi-copy   Left cursor-left
bind-key -t vi-copy  Right cursor-right
bind-key -t vi-copy   C-Up scroll-up
bind-key -t vi-copy C-Down scroll-down
4
  • I don't get it again. Given a Vim window with a vertical split, how do you select a rectangle in the first split only? Here, the multiline rectangle will always wrap the full Tmux pane. It's not like a Vim block selection. I'm using tmux 1.5, maybe it's different in your version? Jul 3, 2013 at 16:36
  • Yeah, here, v is mapped to begin-selection. The rectangle-toggle is undefined. So I guess both of you are right, I just need to update my client? Jul 3, 2013 at 16:39
  • If you have a split vim window open in a single tmux pane, can't you use vim's yank and paste ability? If on the other hand you have two tmux panes, each with it's own vim window, tmux select/copy should be able to wrap at the pane edges. I'm using tmux 1.7
    – here
    Jan 28, 2014 at 6:13
  • 1
    With version 3.3a here, the command to getting key bindings is now: :list-keys -T copy-mode-vi
    – unifreak
    Aug 19, 2023 at 23:23
8

Since none of the other answers give an optimal solution to the problem, I'm not above necromancy.

There is a way to have block selection work the same way it does in Vim, without having to press space. Just a simple Ctrl-V, ingrained in your muscle memory.
It requires editing your .tmux.conf (but using vi-mode already does so) and I'm not sure it works for tmux < 2.4.

Add this to your .tmux.conf to replicate Vim selection and yank bindings:

# set vi-mode
set-window-option -g mode-keys vi
# keybindings
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle \; send -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
# comment the preceding line and uncomment the following to yank to X clipboard
# bind-key -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"

Enter selection mode and navigate to where you want to begin the selection. Now v starts regular (character-by character, line-wise) selection, <C-v> starts block selection and V (shift-v) starts line selection. Regardless of the type of selection, y yanks to tmux paste buffer (or X clipboard; see code comments above).

Same as Vim.

2
  • 1
    Worked for me, have an upvote towards your necomancy 👏👏👏
    – mahemoff
    Jan 5, 2018 at 12:43
  • This works great except that after using <C-v>, rectangle selection remains toggled on for future selections, which is annoying. I doubt I'll use it along with normal selection much so this probably works fine for most cases (it might almost never come up outside of playing with this functionality). But is there a smart way to have this untoggle rectangle selection after you exit that particular selection?
    – Connor
    Jan 21, 2020 at 17:30
3

Here is a solution for macOS users

  1. prefix+[ to enter copy mode
  2. navigate to the start or the end of text selection with arrow keys
  3. press space to to start selection, sometimes control+space
  4. move to opposite end of text to copy with arrow keys
  5. press return to copy selected text into tmux clipboard, sometimes control+w or esc+w or alt+w
  6. in the same tmux session, paste with prefix+], to paste into vim, use prefix+] in vim insert mode
2

EDIT: After checking the source code, I've re-written my answer completely.

I originally thought this wasn't possible because I couldn't get this to work, but the other answers are correct about v being the correct key for this, but it's not obvious how to use this, especially if you are used to vim.

Also, it wouldn't work for me because I had v bound to begin-selection - I think I must have blindly copied this idea from somewhere else to mimic the vim way to start a character wise selection, not knowing it would cause problems further down the road with block selections.

$ tmux -V
tmux 1.9a
$ tmux list-keys -t vi-copy  | grep " v "
bind-key -t vi-copy      v begin-selection     # suppressed my block selection mode

Once I took away this binding (by commenting out the line in my .tmux.conf and restarting tmux), it started to work, but it's still rather confusing because it's not the same as vim at all.

With default bindings, it should work as follows:

  1. Make sure you have tmux unning with setw -g mode-keys vi in your .tmux.conf.
  2. type C-a [ to start copy mode
  3. move the cursor to where you want to begin the selection
  4. type v
  5. type Space to start the selection
  6. move the cursor and you will see a rectangular selection
  7. you can press v again to toggle the selection back into character-wise selection or vice-versa.

You don't have to type the v before you press Space. You could start the the character-wise selection with Space first and press v afterwards to toggle to rectangular selection mode.

It's quite different from vim in that in tmux you have to type two characters: Space and v to get into rectangular selection mode. In vim you only have to type Ctrl-V.

Also in vim v starts a character-wise selection, not block.

Sadly, there doesn't seem to be a line-wise selection mode in tmux (Shift-v in vim).
EDIT: It looks like Tmux version 2.0 provides a line-wise selection mode with Shift-v (I haven't tried it yet though!)

6
  • Press "v" and you can select lines. No need for space. Oct 14, 2015 at 6:02
  • 1
    @AmirH.Sadoughi, that's because (as per your answer) you've changed the defaults and bound "v" to begin the selection instead of "space". If you start with an empty .tmux.conf you should find the behaviour I describe is correct; you have to press "space" to start the selection.
    – Lqueryvg
    Oct 14, 2015 at 19:13
  • 1
    Thanks for correcting me. To address your last sentence (about line-wise selection), I was trying to say that with my config, I can do a block selection with c-v-space, and I can do a line selection with v. so, pressing "prefix v" allows me to select lines. Oct 16, 2015 at 4:06
  • I find that very hard to believe because line-wise selection was only added to Tmux recently (Shift-v in release 2.0 March 2015), certainly after my answer and long after your original answer. Perhaps you and I are talking about two different things when we talk about line-wise selection. Please compare with the 3 selection modes in VIM (with v, Shift-v and Ctrl-v).
    – Lqueryvg
    Oct 16, 2015 at 13:02
  • You are right, I just tested it. My v selection is character wise. I am on version 1.9a and don't have the vim-like line-wise selection. So, with version 2.0, the exact three modes that vim has is possible in tmux too, right? Oct 16, 2015 at 13:19
0

Since all suggested solutions rely on tmux key bindings in config, and so require restart of all active tmux session, there's a "hotplug" solution. You can do a rectangle selection without leaving tmux.

How to make a rectangle selection in tmux without restart:

I am assuming your prefix key is Ctrl+B.

Start as usual:

  1. Go to the copy mode: Ctrl+B then [
  2. Move cursor to the middle of a line

The steps below are specific for rectangle selection:

  1. Press Ctrl+B then : (: might actually be a Shift+;) to enter a command prompt.
  2. Type in, depending on tmux version (as mentioned in Amir's answer and several others):
    • tmux >= 2.4: send -X rectangle-toggle
    • tmux < 2.4: rectangle-toggle

Then press Enter to execute command. The command prompt line will disappear.

Now, continue as usual:

  1. Press Ctrl+Space
  2. Move the selection with arrows
  3. Copy to buffer with Alt+W

The rectangle-toggle is one-shot command, so your next selection will remain full-line, unless you call rectangle-toggle before selecting again.

0

I started with this answer but wasn't happy until it behaved exactly like vim:

set-option -g mode-keys vi

bind-key -T copy-mode-vi v {
    if-shell -F "#{selection_present}" {
        if-shell -F "#{rectangle_toggle}" {
            send-keys -X rectangle-off
        } {
            send-keys -X clear-selection
        }
    } {
        send-keys -X begin-selection
    }
}

bind-key -T copy-mode-vi C-v {
    if-shell -F "#{selection_present}" {
        if-shell -F "#{rectangle_toggle}" {
            send-keys -X clear-selection
        } {
            send-keys -X rectangle-on
        }
    } {
        send-keys -X begin-selection
        send-keys -X rectangle-on
    }
}

bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .