aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorJan D2015-05-17 16:46:34 +0200
committerJan D2015-05-17 16:46:34 +0200
commit6445ee0fb751ae2c1dfef900d44721b3d952812f (patch)
treed43006cb93d9ea7b00ea02aabcd5577c41ff827f /lisp/progmodes
parentf92ac2e82ed199d6f25d2a59508e08addb1150ac (diff)
parentc9c4708ed47b18987940a71b98eb9873150d2b95 (diff)
downloademacs-6445ee0fb751ae2c1dfef900d44721b3d952812f.tar.gz
emacs-6445ee0fb751ae2c1dfef900d44721b3d952812f.zip
Merge branch 'master' into cairo
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-awk.el1
-rw-r--r--lisp/progmodes/cc-cmds.el3
-rw-r--r--lisp/progmodes/cmacexp.el4
-rw-r--r--lisp/progmodes/elisp-mode.el143
-rw-r--r--lisp/progmodes/etags.el23
-rw-r--r--lisp/progmodes/idlw-shell.el14
-rw-r--r--lisp/progmodes/js.el4
-rw-r--r--lisp/progmodes/python.el3
-rw-r--r--lisp/progmodes/tcl.el3
-rw-r--r--lisp/progmodes/verilog-mode.el282
-rw-r--r--lisp/progmodes/xref.el181
11 files changed, 484 insertions, 177 deletions
diff --git a/lisp/progmodes/cc-awk.el b/lisp/progmodes/cc-awk.el
index 1ef80c801ee..ad0248561a8 100644
--- a/lisp/progmodes/cc-awk.el
+++ b/lisp/progmodes/cc-awk.el
@@ -61,6 +61,7 @@
61(cc-bytecomp-defun c-backward-token-1) 61(cc-bytecomp-defun c-backward-token-1)
62(cc-bytecomp-defun c-beginning-of-statement-1) 62(cc-bytecomp-defun c-beginning-of-statement-1)
63(cc-bytecomp-defun c-backward-sws) 63(cc-bytecomp-defun c-backward-sws)
64(cc-bytecomp-defun c-forward-sws)
64 65
65(defvar awk-mode-syntax-table 66(defvar awk-mode-syntax-table
66 (let ((st (make-syntax-table))) 67 (let ((st (make-syntax-table)))
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 68075f356ab..94dc34bb20e 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1317,6 +1317,9 @@ keyword on the line, the keyword is not inserted inside a literal, and
1317 (autoload 'c-subword-mode "cc-subword" 1317 (autoload 'c-subword-mode "cc-subword"
1318 "Mode enabling subword movement and editing keys." t))) 1318 "Mode enabling subword movement and editing keys." t)))
1319 1319
1320(declare-function c-forward-subword "ext:cc-subword" (&optional arg))
1321(declare-function c-backward-subword "ext:cc-subword" (&optional arg))
1322
1320;; "nomenclature" functions + c-scope-operator. 1323;; "nomenclature" functions + c-scope-operator.
1321(defun c-forward-into-nomenclature (&optional arg) 1324(defun c-forward-into-nomenclature (&optional arg)
1322 "Compatibility alias for `c-forward-subword'." 1325 "Compatibility alias for `c-forward-subword'."
diff --git a/lisp/progmodes/cmacexp.el b/lisp/progmodes/cmacexp.el
index 357625d10cf..19d0473c42d 100644
--- a/lisp/progmodes/cmacexp.el
+++ b/lisp/progmodes/cmacexp.el
@@ -364,8 +364,8 @@ Optional arg DISPLAY non-nil means show messages in the echo area."
364 ;; Find and delete the mark of the start of the expansion. 364 ;; Find and delete the mark of the start of the expansion.
365 ;; Look for `# nn "file.c"' lines and delete them. 365 ;; Look for `# nn "file.c"' lines and delete them.
366 (goto-char (point-min)) 366 (goto-char (point-min))
367 (search-forward startmarker) 367 (if (search-forward startmarker nil t)
368 (delete-region 1 (point))) 368 (delete-region 1 (point))))
369 (while (re-search-forward (concat "^# [0-9]+ \"" 369 (while (re-search-forward (concat "^# [0-9]+ \""
370 (regexp-quote filename) 370 (regexp-quote filename)
371 "\"") nil t) 371 "\"") nil t)
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index ad35c48a101..e06b920e5d7 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -30,7 +30,6 @@
30 30
31(require 'lisp-mode) 31(require 'lisp-mode)
32 32
33(defvar emacs-lisp-mode-abbrev-table nil)
34(define-abbrev-table 'emacs-lisp-mode-abbrev-table () 33(define-abbrev-table 'emacs-lisp-mode-abbrev-table ()
35 "Abbrev table for Emacs Lisp mode. 34 "Abbrev table for Emacs Lisp mode.
36It has `lisp-mode-abbrev-table' as its parent." 35It has `lisp-mode-abbrev-table' as its parent."
@@ -476,11 +475,12 @@ It can be quoted, or be inside a quoted form."
476 (point))) 475 (point)))
477 (scan-error pos)))) 476 (scan-error pos))))
478 ;; t if in function position. 477 ;; t if in function position.
479 (funpos (eq (char-before beg) ?\())) 478 (funpos (eq (char-before beg) ?\())
479 (quoted (elisp--form-quoted-p beg)))
480 (when (and end (or (not (nth 8 (syntax-ppss))) 480 (when (and end (or (not (nth 8 (syntax-ppss)))
481 (eq (char-before beg) ?`))) 481 (eq (char-before beg) ?`)))
482 (let ((table-etc 482 (let ((table-etc
483 (if (not funpos) 483 (if (or (not funpos) quoted)
484 ;; FIXME: We could look at the first element of the list and 484 ;; FIXME: We could look at the first element of the list and
485 ;; use it to provide a more specific completion table in some 485 ;; use it to provide a more specific completion table in some
486 ;; cases. E.g. filter out keywords that are not understood by 486 ;; cases. E.g. filter out keywords that are not understood by
@@ -492,7 +492,7 @@ It can be quoted, or be inside a quoted form."
492 :company-doc-buffer #'elisp--company-doc-buffer 492 :company-doc-buffer #'elisp--company-doc-buffer
493 :company-docsig #'elisp--company-doc-string 493 :company-docsig #'elisp--company-doc-string
494 :company-location #'elisp--company-location)) 494 :company-location #'elisp--company-location))
495 ((elisp--form-quoted-p beg) 495 (quoted
496 (list nil obarray 496 (list nil obarray
497 ;; Don't include all symbols (bug#16646). 497 ;; Don't include all symbols (bug#16646).
498 :predicate (lambda (sym) 498 :predicate (lambda (sym)
@@ -544,10 +544,11 @@ It can be quoted, or be inside a quoted form."
544 (< (point) beg))))) 544 (< (point) beg)))))
545 (list t obarray 545 (list t obarray
546 :predicate (lambda (sym) (get sym 'error-conditions)))) 546 :predicate (lambda (sym) (get sym 'error-conditions))))
547 ((and ?\( 547 ((and (or ?\( `let `let*)
548 (guard (save-excursion 548 (guard (save-excursion
549 (goto-char (1- beg)) 549 (goto-char (1- beg))
550 (up-list -1) 550 (when (eq parent ?\()
551 (up-list -1))
551 (forward-symbol -1) 552 (forward-symbol -1)
552 (looking-at "\\_<let\\*?\\_>")))) 553 (looking-at "\\_<let\\*?\\_>"))))
553 (list t obarray 554 (list t obarray
@@ -580,6 +581,7 @@ It can be quoted, or be inside a quoted form."
580(declare-function xref-make-elisp-location "xref" (symbol type file)) 581(declare-function xref-make-elisp-location "xref" (symbol type file))
581(declare-function xref-make-bogus-location "xref" (message)) 582(declare-function xref-make-bogus-location "xref" (message))
582(declare-function xref-make "xref" (description location)) 583(declare-function xref-make "xref" (description location))
584(declare-function xref-collect-matches "xref" (input dir &optional kind))
583 585
584(defun elisp-xref-find (action id) 586(defun elisp-xref-find (action id)
585 (require 'find-func) 587 (require 'find-func)
@@ -588,6 +590,10 @@ It can be quoted, or be inside a quoted form."
588 (let ((sym (intern-soft id))) 590 (let ((sym (intern-soft id)))
589 (when sym 591 (when sym
590 (elisp--xref-find-definitions sym)))) 592 (elisp--xref-find-definitions sym))))
593 (`references
594 (elisp--xref-find-matches id 'symbol))
595 (`matches
596 (elisp--xref-find-matches id 'regexp))
591 (`apropos 597 (`apropos
592 (elisp--xref-find-apropos id)))) 598 (elisp--xref-find-apropos id))))
593 599
@@ -600,12 +606,16 @@ It can be quoted, or be inside a quoted form."
600 (setq sym (car fun-lib)) 606 (setq sym (car fun-lib))
601 (cdr fun-lib)))) 607 (cdr fun-lib))))
602 (`defvar (and (boundp sym) 608 (`defvar (and (boundp sym)
603 ;; Don't show minor modes twice. 609 (let ((el-file (symbol-file sym 'defvar)))
604 ;; TODO: If TYPE ever becomes dependent on the 610 (if el-file
605 ;; context, move this check outside. 611 (and
606 (not (fboundp sym)) 612 ;; Don't show minor modes twice.
607 (or (symbol-file sym 'defvar) 613 ;; TODO: If TYPE ever becomes dependent on the
608 (help-C-file-name sym 'var)))) 614 ;; context, move this check outside.
615 (not (and (fboundp sym)
616 (memq sym minor-mode-list)))
617 el-file)
618 (help-C-file-name sym 'var)))))
609 (`feature (and (featurep sym) 619 (`feature (and (featurep sym)
610 ;; Skip when a function with the same name 620 ;; Skip when a function with the same name
611 ;; is defined, because it's probably in the 621 ;; is defined, because it's probably in the
@@ -620,6 +630,12 @@ It can be quoted, or be inside a quoted form."
620 (setq file (substring file 0 -1))) 630 (setq file (substring file 0 -1)))
621 (xref-make-elisp-location sym type file)))) 631 (xref-make-elisp-location sym type file))))
622 632
633(defvar elisp--xref-format
634 (let ((str "(%s %s)"))
635 (put-text-property 1 3 'face 'font-lock-keyword-face str)
636 (put-text-property 4 6 'face 'font-lock-function-name-face str)
637 str))
638
623(defun elisp--xref-find-definitions (symbol) 639(defun elisp--xref-find-definitions (symbol)
624 (save-excursion 640 (save-excursion
625 (let (lst) 641 (let (lst)
@@ -631,11 +647,35 @@ It can be quoted, or be inside a quoted form."
631 (xref-make-bogus-location (error-message-string err)))))) 647 (xref-make-bogus-location (error-message-string err))))))
632 (when loc 648 (when loc
633 (push 649 (push
634 (xref-make (format "(%s %s)" type symbol) 650 (xref-make (format elisp--xref-format type symbol)
635 loc) 651 loc)
636 lst)))) 652 lst))))
637 lst))) 653 lst)))
638 654
655(defvar package-user-dir)
656
657(defun elisp--xref-find-matches (symbol kind)
658 (let* ((dirs (sort
659 (mapcar
660 (lambda (dir)
661 (file-name-as-directory (expand-file-name dir)))
662 ;; It's one level above a number of `load-path'
663 ;; elements (one for each installed package).
664 ;; Save us some process calls.
665 (cons package-user-dir load-path))
666 #'string<))
667 (ref dirs))
668 ;; Delete subdirectories from the list.
669 (while (cdr ref)
670 (if (string-prefix-p (car ref) (cadr ref))
671 (setcdr ref (cddr ref))
672 (setq ref (cdr ref))))
673 (cl-mapcan
674 (lambda (dir)
675 (and (file-exists-p dir)
676 (xref-collect-matches symbol dir kind)))
677 dirs)))
678
639(defun elisp--xref-find-apropos (regexp) 679(defun elisp--xref-find-apropos (regexp)
640 (apply #'nconc 680 (apply #'nconc
641 (let (lst) 681 (let (lst)
@@ -1141,13 +1181,13 @@ which see."
1141 (cond ((null current-fnsym) 1181 (cond ((null current-fnsym)
1142 nil) 1182 nil)
1143 ((eq current-symbol (car current-fnsym)) 1183 ((eq current-symbol (car current-fnsym))
1144 (or (apply #'elisp--get-fnsym-args-string current-fnsym) 1184 (or (apply #'elisp-get-fnsym-args-string current-fnsym)
1145 (elisp--get-var-docstring current-symbol))) 1185 (elisp-get-var-docstring current-symbol)))
1146 (t 1186 (t
1147 (or (elisp--get-var-docstring current-symbol) 1187 (or (elisp-get-var-docstring current-symbol)
1148 (apply #'elisp--get-fnsym-args-string current-fnsym)))))) 1188 (apply #'elisp-get-fnsym-args-string current-fnsym))))))
1149 1189
1150(defun elisp--get-fnsym-args-string (sym &optional index) 1190(defun elisp-get-fnsym-args-string (sym &optional index prefix)
1151 "Return a string containing the parameter list of the function SYM. 1191 "Return a string containing the parameter list of the function SYM.
1152If SYM is a subr and no arglist is obtainable from the docstring 1192If SYM is a subr and no arglist is obtainable from the docstring
1153or elsewhere, return a 1-line docstring." 1193or elsewhere, return a 1-line docstring."
@@ -1164,20 +1204,29 @@ or elsewhere, return a 1-line docstring."
1164 (args 1204 (args
1165 (cond 1205 (cond
1166 ((listp advertised) advertised) 1206 ((listp advertised) advertised)
1167 ((setq doc (help-split-fundoc (documentation sym t) sym)) 1207 ((setq doc (help-split-fundoc
1208 (condition-case nil (documentation sym t)
1209 (invalid-function nil))
1210 sym))
1168 (car doc)) 1211 (car doc))
1169 (t (help-function-arglist sym))))) 1212 (t (help-function-arglist sym)))))
1170 ;; Stringify, and store before highlighting, downcasing, etc. 1213 ;; Stringify, and store before highlighting, downcasing, etc.
1171 ;; FIXME should truncate before storing. 1214 (elisp--last-data-store sym (elisp-function-argstring args)
1172 (elisp--last-data-store sym (elisp--function-argstring args)
1173 'function)))))) 1215 'function))))))
1174 ;; Highlight, truncate. 1216 ;; Highlight, truncate.
1175 (if argstring 1217 (if argstring
1176 (elisp--highlight-function-argument sym argstring index)))) 1218 (elisp--highlight-function-argument
1177 1219 sym argstring index
1178(defun elisp--highlight-function-argument (sym args index) 1220 (or prefix
1221 (concat (propertize (symbol-name sym) 'face
1222 (if (functionp sym)
1223 'font-lock-function-name-face
1224 'font-lock-keyword-face))
1225 ": "))))))
1226
1227(defun elisp--highlight-function-argument (sym args index prefix)
1179 "Highlight argument INDEX in ARGS list for function SYM. 1228 "Highlight argument INDEX in ARGS list for function SYM.
1180In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." 1229In the absence of INDEX, just call `eldoc-docstring-format-sym-doc'."
1181 ;; FIXME: This should probably work on the list representation of `args' 1230 ;; FIXME: This should probably work on the list representation of `args'
1182 ;; rather than its string representation. 1231 ;; rather than its string representation.
1183 ;; FIXME: This function is much too long, we need to split it up! 1232 ;; FIXME: This function is much too long, we need to split it up!
@@ -1262,9 +1311,9 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'."
1262 ((string= argument "&allow-other-keys")) ; Skip. 1311 ((string= argument "&allow-other-keys")) ; Skip.
1263 ;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc... 1312 ;; Back to index 0 in ARG1 ARG2 ARG2 ARG3 etc...
1264 ;; like in `setq'. 1313 ;; like in `setq'.
1265 ((or (and (string-match-p "\\.\\.\\.$" argument) 1314 ((or (and (string-match-p "\\.\\.\\.\\'" argument)
1266 (string= argument (car (last args-lst)))) 1315 (string= argument (car (last args-lst))))
1267 (and (string-match-p "\\.\\.\\.$" 1316 (and (string-match-p "\\.\\.\\.\\'"
1268 (substring args 1 (1- (length args)))) 1317 (substring args 1 (1- (length args))))
1269 (= (length (remove "..." args-lst)) 2) 1318 (= (length (remove "..." args-lst)) 2)
1270 (> index 1) (eq (logand index 1) 1))) 1319 (> index 1) (eq (logand index 1) 1)))
@@ -1279,14 +1328,12 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'."
1279 (when start 1328 (when start
1280 (setq doc (copy-sequence args)) 1329 (setq doc (copy-sequence args))
1281 (add-text-properties start end (list 'face argument-face) doc)) 1330 (add-text-properties start end (list 'face argument-face) doc))
1282 (setq doc (elisp--docstring-format-sym-doc 1331 (setq doc (eldoc-docstring-format-sym-doc prefix doc))
1283 sym doc (if (functionp sym) 'font-lock-function-name-face
1284 'font-lock-keyword-face)))
1285 doc))) 1332 doc)))
1286 1333
1287;; Return a string containing a brief (one-line) documentation string for 1334;; Return a string containing a brief (one-line) documentation string for
1288;; the variable. 1335;; the variable.
1289(defun elisp--get-var-docstring (sym) 1336(defun elisp-get-var-docstring (sym)
1290 (cond ((not sym) nil) 1337 (cond ((not sym) nil)
1291 ((and (eq sym (aref elisp--eldoc-last-data 0)) 1338 ((and (eq sym (aref elisp--eldoc-last-data 0))
1292 (eq 'variable (aref elisp--eldoc-last-data 2))) 1339 (eq 'variable (aref elisp--eldoc-last-data 2)))
@@ -1294,7 +1341,7 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'."
1294 (t 1341 (t
1295 (let ((doc (documentation-property sym 'variable-documentation t))) 1342 (let ((doc (documentation-property sym 'variable-documentation t)))
1296 (when doc 1343 (when doc
1297 (let ((doc (elisp--docstring-format-sym-doc 1344 (let ((doc (eldoc-docstring-format-sym-doc
1298 sym (elisp--docstring-first-line doc) 1345 sym (elisp--docstring-first-line doc)
1299 'font-lock-variable-name-face))) 1346 'font-lock-variable-name-face)))
1300 (elisp--last-data-store sym doc 'variable))))))) 1347 (elisp--last-data-store sym doc 'variable)))))))
@@ -1318,36 +1365,6 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'."
1318 (substring doc start (match-beginning 0))) 1365 (substring doc start (match-beginning 0)))
1319 ((zerop start) doc) 1366 ((zerop start) doc)
1320 (t (substring doc start)))))))) 1367 (t (substring doc start))))))))
1321
1322(defvar eldoc-echo-area-use-multiline-p)
1323
1324;; If the entire line cannot fit in the echo area, the symbol name may be
1325;; truncated or eliminated entirely from the output to make room for the
1326;; description.
1327(defun elisp--docstring-format-sym-doc (sym doc face)
1328 (save-match-data
1329 (let* ((name (symbol-name sym))
1330 (ea-multi eldoc-echo-area-use-multiline-p)
1331 ;; Subtract 1 from window width since emacs will not write
1332 ;; any chars to the last column, or in later versions, will
1333 ;; cause a wraparound and resize of the echo area.
1334 (ea-width (1- (window-width (minibuffer-window))))
1335 (strip (- (+ (length name) (length ": ") (length doc)) ea-width)))
1336 (cond ((or (<= strip 0)
1337 (eq ea-multi t)
1338 (and ea-multi (> (length doc) ea-width)))
1339 (format "%s: %s" (propertize name 'face face) doc))
1340 ((> (length doc) ea-width)
1341 (substring (format "%s" doc) 0 ea-width))
1342 ((>= strip (length name))
1343 (format "%s" doc))
1344 (t
1345 ;; Show the end of the partial symbol name, rather
1346 ;; than the beginning, since the former is more likely
1347 ;; to be unique given package namespace conventions.
1348 (setq name (substring name strip))
1349 (format "%s: %s" (propertize name 'face face) doc))))))
1350
1351 1368
1352;; Return a list of current function name and argument index. 1369;; Return a list of current function name and argument index.
1353(defun elisp--fnsym-in-current-sexp () 1370(defun elisp--fnsym-in-current-sexp ()
@@ -1392,7 +1409,7 @@ In the absence of INDEX, just call `elisp--docstring-format-sym-doc'."
1392 (memq (char-syntax c) '(?w ?_)) 1409 (memq (char-syntax c) '(?w ?_))
1393 (intern-soft (current-word))))) 1410 (intern-soft (current-word)))))
1394 1411
1395(defun elisp--function-argstring (arglist) 1412(defun elisp-function-argstring (arglist)
1396 "Return ARGLIST as a string enclosed by (). 1413 "Return ARGLIST as a string enclosed by ().
1397ARGLIST is either a string, or a list of strings or symbols." 1414ARGLIST is either a string, or a list of strings or symbols."
1398 (let ((str (cond ((stringp arglist) arglist) 1415 (let ((str (cond ((stringp arglist) arglist)
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index b470352f8dc..7a87377503d 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -947,6 +947,7 @@ onto a ring and may be popped back to with \\[pop-tag-mark].
947Contrast this with the ring of marks gone to by the command. 947Contrast this with the ring of marks gone to by the command.
948 948
949See documentation of variable `tags-file-name'." 949See documentation of variable `tags-file-name'."
950 (declare (obsolete xref-find-definitions "25.1"))
950 (interactive (find-tag-interactive "Find tag: ")) 951 (interactive (find-tag-interactive "Find tag: "))
951 (let* ((buf (find-tag-noselect tagname next-p regexp-p)) 952 (let* ((buf (find-tag-noselect tagname next-p regexp-p))
952 (pos (with-current-buffer buf (point)))) 953 (pos (with-current-buffer buf (point))))
@@ -2073,12 +2074,28 @@ for \\[find-tag] (which see)."
2073;; we hit the limit rarely. 2074;; we hit the limit rarely.
2074(defconst etags--xref-limit 1000) 2075(defconst etags--xref-limit 1000)
2075 2076
2077(defvar etags-xref-find-definitions-tag-order '(tag-exact-match-p
2078 tag-implicit-name-match-p)
2079 "Tag order used in `etags-xref-find' to look for definitions.")
2080
2076;;;###autoload 2081;;;###autoload
2077(defun etags-xref-find (action id) 2082(defun etags-xref-find (action id)
2078 (pcase action 2083 (pcase action
2079 (`definitions (etags--xref-find-definitions id)) 2084 (`definitions (etags--xref-find-definitions id))
2085 (`references (etags--xref-find-matches id 'symbol))
2086 (`matches (etags--xref-find-matches id 'regexp))
2080 (`apropos (etags--xref-find-definitions id t)))) 2087 (`apropos (etags--xref-find-definitions id t))))
2081 2088
2089(defun etags--xref-find-matches (input kind)
2090 (let ((dirs (if tags-table-list
2091 (mapcar #'file-name-directory tags-table-list)
2092 ;; If no tags files are loaded, prompt for the dir.
2093 (list (read-directory-name "In directory: " nil nil t)))))
2094 (cl-mapcan
2095 (lambda (dir)
2096 (xref-collect-matches input dir kind))
2097 dirs)))
2098
2082(defun etags--xref-find-definitions (pattern &optional regexp?) 2099(defun etags--xref-find-definitions (pattern &optional regexp?)
2083 ;; This emulates the behaviour of `find-tag-in-order' but instead of 2100 ;; This emulates the behaviour of `find-tag-in-order' but instead of
2084 ;; returning one match at a time all matches are returned as list. 2101 ;; returning one match at a time all matches are returned as list.
@@ -2094,7 +2111,7 @@ for \\[find-tag] (which see)."
2094 (while (visit-tags-table-buffer (not first-time)) 2111 (while (visit-tags-table-buffer (not first-time))
2095 (setq first-time nil) 2112 (setq first-time nil)
2096 (dolist (order-fun (cond (regexp? find-tag-regexp-tag-order) 2113 (dolist (order-fun (cond (regexp? find-tag-regexp-tag-order)
2097 (t find-tag-tag-order))) 2114 (t etags-xref-find-definitions-tag-order)))
2098 (goto-char (point-min)) 2115 (goto-char (point-min))
2099 (while (and (funcall search-fun pattern nil t) 2116 (while (and (funcall search-fun pattern nil t)
2100 (< (hash-table-count marks) etags--xref-limit)) 2117 (< (hash-table-count marks) etags--xref-limit))
@@ -2129,6 +2146,10 @@ for \\[find-tag] (which see)."
2129 (etags-goto-tag-location tag-info) 2146 (etags-goto-tag-location tag-info)
2130 (point-marker))))) 2147 (point-marker)))))
2131 2148
2149(cl-defmethod xref-location-line ((l xref-etags-location))
2150 (with-slots (tag-info) l
2151 (nth 1 tag-info)))
2152
2132 2153
2133(provide 'etags) 2154(provide 'etags)
2134 2155
diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el
index 40c40eef302..02a8ec8a560 100644
--- a/lisp/progmodes/idlw-shell.el
+++ b/lisp/progmodes/idlw-shell.el
@@ -1445,12 +1445,8 @@ Otherwise just move the line. Move down unless UP is non-nil."
1445 (interactive "p") 1445 (interactive "p")
1446 (idlwave-shell-move-or-history nil arg)) 1446 (idlwave-shell-move-or-history nil arg))
1447 1447
1448;; Newer versions of comint.el changed the name of comint-filter to 1448(define-obsolete-function-alias 'idlwave-shell-comint-filter
1449;; comint-output-filter. 1449 'comint-output-filter "25.1")
1450(defalias 'idlwave-shell-comint-filter
1451 (if (fboundp 'comint-output-filter)
1452 #'comint-output-filter
1453 #'comint-filter))
1454 1450
1455(defun idlwave-shell-is-running () 1451(defun idlwave-shell-is-running ()
1456 "Return t if the shell process is running." 1452 "Return t if the shell process is running."
@@ -1496,7 +1492,7 @@ and then calls `idlwave-shell-send-command' for any pending commands."
1496 (get-buffer-create idlwave-shell-hidden-output-buffer)) 1492 (get-buffer-create idlwave-shell-hidden-output-buffer))
1497 (goto-char (point-max)) 1493 (goto-char (point-max))
1498 (insert string)) 1494 (insert string))
1499 (idlwave-shell-comint-filter proc string)) 1495 (comint-output-filter proc string))
1500 ;; Watch for magic - need to accumulate the current line 1496 ;; Watch for magic - need to accumulate the current line
1501 ;; since it may not be sent all at once. 1497 ;; since it may not be sent all at once.
1502 (if (string-match "\n" string) 1498 (if (string-match "\n" string)
@@ -1552,7 +1548,7 @@ and then calls `idlwave-shell-send-command' for any pending commands."
1552 (if idlwave-shell-hide-output 1548 (if idlwave-shell-hide-output
1553 (if (and idlwave-shell-show-if-error 1549 (if (and idlwave-shell-show-if-error
1554 (eq idlwave-shell-current-state 'error)) 1550 (eq idlwave-shell-current-state 'error))
1555 (idlwave-shell-comint-filter proc full-output) 1551 (comint-output-filter proc full-output)
1556 ;; If it's only *mostly* hidden, filter % lines, 1552 ;; If it's only *mostly* hidden, filter % lines,
1557 ;; and show anything that remains 1553 ;; and show anything that remains
1558 (if (eq idlwave-shell-hide-output 'mostly) 1554 (if (eq idlwave-shell-hide-output 'mostly)
@@ -1560,7 +1556,7 @@ and then calls `idlwave-shell-send-command' for any pending commands."
1560 (idlwave-shell-filter-hidden-output 1556 (idlwave-shell-filter-hidden-output
1561 full-output))) 1557 full-output)))
1562 (if filtered 1558 (if filtered
1563 (idlwave-shell-comint-filter 1559 (comint-output-filter
1564 proc filtered)))))) 1560 proc filtered))))))
1565 1561
1566 ;; Call the post-command hook 1562 ;; Call the post-command hook
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 62f19f42df1..f06c5c75b1a 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -2852,10 +2852,6 @@ with `js--js-encode-value'."
2852(defsubst js--js-true (value) 2852(defsubst js--js-true (value)
2853 (not (js--js-not value))) 2853 (not (js--js-not value)))
2854 2854
2855;; The somewhat complex code layout confuses the byte-compiler into
2856;; thinking this function "might not be defined at runtime".
2857(declare-function js--optimize-arglist "js" (arglist))
2858
2859(eval-and-compile 2855(eval-and-compile
2860 (defun js--optimize-arglist (arglist) 2856 (defun js--optimize-arglist (arglist)
2861 "Convert immediate js< and js! references to deferred ones." 2857 "Convert immediate js< and js! references to deferred ones."
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index eb17d075921..4b0a028faa3 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2268,7 +2268,8 @@ banner and the initial prompt are received separately."
2268 (while t 2268 (while t
2269 (when (not (accept-process-output process timeout)) 2269 (when (not (accept-process-output process timeout))
2270 (throw 'found nil)) 2270 (throw 'found nil))
2271 (when (looking-back regexp) 2271 (when (looking-back
2272 regexp (car (python-util-comint-last-prompt)))
2272 (throw 'found t)))))) 2273 (throw 'found t))))))
2273 2274
2274(defun python-shell-comint-end-of-output-p (output) 2275(defun python-shell-comint-end-of-output-p (output)
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index 8f7705ba17d..e4e96554c95 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -1028,7 +1028,8 @@ Returns nil if line starts inside a string, t if in a comment."
1028 (with-current-buffer (process-buffer proc) 1028 (with-current-buffer (process-buffer proc)
1029 ;; Delete prompt if requested. 1029 ;; Delete prompt if requested.
1030 (when (marker-buffer inferior-tcl-delete-prompt-marker) 1030 (when (marker-buffer inferior-tcl-delete-prompt-marker)
1031 (delete-region (process-mark proc) inferior-tcl-delete-prompt-marker) 1031 (let ((inhibit-read-only t))
1032 (delete-region (process-mark proc) inferior-tcl-delete-prompt-marker))
1032 (set-marker inferior-tcl-delete-prompt-marker nil)))) 1033 (set-marker inferior-tcl-delete-prompt-marker nil))))
1033 (comint-output-filter proc string)) 1034 (comint-output-filter proc string))
1034 1035
diff --git a/lisp/progmodes/verilog-mode.el b/lisp/progmodes/verilog-mode.el
index 57206544b9b..a1ad49e9a2c 100644
--- a/lisp/progmodes/verilog-mode.el
+++ b/lisp/progmodes/verilog-mode.el
@@ -123,7 +123,7 @@
123;;; Code: 123;;; Code:
124 124
125;; This variable will always hold the version number of the mode 125;; This variable will always hold the version number of the mode
126(defconst verilog-mode-version "2015-02-20-0d6420b-vpo" 126(defconst verilog-mode-version "2015-05-14-6232468-vpo-GNU"
127 "Version of this Verilog mode.") 127 "Version of this Verilog mode.")
128(defconst verilog-mode-release-emacs t 128(defconst verilog-mode-release-emacs t
129 "If non-nil, this version of Verilog mode was released with Emacs itself.") 129 "If non-nil, this version of Verilog mode was released with Emacs itself.")
@@ -282,6 +282,50 @@ STRING should be given if the last search was by `string-match' on STRING."
282 ;; Emacs. 282 ;; Emacs.
283 (defalias 'verilog-regexp-opt 'regexp-opt))) 283 (defalias 'verilog-regexp-opt 'regexp-opt)))
284 284
285;; emacs >=22 has looking-back, but older emacs and xemacs don't.
286;; This function is lifted directly from emacs's subr.el
287;; so that it can be used by xemacs.
288;; The idea for this was borrowed from org-mode via this link:
289;; https://lists.gnu.org/archive/html/emacs-orgmode/2009-12/msg00032.html
290(eval-and-compile
291 (cond
292 ((fboundp 'looking-back)
293 (defalias 'verilog-looking-back 'looking-back))
294 (t
295 (defun verilog-looking-back (regexp limit &optional greedy)
296 "Return non-nil if text before point matches regular expression REGEXP.
297Like `looking-at' except matches before point, and is slower.
298LIMIT if non-nil speeds up the search by specifying a minimum
299starting position, to avoid checking matches that would start
300before LIMIT.
301
302If GREEDY is non-nil, extend the match backwards as far as
303possible, stopping when a single additional previous character
304cannot be part of a match for REGEXP. When the match is
305extended, its starting position is allowed to occur before
306LIMIT.
307
308As a general recommendation, try to avoid using `looking-back'
309wherever possible, since it is slow."
310 (let ((start (point))
311 (pos
312 (save-excursion
313 (and (re-search-backward (concat "\\(?:" regexp "\\)\\=") limit t)
314 (point)))))
315 (if (and greedy pos)
316 (save-restriction
317 (narrow-to-region (point-min) start)
318 (while (and (> pos (point-min))
319 (save-excursion
320 (goto-char pos)
321 (backward-char 1)
322 (looking-at (concat "\\(?:" regexp "\\)\\'"))))
323 (setq pos (1- pos)))
324 (save-excursion
325 (goto-char pos)
326 (looking-at (concat "\\(?:" regexp "\\)\\'")))))
327 (not (null pos)))))))
328
285(eval-and-compile 329(eval-and-compile
286 ;; Both xemacs and emacs 330 ;; Both xemacs and emacs
287 (condition-case nil 331 (condition-case nil
@@ -662,9 +706,10 @@ to see the effect as font color choices are cached by Emacs."
662 706
663(defcustom verilog-highlight-grouping-keywords nil 707(defcustom verilog-highlight-grouping-keywords nil
664 "Non-nil means highlight grouping keywords more dramatically. 708 "Non-nil means highlight grouping keywords more dramatically.
665If false, these words are in the `font-lock-type-face'; if True then they are in 709If false, these words are in the `font-lock-type-face'; if True
666`verilog-font-lock-ams-face'. Some find that special highlighting on these 710then they are in `verilog-font-lock-grouping-keywords-face'.
667grouping constructs allow the structure of the code to be understood at a glance." 711Some find that special highlighting on these grouping constructs
712allow the structure of the code to be understood at a glance."
668 :group 'verilog-mode-indent 713 :group 'verilog-mode-indent
669 :type 'boolean) 714 :type 'boolean)
670(put 'verilog-highlight-grouping-keywords 'safe-local-variable 'verilog-booleanp) 715(put 'verilog-highlight-grouping-keywords 'safe-local-variable 'verilog-booleanp)
@@ -1880,14 +1925,22 @@ find the errors."
1880(if (featurep 'xemacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-xemacs)) 1925(if (featurep 'xemacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-xemacs))
1881(if (featurep 'emacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-emacs)) 1926(if (featurep 'emacs) (add-hook 'compilation-mode-hook 'verilog-error-regexp-add-emacs))
1882 1927
1883(defconst verilog-directive-re 1928(defconst verilog-compiler-directives
1884 (eval-when-compile 1929 (eval-when-compile
1885 (verilog-regexp-words 1930 '( ;; compiler directives, from IEEE 1800-2012 section 22.1
1886 '( 1931 "`__FILE__" "`__LINE" "`begin_keywords" "`celldefine" "`default_nettype"
1887 "`case" "`default" "`define" "`else" "`elsif" "`endfor" "`endif" 1932 "`define" "`else" "`elsif" "`end_keywords" "`endcelldefine" "`endif"
1888 "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef" 1933 "`ifdef" "`ifndef" "`include" "`line" "`nounconnected_drive" "`pragma"
1889 "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale" 1934 "`resetall" "`timescale" "`unconnected_drive" "`undef" "`undefineall"
1890 "`time_scale" "`undef" "`while" )))) 1935 ;; compiler directives not covered by IEEE 1800
1936 "`case" "`default" "`endfor" "`endprotect" "`endswitch" "`endwhile" "`for"
1937 "`format" "`if" "`let" "`protect" "`switch" "`timescale" "`time_scale"
1938 "`while"
1939 ))
1940 "List of Verilog compiler directives.")
1941
1942(defconst verilog-directive-re
1943 (verilog-regexp-words verilog-compiler-directives))
1891 1944
1892(defconst verilog-directive-re-1 1945(defconst verilog-directive-re-1
1893 (concat "[ \t]*" verilog-directive-re)) 1946 (concat "[ \t]*" verilog-directive-re))
@@ -2411,11 +2464,9 @@ find the errors."
2411 "\\(\\<begin\\>\\)\\|" ; 1 2464 "\\(\\<begin\\>\\)\\|" ; 1
2412 "\\(\\<else\\>\\)\\|" ; 2 2465 "\\(\\<else\\>\\)\\|" ; 2
2413 "\\(\\<end\\>\\s-+\\<else\\>\\)\\|" ; 3 2466 "\\(\\<end\\>\\s-+\\<else\\>\\)\\|" ; 3
2414 "\\(\\<always_comb\\>\\(\[ \t\]*@\\)?\\)\\|" ; 4 2467 "\\(\\<always\\(?:_ff\\)?\\>\\(?:\[ \t\]*@\\)\\)\\|" ; 4 (matches always or always_ff w/ @...)
2415 "\\(\\<always_ff\\>\\(\[ \t\]*@\\)?\\)\\|" ; 5 2468 "\\(\\<always\\(?:_comb\\|_latch\\)?\\>\\)\\|" ; 5 (matches always, always_comb, always_latch w/o @...)
2416 "\\(\\<always_latch\\>\\(\[ \t\]*@\\)?\\)\\|" ; 6
2417 "\\(\\<fork\\>\\)\\|" ; 7 2469 "\\(\\<fork\\>\\)\\|" ; 7
2418 "\\(\\<always\\>\\(\[ \t\]*@\\)?\\)\\|"
2419 "\\(\\<if\\>\\)\\|" 2470 "\\(\\<if\\>\\)\\|"
2420 verilog-property-re "\\|" 2471 verilog-property-re "\\|"
2421 "\\(\\(" verilog-label-re "\\)?\\<assert\\>\\)\\|" 2472 "\\(\\(" verilog-label-re "\\)?\\<assert\\>\\)\\|"
@@ -2581,10 +2632,10 @@ find the errors."
2581(defconst verilog-declaration-re 2632(defconst verilog-declaration-re
2582 (concat "\\(" verilog-declaration-prefix-re "\\s-*\\)?" verilog-declaration-core-re)) 2633 (concat "\\(" verilog-declaration-prefix-re "\\s-*\\)?" verilog-declaration-core-re))
2583(defconst verilog-range-re "\\(\\[[^]]*\\]\\s-*\\)+") 2634(defconst verilog-range-re "\\(\\[[^]]*\\]\\s-*\\)+")
2584(defconst verilog-optional-signed-re "\\s-*\\(signed\\)?") 2635(defconst verilog-optional-signed-re "\\s-*\\(\\(un\\)?signed\\)?")
2585(defconst verilog-optional-signed-range-re 2636(defconst verilog-optional-signed-range-re
2586 (concat 2637 (concat
2587 "\\s-*\\(\\<\\(reg\\|wire\\)\\>\\s-*\\)?\\(\\<signed\\>\\s-*\\)?\\(" verilog-range-re "\\)?")) 2638 "\\s-*\\(\\<\\(reg\\|wire\\)\\>\\s-*\\)?\\(\\<\\(un\\)?signed\\>\\s-*\\)?\\(" verilog-range-re "\\)?"))
2588(defconst verilog-macroexp-re "`\\sw+") 2639(defconst verilog-macroexp-re "`\\sw+")
2589 2640
2590(defconst verilog-delay-re "#\\s-*\\(\\([0-9_]+\\('s?[hdxbo][0-9a-fA-F_xz]+\\)?\\)\\|\\(([^()]*)\\)\\|\\(\\sw+\\)\\)") 2641(defconst verilog-delay-re "#\\s-*\\(\\([0-9_]+\\('s?[hdxbo][0-9a-fA-F_xz]+\\)?\\)\\|\\(([^()]*)\\)\\|\\(\\sw+\\)\\)")
@@ -2799,17 +2850,23 @@ find the errors."
2799 ;; from http://www.emacswiki.org/emacs/MultilineRegexp 2850 ;; from http://www.emacswiki.org/emacs/MultilineRegexp
2800 (concat "\\<\\(`define\\|`if\\)\\>" ;; directive 2851 (concat "\\<\\(`define\\|`if\\)\\>" ;; directive
2801 "\\s-+" ;; separator 2852 "\\s-+" ;; separator
2802 "\\(.*\\(?:\n.*\\)*?\\)" ;; definition: to tend of line, the maybe more lines (excludes any trailing \n) 2853 "\\(?:.*?\\(?:\n.*\\)*?\\)" ;; definition: to end of line, then maybe more lines (excludes any trailing \n)
2854 "\\(?:\n\\s-*\n\\|\\'\\)") ;; blank line or EOF
2855 "\\)\\|\\(?:"
2856 ;; `<macro>() : i.e. `uvm_info(a,b,c) or any other pre-defined macro
2857 ;; Since parameters inside the macro can have parentheses, and
2858 ;; the macro can span multiple lines, just look for the opening
2859 ;; parentheses and then continue to the end of the first
2860 ;; non-escaped EOL
2861 (concat "\\<`\\w+\\>\\s-*("
2862 "\\(?:.*?\\(?:\n.*\\)*?\\)" ;; definition: to end of line, then maybe more lines (excludes any trailing \n)
2803 "\\(?:\n\\s-*\n\\|\\'\\)") ;; blank line or EOF 2863 "\\(?:\n\\s-*\n\\|\\'\\)") ;; blank line or EOF
2804 "\\)" 2864 "\\)"
2805 ))) 2865 )))
2806 2866
2807(defconst verilog-keywords 2867(defconst verilog-keywords
2808 '( "`case" "`default" "`define" "`else" "`endfor" "`endif" 2868 (append verilog-compiler-directives
2809 "`endprotect" "`endswitch" "`endwhile" "`for" "`format" "`if" "`ifdef" 2869 '(
2810 "`ifndef" "`include" "`let" "`protect" "`switch" "`timescale"
2811 "`time_scale" "`undef" "`while"
2812
2813 "after" "alias" "always" "always_comb" "always_ff" "always_latch" "and" 2870 "after" "alias" "always" "always_comb" "always_ff" "always_latch" "and"
2814 "assert" "assign" "assume" "automatic" "before" "begin" "bind" 2871 "assert" "assign" "assume" "automatic" "before" "begin" "bind"
2815 "bins" "binsof" "bit" "break" "buf" "bufif0" "bufif1" "byte" 2872 "bins" "binsof" "bit" "break" "buf" "bufif0" "bufif1" "byte"
@@ -2851,7 +2908,7 @@ find the errors."
2851 "sync_reject_on" "unique0" "until" "until_with" "untyped" "weak" 2908 "sync_reject_on" "unique0" "until" "until_with" "untyped" "weak"
2852 ;; 1800-2012 2909 ;; 1800-2012
2853 "implements" "interconnect" "nettype" "soft" 2910 "implements" "interconnect" "nettype" "soft"
2854 ) 2911 ))
2855 "List of Verilog keywords.") 2912 "List of Verilog keywords.")
2856 2913
2857(defconst verilog-comment-start-regexp "//\\|/\\*" 2914(defconst verilog-comment-start-regexp "//\\|/\\*"
@@ -2955,10 +3012,10 @@ See also `verilog-font-lock-extra-types'.")
2955(defface verilog-font-lock-grouping-keywords-face 3012(defface verilog-font-lock-grouping-keywords-face
2956 '((((class color) 3013 '((((class color)
2957 (background light)) 3014 (background light))
2958 (:foreground "red4" :bold t )) 3015 (:foreground "Purple" :bold t ))
2959 (((class color) 3016 (((class color)
2960 (background dark)) 3017 (background dark))
2961 (:foreground "red4" :bold t )) 3018 (:foreground "orange1" :bold t ))
2962 (t (:italic t))) 3019 (t (:italic t)))
2963 "Font lock mode face used to highlight verilog grouping keywords." 3020 "Font lock mode face used to highlight verilog grouping keywords."
2964 :group 'font-lock-highlighting-faces) 3021 :group 'font-lock-highlighting-faces)
@@ -3068,7 +3125,7 @@ See also `verilog-font-lock-extra-types'.")
3068 ;; Fontify all types 3125 ;; Fontify all types
3069 (if verilog-highlight-grouping-keywords 3126 (if verilog-highlight-grouping-keywords
3070 (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>") 3127 (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
3071 'verilog-font-lock-ams-face) 3128 'verilog-font-lock-grouping-keywords-face)
3072 (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>") 3129 (cons (concat "\\<\\(" verilog-font-grouping-keywords "\\)\\>")
3073 'font-lock-type-face)) 3130 'font-lock-type-face))
3074 (cons (concat "\\<\\(" verilog-type-font-keywords "\\)\\>") 3131 (cons (concat "\\<\\(" verilog-type-font-keywords "\\)\\>")
@@ -4200,6 +4257,8 @@ Uses `verilog-scan' cache."
4200 (not (or 4257 (not (or
4201 ;; stop if beginning of buffer 4258 ;; stop if beginning of buffer
4202 (bobp) 4259 (bobp)
4260 ;; stop if looking at a pre-processor directive
4261 (looking-at "`\\w+")
4203 ;; stop if we find a ; 4262 ;; stop if we find a ;
4204 (= (preceding-char) ?\;) 4263 (= (preceding-char) ?\;)
4205 ;; stop if we see a named coverpoint 4264 ;; stop if we see a named coverpoint
@@ -4208,12 +4267,13 @@ Uses `verilog-scan' cache."
4208 (not (or (looking-at "\\<") (forward-word -1))) 4267 (not (or (looking-at "\\<") (forward-word -1)))
4209 ;; stop if we see an assertion (perhaps labeled) 4268 ;; stop if we see an assertion (perhaps labeled)
4210 (and 4269 (and
4211 (looking-at "\\(\\<\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(\\<assert\\>\\)") 4270 (looking-at "\\(\\w+\\W*:\\W*\\)?\\(\\<\\(assert\\|assume\\|cover\\)\\>\\s-+\\<property\\>\\)\\|\\(\\<assert\\>\\)")
4212 (progn 4271 (progn
4213 (setq h (point)) 4272 (setq h (point))
4214 (save-excursion 4273 (save-excursion
4215 (verilog-backward-token) 4274 (verilog-backward-token)
4216 (if (looking-at verilog-label-re) 4275 (if (and (looking-at verilog-label-re)
4276 (not (looking-at verilog-end-block-re)))
4217 (setq h (point)))) 4277 (setq h (point))))
4218 (goto-char h))) 4278 (goto-char h)))
4219 ;; stop if we see an extended complete reg, perhaps a complete one 4279 ;; stop if we see an extended complete reg, perhaps a complete one
@@ -4715,8 +4775,8 @@ primitive or interface named NAME."
4715 (setq str (concat " // else: !assert " str )) 4775 (setq str (concat " // else: !assert " str ))
4716 (throw 'skip 1))))))))) 4776 (throw 'skip 1)))))))))
4717 4777
4718 (; always_comb, always_ff, always_latch 4778 (; always, always_comb, always_latch w/o @...
4719 (or (match-end 4) (match-end 5) (match-end 6)) 4779 (match-end 5)
4720 (goto-char (match-end 0)) 4780 (goto-char (match-end 0))
4721 (setq there (point)) 4781 (setq there (point))
4722 (setq err nil) 4782 (setq err nil)
@@ -4800,6 +4860,9 @@ primitive or interface named NAME."
4800 (throw 'skip 1)))) 4860 (throw 'skip 1))))
4801 )))) 4861 ))))
4802 (end-of-line) 4862 (end-of-line)
4863 (if kill-existing-comment
4864 (verilog-kill-existing-comment))
4865 (delete-horizontal-space)
4803 (insert (concat " // " string )))) 4866 (insert (concat " // " string ))))
4804 4867
4805 (;- this is end{function,generate,task,module,primitive,table,generate} 4868 (;- this is end{function,generate,task,module,primitive,table,generate}
@@ -5161,7 +5224,8 @@ FILENAME to find directory to run in, or defaults to `buffer-file-name`."
5161 ;; We should use font-lock-ensure in preference to 5224 ;; We should use font-lock-ensure in preference to
5162 ;; font-lock-fontify-buffer, but IIUC the problem this is supposed to 5225 ;; font-lock-fontify-buffer, but IIUC the problem this is supposed to
5163 ;; solve only appears in Emacsen older than font-lock-ensure anyway. 5226 ;; solve only appears in Emacsen older than font-lock-ensure anyway.
5164 (when fontlocked (font-lock-fontify-buffer))))))) 5227 ;; So avoid bytecomp's interactive-only by going through intern.
5228 (when fontlocked (funcall (intern "font-lock-fontify-buffer"))))))))
5165 5229
5166 5230
5167;; 5231;;
@@ -5530,8 +5594,12 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
5530 ((equal (char-after) ?\{) 5594 ((equal (char-after) ?\{)
5531 ;; block type returned based on outer constraint { or inner 5595 ;; block type returned based on outer constraint { or inner
5532 (if (verilog-at-constraint-p) 5596 (if (verilog-at-constraint-p)
5533 (cond (inconstraint (throw 'nesting 'constraint)) 5597 (cond (inconstraint
5534 (t (throw 'nesting 'statement))))) 5598 (beginning-of-line nil)
5599 (skip-chars-forward " \t")
5600 (throw 'nesting 'constraint))
5601 (t
5602 (throw 'nesting 'statement)))))
5535 ((equal (char-after) ?\}) 5603 ((equal (char-after) ?\})
5536 (let (par-pos 5604 (let (par-pos
5537 (there (verilog-at-close-constraint-p))) 5605 (there (verilog-at-close-constraint-p)))
@@ -6044,7 +6112,16 @@ Optional BOUND limits search."
6044 (save-match-data 6112 (save-match-data
6045 (save-excursion 6113 (save-excursion
6046 (verilog-re-search-backward "\\((\\*\\)\\|\\(\\*)\\)" nil 'move) 6114 (verilog-re-search-backward "\\((\\*\\)\\|\\(\\*)\\)" nil 'move)
6047 (numberp (match-beginning 1))))) 6115 (cond
6116 ((match-end 1)
6117 (progn (goto-char (match-end 1))
6118 (not (looking-at "\\s-*)")))
6119 nil)
6120 ((match-end 2)
6121 (progn (goto-char (match-beginning 2))
6122 (not (looking-at "(\\s-*")))
6123 nil)
6124 (t nil)))))
6048 6125
6049(defun verilog-in-parameter-p () 6126(defun verilog-in-parameter-p ()
6050 "Return true if point is in a parameter assignment #( p1=1, p2=5)." 6127 "Return true if point is in a parameter assignment #( p1=1, p2=5)."
@@ -6176,7 +6253,7 @@ Return >0 for nested struct."
6176 )) 6253 ))
6177 ;; if first word token not keyword, it maybe the instance name 6254 ;; if first word token not keyword, it maybe the instance name
6178 ;; check next word token 6255 ;; check next word token
6179 (if (looking-at "\\<\\w+\\>\\|\\s-*(\\s-*\\w+") 6256 (if (looking-at "\\<\\w+\\>\\|\\s-*(\\s-*\\S-+")
6180 (progn (verilog-beg-of-statement) 6257 (progn (verilog-beg-of-statement)
6181 (if (looking-at (concat "\\<\\(constraint\\|" 6258 (if (looking-at (concat "\\<\\(constraint\\|"
6182 "\\(?:\\w+\\s-*:\\s-*\\)?\\(coverpoint\\|cross\\)" 6259 "\\(?:\\w+\\s-*:\\s-*\\)?\\(coverpoint\\|cross\\)"
@@ -6275,8 +6352,8 @@ Return >0 for nested struct."
6275 (goto-char (- (point) 2)) 6352 (goto-char (- (point) 2))
6276 t) ;; Let nth 4 state handle the rest 6353 t) ;; Let nth 4 state handle the rest
6277 ((and (not (bobp)) 6354 ((and (not (bobp))
6278 (= (char-before) ?\)) 6355 (verilog-looking-back "\\*)" nil)
6279 (= (char-before (1- (point))) ?\*)) 6356 (not (verilog-looking-back "(\\s-*\\*)" nil)))
6280 (goto-char (- (point) 2)) 6357 (goto-char (- (point) 2))
6281 (if (search-backward "(*" nil t) 6358 (if (search-backward "(*" nil t)
6282 (progn 6359 (progn
@@ -6320,7 +6397,8 @@ Return >0 for nested struct."
6320 (progn 6397 (progn
6321 (goto-char h) 6398 (goto-char h)
6322 nil)))) 6399 nil))))
6323 ((looking-at "(\\*") 6400 ((and (looking-at "(\\*") ;; attribute start, but not an event (*) or (* )
6401 (not (looking-at "(\\*\\s-*)")))
6324 (progn 6402 (progn
6325 (setq h (point)) 6403 (setq h (point))
6326 (goto-char (match-end 0)) 6404 (goto-char (match-end 0))
@@ -6375,7 +6453,6 @@ Only look at a few lines to determine indent level."
6375 (cond 6453 (cond
6376 ((or 6454 ((or
6377 (= (preceding-char) ?\,) 6455 (= (preceding-char) ?\,)
6378 (= (preceding-char) ?\])
6379 (save-excursion 6456 (save-excursion
6380 (verilog-beg-of-statement-1) 6457 (verilog-beg-of-statement-1)
6381 (looking-at verilog-declaration-re))) 6458 (looking-at verilog-declaration-re)))
@@ -7830,6 +7907,48 @@ Signals must be in standard (base vector) form."
7830 (nreverse out-list))))) 7907 (nreverse out-list)))))
7831;;(verilog-signals-not-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("EXT" ""))) 7908;;(verilog-signals-not-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("EXT" "")))
7832 7909
7910(defun verilog-signals-not-in-struct (in-list not-list)
7911 "Return list of signals in IN-LIST that aren't also in NOT-LIST.
7912Also remove any duplicates in IN-LIST.
7913Any structure in not-list will remove all members in in-list.
7914Signals must be in standard (base vector) form."
7915 (cond ((eval-when-compile (fboundp 'make-hash-table))
7916 (let ((ht (make-hash-table :test 'equal :rehash-size 4.0))
7917 out-list addit nm)
7918 (while not-list
7919 (puthash (car (car not-list)) t ht)
7920 (setq not-list (cdr not-list)))
7921 (while in-list
7922 (setq nm (verilog-sig-name (car in-list)))
7923 (when (not (gethash nm ht))
7924 (setq addit t)
7925 (while (string-match "^\\([^\\].*\\)\\.[^.]+$" nm)
7926 (setq nm (match-string 1 nm))
7927 (setq addit (and addit
7928 (not (gethash nm ht)))))
7929 (when addit
7930 (setq out-list (cons (car in-list) out-list))
7931 (puthash (verilog-sig-name (car in-list)) t ht)))
7932 (setq in-list (cdr in-list)))
7933 (nreverse out-list)))
7934 ;; Slower Fallback if no hash tables (pre Emacs 21.1/XEmacs 21.4)
7935 (t
7936 (let (out-list addit nm)
7937 (while in-list
7938 (setq nm (verilog-sig-name (car in-list)))
7939 (when (and (not (assoc nm not-list))
7940 (not (assoc nm out-list)))
7941 (setq addit t)
7942 (while (string-match "^\\([^\\].*\\)\\.[^.]+$" nm)
7943 (setq nm (match-string 1 nm))
7944 (setq addit (and addit
7945 (not (assoc nm not-list)))))
7946 (when addit
7947 (setq out-list (cons (car in-list) out-list))))
7948 (setq in-list (cdr in-list)))
7949 (nreverse out-list)))))
7950;;(verilog-signals-not-in-struct '(("A" "") ("B" "") ("DEL.SUB.A" "[2:3]")) '(("DEL.SUB" "") ("EXT" "")))
7951
7833(defun verilog-signals-memory (in-list) 7952(defun verilog-signals-memory (in-list)
7834 "Return list of signals in IN-LIST that are memorized (multidimensional)." 7953 "Return list of signals in IN-LIST that are memorized (multidimensional)."
7835 (let (out-list) 7954 (let (out-list)
@@ -8281,10 +8400,9 @@ Return an array of [outputs inouts inputs wire reg assign const]."
8281 typedefed nil multidim nil ptype nil modport nil 8400 typedefed nil multidim nil ptype nil modport nil
8282 expect-signal 'sigs-assign sig-paren paren)) 8401 expect-signal 'sigs-assign sig-paren paren))
8283 ((member keywd '("localparam" "genvar")) 8402 ((member keywd '("localparam" "genvar"))
8284 (unless io 8403 (setq vec nil enum nil rvalue nil signed nil
8285 (setq vec nil enum nil rvalue nil signed nil 8404 typedefed nil multidim nil ptype nil modport nil
8286 typedefed nil multidim nil ptype nil modport nil 8405 expect-signal 'sigs-const sig-paren paren))
8287 expect-signal 'sigs-const sig-paren paren)))
8288 ((member keywd '("signed" "unsigned")) 8406 ((member keywd '("signed" "unsigned"))
8289 (setq signed keywd)) 8407 (setq signed keywd))
8290 ((member keywd '("assert" "assume" "cover" "expect" "restrict")) 8408 ((member keywd '("assert" "assume" "cover" "expect" "restrict"))
@@ -12134,20 +12252,26 @@ You may also provide an optional third argument regular
12134expression, in which case only signals which have that pin 12252expression, in which case only signals which have that pin
12135direction and data type matching that regular expression will be 12253direction and data type matching that regular expression will be
12136included. This matches against everything before the signal name 12254included. This matches against everything before the signal name
12137in the declaration, for example against \"input\" (single bit), 12255in the declaration, for example against \"input\" (single
12138\"output logic\" (direction and type) or \"output 12256bit), \"output logic\" (direction and type) or
12139[1:0]\" (direction and implicit type). You also probably want to 12257\"output [1:0]\" (direction and implicit type). You also
12140skip spaces in your regexp. 12258probably want to skip spaces in your regexp.
12141 12259
12142For example, the below will result in matching the output \"o\" 12260For example, the below will result in matching the output \"o\"
12143against the previous example's module: 12261against the previous example's module:
12144 12262
12145 /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/" 12263 /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/
12264
12265You may also provide an optional fourth argument regular
12266expression, which if not \"\" only signals which do NOT match
12267that expression are included."
12268 ;; Beware spacing of quotes in above as can mess up Emacs indenter
12146 (save-excursion 12269 (save-excursion
12147 (let* ((params (verilog-read-auto-params 1 3)) 12270 (let* ((params (verilog-read-auto-params 1 4))
12148 (submod (nth 0 params)) 12271 (submod (nth 0 params))
12149 (regexp (nth 1 params)) 12272 (regexp (nth 1 params))
12150 (direction-re (nth 2 params)) 12273 (direction-re (nth 2 params))
12274 (not-re (nth 3 params))
12151 submodi) 12275 submodi)
12152 ;; Lookup position, etc of co-module 12276 ;; Lookup position, etc of co-module
12153 ;; Note this may raise an error 12277 ;; Note this may raise an error
@@ -12182,20 +12306,24 @@ against the previous example's module:
12182 (append (verilog-decls-get-interfaces moddecls))))) 12306 (append (verilog-decls-get-interfaces moddecls)))))
12183 (forward-line 1) 12307 (forward-line 1)
12184 (setq sig-list-i (verilog-signals-edit-wire-reg 12308 (setq sig-list-i (verilog-signals-edit-wire-reg
12185 (verilog-signals-matching-dir-re 12309 (verilog-signals-not-matching-regexp
12186 (verilog-signals-matching-regexp sig-list-i regexp) 12310 (verilog-signals-matching-dir-re
12187 "input" direction-re)) 12311 (verilog-signals-matching-regexp sig-list-i regexp)
12312 "input" direction-re) not-re))
12188 sig-list-o (verilog-signals-edit-wire-reg 12313 sig-list-o (verilog-signals-edit-wire-reg
12189 (verilog-signals-matching-dir-re 12314 (verilog-signals-not-matching-regexp
12190 (verilog-signals-matching-regexp sig-list-o regexp) 12315 (verilog-signals-matching-dir-re
12191 "output" direction-re)) 12316 (verilog-signals-matching-regexp sig-list-o regexp)
12317 "output" direction-re) not-re))
12192 sig-list-io (verilog-signals-edit-wire-reg 12318 sig-list-io (verilog-signals-edit-wire-reg
12319 (verilog-signals-not-matching-regexp
12320 (verilog-signals-matching-dir-re
12321 (verilog-signals-matching-regexp sig-list-io regexp)
12322 "inout" direction-re) not-re))
12323 sig-list-if (verilog-signals-not-matching-regexp
12193 (verilog-signals-matching-dir-re 12324 (verilog-signals-matching-dir-re
12194 (verilog-signals-matching-regexp sig-list-io regexp) 12325 (verilog-signals-matching-regexp sig-list-if regexp)
12195 "inout" direction-re)) 12326 "interface" direction-re) not-re))
12196 sig-list-if (verilog-signals-matching-dir-re
12197 (verilog-signals-matching-regexp sig-list-if regexp)
12198 "interface" direction-re))
12199 (when v2k (verilog-repair-open-comma)) 12327 (when v2k (verilog-repair-open-comma))
12200 (when (or sig-list-i sig-list-o sig-list-io sig-list-if) 12328 (when (or sig-list-i sig-list-o sig-list-io sig-list-if)
12201 (verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n") 12329 (verilog-insert-indent "// Beginning of automatic in/out/inouts (from specific module)\n")
@@ -12262,15 +12390,20 @@ You may also provide an optional third argument regular
12262expression, in which case only signals which have that pin 12390expression, in which case only signals which have that pin
12263direction and data type matching that regular expression will be 12391direction and data type matching that regular expression will be
12264included. This matches against everything before the signal name 12392included. This matches against everything before the signal name
12265in the declaration, for example against \"input\" (single bit), 12393in the declaration, for example against \"input\" (single
12266\"output logic\" (direction and type) or \"output 12394bit), \"output logic\" (direction and type)
12267[1:0]\" (direction and implicit type). You also probably want to 12395or \"output [1:0]\" (direction and implicit type). You also
12268skip spaces in your regexp. 12396probably want to skip spaces in your regexp.
12269 12397
12270For example, the below will result in matching the output \"o\" 12398For example, the below will result in matching the output \"o\"
12271against the previous example's module: 12399against the previous example's module:
12272 12400
12273 /*AUTOINOUTCOMP(\"ExampMain\",\"\",\"^output.*\")*/" 12401 /*AUTOINOUTCOMP(\"ExampMain\",\"\",\"^output.*\")*/
12402
12403You may also provide an optional fourth argument regular
12404expression, which if not \"\" only signals which do NOT match
12405that expression are included."
12406 ;; Beware spacing of quotes in above as can mess up Emacs indenter
12274 (verilog-auto-inout-module t nil)) 12407 (verilog-auto-inout-module t nil))
12275 12408
12276(defun verilog-auto-inout-in () 12409(defun verilog-auto-inout-in ()
@@ -12793,14 +12926,15 @@ Typing \\[verilog-auto] will make this into:
12793 (verilog-re-search-backward-quick "\\(@\\|\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\)\\>\\)" nil t) 12926 (verilog-re-search-backward-quick "\\(@\\|\\<\\(always\\(_latch\\|_ff\\|_comb\\)?\\)\\>\\)" nil t)
12794 (setq sigss (verilog-read-always-signals))) 12927 (setq sigss (verilog-read-always-signals)))
12795 (setq dly-list (verilog-alw-get-outputs-delayed sigss)) 12928 (setq dly-list (verilog-alw-get-outputs-delayed sigss))
12796 (setq sig-list (verilog-signals-not-in (append 12929 (setq sig-list (verilog-signals-not-in-struct
12797 (verilog-alw-get-outputs-delayed sigss) 12930 (append
12798 (when (or (not (verilog-alw-get-uses-delayed sigss)) 12931 (verilog-alw-get-outputs-delayed sigss)
12799 verilog-auto-reset-blocking-in-non) 12932 (when (or (not (verilog-alw-get-uses-delayed sigss))
12800 (verilog-alw-get-outputs-immediate sigss))) 12933 verilog-auto-reset-blocking-in-non)
12801 (append 12934 (verilog-alw-get-outputs-immediate sigss)))
12802 (verilog-alw-get-temps sigss) 12935 (append
12803 prereset-sigs))) 12936 (verilog-alw-get-temps sigss)
12937 prereset-sigs)))
12804 (setq sig-list (sort sig-list `verilog-signals-sort-compare)) 12938 (setq sig-list (sort sig-list `verilog-signals-sort-compare))
12805 (when sig-list 12939 (when sig-list
12806 (insert "\n"); 12940 (insert "\n");
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 0257210a6c7..ef46e34e78f 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -73,13 +73,17 @@
73 "Return a string used to group a set of locations. 73 "Return a string used to group a set of locations.
74This is typically the filename.") 74This is typically the filename.")
75 75
76(cl-defgeneric xref-location-line (_location)
77 "Return the line number corresponding to the location."
78 nil)
79
76;;;; Commonly needed location classes are defined here: 80;;;; Commonly needed location classes are defined here:
77 81
78;; FIXME: might be useful to have an optional "hint" i.e. a string to 82;; FIXME: might be useful to have an optional "hint" i.e. a string to
79;; search for in case the line number is sightly out of date. 83;; search for in case the line number is sightly out of date.
80(defclass xref-file-location (xref-location) 84(defclass xref-file-location (xref-location)
81 ((file :type string :initarg :file) 85 ((file :type string :initarg :file)
82 (line :type fixnum :initarg :line) 86 (line :type fixnum :initarg :line :reader xref-location-line)
83 (column :type fixnum :initarg :column)) 87 (column :type fixnum :initarg :column))
84 :documentation "A file location is a file/line/column triple. 88 :documentation "A file location is a file/line/column triple.
85Line numbers start from 1 and columns from 0.") 89Line numbers start from 1 and columns from 0.")
@@ -203,6 +207,9 @@ found, return nil.
203 (apropos PATTERN): Find all symbols that match PATTERN. PATTERN 207 (apropos PATTERN): Find all symbols that match PATTERN. PATTERN
204is a regexp. 208is a regexp.
205 209
210 (matches REGEXP): Find all matches for REGEXP in the related
211files. REGEXP is an Emacs regular expression.
212
206IDENTIFIER can be any string returned by 213IDENTIFIER can be any string returned by
207`xref-identifier-at-point-function', or from the table returned 214`xref-identifier-at-point-function', or from the table returned
208by `xref-identifier-completion-table-function'. 215by `xref-identifier-completion-table-function'.
@@ -276,6 +283,20 @@ backward."
276 :type 'integer 283 :type 'integer
277 :version "25.1") 284 :version "25.1")
278 285
286(defcustom xref-prompt-for-identifier nil
287 "When non-nil, always prompt for the identifier name.
288
289Otherwise, only prompt when there's no value at point we can use,
290or when the command has been called with the prefix argument."
291 :type '(choice (const :tag "always" t)
292 (const :tag "auto" nil))
293 :version "25.1")
294
295(defcustom xref-pulse-on-jump t
296 "When non-nil, momentarily highlight jump locations."
297 :type 'boolean
298 :version "25.1")
299
279(defvar xref--marker-ring (make-ring xref-marker-ring-length) 300(defvar xref--marker-ring (make-ring xref-marker-ring-length)
280 "Ring of markers to implement the marker stack.") 301 "Ring of markers to implement the marker stack.")
281 302
@@ -294,7 +315,20 @@ backward."
294 (switch-to-buffer (or (marker-buffer marker) 315 (switch-to-buffer (or (marker-buffer marker)
295 (error "The marked buffer has been deleted"))) 316 (error "The marked buffer has been deleted")))
296 (goto-char (marker-position marker)) 317 (goto-char (marker-position marker))
297 (set-marker marker nil nil)))) 318 (set-marker marker nil nil)
319 (xref--maybe-pulse))))
320
321(defun xref--maybe-pulse ()
322 (when xref-pulse-on-jump
323 (let (beg end)
324 (save-excursion
325 (back-to-indentation)
326 (if (eolp)
327 (setq beg (line-beginning-position)
328 end (1+ (point)))
329 (setq beg (point)
330 end (line-end-position))))
331 (pulse-momentary-highlight-region beg end 'next-error))))
298 332
299;; etags.el needs this 333;; etags.el needs this
300(defun xref-clear-marker-stack () 334(defun xref-clear-marker-stack ()
@@ -329,7 +363,8 @@ WINDOW controls how the buffer is displayed:
329 (cl-ecase window 363 (cl-ecase window
330 ((nil) (switch-to-buffer (current-buffer))) 364 ((nil) (switch-to-buffer (current-buffer)))
331 (window (pop-to-buffer (current-buffer) t)) 365 (window (pop-to-buffer (current-buffer) t))
332 (frame (let ((pop-up-frames t)) (pop-to-buffer (current-buffer) t))))) 366 (frame (let ((pop-up-frames t)) (pop-to-buffer (current-buffer) t))))
367 (xref--maybe-pulse))
333 368
334 369
335;;; XREF buffer (part of the UI) 370;;; XREF buffer (part of the UI)
@@ -365,6 +400,7 @@ Used for temporary buffers.")
365 (with-selected-window (display-buffer (current-buffer) other-window) 400 (with-selected-window (display-buffer (current-buffer) other-window)
366 (goto-char pos) 401 (goto-char pos)
367 (recenter recenter-arg) 402 (recenter recenter-arg)
403 (xref--maybe-pulse)
368 (let ((buf (current-buffer)) 404 (let ((buf (current-buffer))
369 (win (selected-window))) 405 (win (selected-window)))
370 (with-current-buffer xref-buf 406 (with-current-buffer xref-buf
@@ -406,7 +442,9 @@ Used for temporary buffers.")
406 (xref-show-location-at-point)) 442 (xref-show-location-at-point))
407 443
408(defun xref--location-at-point () 444(defun xref--location-at-point ()
409 (get-text-property (point) 'xref-location)) 445 (save-excursion
446 (back-to-indentation)
447 (get-text-property (point) 'xref-location)))
410 448
411(defvar-local xref--window nil 449(defvar-local xref--window nil
412 "ACTION argument to call `display-buffer' with.") 450 "ACTION argument to call `display-buffer' with.")
@@ -414,7 +452,6 @@ Used for temporary buffers.")
414(defun xref-goto-xref () 452(defun xref-goto-xref ()
415 "Jump to the xref on the current line and bury the xref buffer." 453 "Jump to the xref on the current line and bury the xref buffer."
416 (interactive) 454 (interactive)
417 (back-to-indentation)
418 (let ((loc (or (xref--location-at-point) 455 (let ((loc (or (xref--location-at-point)
419 (user-error "No reference at point"))) 456 (user-error "No reference at point")))
420 (window xref--window)) 457 (window xref--window))
@@ -435,7 +472,22 @@ Used for temporary buffers.")
435 472
436(define-derived-mode xref--xref-buffer-mode special-mode "XREF" 473(define-derived-mode xref--xref-buffer-mode special-mode "XREF"
437 "Mode for displaying cross-references." 474 "Mode for displaying cross-references."
438 (setq buffer-read-only t)) 475 (setq buffer-read-only t)
476 (setq next-error-function #'xref--next-error-function)
477 (setq next-error-last-buffer (current-buffer)))
478
479(defun xref--next-error-function (n reset?)
480 (when reset?
481 (goto-char (point-min)))
482 (let ((backward (< n 0))
483 (n (abs n))
484 (loc nil))
485 (dotimes (_ n)
486 (setq loc (xref--search-property 'xref-location backward)))
487 (cond (loc
488 (xref--pop-to-location loc))
489 (t
490 (error "No %s xref" (if backward "previous" "next"))))))
439 491
440(defun xref-quit (&optional kill) 492(defun xref-quit (&optional kill)
441 "Bury temporarily displayed buffers, then quit the current window. 493 "Bury temporarily displayed buffers, then quit the current window.
@@ -485,22 +537,35 @@ meantime are preserved."
485XREF-ALIST is of the form ((GROUP . (XREF ...)) ...). Where 537XREF-ALIST is of the form ((GROUP . (XREF ...)) ...). Where
486GROUP is a string for decoration purposes and XREF is an 538GROUP is a string for decoration purposes and XREF is an
487`xref--xref' object." 539`xref--xref' object."
488 (cl-loop for ((group . xrefs) . more1) on xref-alist do 540 (require 'compile) ; For the compilation faces.
489 (xref--insert-propertized '(face bold) group "\n") 541 (cl-loop for ((group . xrefs) . more1) on xref-alist
542 for max-line-width =
543 (cl-loop for xref in xrefs
544 maximize (let ((line (xref-location-line
545 (oref xref :location))))
546 (length (and line (format "%d" line)))))
547 for line-format = (and max-line-width
548 (format "%%%dd: " max-line-width))
549 do
550 (xref--insert-propertized '(face compilation-info) group "\n")
490 (cl-loop for (xref . more2) on xrefs do 551 (cl-loop for (xref . more2) on xrefs do
491 (insert " ")
492 (with-slots (description location) xref 552 (with-slots (description location) xref
493 (xref--insert-propertized 553 (let* ((line (xref-location-line location))
494 (list 'xref-location location 554 (prefix
495 'face 'font-lock-keyword-face 555 (if line
496 'mouse-face 'highlight 556 (propertize (format line-format line)
497 'keymap xref--button-map 557 'face 'compilation-line-number)
498 'help-echo 558 " ")))
499 (concat "mouse-2: display in another window, " 559 (xref--insert-propertized
500 "RET or mouse-1: follow reference")) 560 (list 'xref-location location
501 description)) 561 ;; 'face 'font-lock-keyword-face
502 (when (or more1 more2) 562 'mouse-face 'highlight
503 (insert "\n"))))) 563 'keymap xref--button-map
564 'help-echo
565 (concat "mouse-2: display in another window, "
566 "RET or mouse-1: follow reference"))
567 prefix description)))
568 (insert "\n"))))
504 569
505(defun xref--analyze (xrefs) 570(defun xref--analyze (xrefs)
506 "Find common filenames in XREFS. 571 "Find common filenames in XREFS.
@@ -559,10 +624,10 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
559(defun xref--read-identifier (prompt) 624(defun xref--read-identifier (prompt)
560 "Return the identifier at point or read it from the minibuffer." 625 "Return the identifier at point or read it from the minibuffer."
561 (let ((id (funcall xref-identifier-at-point-function))) 626 (let ((id (funcall xref-identifier-at-point-function)))
562 (cond ((or current-prefix-arg (not id)) 627 (cond ((or current-prefix-arg xref-prompt-for-identifier (not id))
563 (completing-read prompt 628 (completing-read prompt
564 (funcall xref-identifier-completion-table-function) 629 (funcall xref-identifier-completion-table-function)
565 nil t nil 630 nil nil nil
566 'xref--read-identifier-history id)) 631 'xref--read-identifier-history id))
567 (t id)))) 632 (t id))))
568 633
@@ -599,6 +664,12 @@ With prefix argument, prompt for the identifier."
599 (interactive (list (xref--read-identifier "Find references of: "))) 664 (interactive (list (xref--read-identifier "Find references of: ")))
600 (xref--show-xrefs identifier 'references identifier nil)) 665 (xref--show-xrefs identifier 'references identifier nil))
601 666
667;;;###autoload
668(defun xref-find-regexp (regexp)
669 "Find all matches for REGEXP."
670 (interactive (list (xref--read-identifier "Find regexp: ")))
671 (xref--show-xrefs regexp 'matches regexp nil))
672
602(declare-function apropos-parse-pattern "apropos" (pattern)) 673(declare-function apropos-parse-pattern "apropos" (pattern))
603 674
604;;;###autoload 675;;;###autoload
@@ -650,6 +721,72 @@ and just use etags."
650 (setq-local xref-identifier-completion-table-function 721 (setq-local xref-identifier-completion-table-function
651 (cdr xref-etags-mode--saved)))) 722 (cdr xref-etags-mode--saved))))
652 723
724(declare-function semantic-symref-find-references-by-name "semantic/symref")
725(declare-function semantic-symref-find-text "semantic/symref")
726(declare-function semantic-find-file-noselect "semantic/fw")
727
728(defun xref-collect-matches (input dir &optional kind)
729 "Collect KIND matches for INPUT inside DIR according.
730KIND can be `symbol', `regexp' or nil, the last of which means
731literal matches. This function uses the Semantic Symbol
732Reference API, see `semantic-symref-find-references-by-name' for
733details on which tools are used, and when."
734 (require 'semantic/symref)
735 (defvar semantic-symref-tool)
736 (cl-assert (directory-name-p dir))
737 (when (null kind)
738 (setq input (regexp-quote input)))
739 (let* ((default-directory dir)
740 (semantic-symref-tool 'detect)
741 (res (if (eq kind 'symbol)
742 (semantic-symref-find-references-by-name input 'subdirs)
743 (semantic-symref-find-text (xref--regexp-to-extended input)
744 'subdirs)))
745 (hits (and res (oref res :hit-lines)))
746 (orig-buffers (buffer-list)))
747 (unwind-protect
748 (delq nil
749 (mapcar (lambda (hit) (xref--collect-match hit input kind)) hits))
750 (mapc #'kill-buffer
751 (cl-set-difference (buffer-list) orig-buffers)))))
752
753(defun xref--regexp-to-extended (str)
754 (replace-regexp-in-string
755 ;; FIXME: Add tests. Move to subr.el, make a public function.
756 ;; Maybe error on Emacs-only constructs.
757 "\\(?:\\\\\\\\\\)*\\(?:\\\\[][]\\)?\\(?:\\[.+?\\]\\|\\(\\\\?[(){}|]\\)\\)"
758 (lambda (str)
759 (cond
760 ((not (match-beginning 1))
761 str)
762 ((eq (length (match-string 1 str)) 2)
763 (concat (substring str 0 (match-beginning 1))
764 (substring (match-string 1 str) 1 2)))
765 (t
766 (concat (substring str 0 (match-beginning 1))
767 "\\"
768 (match-string 1 str)))))
769 str t t))
770
771(defun xref--collect-match (hit input kind)
772 (pcase-let* ((`(,line . ,file) hit)
773 (buf (or (find-buffer-visiting file)
774 (semantic-find-file-noselect file)))
775 (input (if (eq kind 'symbol)
776 (format "\\_<%s\\_>" (regexp-quote input))
777 input)))
778 (with-current-buffer buf
779 (save-excursion
780 (goto-char (point-min))
781 (forward-line (1- line))
782 (when (re-search-forward input (line-end-position) t)
783 (goto-char (match-beginning 0))
784 (xref-make (buffer-substring
785 (line-beginning-position)
786 (line-end-position))
787 (xref-make-file-location file line
788 (current-column))))))))
789
653 790
654(provide 'xref) 791(provide 'xref)
655 792