diff options
| -rw-r--r-- | lisp/progmodes/make-mode.el | 116 |
1 files changed, 70 insertions, 46 deletions
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index bc30bfdfc56..8467310d1da 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el | |||
| @@ -257,26 +257,24 @@ not be enclosed in { } or ( )." | |||
| 257 | ;; Note that the first big subexpression is used by font lock. Note | 257 | ;; Note that the first big subexpression is used by font lock. Note |
| 258 | ;; that if you change this regexp you might have to fix the imenu | 258 | ;; that if you change this regexp you might have to fix the imenu |
| 259 | ;; index in makefile-imenu-generic-expression. | 259 | ;; index in makefile-imenu-generic-expression. |
| 260 | (defconst makefile-dependency-regex | 260 | (defvar makefile-dependency-regex |
| 261 | ;; Allow for one nested level $($(var:a=b):c=d) | 261 | ;; Allow for two nested levels $(v1:$(v2:$(v3:a=b)=c)=d) |
| 262 | ;; Scan non-$ constructs char by char, so we don't miss a $ while allowing $$. | 262 | "^ *\\(\\(?: *\\$\\(?:[({]\\(?:\\$\\(?:[({]\\(?:\\$\\(?:[^({]\\|.[^\n$#})]+?[})]\\)\\|[^\n$#)}]\\)+?[})]\\|[^({]\\)\\|[^\n$#)}]\\)+?[})]\\|[^({]\\)\\| *[^ \n$#:=]+\\)+?\\)[ \t]*\\(:\\)\\(?:[ \t]*$\\|[^=\n]\\(?:[^#\n]*?;[ \t]*\\(.+\\)\\)?\\)" |
| 263 | ;; Since we must allow space between targets, I then don't know how to evite a command starting with :. | ||
| 264 | "^ *\\(\\(?:\\$[({]\\(?:\\$[({][^ \t\n#})]+?[})]\\|[^\n#]\\)+?[})]\\|[^\n#:=]\\)+?\\)[ \t]*:\\(?:[ \t]*$\\|[^=\n].*$\\)" | ||
| 265 | "Regex used to find dependency lines in a makefile.") | 263 | "Regex used to find dependency lines in a makefile.") |
| 266 | 264 | ||
| 267 | (defconst makefile-rule-action-regex | 265 | (defvar makefile-rule-action-regex |
| 268 | "^\t[ \t]*\\([-@]*\\)[ \t]*\\(.+\\)" | 266 | "^\t[ \t]*\\([-@]*\\)[ \t]*\\(\\(?:.+\\\\\n\\)*.+\\)" |
| 269 | "Regex used to highlight rule action lines in font lock mode.") | 267 | "Regex used to highlight rule action lines in font lock mode.") |
| 270 | 268 | ||
| 271 | ;; Note that the first and second subexpression is used by font lock. Note | 269 | ;; Note that the first and second subexpression is used by font lock. Note |
| 272 | ;; that if you change this regexp you might have to fix the imenu index in | 270 | ;; that if you change this regexp you might have to fix the imenu index in |
| 273 | ;; makefile-imenu-generic-expression. | 271 | ;; makefile-imenu-generic-expression. |
| 274 | (defconst makefile-macroassign-regex | 272 | (defconst makefile-macroassign-regex |
| 275 | "^ *\\([^ \n\t][^:#= \t\n]*\\)[ \t]*\\(?:!=[ \t]*\\(.*\\)\\|[*:+]?[:?]?=\\)" | 273 | "^ *\\([^ \n\t][^:#= \t\n]*\\)[ \t]*\\(?:!=[ \t]*\\(\\(?:.+\\\\\n\\)*.+\\)\\|[*:+]?[:?]?=\\)" |
| 276 | "Regex used to find macro assignment lines in a makefile.") | 274 | "Regex used to find macro assignment lines in a makefile.") |
| 277 | 275 | ||
| 278 | (defconst makefile-var-use-regex | 276 | (defconst makefile-var-use-regex |
| 279 | "[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\|[@%<?^+*][FD]?\\)[}):]" | 277 | "[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\|[@%<?^+*][FD]?\\)" |
| 280 | "Regex used to find $(macro) uses in a makefile.") | 278 | "Regex used to find $(macro) uses in a makefile.") |
| 281 | 279 | ||
| 282 | (defconst makefile-ignored-files-in-pickup-regex | 280 | (defconst makefile-ignored-files-in-pickup-regex |
| @@ -323,20 +321,17 @@ not be enclosed in { } or ( )." | |||
| 323 | ".endif" ".for" ".if" ".ifdef" ".ifmake" ".ifndef" ".ifnmake" ".undef") | 321 | ".endif" ".for" ".if" ".ifdef" ".ifmake" ".ifndef" ".ifnmake" ".undef") |
| 324 | "List of keywords understood by BSD make.") | 322 | "List of keywords understood by BSD make.") |
| 325 | 323 | ||
| 326 | (defun makefile-make-font-lock-keywords (dependency action var keywords space | 324 | (defun makefile-make-font-lock-keywords (var keywords space |
| 327 | &optional negation | 325 | &optional negation |
| 328 | &rest font-lock-keywords) | 326 | &rest font-lock-keywords) |
| 329 | `(;; Do macro assignments. These get the "variable-name" face. | 327 | `(;; Do macro assignments. These get the "variable-name" face. |
| 330 | (,makefile-macroassign-regex | 328 | (,makefile-macroassign-regex |
| 331 | (1 font-lock-variable-name-face) | 329 | (1 font-lock-variable-name-face) |
| 332 | ;; This is for after != | 330 | ;; This is for after != |
| 333 | (2 'makefile-shell-face prepend t)) | 331 | (2 'makefile-shell-face prepend t)) |
| 334 | 332 | ||
| 335 | ;; Do dependencies. | ||
| 336 | (,dependency 1 'makefile-targets-face prepend) | ||
| 337 | |||
| 338 | ;; Rule actions. | 333 | ;; Rule actions. |
| 339 | (,action | 334 | (makefile-match-action |
| 340 | (1 font-lock-type-face) | 335 | (1 font-lock-type-face) |
| 341 | (2 'makefile-shell-face prepend) | 336 | (2 'makefile-shell-face prepend) |
| 342 | ;; Only makepp has builtin commands. | 337 | ;; Only makepp has builtin commands. |
| @@ -359,9 +354,9 @@ not be enclosed in { } or ( )." | |||
| 359 | "\\>[ \t]*\\([^: \t\n#]*\\)") | 354 | "\\>[ \t]*\\([^: \t\n#]*\\)") |
| 360 | (1 font-lock-keyword-face) (2 font-lock-variable-name-face)) | 355 | (1 font-lock-keyword-face) (2 font-lock-variable-name-face)) |
| 361 | 356 | ||
| 362 | ,(if negation | 357 | ,@(if negation |
| 363 | `(,negation (1 font-lock-negation-char-face prepend) | 358 | `((,negation (1 font-lock-negation-char-face prepend) |
| 364 | (2 font-lock-negation-char-face prepend t))) | 359 | (2 font-lock-negation-char-face prepend t)))) |
| 365 | 360 | ||
| 366 | ,@(if space | 361 | ,@(if space |
| 367 | '(;; Highlight lines that contain just whitespace. | 362 | '(;; Highlight lines that contain just whitespace. |
| @@ -376,28 +371,27 @@ not be enclosed in { } or ( )." | |||
| 376 | ;; They can make a tab fail to be effective. | 371 | ;; They can make a tab fail to be effective. |
| 377 | ("^\\( +\\)\t" 1 makefile-space-face))) | 372 | ("^\\( +\\)\t" 1 makefile-space-face))) |
| 378 | 373 | ||
| 379 | ,@font-lock-keywords)) | 374 | ,@font-lock-keywords |
| 375 | |||
| 376 | ;; Do dependencies. | ||
| 377 | (makefile-match-dependency | ||
| 378 | (1 'makefile-targets-face prepend) | ||
| 379 | (3 'makefile-shell-face prepend t)))) | ||
| 380 | 380 | ||
| 381 | (defconst makefile-font-lock-keywords | 381 | (defconst makefile-font-lock-keywords |
| 382 | (makefile-make-font-lock-keywords | 382 | (makefile-make-font-lock-keywords |
| 383 | makefile-dependency-regex | ||
| 384 | makefile-rule-action-regex | ||
| 385 | makefile-var-use-regex | 383 | makefile-var-use-regex |
| 386 | makefile-statements | 384 | makefile-statements |
| 387 | t)) | 385 | t)) |
| 388 | 386 | ||
| 389 | (defconst makefile-automake-font-lock-keywords | 387 | (defconst makefile-automake-font-lock-keywords |
| 390 | (makefile-make-font-lock-keywords | 388 | (makefile-make-font-lock-keywords |
| 391 | makefile-dependency-regex | ||
| 392 | makefile-rule-action-regex | ||
| 393 | makefile-var-use-regex | 389 | makefile-var-use-regex |
| 394 | makefile-automake-statements | 390 | makefile-automake-statements |
| 395 | t)) | 391 | t)) |
| 396 | 392 | ||
| 397 | (defconst makefile-gmake-font-lock-keywords | 393 | (defconst makefile-gmake-font-lock-keywords |
| 398 | (makefile-make-font-lock-keywords | 394 | (makefile-make-font-lock-keywords |
| 399 | makefile-dependency-regex | ||
| 400 | makefile-rule-action-regex | ||
| 401 | makefile-var-use-regex | 395 | makefile-var-use-regex |
| 402 | makefile-gmake-statements | 396 | makefile-gmake-statements |
| 403 | t | 397 | t |
| @@ -407,8 +401,8 @@ not be enclosed in { } or ( )." | |||
| 407 | 1 'makefile-targets-face prepend) | 401 | 1 'makefile-targets-face prepend) |
| 408 | 402 | ||
| 409 | ;; $(function ...) ${function ...} | 403 | ;; $(function ...) ${function ...} |
| 410 | '("[^$]\\$[({]\\(\\S +\\s \\)" | 404 | '("[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\s \\)" |
| 411 | 1 font-lock-function-name-face) | 405 | 1 font-lock-function-name-face prepend) |
| 412 | 406 | ||
| 413 | ;; $(shell ...) ${shell ...} | 407 | ;; $(shell ...) ${shell ...} |
| 414 | '("[^$]\\$\\([({]\\)shell[ \t]+" | 408 | '("[^$]\\$\\([({]\\)shell[ \t]+" |
| @@ -417,24 +411,23 @@ not be enclosed in { } or ( )." | |||
| 417 | 411 | ||
| 418 | (defconst makefile-makepp-font-lock-keywords | 412 | (defconst makefile-makepp-font-lock-keywords |
| 419 | (makefile-make-font-lock-keywords | 413 | (makefile-make-font-lock-keywords |
| 420 | makefile-dependency-regex | ||
| 421 | ;; Don't care about initial tab, but I don't know how to font-lock correctly without. | ||
| 422 | "^\t[ \t]*\\(\\(?:[ \t]*noecho\\>\\|[ \t]*ignore[-_]error\\>\\|[ \t]*[-@]+\\)*\\)[ \t]*\\(\\(&\\S +\\)?.+\\)" | ||
| 423 | makefile-var-use-regex | 414 | makefile-var-use-regex |
| 424 | makefile-makepp-statements | 415 | makefile-makepp-statements |
| 425 | nil | 416 | nil |
| 426 | "^\\(?: [ \t]*\\)?\\(?:and[ \t]+\\|else[ \t]+\\|or[ \t]+\\)?if\\(n\\)\\(?:def\\|eq\\|sys\\)\\>" | 417 | "^\\(?: [ \t]*\\)?\\(?:and[ \t]+\\|else[ \t]+\\|or[ \t]+\\)?if\\(n\\)\\(?:def\\|eq\\|sys\\)\\>" |
| 427 | 418 | ||
| 428 | '("[^$]\\(\\$[({]\\(?:target\\|output\\)s?[})]\\)" | 419 | '("[^$]\\(\\$[({]\\(?:target\\|output\\)s?\\_>.*?[})]\\)" |
| 429 | 1 'makefile-targets-face prepend) | 420 | 1 'makefile-targets-face prepend) |
| 430 | 421 | ||
| 431 | ;; Colon modifier keywords. | 422 | ;; Colon modifier keywords. |
| 432 | '(":\\s *\\(build_c\\(?:ache\\|heck\\)\\|env\\(?:ironment\\)?\\|foreach\\|signature\\|scanner\\|quickscan\\|smartscan\\)\\>" | 423 | '("\\(:\\s *\\)\\(build_c\\(?:ache\\|heck\\)\\|env\\(?:ironment\\)?\\|foreach\\|signature\\|scanner\\|quickscan\\|smartscan\\)\\>\\([^:\n]*\\)" |
| 433 | 1 font-lock-keyword-face t) | 424 | (1 font-lock-type-face t) |
| 425 | (2 font-lock-keyword-face t) | ||
| 426 | (3 font-lock-variable-name-face t)) | ||
| 434 | 427 | ||
| 435 | ;; $(function ...) $((function ...)) ${function ...} ${{function ...}} | 428 | ;; $(function ...) $((function ...)) ${function ...} ${{function ...}} |
| 436 | '("[^$]\\$\\(((?\\|{{?\\)\\(\\S +\\s \\)" | 429 | '("[^$]\\$\\(?:((?\\|{{?\\)\\([-a-zA-Z0-9_.]+\\s \\)" |
| 437 | 2 font-lock-function-name-face) | 430 | 1 font-lock-function-name-face prepend) |
| 438 | 431 | ||
| 439 | ;; $(shell ...) $((shell ...)) ${shell ...} ${{shell ...}} | 432 | ;; $(shell ...) $((shell ...)) ${shell ...} ${{shell ...}} |
| 440 | '("[^$]\\$\\(((?\\|{{?\\)shell\\(?:[-_]\\(?:global[-_]\\)?once\\)?[ \t]+" | 433 | '("[^$]\\$\\(((?\\|{{?\\)shell\\(?:[-_]\\(?:global[-_]\\)?once\\)?[ \t]+" |
| @@ -466,11 +459,9 @@ not be enclosed in { } or ( )." | |||
| 466 | '("perl[-_]begin\\s *\\(?:\\s #.*\\)?\n\\(\\(?:.*\n\\)+?\\)\\s *perl[-_]end\\>" | 459 | '("perl[-_]begin\\s *\\(?:\\s #.*\\)?\n\\(\\(?:.*\n\\)+?\\)\\s *perl[-_]end\\>" |
| 467 | 1 'makefile-makepp-perl-face t))) | 460 | 1 'makefile-makepp-perl-face t))) |
| 468 | 461 | ||
| 469 | ;; A lot more could be done for variables here: | ||
| 470 | (defconst makefile-bsdmake-font-lock-keywords | 462 | (defconst makefile-bsdmake-font-lock-keywords |
| 471 | (makefile-make-font-lock-keywords | 463 | (makefile-make-font-lock-keywords |
| 472 | "^ *\\(\\(?:\\$[({]\\(?:\\$[({][^\n#})]+?[})]\\|[^\n#]\\)+?[})]\\|[^\n#:=]\\)+?\\)[ \t]*[:!]\\(?:[ \t]*$\\|[^=\n].*$\\)" | 464 | ;; A lot more could be done for variables here: |
| 473 | "^\t[ \t]*\\([-+@]*\\)[ \t]*\\(.+\\)" | ||
| 474 | makefile-var-use-regex | 465 | makefile-var-use-regex |
| 475 | makefile-bsdmake-statements | 466 | makefile-bsdmake-statements |
| 476 | t | 467 | t |
| @@ -489,9 +480,8 @@ not be enclosed in { } or ( )." | |||
| 489 | ("\\\\\n" 0 "."))) | 480 | ("\\\\\n" 0 "."))) |
| 490 | 481 | ||
| 491 | (defvar makefile-imenu-generic-expression | 482 | (defvar makefile-imenu-generic-expression |
| 492 | (list | 483 | `(("Dependencies" ,makefile-dependency-regex 1) |
| 493 | (list "Dependencies" makefile-dependency-regex 1) | 484 | ("Macro Assignment" ,makefile-macroassign-regex 1)) |
| 494 | (list "Macro Assignment" makefile-macroassign-regex 1)) | ||
| 495 | "Imenu generic expression for Makefile mode. See `imenu-generic-expression'.") | 485 | "Imenu generic expression for Makefile mode. See `imenu-generic-expression'.") |
| 496 | 486 | ||
| 497 | ;;; ------------------------------------------------------------ | 487 | ;;; ------------------------------------------------------------ |
| @@ -695,6 +685,11 @@ last should be correctly chosen based on the file name, except if | |||
| 695 | it is *.mk. This function ends by invoking the function(s) | 685 | it is *.mk. This function ends by invoking the function(s) |
| 696 | `makefile-mode-hook'. | 686 | `makefile-mode-hook'. |
| 697 | 687 | ||
| 688 | It is strongly recommended to use `font-lock-mode', because that | ||
| 689 | provides additional parsing information. This is used for | ||
| 690 | example to see that a rule action `echo foo: bar' is a not rule | ||
| 691 | dependency, despite the colon. | ||
| 692 | |||
| 698 | \\{makefile-mode-map} | 693 | \\{makefile-mode-map} |
| 699 | 694 | ||
| 700 | In the browser, use the following keys: | 695 | In the browser, use the following keys: |
| @@ -849,14 +844,26 @@ Makefile mode can be configured by modifying the following variables: | |||
| 849 | ;;;###autoload | 844 | ;;;###autoload |
| 850 | (define-derived-mode makefile-makepp-mode makefile-mode "Makeppfile" | 845 | (define-derived-mode makefile-makepp-mode makefile-mode "Makeppfile" |
| 851 | "An adapted `makefile-mode' that knows about makepp." | 846 | "An adapted `makefile-mode' that knows about makepp." |
| 847 | (set (make-local-variable 'makefile-rule-action-regex) | ||
| 848 | ;; Don't care about initial tab, but I don't know how to font-lock correctly without. | ||
| 849 | "^\t[ \t]*\\(\\(?:\\(?:noecho\\|ignore[-_]error\\|[-@]+\\)[ \t]*\\)*\\)\\(\\(&\\S +\\)?\\(?:.+\\\\\n\\)*.+\\)") | ||
| 850 | |||
| 852 | (setq font-lock-defaults | 851 | (setq font-lock-defaults |
| 853 | `(makefile-makepp-font-lock-keywords ,@(cdr font-lock-defaults)))) | 852 | `(makefile-makepp-font-lock-keywords ,@(cdr font-lock-defaults)))) |
| 854 | 853 | ||
| 855 | ;;;###autoload | 854 | ;;;###autoload |
| 856 | (define-derived-mode makefile-bsdmake-mode makefile-mode "BSDmakefile" | 855 | (define-derived-mode makefile-bsdmake-mode makefile-mode "BSDmakefile" |
| 857 | "An adapted `makefile-mode' that knows about BSD make." | 856 | "An adapted `makefile-mode' that knows about BSD make." |
| 857 | (set (make-local-variable 'makefile-dependency-regex) | ||
| 858 | ;; Identical to default, except allows `!' instead of `:'. | ||
| 859 | "^ *\\(\\(?: *\\$\\(?:[({]\\(?:\\$\\(?:[({]\\(?:\\$\\(?:[^({]\\|.[^\n$#})]+?[})]\\)\\|[^\n$#)}]\\)+?[})]\\|[^({]\\)\\|[^\n$#)}]\\)+?[})]\\|[^({]\\)\\| *[^ \n$#:=]+\\)+?\\)[ \t]*\\([:!]\\)\\(?:[ \t]*$\\|[^=\n]\\(?:[^#\n]*?;[ \t]*\\(.+\\)\\)?\\)") | ||
| 860 | (set (make-local-variable 'makefile-rule-action-regex) | ||
| 861 | "^\t[ \t]*\\([-+@]*\\)[ \t]*\\(\\(?:.+\\\\\n\\)*.+\\)") | ||
| 858 | (setq font-lock-defaults | 862 | (setq font-lock-defaults |
| 859 | `(makefile-bsdmake-font-lock-keywords ,@(cdr font-lock-defaults)))) | 863 | `(makefile-bsdmake-font-lock-keywords ,@(cdr font-lock-defaults)) |
| 864 | imenu-generic-expression | ||
| 865 | `(("Dependencies" ,makefile-dependency-regex 1) | ||
| 866 | ,@(cdr imenu-generic-expression)))) | ||
| 860 | 867 | ||
| 861 | 868 | ||
| 862 | 869 | ||
| @@ -867,7 +874,7 @@ Makefile mode can be configured by modifying the following variables: | |||
| 867 | (interactive) | 874 | (interactive) |
| 868 | (let ((here (point))) | 875 | (let ((here (point))) |
| 869 | (end-of-line) | 876 | (end-of-line) |
| 870 | (if (re-search-forward makefile-dependency-regex (point-max) t) | 877 | (if (makefile-match-dependency (point-max)) |
| 871 | (progn (beginning-of-line) t) ; indicate success | 878 | (progn (beginning-of-line) t) ; indicate success |
| 872 | (goto-char here) nil))) | 879 | (goto-char here) nil))) |
| 873 | 880 | ||
| @@ -876,7 +883,7 @@ Makefile mode can be configured by modifying the following variables: | |||
| 876 | (interactive) | 883 | (interactive) |
| 877 | (let ((here (point))) | 884 | (let ((here (point))) |
| 878 | (beginning-of-line) | 885 | (beginning-of-line) |
| 879 | (if (re-search-backward makefile-dependency-regex (point-min) t) | 886 | (if (makefile-match-dependency (point-min) t) |
| 880 | (progn (beginning-of-line) t) ; indicate success | 887 | (progn (beginning-of-line) t) ; indicate success |
| 881 | (goto-char here) nil))) | 888 | (goto-char here) nil))) |
| 882 | 889 | ||
| @@ -983,7 +990,7 @@ Anywhere else just self-inserts." | |||
| 983 | (setq makefile-has-prereqs nil) | 990 | (setq makefile-has-prereqs nil) |
| 984 | (save-excursion | 991 | (save-excursion |
| 985 | (goto-char (point-min)) | 992 | (goto-char (point-min)) |
| 986 | (while (re-search-forward makefile-dependency-regex nil t) | 993 | (while (makefile-match-dependency nil) |
| 987 | (makefile-add-this-line-targets))) | 994 | (makefile-add-this-line-targets))) |
| 988 | (message "Read targets OK."))) | 995 | (message "Read targets OK."))) |
| 989 | 996 | ||
| @@ -1676,6 +1683,23 @@ The anchor must have matched the opening parens in the first group." | |||
| 1676 | ((string= s "{{") "\\(.*?\\)[ \t]*}}"))) | 1683 | ((string= s "{{") "\\(.*?\\)[ \t]*}}"))) |
| 1677 | (if s (looking-at s)))) | 1684 | (if s (looking-at s)))) |
| 1678 | 1685 | ||
| 1686 | (defun makefile-match-dependency (bound &optional backward) | ||
| 1687 | "Search for `makefile-dependency-regex' up to BOUND. | ||
| 1688 | Optionally search BACKWARD. | ||
| 1689 | Checks that the colon has not already been fontified, else we | ||
| 1690 | matched in a rule action." | ||
| 1691 | (catch 'found | ||
| 1692 | (while (funcall (if backward 're-search-backward 're-search-forward) | ||
| 1693 | makefile-dependency-regex bound t) | ||
| 1694 | (or (get-text-property (match-beginning 2) 'face) | ||
| 1695 | (throw 'found t))))) | ||
| 1696 | |||
| 1697 | (defun makefile-match-action (bound) | ||
| 1698 | (catch 'found | ||
| 1699 | (while (re-search-forward makefile-rule-action-regex bound t) | ||
| 1700 | (or (eq ?\\ (char-after (- (match-beginning 0) 2))) | ||
| 1701 | (throw 'found t))))) | ||
| 1702 | |||
| 1679 | (defun makefile-do-macro-insertion (macro-name) | 1703 | (defun makefile-do-macro-insertion (macro-name) |
| 1680 | "Insert a macro reference." | 1704 | "Insert a macro reference." |
| 1681 | (if (not (zerop (length macro-name))) | 1705 | (if (not (zerop (length macro-name))) |