diff options
| author | Jan D | 2015-05-17 16:46:34 +0200 |
|---|---|---|
| committer | Jan D | 2015-05-17 16:46:34 +0200 |
| commit | 6445ee0fb751ae2c1dfef900d44721b3d952812f (patch) | |
| tree | d43006cb93d9ea7b00ea02aabcd5577c41ff827f /lisp/progmodes | |
| parent | f92ac2e82ed199d6f25d2a59508e08addb1150ac (diff) | |
| parent | c9c4708ed47b18987940a71b98eb9873150d2b95 (diff) | |
| download | emacs-6445ee0fb751ae2c1dfef900d44721b3d952812f.tar.gz emacs-6445ee0fb751ae2c1dfef900d44721b3d952812f.zip | |
Merge branch 'master' into cairo
Diffstat (limited to 'lisp/progmodes')
| -rw-r--r-- | lisp/progmodes/cc-awk.el | 1 | ||||
| -rw-r--r-- | lisp/progmodes/cc-cmds.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/cmacexp.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/elisp-mode.el | 143 | ||||
| -rw-r--r-- | lisp/progmodes/etags.el | 23 | ||||
| -rw-r--r-- | lisp/progmodes/idlw-shell.el | 14 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/python.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/tcl.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/verilog-mode.el | 282 | ||||
| -rw-r--r-- | lisp/progmodes/xref.el | 181 |
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. |
| 36 | It has `lisp-mode-abbrev-table' as its parent." | 35 | It 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. |
| 1152 | If SYM is a subr and no arglist is obtainable from the docstring | 1192 | If SYM is a subr and no arglist is obtainable from the docstring |
| 1153 | or elsewhere, return a 1-line docstring." | 1193 | or 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. |
| 1180 | In the absence of INDEX, just call `elisp--docstring-format-sym-doc'." | 1229 | In 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 (). |
| 1397 | ARGLIST is either a string, or a list of strings or symbols." | 1414 | ARGLIST 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]. | |||
| 947 | Contrast this with the ring of marks gone to by the command. | 947 | Contrast this with the ring of marks gone to by the command. |
| 948 | 948 | ||
| 949 | See documentation of variable `tags-file-name'." | 949 | See 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. | ||
| 297 | Like `looking-at' except matches before point, and is slower. | ||
| 298 | LIMIT if non-nil speeds up the search by specifying a minimum | ||
| 299 | starting position, to avoid checking matches that would start | ||
| 300 | before LIMIT. | ||
| 301 | |||
| 302 | If GREEDY is non-nil, extend the match backwards as far as | ||
| 303 | possible, stopping when a single additional previous character | ||
| 304 | cannot be part of a match for REGEXP. When the match is | ||
| 305 | extended, its starting position is allowed to occur before | ||
| 306 | LIMIT. | ||
| 307 | |||
| 308 | As a general recommendation, try to avoid using `looking-back' | ||
| 309 | wherever 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. |
| 665 | If false, these words are in the `font-lock-type-face'; if True then they are in | 709 | If 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 | 710 | then they are in `verilog-font-lock-grouping-keywords-face'. |
| 667 | grouping constructs allow the structure of the code to be understood at a glance." | 711 | Some find that special highlighting on these grouping constructs |
| 712 | allow 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. | ||
| 7912 | Also remove any duplicates in IN-LIST. | ||
| 7913 | Any structure in not-list will remove all members in in-list. | ||
| 7914 | Signals 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 | |||
| 12134 | expression, in which case only signals which have that pin | 12252 | expression, in which case only signals which have that pin |
| 12135 | direction and data type matching that regular expression will be | 12253 | direction and data type matching that regular expression will be |
| 12136 | included. This matches against everything before the signal name | 12254 | included. This matches against everything before the signal name |
| 12137 | in the declaration, for example against \"input\" (single bit), | 12255 | in the declaration, for example against \"input\" (single |
| 12138 | \"output logic\" (direction and type) or \"output | 12256 | bit), \"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 |
| 12140 | skip spaces in your regexp. | 12258 | probably want to skip spaces in your regexp. |
| 12141 | 12259 | ||
| 12142 | For example, the below will result in matching the output \"o\" | 12260 | For example, the below will result in matching the output \"o\" |
| 12143 | against the previous example's module: | 12261 | against the previous example's module: |
| 12144 | 12262 | ||
| 12145 | /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/" | 12263 | /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/ |
| 12264 | |||
| 12265 | You may also provide an optional fourth argument regular | ||
| 12266 | expression, which if not \"\" only signals which do NOT match | ||
| 12267 | that 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 | |||
| 12262 | expression, in which case only signals which have that pin | 12390 | expression, in which case only signals which have that pin |
| 12263 | direction and data type matching that regular expression will be | 12391 | direction and data type matching that regular expression will be |
| 12264 | included. This matches against everything before the signal name | 12392 | included. This matches against everything before the signal name |
| 12265 | in the declaration, for example against \"input\" (single bit), | 12393 | in the declaration, for example against \"input\" (single |
| 12266 | \"output logic\" (direction and type) or \"output | 12394 | bit), \"output logic\" (direction and type) |
| 12267 | [1:0]\" (direction and implicit type). You also probably want to | 12395 | or \"output [1:0]\" (direction and implicit type). You also |
| 12268 | skip spaces in your regexp. | 12396 | probably want to skip spaces in your regexp. |
| 12269 | 12397 | ||
| 12270 | For example, the below will result in matching the output \"o\" | 12398 | For example, the below will result in matching the output \"o\" |
| 12271 | against the previous example's module: | 12399 | against the previous example's module: |
| 12272 | 12400 | ||
| 12273 | /*AUTOINOUTCOMP(\"ExampMain\",\"\",\"^output.*\")*/" | 12401 | /*AUTOINOUTCOMP(\"ExampMain\",\"\",\"^output.*\")*/ |
| 12402 | |||
| 12403 | You may also provide an optional fourth argument regular | ||
| 12404 | expression, which if not \"\" only signals which do NOT match | ||
| 12405 | that 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. |
| 74 | This is typically the filename.") | 74 | This 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. |
| 85 | Line numbers start from 1 and columns from 0.") | 89 | Line 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 |
| 204 | is a regexp. | 208 | is a regexp. |
| 205 | 209 | ||
| 210 | (matches REGEXP): Find all matches for REGEXP in the related | ||
| 211 | files. REGEXP is an Emacs regular expression. | ||
| 212 | |||
| 206 | IDENTIFIER can be any string returned by | 213 | IDENTIFIER 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 |
| 208 | by `xref-identifier-completion-table-function'. | 215 | by `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 | |||
| 289 | Otherwise, only prompt when there's no value at point we can use, | ||
| 290 | or 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." | |||
| 485 | XREF-ALIST is of the form ((GROUP . (XREF ...)) ...). Where | 537 | XREF-ALIST is of the form ((GROUP . (XREF ...)) ...). Where |
| 486 | GROUP is a string for decoration purposes and XREF is an | 538 | GROUP 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. | ||
| 730 | KIND can be `symbol', `regexp' or nil, the last of which means | ||
| 731 | literal matches. This function uses the Semantic Symbol | ||
| 732 | Reference API, see `semantic-symref-find-references-by-name' for | ||
| 733 | details 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 | ||