tmux copy mode - select text block

41

18

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?

Srećko Toroman

Posted 2012-02-29T00:18:26.760

Reputation: 513

Nope, still no solution. – Srećko Toroman – 2015-07-14T18:37:41.820

Actually, there is a solution. – Srećko Toroman – 2015-07-14T18:41:38.287

bind-key -t vi-copy 'C-v' rectangle-toggle – Srećko Toroman – 2015-07-14T18:41:41.953

How do you activate Vi keybindings in tmux? – romainl – 2012-02-29T06:40:37.387

add "set-window-option -g mode-keys vi" to your ~/.tmux.conf – Srećko Toroman – 2013-04-29T20:45:58.967

1It 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 – 2014-04-23T14:38:50.620

Answers

48

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.

Amir H. Sadoughi

Posted 2012-02-29T00:18:26.760

Reputation: 596

1Thank 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. – Srećko Toroman – 2015-07-14T18:42:46.593

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 – 2015-10-15T08:54:06.200

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 – 2019-04-02T22:53:43.877

What is the difference between send and send-keys. I see in https://superuser.com/questions/196060/selecting-text-in-tmux-copy-mode send-key is used. Also are the quotation marks important?

– user2442366 – 2019-10-18T16:54:40.430

15

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

Lars Kotthoff

Posted 2012-02-29T00:18:26.760

Reputation: 1 447

2That 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) :) – Srećko Toroman – 2013-04-29T20:44:31.400

1@Srećko Toroman what do you mean exactly with full width? – gitaarik – 2014-01-02T16:24:20.403

9

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 vi-copy 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

here

Posted 2012-02-29T00:18:26.760

Reputation: 190

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? – Srećko Toroman – 2013-07-03T16:36:40.193

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? – Srećko Toroman – 2013-07-03T16:39:53.263

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 – 2014-01-28T06:13:21.237

7

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.

andrejr

Posted 2012-02-29T00:18:26.760

Reputation: 171

Worked for me, have an upvote towards your necomancy – mahemoff – 2018-01-05T12:43:35.957

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 – 2020-01-21T17:30:52.313

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!)

Lqueryvg

Posted 2012-02-29T00:18:26.760

Reputation: 558

Press "v" and you can select lines. No need for space. – Amir H. Sadoughi – 2015-10-14T06:02:32.843

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 – 2015-10-14T19:13:37.163

1Thanks 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. – Amir H. Sadoughi – 2015-10-16T04:06:27.617

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 – 2015-10-16T13:02:17.533

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? – Amir H. Sadoughi – 2015-10-16T13:19:56.317

Yes I believe so. The source code on git seems to suggest it should work. I'd be interested to know if it does; I think it throws slightly different light on the original question here. – Lqueryvg – 2015-10-16T13:32:53.763