0

I am working inside a git-repo. Here I want to apply my search operation based on the root directory of the git repo that current buffer is open.

Here I do: find-dired "~/my_project" ... in order to replace all Python files.

(defun my-find-files ()
  (interactive)
  (message "press t to toggle mark for all files found && Press Q for Query-Replace in Files...")
  (find-dired "~/my_project" "-name \\*.py ! -name flycheck_\\*.py ! -name __init__.py"))

(global-set-key (kbd "M-z") 'my-find-files)

Instead how can I set "~/my_project" folder path dynamically based on the current buffer's root git repo.

git rev-parse --show-toplevel returns the root of the git repository where the file lives. I was wondering would it be possible to pass its return value instead of "~/my_project"?

Related: Using Emacs to recursively find and replace in text files not already open

Drew
  • 75,699
  • 9
  • 109
  • 225
alper
  • 1,238
  • 11
  • 30

3 Answers3

3

You can use project-find-regexp (C-x p g), from project.el, to find the regexp you are looking for and in the resulting buffer you can hit r (xref-query-replace-in-results) to replace what you need.

If your Emacs version does not come with project.el already built-in, you can get it from ELPA: https://elpa.gnu.org/packages/project.html

Manuel Uberti
  • 3,150
  • 18
  • 36
2

You can use (vc-git-root (buffer-file-name)) in place of "~/my_project". It walks up the tree until it finds the directory that contains the .git subdir and declares that to be the root of the repo.

NickD
  • 27,023
  • 3
  • 23
  • 42
  • Can we also check condition if there is no git-repo in the folder in order to prevent `Error running timer: (void-function vc-git-root)` message? – alper Oct 26 '21 at 13:03
  • You should ask this in a separate question: nobody will see this comment otherwise :-) You can refer back to this question for context. – NickD Oct 26 '21 at 15:27
  • Please see: https://emacs.stackexchange.com/q/69097/18414 . PS I am sorry for askling too many questions – alper Oct 26 '21 at 19:33
  • 2
    Don't worry about asking "too many" questions: just try to make each one a *good* question: crisp and clear statement of the problem, as much information as necessary (but no more: *long*, meandering questions will discourage most responders), things you tried that failed to resolve the problem, version information etc. are all good things to include. Plus the standard rules: one question per question and do not change the question after posting (except for corrections and adding detail) - in particular, never change the original question to ask a different one: ask a new question instead. – NickD Oct 26 '21 at 19:58
0
  • Install counsel (https://elpa.gnu.org/packages/counsel.html)
  • M-x counsel-git-grep
  • Press C-c C-o or M-x ivy-occur to export result to a buffer in ivy-occur-grep-mode
  • Press C-x C-q or M-x ivy-grep-change-to-wgrep-mode to switch to wgrep-mode and make the buffer editable
  • Edit the buffer and press C-c C-c or M-x wgrep-finish-edit to commit the changes of the buffer. Then corresponding files will be updated

I use counsel&ivy because it provides the integration of wgrep-mode. Other completion/filter frameworks (helm, eg) could do the same thing.

Or you could integrate wgrep-mode into your own grep command.

Here is an example I grep my "emacs.d" and export the result of the buffer in wgrep-mode,

enter image description here

The key technology is wgrep-mode. You can edit one text buffer and change multiple files in one shot. Many techniques could be applied the text buffer first. For example, if I don't want to touch README.org, I just delete the line containing README.org.

chen bin
  • 4,781
  • 18
  • 36