2008-12-22

working with rectangular selections

When editing text, sometimes it is useful to work with rectangular selections. Suppose we have some list of names and years of birth/death; however we want have a list of only the names. Normal selection of text won't work, because it selects full lines of text between the starting and finish points, something like this:
1. Isaac Newton          1643-1727
2. Carl Friedrich Gauss  1777-1855
3. Charles Darwin        1809-1882
4. Albert Einstein       1879-1955
5. Your Name             1972-?
example 1: normal selection

Clearly, that is not what we want. Instead, we'd like to do a rectangular selection, like this:

1. Isaac Newton          1643-1727
2. Carl Friedrich Gauss  1777-1855
3. Charles Darwin        1809-1882
4. Albert Einstein       1879-1955
5. Your Name             1972-?
example 2: rectangular selection

Emacs has been able to do rectangular selections since a long time; see the section in the GNU/Emacs manual. You can do something like C-x r k to cut ('kill') a rectangle, and then use C-x r y to paste ('yank').

However, one thing to remember is that the selection itself is done in the 'normal' way (see the entry on selections); i.e. you start the selection with C-SPC, and the selected area ('region') will be the anything between the starting point ('mark') and the current cursor position ('point'). Emacs does not distinguish the selection as being either a normal or rectangular -- it cannot read your mind. For example, C-w gives a 'normal' cut, while C-x r k cuts the rectangular selection.

This worked pretty well when Emacs selections were not visible (once more, see the entry on selections). You couldn't see any selection, so it was up to you to interpret it as either normal or rectangular. However, today we usually do have visual selections, which makes all selections, normal or rectangular, look like example 1.

To overcome the cognitive dissonance, there's the rect-mark-package, which makes rectangular selections visible as in example 2.

You can install the package in the normal way, and add some key bindings to your .emacs.

(require 'rect-mark)
(global-set-key (kbd "C-x r C-SPC") 'rm-set-mark)
(global-set-key (kbd "C-x r C-x")   'rm-exchange-point-and-mark)
(global-set-key (kbd "C-x r C-w")   'rm-kill-region)
(global-set-key (kbd "C-x r M-w")   'rm-kill-ring-save)
The keybindings are suggested by the package - you have to prefix the normal cut/copy/paste keybindings with C-x r. If you are a bit more adventurous, and willing to override some very basic key bindings, instead of the above, you could try:
(require 'rect-mark)
(global-set-key (kbd "C-x r C-SPC") 'rm-set-mark)
(global-set-key (kbd "C-w")  
  '(lambda(b e) (interactive "r") 
     (if rm-mark-active 
       (rm-kill-region b e) (kill-region b e))))
(global-set-key (kbd "M-w")  
  '(lambda(b e) (interactive "r") 
     (if rm-mark-active 
       (rm-kill-ring-save b e) (kill-ring-save b e))))
(global-set-key (kbd "C-x C-x")  
  '(lambda(&optional p) (interactive "p") 
     (if rm-mark-active 
       (rm-exchange-point-and-mark p) (exchange-point-and-mark p))))
This way, you only need to remember that C-x r C-SPC starts a rectangular selection, and after that, the normal keybindings (C-w, C-m and C-x C-x) work, and do the 'right thing', depending on whether you made a rectangular or normal selection. I don't really like overriding such basic key bindings, but in practice it seems to work quite well. A limitation is that this only works when using the key binding; if you copy-paste using the menu or click the icon, it won't work -- you'd need more intrusive changes for that.

You also might want to add the following key bindings to allow for rectangular selection with the mouse after pressing C-x r:

(global-set-key (kbd "C-x r <down-mouse-1>") 'rm-mouse-drag-region)

I think it would be useful if emacs included rectangular selection functionality on a bit deeper level, where all functions that work on selections would automatically use either the normal or rectangular version. Right now, rectangular selections are a more difficult to use than they have to.

3 comments:

Anonymous said...

Check also the rectangle functionality of CUA-mode, activated M-x cua-mode, C-enter

djcb said...

@Anonymous: yeah, cua's handling of rectangular selections is a bit saner.

in fact, cua's rectangular-selection part might be a good starting point for adding the functionality to emacs proper.

boskom said...

Just to report broken link/missing page:

http://emacs-fu.blogspot.com/2000/12/installing-packages.html