Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] Make "*Embark Occur*" supporting wgrep for some special command #47

Closed
jixiuf opened this issue Dec 12, 2020 · 11 comments

Comments

@jixiuf
Copy link

jixiuf commented Dec 12, 2020

Xref provides helpful commands for code navigation and discovery, such as xref-find-definitions and project-find-regexp ,and project-find-regexp support ripgrep now( on emacs master) .

When a xref query hits multiple candidates Emacs shows a Xref
buffer with the various candidates and their location.

On emacs master, it support using completing-read showing the multiple candidates now with xref--show-defs-minibuffer

https://lists.gnu.org/archive/html/emacs-devel/2020-11/msg00707.html

(with-eval-after-load 'xref
  (setq xref-search-program 'ripgrep)     ;default `grep`,  for project-find-regexp
  (when (functionp 'xref--show-defs-minibuffer)
    (setq xref-show-definitions-function 'xref--show-defs-minibuffer) ; using completing-read
    (setq xref-show-xrefs-function 'xref--show-defs-minibuffer)))

this is a screenshot of project-find-regexp in minibuffer
image

And I can export the result to "Embark Occur" with embark-occur

image

So I think it is great for "Embark Occur" support wgrep like ivy-occur/grep,
I think minad/consult#46 can benefit from it too, once consult-rg/ag is implemented.

@oantolin
Copy link
Owner

I wouldn't want to reinvent wgrep here. So I think the best option is to not use embark-occur, but rather make it so embark-export works with these functions you mentioned, and produces an actual grep buffer you can use with the standard wgrep.

@jixiuf
Copy link
Author

jixiuf commented Dec 13, 2020

it’s ok for me

@manuel-uberti
Copy link

I second @jixiuf enthusiasm on this. :)

@jixiuf
Copy link
Author

jixiuf commented Dec 19, 2020

(require 'wgrep)

;;;###autoload
(defun embark-occur-wgrep-setup ()
  (set (make-local-variable 'wgrep-header/footer-parser)
       'embark-occur-wgrep-prepare-header/footer)
  (set (make-local-variable 'wgrep-results-parser)
       'embark-occur-wgrep-parse-command-results)
  (wgrep-setup-internal))

(defun embark-occur-wgrep-prepare-header/footer ()
  (let ((beg (point-min))
        (end (point-min))
        (overlays (overlays-at (point-min))))
    ;; Set read-only grep result header
    (dolist (o overlays)
      (when (eq (overlay-get o 'face) 'tabulated-list-fake-header)
        (setq end (overlay-end o))))
    (put-text-property beg end 'read-only t)
    (put-text-property beg end 'wgrep-header t)
    ;; embark-occur-mode have NO footer.
    (put-text-property (1- (point-max)) (point-max) 'read-only t)
    (put-text-property (1- (point-max)) (point-max) 'wgrep-footer t)))


(defun embark-occur-wgrep-parse-command-results ()
  (while (not (eobp))
    (when (looking-at wgrep-line-file-regexp)
      (let* ((start (match-beginning 0))
             (end (match-end 0))
             (line (string-to-number (match-string 3)))
             (fn (match-string 1))
             (fnamelen (length fn))
             (dir (locate-dominating-file default-directory fn)))
        (unless (file-name-absolute-p fn)
          (setq fn (expand-file-name fn dir)))
        (let* ((fprop (wgrep-construct-filename-property fn)))
          (put-text-property start end 'wgrep-line-filename fn)
          (put-text-property start end 'wgrep-line-number line)
          (put-text-property start (+ start fnamelen) fprop fn))))
    (forward-line 1)))


;;;###autoload
(add-hook 'embark-occur-mode-hook 'embark-occur-wgrep-setup)

With this code, "Embark Occur" should support wgrep for project-find-regexp xref-find-definitions .

Edit: still has bug, and need wgrep change something in https://github.com/mhayashi1120/Emacs-wgrep/blob/master/wgrep.el#L416 wgrep-set-readonly-area.
"Embark Occur" do not has a wgrep-header, and it make wgrep-set-readonly-area does not work

@manuel-uberti
Copy link

Thanks, but I am not able to save the changes with it. I can edit the Embark Occur buffer, replace something in it with query-replace and see the changes in the buffer, but I cannot "commit" the changes nor save the modified files. Am I missing something?

@oantolin
Copy link
Owner

I'm sorry I took so long, this turned out to be trivial to do!

I added an exporter for grep mode results, and I associated it to category grep because that's the category consult uses for consult-grep, consult-git-grep and consult-ripgrep. If you want to use the exporter for project-find-regexp, the easiest way is to install Marginalia, add (project-find-regexp . grep) to marginalia-command-categories, and activate marginalia-mode (same for any other commands you might

Once you've done that, running embark-export (which you can get as action E in embark-act) from one of these grepping commands, will produce a normal grep buffer. Then you can use wgrep on it as usual.

@oantolin
Copy link
Owner

oantolin commented Dec 29, 2020

Oh, I spoke too soon. The grep mode buffers produced by export seem to work fine as grep buffers (pressing RET on a link works, and next/previous-error works too), but wgrep doesn't seem to work on them, it makes the text read-only, which is the opposite of what you want.

@oantolin
Copy link
Owner

OK, I inserted a fake header into the exported buffer, and now wgrep works.

If wgrep accepts your pull request, @jixiuf, then we could remove this fake header.

@oantolin
Copy link
Owner

Please test, and reopen or file another issue if there is any problem.

@oantolin
Copy link
Owner

@jixiuf, I noticed that Emacs 28 will report xref-location as the category when prompting you in the minibuffer for a grep result. So you can add (xref-location . embark-export-grep) to embark-exporters-alist instead of configuring Marginalia as I described above. If you can confirm that adding xref-location works, I'll add it to the defaults in Embark. (My Emacs doesn't have these xref features yet).

@oantolin
Copy link
Owner

Quick update: Embark now uses the grep exporter for the xref-location category (instead of grep), so it should work with project-find-regexp out of the box now, as well as with the consult-*grep family of commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants