开发者

Emacs copy matching lines

开发者 https://www.devze.com 2022-12-20 18:58 出处:网络
In Emacs how can I easily copy all lines matching a particular regex?Preferably highlighting the matching line开发者_如何转开发s as I type.

In Emacs how can I easily copy all lines matching a particular regex? Preferably highlighting the matching line开发者_如何转开发s as I type.

occur gets partway there by coping them into a buffer, but it adds lots of extra stuff.


As of Emacs 24, occur does in fact provide a simple solution:

C-uM-so .*pattern.* RET

When you use C-u on its own as the prefix argument, the matching portion of each line is inserted into the *Occur* buffer, without all the normal adornments.

Note that because only the part of the line matching the regexp is used (unlike a normal occur), you need the leading and trailing .* to ensure that you capture the entire line.

The details of how occur treats arguments are a little tricky, so read C-hf occur RET carefully if you want to know more.


How about this:

(defun copy-lines-matching-re (re)
  "find all lines matching the regexp RE in the current buffer
putting the matching lines in a buffer named *matching*"
  (interactive "sRegexp to match: ")
  (let ((result-buffer (get-buffer-create "*matching*")))
    (with-current-buffer result-buffer 
      (erase-buffer))
    (save-match-data 
      (save-excursion
        (goto-char (point-min))
        (while (re-search-forward re nil t)
          (princ (buffer-substring-no-properties (line-beginning-position) 
                                                 (line-beginning-position 2))
                 result-buffer))))
    (pop-to-buffer result-buffer)))


You can use keep-lines to get what you want, copy them, and then undo. For the opposite, there is also flush-lines to get rid of lines you don't want.


I've been using this happily for a long time:

    (defun occur-mode-clean-buffer ()
  "Removes all commentary from the *Occur* buffer, leaving the
unadorned lines."
  (interactive)
  (if (get-buffer "*Occur*")
      (save-excursion
        (set-buffer (get-buffer "*Occur*"))
        (fundamental-mode)
        (goto-char (point-min))
        (toggle-read-only 0)
        (set-text-properties (point-min) (point-max) nil)
        (if (looking-at (rx bol (one-or-more digit)
                            (or " lines matching \""
                                " matches for \"")))
            (kill-line 1))
        (while (re-search-forward (rx bol
                                      (zero-or-more blank)
                                      (one-or-more digit)
                                      ":")
                                  (point-max)
                                  t)
          (replace-match "")
          (forward-line 1)))

    (message "There is no buffer named \"*Occur*\".")))

(define-key occur-mode-map (kbd "C-c C-x") 'occur-mode-clean-buffer)


You can install package all. Then M-x all lets you edit all the lines in the buffer matching a regexp. Instead of editing, you can just copy them too.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号