Created
November 29, 2012 03:52
-
-
Save deangiberson/4166712 to your computer and use it in GitHub Desktop.
Integrate Emacs with git grep for grepping and interactive search and replace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defun* get-closest-pathname (&optional (file "Makefile")) | |
"Determine the pathname of the first instance of FILE starting from the | |
current directory towards root. This may not do the correct thing in presence | |
of links. If it does not find FILE, then it shall return the name of FILE in | |
the current directory, suitable for creation" | |
(let ((root (expand-file-name "/"))) | |
(expand-file-name file | |
(loop | |
for d = default-directory | |
then (expand-file-name ".." d) | |
if (file-exists-p (expand-file-name file d)) | |
return d | |
if (equal d root) | |
return nil)))) | |
(defun region-or-symbol-at-point () | |
(if mark-active | |
(buffer-substring-no-properties (region-beginning) (region-end)) | |
(or (symbol-name (symbol-at-point)) ""))) | |
(defun git-grep (regexp) | |
(interactive | |
(let ((regexp (read-string | |
(format "Grep (default %s): " (region-or-symbol-at-point)) | |
nil 'git-grep (region-or-symbol-at-point)))) | |
(list regexp))) | |
(print regexp) | |
(let ((grep-use-null-device nil) | |
(default-directory (file-name-directory (get-closest-pathname ".git")))) | |
(grep (format "git grep --extended-regexp -I -n --ignore-case -e %s | cat" | |
regexp)))) | |
(defun git-grep-query-replace (regexp to-string) | |
(interactive | |
(let* ((last-regexp (and (boundp 'git-grep-query-replace-regexp) | |
git-grep-query-replace-regexp | |
(car git-grep-query-replace-regexp))) | |
(last-to-string (and (boundp 'git-grep-query-replace-to-string) | |
git-grep-query-replace-to-string | |
(car git-grep-query-replace-to-string))) | |
(regexp | |
(if (and last-regexp last-to-string) | |
(read-string | |
(format "Query replace (%s -> %s): " last-regexp last-to-string) | |
nil 'git-grep-query-replace-regexp) | |
(read-string "Query replace: " nil | |
'git-grep-query-replace-regexp))) | |
(to-string | |
(if (and regexp (not (string= "" regexp))) | |
(read-string (format "Query replace %s with: " regexp) | |
nil 'git-grep-query-replace-to-string)))) | |
(if (and regexp (not (string= "" regexp))) | |
(list regexp to-string) | |
(list last-regexp last-to-string)))) | |
(let* ((default-directory (file-name-directory (get-closest-pathname ".git"))) | |
(buffer-name (concat "*Git Grep Dired " default-directory "*"))) | |
(switch-to-buffer buffer-name) | |
(fundamental-mode) | |
(let ((buffer-read-only nil)) | |
(erase-buffer) | |
(call-process-shell-command | |
(format (concat | |
"git grep --extended-regexp -l -I -n --ignore-case -e %s | " | |
"cat | xargs ls -l | sed -e 's/^/ /g'") regexp) nil t) | |
(dired-mode) | |
(dired-toggle-marks) | |
(if (fboundp 'dired-simple-subdir-alist) | |
(dired-simple-subdir-alist) | |
(set (make-local-variable 'dired-subdir-alist) | |
(list (cons default-directory (point-min-marker))))) | |
(bury-buffer) | |
(with-current-buffer buffer-name | |
(dired-do-query-replace-regexp regexp to-string))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment