aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorPaul Eggert2016-04-18 14:05:31 -0700
committerPaul Eggert2016-04-18 14:05:31 -0700
commitdd92b5f5047931f6020045ce47360b62d1c2cb72 (patch)
tree336a9b31454bbf0f9c888ea6169c852e7eae9462 /lisp
parentd11abb25428e9a468a5525c462489eb5a854798f (diff)
parent32364bbbaa8bda68228a3b0191c0b340c252d2a2 (diff)
downloademacs-dd92b5f5047931f6020045ce47360b62d1c2cb72.tar.gz
emacs-dd92b5f5047931f6020045ce47360b62d1c2cb72.zip
Merge from origin/emacs-25
32364bb substitute-command-keys keeps quotes’ text props 567ab52 * src/xwidget.c (x_draw_xwidget_glyph_string): More clipping ... 24b87a1 Add semantic-symref-filepattern-alist entry for lisp-interact... cc0b713 Perform xref searches without visiting unopened files 5045575 Revert "Prevent bootstrap autoload backup files"
Diffstat (limited to 'lisp')
-rw-r--r--lisp/cedet/semantic/symref/cscope.el12
-rw-r--r--lisp/cedet/semantic/symref/global.el10
-rw-r--r--lisp/cedet/semantic/symref/grep.el11
-rw-r--r--lisp/cedet/semantic/symref/idutils.el12
-rw-r--r--lisp/emacs-lisp/autoload.el42
-rw-r--r--lisp/progmodes/xref.el140
6 files changed, 136 insertions, 91 deletions
diff --git a/lisp/cedet/semantic/symref/cscope.el b/lisp/cedet/semantic/symref/cscope.el
index 4890b5b5755..3abd8b3f51c 100644
--- a/lisp/cedet/semantic/symref/cscope.el
+++ b/lisp/cedet/semantic/symref/cscope.el
@@ -60,6 +60,9 @@ See the function `cedet-cscope-search' for more details.")
60 (semantic-symref-parse-tool-output tool b) 60 (semantic-symref-parse-tool-output tool b)
61 )) 61 ))
62 62
63(defconst semantic-symref-cscope--line-re
64 "^\\([^ ]+\\) [^ ]+ \\([0-9]+\\) ")
65
63(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-cscope)) 66(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-cscope))
64 "Parse one line of grep output, and return it as a match list. 67 "Parse one line of grep output, and return it as a match list.
65Moves cursor to end of the match." 68Moves cursor to end of the match."
@@ -78,8 +81,13 @@ Moves cursor to end of the match."
78 ;; We have to return something at this point. 81 ;; We have to return something at this point.
79 subtxt))) 82 subtxt)))
80 ) 83 )
81 (t 84 ((eq (oref tool :resulttype) 'line-and-text)
82 (when (re-search-forward "^\\([^ ]+\\) [^ ]+ \\([0-9]+\\) " nil t) 85 (when (re-search-forward semantic-symref-cscope--line-re nil t)
86 (list (string-to-number (match-string 2))
87 (expand-file-name (match-string 1))
88 (buffer-substring-no-properties (point) (line-end-position)))))
89 (t ; :resulttype is 'line
90 (when (re-search-forward semantic-symref-cscope--line-re nil t)
83 (cons (string-to-number (match-string 2)) 91 (cons (string-to-number (match-string 2))
84 (expand-file-name (match-string 1))) 92 (expand-file-name (match-string 1)))
85 )))) 93 ))))
diff --git a/lisp/cedet/semantic/symref/global.el b/lisp/cedet/semantic/symref/global.el
index e4c114e9c89..a33427e93a6 100644
--- a/lisp/cedet/semantic/symref/global.el
+++ b/lisp/cedet/semantic/symref/global.el
@@ -49,6 +49,9 @@ See the function `cedet-gnu-global-search' for more details.")
49 (semantic-symref-parse-tool-output tool b) 49 (semantic-symref-parse-tool-output tool b)
50 )) 50 ))
51 51
52(defconst semantic-symref-global--line-re
53 "^\\([^ ]+\\) +\\([0-9]+\\) \\([^ ]+\\) ")
54
52(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-global)) 55(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-global))
53 "Parse one line of grep output, and return it as a match list. 56 "Parse one line of grep output, and return it as a match list.
54Moves cursor to end of the match." 57Moves cursor to end of the match."
@@ -57,8 +60,13 @@ Moves cursor to end of the match."
57 ;; Search for files 60 ;; Search for files
58 (when (re-search-forward "^\\([^\n]+\\)$" nil t) 61 (when (re-search-forward "^\\([^\n]+\\)$" nil t)
59 (match-string 1))) 62 (match-string 1)))
63 ((eq (oref tool :resulttype) 'line-and-text)
64 (when (re-search-forward semantic-symref-global--line-re nil t)
65 (list (string-to-number (match-string 2))
66 (match-string 3)
67 (buffer-substring-no-properties (point) (line-end-position)))))
60 (t 68 (t
61 (when (re-search-forward "^\\([^ ]+\\) +\\([0-9]+\\) \\([^ ]+\\) " nil t) 69 (when (re-search-forward semantic-symref-global--line-re nil t)
62 (cons (string-to-number (match-string 2)) 70 (cons (string-to-number (match-string 2))
63 (match-string 3)) 71 (match-string 3))
64 )))) 72 ))))
diff --git a/lisp/cedet/semantic/symref/grep.el b/lisp/cedet/semantic/symref/grep.el
index 5d1fea8c829..36e97da818d 100644
--- a/lisp/cedet/semantic/symref/grep.el
+++ b/lisp/cedet/semantic/symref/grep.el
@@ -50,6 +50,7 @@ and those hits returned.")
50 "Rakefile" "Thorfile" "Capfile" "Guardfile" "Vagrantfile") 50 "Rakefile" "Thorfile" "Capfile" "Guardfile" "Vagrantfile")
51 (perl-mode "*.pl" "*.PL") 51 (perl-mode "*.pl" "*.PL")
52 (cperl-mode "*.pl" "*.PL") 52 (cperl-mode "*.pl" "*.PL")
53 (lisp-interaction-mode "*.el" "*.ede" ".emacs" "_emacs")
53 ) 54 )
54 "List of major modes and file extension pattern. 55 "List of major modes and file extension pattern.
55See find -name man page for format.") 56See find -name man page for format.")
@@ -188,6 +189,9 @@ This shell should support pipe redirect syntax."
188 ;; Return the answer 189 ;; Return the answer
189 ans)) 190 ans))
190 191
192(defconst semantic-symref-grep--line-re
193 "^\\(\\(?:[a-zA-Z]:\\)?[^:\n]+\\):\\([0-9]+\\):")
194
191(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-grep)) 195(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-grep))
192 "Parse one line of grep output, and return it as a match list. 196 "Parse one line of grep output, and return it as a match list.
193Moves cursor to end of the match." 197Moves cursor to end of the match."
@@ -195,8 +199,13 @@ Moves cursor to end of the match."
195 ;; Search for files 199 ;; Search for files
196 (when (re-search-forward "^\\([^\n]+\\)$" nil t) 200 (when (re-search-forward "^\\([^\n]+\\)$" nil t)
197 (match-string 1))) 201 (match-string 1)))
202 ((eq (oref tool :resulttype) 'line-and-text)
203 (when (re-search-forward semantic-symref-grep--line-re nil t)
204 (list (string-to-number (match-string 2))
205 (match-string 1)
206 (buffer-substring-no-properties (point) (line-end-position)))))
198 (t 207 (t
199 (when (re-search-forward "^\\(\\(?:[a-zA-Z]:\\)?[^:\n]+\\):\\([0-9]+\\):" nil t) 208 (when (re-search-forward semantic-symref-grep--line-re nil t)
200 (cons (string-to-number (match-string 2)) 209 (cons (string-to-number (match-string 2))
201 (match-string 1)) 210 (match-string 1))
202 )))) 211 ))))
diff --git a/lisp/cedet/semantic/symref/idutils.el b/lisp/cedet/semantic/symref/idutils.el
index 4127d7ae4ea..db3e9a0dddb 100644
--- a/lisp/cedet/semantic/symref/idutils.el
+++ b/lisp/cedet/semantic/symref/idutils.el
@@ -49,6 +49,9 @@ See the function `cedet-idutils-search' for more details.")
49 (semantic-symref-parse-tool-output tool b) 49 (semantic-symref-parse-tool-output tool b)
50 )) 50 ))
51 51
52(defconst semantic-symref-idutils--line-re
53 "^\\(\\(?:[a-zA-Z]:\\)?[^:\n]+\\):\\([0-9]+\\):")
54
52(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-idutils)) 55(cl-defmethod semantic-symref-parse-tool-output-one-line ((tool semantic-symref-tool-idutils))
53 "Parse one line of grep output, and return it as a match list. 56 "Parse one line of grep output, and return it as a match list.
54Moves cursor to end of the match." 57Moves cursor to end of the match."
@@ -59,8 +62,13 @@ Moves cursor to end of the match."
59 ((eq (oref tool :searchtype) 'tagcompletions) 62 ((eq (oref tool :searchtype) 'tagcompletions)
60 (when (re-search-forward "^\\([^ ]+\\) " nil t) 63 (when (re-search-forward "^\\([^ ]+\\) " nil t)
61 (match-string 1))) 64 (match-string 1)))
62 (t 65 ((eq (oref tool :resulttype) 'line-and-text)
63 (when (re-search-forward "^\\(\\(?:[a-zA-Z]:\\)?[^:\n]+\\):\\([0-9]+\\):" nil t) 66 (when (re-search-forward semantic-symref-idutils--line-re nil t)
67 (list (string-to-number (match-string 2))
68 (expand-file-name (match-string 1) default-directory)
69 (buffer-substring-no-properties (point) (line-end-position)))))
70 (t ; resulttype is line
71 (when (re-search-forward semantic-symref-idutils--line-re nil t)
64 (cons (string-to-number (match-string 2)) 72 (cons (string-to-number (match-string 2))
65 (expand-file-name (match-string 1) default-directory)) 73 (expand-file-name (match-string 1) default-directory))
66 )))) 74 ))))
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el
index 14e584df672..1b06fb6a51d 100644
--- a/lisp/emacs-lisp/autoload.el
+++ b/lisp/emacs-lisp/autoload.el
@@ -251,22 +251,9 @@ If a buffer is visiting the desired autoload file, return it."
251 (enable-local-eval nil)) 251 (enable-local-eval nil))
252 ;; We used to use `raw-text' to read this file, but this causes 252 ;; We used to use `raw-text' to read this file, but this causes
253 ;; problems when the file contains non-ASCII characters. 253 ;; problems when the file contains non-ASCII characters.
254 (let* ((delay-mode-hooks t) 254 (let ((delay-mode-hooks t))
255 (file (autoload-generated-file)) 255 (find-file-noselect
256 (file-missing (not (file-exists-p file)))) 256 (autoload-ensure-default-file (autoload-generated-file))))))
257 (when file-missing
258 (autoload-ensure-default-file file))
259 (with-current-buffer
260 (find-file-noselect
261 (autoload-ensure-file-writeable
262 file))
263 ;; block backups when the file has just been created, since
264 ;; the backups will just be the auto-generated headers.
265 ;; bug#23203
266 (when file-missing
267 (setq buffer-backed-up t)
268 (save-buffer))
269 (current-buffer)))))
270 257
271(defun autoload-generated-file () 258(defun autoload-generated-file ()
272 (expand-file-name generated-autoload-file 259 (expand-file-name generated-autoload-file
@@ -387,22 +374,21 @@ not be relied upon."
387;;;###autoload 374;;;###autoload
388(put 'autoload-ensure-writable 'risky-local-variable t) 375(put 'autoload-ensure-writable 'risky-local-variable t)
389 376
390(defun autoload-ensure-file-writeable (file)
391 ;; Probably pointless, but replaces the old AUTOGEN_VCS in lisp/Makefile,
392 ;; which was designed to handle CVSREAD=1 and equivalent.
393 (and autoload-ensure-writable
394 (let ((modes (file-modes file)))
395 (if (zerop (logand modes #o0200))
396 ;; Ignore any errors here, and let subsequent attempts
397 ;; to write the file raise any real error.
398 (ignore-errors (set-file-modes file (logior modes #o0200))))))
399 file)
400
401(defun autoload-ensure-default-file (file) 377(defun autoload-ensure-default-file (file)
402 "Make sure that the autoload file FILE exists, creating it if needed. 378 "Make sure that the autoload file FILE exists, creating it if needed.
403If the file already exists and `autoload-ensure-writable' is non-nil, 379If the file already exists and `autoload-ensure-writable' is non-nil,
404make it writable." 380make it writable."
405 (write-region (autoload-rubric file) nil file)) 381 (if (file-exists-p file)
382 ;; Probably pointless, but replaces the old AUTOGEN_VCS in lisp/Makefile,
383 ;; which was designed to handle CVSREAD=1 and equivalent.
384 (and autoload-ensure-writable
385 (let ((modes (file-modes file)))
386 (if (zerop (logand modes #o0200))
387 ;; Ignore any errors here, and let subsequent attempts
388 ;; to write the file raise any real error.
389 (ignore-errors (set-file-modes file (logior modes #o0200))))))
390 (write-region (autoload-rubric file) nil file))
391 file)
406 392
407(defun autoload-insert-section-header (outbuf autoloads load-name file time) 393(defun autoload-insert-section-header (outbuf autoloads load-name file time)
408 "Insert the section-header line, 394 "Insert the section-header line,
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index feed0fb36d9..f674c70b104 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -839,16 +839,16 @@ and just use etags."
839 (kill-local-variable 'xref-backend-functions)) 839 (kill-local-variable 'xref-backend-functions))
840 (setq-local xref-backend-functions xref-etags-mode--saved))) 840 (setq-local xref-backend-functions xref-etags-mode--saved)))
841 841
842(declare-function semantic-symref-find-references-by-name "semantic/symref") 842(declare-function semantic-symref-instantiate "semantic/symref")
843(declare-function semantic-find-file-noselect "semantic/fw") 843(declare-function semantic-symref-perform-search "semantic/symref")
844(declare-function grep-expand-template "grep") 844(declare-function grep-expand-template "grep")
845(defvar ede-minor-mode) ;; ede.el 845(defvar ede-minor-mode) ;; ede.el
846 846
847(defun xref-collect-references (symbol dir) 847(defun xref-collect-references (symbol dir)
848 "Collect references to SYMBOL inside DIR. 848 "Collect references to SYMBOL inside DIR.
849This function uses the Semantic Symbol Reference API, see 849This function uses the Semantic Symbol Reference API, see
850`semantic-symref-find-references-by-name' for details on which 850`semantic-symref-tool-alist' for details on which tools are used,
851tools are used, and when." 851and when."
852 (cl-assert (directory-name-p dir)) 852 (cl-assert (directory-name-p dir))
853 (require 'semantic/symref) 853 (require 'semantic/symref)
854 (defvar semantic-symref-tool) 854 (defvar semantic-symref-tool)
@@ -859,19 +859,19 @@ tools are used, and when."
859 ;; to force the backend to use `default-directory'. 859 ;; to force the backend to use `default-directory'.
860 (let* ((ede-minor-mode nil) 860 (let* ((ede-minor-mode nil)
861 (default-directory dir) 861 (default-directory dir)
862 ;; FIXME: Remove CScope and Global from the recognized tools?
863 ;; The current implementations interpret the symbol search as
864 ;; "find all calls to the given function", but not function
865 ;; definition. And they return nothing when passed a variable
866 ;; name, even a global one.
862 (semantic-symref-tool 'detect) 867 (semantic-symref-tool 'detect)
863 (case-fold-search nil) 868 (case-fold-search nil)
864 (res (semantic-symref-find-references-by-name symbol 'subdirs)) 869 (inst (semantic-symref-instantiate :searchfor symbol
865 (hits (and res (oref res hit-lines))) 870 :searchtype 'symbol
866 (orig-buffers (buffer-list))) 871 :searchscope 'subdirs
867 (unwind-protect 872 :resulttype 'line-and-text)))
868 (cl-mapcan (lambda (hit) (xref--collect-matches 873 (xref--convert-hits (semantic-symref-perform-search inst)
869 hit (format "\\_<%s\\_>" (regexp-quote symbol)))) 874 (format "\\_<%s\\_>" (regexp-quote symbol)))))
870 hits)
871 ;; TODO: Implement "lightweight" buffer visiting, so that we
872 ;; don't have to kill them.
873 (mapc #'kill-buffer
874 (cl-set-difference (buffer-list) orig-buffers)))))
875 875
876;;;###autoload 876;;;###autoload
877(defun xref-collect-matches (regexp files dir ignores) 877(defun xref-collect-matches (regexp files dir ignores)
@@ -890,34 +890,19 @@ IGNORES is a list of glob patterns."
890 files 890 files
891 (expand-file-name dir) 891 (expand-file-name dir)
892 ignores)) 892 ignores))
893 (orig-buffers (buffer-list))
894 (buf (get-buffer-create " *xref-grep*")) 893 (buf (get-buffer-create " *xref-grep*"))
895 (grep-re (caar grep-regexp-alist)) 894 (grep-re (caar grep-regexp-alist))
896 (counter 0)
897 reporter
898 hits) 895 hits)
899 (with-current-buffer buf 896 (with-current-buffer buf
900 (erase-buffer) 897 (erase-buffer)
901 (call-process-shell-command command nil t) 898 (call-process-shell-command command nil t)
902 (goto-char (point-min)) 899 (goto-char (point-min))
903 (while (re-search-forward grep-re nil t) 900 (while (re-search-forward grep-re nil t)
904 (push (cons (string-to-number (match-string 2)) 901 (push (list (string-to-number (match-string 2))
905 (match-string 1)) 902 (match-string 1)
903 (buffer-substring-no-properties (point) (line-end-position)))
906 hits))) 904 hits)))
907 (setq reporter (make-progress-reporter 905 (xref--convert-hits hits regexp)))
908 (format "Collecting search results...")
909 0 (length hits)))
910 (unwind-protect
911 (cl-mapcan (lambda (hit)
912 (prog1
913 (progress-reporter-update reporter counter)
914 (cl-incf counter))
915 (xref--collect-matches hit regexp))
916 (nreverse hits))
917 (progress-reporter-done reporter)
918 ;; TODO: Same as above.
919 (mapc #'kill-buffer
920 (cl-set-difference (buffer-list) orig-buffers)))))
921 906
922(defun xref--rgrep-command (regexp files dir ignores) 907(defun xref--rgrep-command (regexp files dir ignores)
923 (require 'find-dired) ; for `find-name-arg' 908 (require 'find-dired) ; for `find-name-arg'
@@ -980,30 +965,71 @@ directory, used as the root of the ignore globs."
980 (match-string 1 str))))) 965 (match-string 1 str)))))
981 str t t)) 966 str t t))
982 967
983(defun xref--collect-matches (hit regexp) 968(defvar xref--last-visiting-buffer nil)
984 (pcase-let* ((`(,line . ,file) hit) 969(defvar xref--temp-buffer-file-name nil)
985 (buf (or (find-buffer-visiting file) 970
986 (semantic-find-file-noselect file)))) 971(defun xref--convert-hits (hits regexp)
987 (with-current-buffer buf 972 (let (xref--last-visiting-buffer
988 (save-excursion 973 (tmp-buffer (generate-new-buffer " *xref-temp*")))
974 (unwind-protect
975 (cl-mapcan (lambda (hit) (xref--collect-matches hit regexp tmp-buffer))
976 hits)
977 (kill-buffer tmp-buffer))))
978
979(defun xref--collect-matches (hit regexp tmp-buffer)
980 (pcase-let* ((`(,line ,file ,text) hit)
981 (buf (xref--find-buffer-visiting file)))
982 (if buf
983 (with-current-buffer buf
984 (save-excursion
985 (goto-char (point-min))
986 (forward-line (1- line))
987 (xref--collect-matches-1 regexp file line
988 (line-beginning-position)
989 (line-end-position))))
990 ;; Using the temporary buffer is both a performance and a buffer
991 ;; management optimization.
992 (with-current-buffer tmp-buffer
993 (erase-buffer)
994 (unless (equal file xref--temp-buffer-file-name)
995 (insert-file-contents file nil 0 200)
996 ;; Can't (setq-local delay-mode-hooks t) because of
997 ;; bug#23272, but the performance penalty seems minimal.
998 (let ((buffer-file-name file)
999 (inhibit-message t)
1000 message-log-max)
1001 (ignore-errors
1002 (set-auto-mode t)))
1003 (setq-local xref--temp-buffer-file-name file)
1004 (setq-local inhibit-read-only t)
1005 (erase-buffer))
1006 (insert text)
989 (goto-char (point-min)) 1007 (goto-char (point-min))
990 (forward-line (1- line)) 1008 (xref--collect-matches-1 regexp file line
991 (let ((line-end (line-end-position)) 1009 (point)
992 (line-beg (line-beginning-position)) 1010 (point-max))))))
993 matches) 1011
994 (syntax-propertize line-end) 1012(defun xref--collect-matches-1 (regexp file line line-beg line-end)
995 ;; FIXME: This results in several lines with the same 1013 (let (matches)
996 ;; summary. Solve with composite pattern? 1014 (syntax-propertize line-end)
997 (while (re-search-forward regexp line-end t) 1015 ;; FIXME: This results in several lines with the same
998 (let* ((beg-column (- (match-beginning 0) line-beg)) 1016 ;; summary. Solve with composite pattern?
999 (end-column (- (match-end 0) line-beg)) 1017 (while (re-search-forward regexp line-end t)
1000 (loc (xref-make-file-location file line beg-column)) 1018 (let* ((beg-column (- (match-beginning 0) line-beg))
1001 (summary (buffer-substring line-beg line-end))) 1019 (end-column (- (match-end 0) line-beg))
1002 (add-face-text-property beg-column end-column 'highlight 1020 (loc (xref-make-file-location file line beg-column))
1003 t summary) 1021 (summary (buffer-substring line-beg line-end)))
1004 (push (xref-make-match summary loc (- end-column beg-column)) 1022 (add-face-text-property beg-column end-column 'highlight
1005 matches))) 1023 t summary)
1006 (nreverse matches)))))) 1024 (push (xref-make-match summary loc (- end-column beg-column))
1025 matches)))
1026 (nreverse matches)))
1027
1028(defun xref--find-buffer-visiting (file)
1029 (unless (equal (car xref--last-visiting-buffer) file)
1030 (setq xref--last-visiting-buffer
1031 (cons file (find-buffer-visiting file))))
1032 (cdr xref--last-visiting-buffer))
1007 1033
1008(provide 'xref) 1034(provide 'xref)
1009 1035