Skip to content

Instantly share code, notes, and snippets.

@unhammer
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save unhammer/8917382 to your computer and use it in GitHub Desktop.
Save unhammer/8917382 to your computer and use it in GitHub Desktop.
First ask for a regex of which lines to match, then do query-replace on only lines that match that regex, like sed '/lineregex/ s/foo/bar/g'
(defvar *query-replace-matching-lines-history* nil)
(defun query-replace-matching-lines-read-arg ()
(let* ((default (or (car *query-replace-matching-lines-history*)
"^"))
(input
(read-from-minibuffer
(concat "Line regexp"
(if default
(format " (default: %s): " (query-replace-descr default))
": "))
nil nil nil
(quote *query-replace-matching-lines-history*)
default)))
(if (equal input "")
default
input)))
(defun query-replace-matching-lines (line-regexp from-string to-string &optional delimited start end)
(interactive
(let ((line-regexp (query-replace-matching-lines-read-arg))
(common
(query-replace-read-args
(concat "Query replace"
(if current-prefix-arg " word" "")
(if (and transient-mark-mode mark-active) " in region" ""))
nil)))
(list line-regexp
(nth 0 common) (nth 1 common) (nth 2 common)
;; These are done separately here
;; so that command-history will record these expressions
;; rather than the values they had this time.
(if (and transient-mark-mode mark-active)
(region-beginning))
(if (and transient-mark-mode mark-active)
(region-end)))))
;; This is mainly the part that's different from query-replace:
(let ((start (or start (point)))
(end (or end (point-max))))
(goto-char start)
(while (and (< (point) end)
(search-forward-regexp line-regexp end 'noerror))
(let ((line-start (min (point) (line-beginning-position)))
(line-end (min end (line-end-position))))
(when (save-excursion
;; Avoid a message if no replacements to be performed:
(search-forward from-string line-end 'noerror))
(perform-replace from-string to-string
'query
nil ; not regexp
delimited nil nil
line-start line-end)))
(forward-line))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment