Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

This is in a similar vein to my earlier question: Removing the last n characters from every line in an emacs buffer. The comments made there all apply here.

Suppose I want to either

insert the same text string on every line of an emacs buffer at the same place (k characters from the beginning)

or

remove n characters from every line of an emacs buffer starting at the same place (k characters from the beginning)

could I do that using replace-regex and if so, how? If not, is there some other way?

EDIT: To be clear, I'd like a solution which uses point and mark to define the location of insertion, as well as one that uses a specific n.

EDIT 2: Thanks to alexis for an answer based on replace-regex. Gilles pointed out that one could use the rectangle commands, e.g. string-rectangle. Though I use these commands regularly, it did not occur to me to use it here. Dumb of me.

share|improve this question

3 Answers 3

up vote 2 down vote accepted

The easiest way to do this is with the rectangle commands.

Go to the first line of the buffer (or more generally the first line where you want to insert text) and move to the column where you want to insert the text. Go to the last line and move to the same column (there's no built-in way to do that). Type C-x r t (string-rectangle) and type the string you want to insert.

You can use the following function to move the cursor to the same column as the mark:

(defun move-to-mark-column ()
  (interactive "@")
  (move-to-column (save-excursion
                    (goto-char (mark))
                    (current-column))))

If you want to move to a column by number, there's move-to-column: C-u 42 M-x move-to-column RET. Unless you bind this to a key, it's shorter to move to the beginning of the line and then by character count (Home C-u 42 Right), but this can move to the next line if the count is too high, whereas move-to-column leaves you at the end of the line in this case. Also move-to-column behaves differently if there are tabs or split lines.

If the point and mark aren't on the same column, they're opposite corner of a rectangle. The rectangle command affect all the characters inside that rectangle. string-rectangle erases the rectangle and puts the specified text on each line instead. C-x r d erases the rectangle. You can also copy-paste (C-x r M-w, C-x r k, C-x r y to copy/kill/yank) and insert or fill with rectangles (C-x r o, C-x r c to open/clear with spaces), and more.

share|improve this answer
    
Hi Gilles. Thank you very much for the answer. I must admit that I use the rectangle commands quite regularly, at least string-rectangle and delete-rectangle, but it didn't occur to me that they could be used here. –  Faheem Mitha Jan 13 at 21:03

Doing this with a replace-regexp is easy:

To insert HELLO after character 15, replace ^.\{15\} with \&HELLO.

This searches for 15 arbitrary characters, starting at the start of the line. It replaces them with themselves (\&) followed by HELLO.

You could write a macro that queries the current column at point and uses it to construct a regexp, but I wouldn't bother.

To remove text, follow the same approach but use a group for the characters that will be kept.

E.g., to remove characters 11-15: Replace ^\(.\{10\}\).\{5\} with \1

share|improve this answer

Using mark and point with rectangles:

For insertion, the easiest rectangle command is string-insert-rectangle. Go to the insertion column on the first line you wish to modify, set-mark (C-space), then move to the last line you wish to modify and move your point to the insertion column or greater. Then use M-x string-insert-rectangle to insert your string at the desired locations.

This is a bit simpler than the rectangle command string-rectangle (C-x rt), as it's similar, but replaces the selected rectangle, whereas string-insert-rectangle will insert ONLY at the leftmost of the two columns. Thus string-insert-rectangle allows you to be sloppier (faster, simpler) about selecting the column.

For deletion, mark a rectangle by setting mark at one corner, moving point to the other, then issuing C-x r k to run kill-rectangle. (This would allow you to later paste with C-x r y).

See more on rectangles in the Emacs manual rectangles section or see the file rect.el in your system. (C-h k C-x r t will display help for string-rectangle with a link to rect.el.)

Using regex - see alexis' answer

share|improve this answer
    
Thanks for pointing out string-insert-rectangle. –  Faheem Mitha Jan 13 at 21:26

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.