Is it possible to perform a replace-string
operation inside of a rectangular region in emacs? If so, how?
Simple Search and Replace Operations When you want to replace every instance of a given string, you can use a simple command that tells Emacs to do just that. Type ESC x replace-string RETURN, then type the search string and press RETURN.
The command C-x SPC ( rectangle-mark-mode ) toggles whether the region-rectangle or the standard region is highlighted (first activating the region if necessary).
If you enable CUA selection mode:
M-x cua-selection-mode
RET
or permanently in your init file:
(cua-selection-mode 1)
You can then use its advanced rectangle editing facilities.
(or if you're a cua-mode
user, then you don't need to do that.)
For documentation, look for the "CUA rectangle support" heading in the commentary in M-x find-library
RET cua-base
RET
If you don't want to use the cua rectangle facilities for some reason (perhaps if you really need replace-string
specifically), a custom function using apply-on-rectangle
would be pretty simply to put together.
Edit: Actually, slightly more complex than I had expected, but most of the code is the interactive spec and the support for the 'delimited' prefix argument behaviour (both based on replace-string
).
Edit 2: I decided this was worth doing in a more fully-featured manner:
The following provides C-xrM-% and C-xrC-M-%, which (hopefully) act the way you would expect.
(require 'rect) (defun my-search-replace-in-rectangle (start end search-pattern replacement search-function literal) "Replace all instances of SEARCH-PATTERN (as found by SEARCH-FUNCTION) with REPLACEMENT, in each line of the rectangle established by the START and END buffer positions. SEARCH-FUNCTION should take the same BOUND and NOERROR arguments as `search-forward' and `re-search-forward'. The LITERAL argument is passed to `replace-match' during replacement. If `case-replace' is nil, do not alter case of replacement text." (apply-on-rectangle (lambda (start-col end-col search-function search-pattern replacement) (move-to-column start-col) (let ((bound (min (+ (point) (- end-col start-col)) (line-end-position))) (fixedcase (not case-replace))) (while (funcall search-function search-pattern bound t) (replace-match replacement fixedcase literal)))) start end search-function search-pattern replacement)) (defun my-replace-regexp-rectangle-read-args (regexp-flag) "Interactively read arguments for `my-replace-regexp-rectangle' or `my-replace-string-rectangle' (depending upon REGEXP-FLAG)." (let ((args (query-replace-read-args (concat "Replace" (if current-prefix-arg " word" "") (if regexp-flag " regexp" " string")) regexp-flag))) (list (region-beginning) (region-end) (nth 0 args) (nth 1 args) (nth 2 args)))) (defun my-replace-regexp-rectangle (start end regexp to-string &optional delimited) "Perform a regexp search and replace on each line of a rectangle established by START and END (interactively, the marked region), similar to `replace-regexp'. Optional arg DELIMITED (prefix arg if interactive), if non-nil, means replace only matches surrounded by word boundaries. If `case-replace' is nil, do not alter case of replacement text." (interactive (my-replace-regexp-rectangle-read-args t)) (when delimited (setq regexp (concat "\\b" regexp "\\b"))) (my-search-replace-in-rectangle start end regexp to-string 're-search-forward nil)) (defun my-replace-string-rectangle (start end from-string to-string &optional delimited) "Perform a string search and replace on each line of a rectangle established by START and END (interactively, the marked region), similar to `replace-string'. Optional arg DELIMITED (prefix arg if interactive), if non-nil, means replace only matches surrounded by word boundaries. If `case-replace' is nil, do not alter case of replacement text." (interactive (my-replace-regexp-rectangle-read-args nil)) (let ((search-function 'search-forward)) (when delimited (setq search-function 're-search-forward from-string (concat "\\b" (regexp-quote from-string) "\\b"))) (my-search-replace-in-rectangle start end from-string to-string search-function t))) (global-set-key (kbd "C-x r M-%") 'my-replace-string-rectangle) (global-set-key (kbd "C-x r C-M-%") 'my-replace-regexp-rectangle)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With