;; This file: ;; http://user.it.uu.se/~embe8573/conf/emacs-init/search-regexp-in-files.el (defalias 'cl-set-xor 'cl-set-exclusive-or) (defun files-as-list (file-regexp) (split-string (with-temp-buffer (call-process-shell-command (format "ls %s" file-regexp) nil t) ; no INFILE, temp BUFFER (buffer-substring (point-min) (point-max)) ))) (defun find-file-goto-line (file line) (interactive) (find-file-other-window file) (goto-char (point-min)) (forward-line (1- line)) (window-resize nil (- 2 (window-height)) nil t) ) (defun regexp-hits-find-hit () (interactive) (beginning-of-line) (let ((file (thing-at-point 'filename nil))) ; NO-PROPERTIES (end-of-line) (search-backward "(") (forward-char 1) (let ((window (selected-window)) (line (thing-at-point 'number nil)) ) (forward-line 1) (find-file-goto-line file line) (select-window window) ))) (defun set-regexp-hits-keys () (local-set-key "\r" #'regexp-hits-find-hit) (local-set-key "i" #'previous-line) (local-set-key "k" #'forward-line) ) (defun search-regexp-in-files (file-regexp regexp) (let ((paths (files-as-list file-regexp)) (regexp-hits "*regexp-hits*") (hits nil) ) (get-buffer-create regexp-hits) (let ((buffers (buffer-list))) ; get list to see if we opened the file - (with-current-buffer regexp-hits (goto-char (point-max)) (insert "---\n") (set-regexp-hits-keys) ) (dolist (p paths) (let ((buffer (find-file p)) ; here - (kill-later (cl-set-xor buffers (buffer-list))) ) ; by comparing! (with-current-buffer buffer (save-excursion (goto-char (point-min)) (while (re-search-forward regexp nil t) ; no BOUND, NOERROR (setq hits t) (let ((hit-line (line-number-at-pos)) (match (match-string-no-properties 0)) ) (with-current-buffer regexp-hits (insert (format "%s [%s] (%s)\n" p match hit-line)) )))) (when kill-later (kill-buffer buffer) )))) (if hits (progn (switch-to-buffer regexp-hits) (set-buffer-modified-p nil) (goto-char (point-min)) ) (message "No hits!") )))) ;; use this to test (when nil ;; find (- x x) - this is line 64 (search-regexp-in-files "~/.emacs.d/emacs-init/**/*.el" "(- \\(.*\\) \\1)") ;; find "kill" - should be some hits even for pacifists (search-regexp-in-files "~/.emacs" "kill") (search-regexp-in-files "~/.emacs.d/emacs-init/*.el" "kill") ;; find the construct (if a a b) if you want to replace it with (or a b) ;; if it works, when applied to this file, it should find the example above! (search-regexp-in-files (buffer-file-name) "([[:space:]\n]*if[[:space:]\n]+\\(.*\\)[[:space:]\n]+\\1[[:space:]\n]+\\(.*\\))" ) ) (provide 'search-regexp-in-files)