dajva / rg.el

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

Help wanted: how to get rg-match result position ? #170

Open liuyinz opened 1 month ago

liuyinz commented 1 month ago

@dajva thanks for your great package ! I write a command to replace matched result with given string as following:

(defun rg-replace(to-string)
    (interactive (list (read-string "Rg replace reulst with: ")))
    (let ((final-pos (point)))
      (unwind-protect
          (let* ((keep-asking t)
                 (stop-replace nil)
                 (from-string (or (rg-search-literal rg-cur-search)
                                  (rg-search-pattern rg-cur-search)))
                 (info (format "Replace match string with %s: (y,n,q,!,.) ?"
                               from-string to-string)))
            (cl-flet ((replace-func (prop)
                        (delete-region (prop-match-beginning prop) (prop-match-end prop))
                        (insert to-string)))
              (wgrep-change-to-wgrep-mode)
              (while (and (not stop-replace)
                          (setq cur-match (text-property-search-forward
                                           'face 'rg-match-face t)))
                (setq final-pos (point))
                (if keep-asking
                    (let ((illegal-key t))
                      (while illegal-key
                        (pcase (read-key info)
                          (?! (replace-func cur-match)
                              (setq keep-asking nil))
                          (?y (replace-func cur-match))
                          (?. (replace-func cur-match)
                              (setq stop-replace t))
                          ((or ?q ?\C-g) (setq stop-replace t))
                          (?n nil))
                        (when (member last-input-event '(?! ?y ?n ?. ?q ?\C-g))
                          (setq illegal-key nil))))
                  (replace-func cur-match)))))
        (wgrep-finish-edit)
        (goto-char final-pos))))

With a while form to search face 'rg-match-face and replace the region, it worked well In most scenarios, however when I use a regex which include "\n"(with option --multiline), the one matched result was highlighed seperated into two results. I guess it's because 'rg-match-face couldn't take effect on "\n" and when I use face to locate result, one result becomes two, my replacement failed.

截屏2024-06-01 04 29 58

for now, my solution for --multiline is to use query-replace-regexp to replace "\n" firstly, then use rg search and replace. Is there any other method to get matched result positions in the rg buffer ?

dajva commented 1 month ago

No, there isn't any tracking of that.