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

3 Answers 3

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.

4
  • 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, 2021 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, 2021 at 15:27
  • Please see: emacs.stackexchange.com/q/69097/18414 . PS I am sorry for askling too many questions
    – alper
    Oct 26, 2021 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, 2021 at 19:58
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

5
  • Would it be possible to make change only on the Python files?
    – alper
    Oct 11, 2021 at 12:40
  • If you do C-u C-x p g you can pick the directory and the file name pattern. Oct 11, 2021 at 13:23
  • Can I set it single time and could it make the pattern search based on that?
    – alper
    Oct 11, 2021 at 13:52
  • You can write your own wrapper around project-find-regexp for that, which calls it with the parameters you need. Oct 11, 2021 at 13:56
  • your own wrapper around project-find-regexp // can you give a small example how can I write a wrapper to handle only Python files?
    – alper
    Oct 11, 2021 at 14:57
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.