dajva / rg.el

Emacs search tool based on ripgrep
https://rgel.readthedocs.io
GNU General Public License v3.0
480 stars 41 forks source link

add buffer local var rg-match-positions to record all match positions #172

Closed liuyinz closed 3 weeks ago

liuyinz commented 3 months ago

with the new var, user can replace matches very easily, how about this ? @dajva

liuyinz commented 3 months ago

A simple replace command

(defun rg-replace (to-string)
  "Replace matched result in rg-mode buffer."
  ;; SEE https://emacs.stackexchange.com/a/72155
  (interactive (list (minibuffer-with-setup-hook
                         (lambda () (set-mark (minibuffer-prompt-end)))
                       (read-string "Rg replace matched string with: "
                                    (pcase-let ((`(,begin . ,length)
                                                 (car rg-match-positions)))
                                      (buffer-substring-no-properties
                                       begin (+ length (marker-position begin))))))))
  (let ((stop-pos (point)))
    (unwind-protect
        (let ((keep-asking t)
              (replace-quit nil)
              (prompt (format "Replace match string with %s: (y,n,q,!,.) ?" to-string))
              (to-replaces (seq-filter (lambda (match)
                                         (< stop-pos
                                            (+ (marker-position (car match))
                                               (cdr match))))
                                       rg-match-positions)))
          (wgrep-change-to-wgrep-mode)
          (catch 'quit
            (dolist (cur-match to-replaces)
              (goto-char (setq stop-pos (car cur-match)))
              (let ((replace-p (not keep-asking)))
                (when keep-asking
                  (catch 'pass
                    (while-let ((key (single-key-description (read-key prompt) t)))
                      (when (member key '("q" "C-g" "ESC" "." "!" "y"
                                          "Y" "SPC" "n" "N" "DEL"))
                        (setq keep-asking (not (string= key "!")))
                        (setq replace-p (member key '("." "!" "y" "Y" "SPC")))
                        (setq replace-quit (member key '("q" "C-g" "ESC" ".")))
                        (throw 'pass nil)))))
                (when replace-p
                  (let ((begin (marker-position (car cur-match))))
                    (delete-region begin (+ begin (cdr cur-match)))
                    (insert to-string)))
                (when replace-quit (throw 'quit nil))))))
      (wgrep-finish-edit)
      (goto-char stop-pos))))
coveralls commented 3 weeks ago

Coverage Status

coverage: 81.869% (+0.1%) from 81.767% when pulling 0c23e586966b5decefab9d4b127b5a5038f5e41d on liuyinz:feat/rgmatch-positions into 6f1e39e811f3afc7fbc5934191790be85ee4cf91 on dajva:master.