diff options
| author | Daniel Pfeiffer | 2005-05-13 07:51:15 +0000 |
|---|---|---|
| committer | Daniel Pfeiffer | 2005-05-13 07:51:15 +0000 |
| commit | 9c859203d9997db5a265ec6fd84806dc5659f784 (patch) | |
| tree | fe702f79bdd1b9b63d2750db60eba6376273e5a1 | |
| parent | a30c8f4bf972a54a70f994284b8ee9ba0947151e (diff) | |
| download | emacs-9c859203d9997db5a265ec6fd84806dc5659f784.tar.gz emacs-9c859203d9997db5a265ec6fd84806dc5659f784.zip | |
(makefile-targets-face, makefile-shell-face, makefile-makepp-perl-face): New faces.
(makefile-dependency-regex): Fix it to not make the colon in $(var:a=b) special.
(makefile-rule-action-regex): New regexp for highlighting embedded Shell strings.
(makefile-macroassign-regex): Handle != for highlighting as embedded Shell strings.
(makefile-var-use-regex): New const.
(makefile-statements, makefile-automake-statements)
(makefile-gmake-statements, makefile-makepp-statements)
(makefile-bsdmake-statements): New consts.
(makefile-make-font-lock-keywords): New function.
(makefile-automake-font-lock-keywords)
(makefile-gmake-font-lock-keywords)
(makefile-makepp-font-lock-keywords)
(makefile-bsdmake-font-lock-keywords): New consts.
(makefile-mode-map): Add switchers between the various submodes.
(makefile-mode): Document the availability of the variants.
(makefile-automake-mode, makefile-gmake-mode)
(makefile-makepp-mode, makefile-bsdmake-mode): New derived modes.
| -rw-r--r-- | lisp/progmodes/make-mode.el | 391 |
1 files changed, 307 insertions, 84 deletions
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index 7c1ccb25fb0..bc30bfdfc56 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el | |||
| @@ -100,12 +100,35 @@ | |||
| 100 | :prefix "makefile-") | 100 | :prefix "makefile-") |
| 101 | 101 | ||
| 102 | (defface makefile-space-face | 102 | (defface makefile-space-face |
| 103 | '((((class color)) (:background "hotpink")) | 103 | '((((class color)) (:background "hotpink")) |
| 104 | (t (:reverse-video t))) | 104 | (t (:reverse-video t))) |
| 105 | "Face to use for highlighting leading spaces in Font-Lock mode." | 105 | "Face to use for highlighting leading spaces in Font-Lock mode." |
| 106 | :group 'faces | 106 | :group 'faces |
| 107 | :group 'makefile) | 107 | :group 'makefile) |
| 108 | 108 | ||
| 109 | (defface makefile-targets-face | ||
| 110 | ;; This needs to go along both with foreground and background colors (i.e. shell) | ||
| 111 | '((t (:underline t))) | ||
| 112 | "Face to use for additionally highlighting rule targets in Font-Lock mode." | ||
| 113 | :group 'faces | ||
| 114 | :group 'makefile) | ||
| 115 | |||
| 116 | (defface makefile-shell-face | ||
| 117 | '((((class color) (background light)) (:background "seashell1")) | ||
| 118 | (((class color) (background dark)) (:background "seashell4")) | ||
| 119 | (t (:reverse-video t))) | ||
| 120 | "Face to use for additionally highlighting Shell commands in Font-Lock mode." | ||
| 121 | :group 'faces | ||
| 122 | :group 'makefile) | ||
| 123 | |||
| 124 | (defface makefile-makepp-perl-face | ||
| 125 | '((((class color) (background light)) (:background "LightBlue1")) ; Camel Book | ||
| 126 | (((class color) (background dark)) (:background "DarkBlue")) | ||
| 127 | (t (:reverse-video t))) | ||
| 128 | "Face to use for additionally highlighting Perl code in Font-Lock mode." | ||
| 129 | :group 'faces | ||
| 130 | :group 'makefile) | ||
| 131 | |||
| 109 | (defcustom makefile-browser-buffer-name "*Macros and Targets*" | 132 | (defcustom makefile-browser-buffer-name "*Macros and Targets*" |
| 110 | "*Name of the macro- and target browser buffer." | 133 | "*Name of the macro- and target browser buffer." |
| 111 | :type 'string | 134 | :type 'string |
| @@ -235,16 +258,27 @@ not be enclosed in { } or ( )." | |||
| 235 | ;; 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 |
| 236 | ;; index in makefile-imenu-generic-expression. | 259 | ;; index in makefile-imenu-generic-expression. |
| 237 | (defconst makefile-dependency-regex | 260 | (defconst makefile-dependency-regex |
| 238 | "^ *\\([^ \n\t#:=]+\\([ \t]+\\([^ \t\n#:=]+\\|\\$[({][^ \t\n#})]+[})]\\)\\)*\\)[ \t]*:\\([ \t]*$\\|\\([^=\n].*$\\)\\)" | 261 | ;; Allow for one nested level $($(var:a=b):c=d) |
| 262 | ;; Scan non-$ constructs char by char, so we don't miss a $ while allowing $$. | ||
| 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].*$\\)" | ||
| 239 | "Regex used to find dependency lines in a makefile.") | 265 | "Regex used to find dependency lines in a makefile.") |
| 240 | 266 | ||
| 241 | ;; Note that the first subexpression is used by font lock. Note | 267 | (defconst makefile-rule-action-regex |
| 242 | ;; that if you change this regexp you might have to fix the imenu | 268 | "^\t[ \t]*\\([-@]*\\)[ \t]*\\(.+\\)" |
| 243 | ;; index in makefile-imenu-generic-expression. | 269 | "Regex used to highlight rule action lines in font lock mode.") |
| 270 | |||
| 271 | ;; 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 | ||
| 273 | ;; makefile-imenu-generic-expression. | ||
| 244 | (defconst makefile-macroassign-regex | 274 | (defconst makefile-macroassign-regex |
| 245 | "^ *\\([^ \n\t][^:#= \t\n]*\\)[ \t]*[*:+]?[:?]?=" | 275 | "^ *\\([^ \n\t][^:#= \t\n]*\\)[ \t]*\\(?:!=[ \t]*\\(.*\\)\\|[*:+]?[:?]?=\\)" |
| 246 | "Regex used to find macro assignment lines in a makefile.") | 276 | "Regex used to find macro assignment lines in a makefile.") |
| 247 | 277 | ||
| 278 | (defconst makefile-var-use-regex | ||
| 279 | "[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\|[@%<?^+*][FD]?\\)[}):]" | ||
| 280 | "Regex used to find $(macro) uses in a makefile.") | ||
| 281 | |||
| 248 | (defconst makefile-ignored-files-in-pickup-regex | 282 | (defconst makefile-ignored-files-in-pickup-regex |
| 249 | "\\(^\\..*\\)\\|\\(.*~$\\)\\|\\(.*,v$\\)\\|\\(\\.[chy]\\)" | 283 | "\\(^\\..*\\)\\|\\(.*~$\\)\\|\\(.*,v$\\)\\|\\(\\.[chy]\\)" |
| 250 | "Regex for filenames that will NOT be included in the target list.") | 284 | "Regex for filenames that will NOT be included in the target list.") |
| @@ -254,50 +288,195 @@ not be enclosed in { } or ( )." | |||
| 254 | (defvar makefile-space-face 'makefile-space-face | 288 | (defvar makefile-space-face 'makefile-space-face |
| 255 | "Face to use for highlighting leading spaces in Font-Lock mode.") | 289 | "Face to use for highlighting leading spaces in Font-Lock mode.") |
| 256 | 290 | ||
| 257 | (defconst makefile-font-lock-keywords | 291 | ;; These lists were inspired by the old solution. But they are silly, because |
| 258 | (list | 292 | ;; you can't differentiate what follows. They need to be split up. |
| 259 | 293 | (defconst makefile-statements '("include") | |
| 260 | ;; Do macro assignments. These get the "variable-name" face rather | 294 | "List of keywords understood by standard make.") |
| 261 | ;; arbitrarily. | 295 | |
| 262 | (list makefile-macroassign-regex 1 'font-lock-variable-name-face) | 296 | (defconst makefile-automake-statements |
| 297 | `("if" "else" "endif" ,@makefile-statements) | ||
| 298 | "List of keywords understood by automake.") | ||
| 299 | |||
| 300 | (defconst makefile-gmake-statements | ||
| 301 | `("-sinclude" "sinclude" "override" "vpath" | ||
| 302 | "ifdef" "ifndef" "ifeq" "ifneq" "-include" "define" "endef" "export" | ||
| 303 | "unexport" | ||
| 304 | ,@(cdr makefile-automake-statements)) | ||
| 305 | "List of keywords understood by gmake.") | ||
| 306 | |||
| 307 | ;; These are even more silly, because you can have more spaces in between. | ||
| 308 | (defconst makefile-makepp-statements | ||
| 309 | `("and ifdef" "and ifndef" "and ifeq" "and ifneq" "and ifperl" | ||
| 310 | "and ifmakeperl" "and ifsys" "and ifnsys" "build_cache" "build_check" | ||
| 311 | "else ifdef" "else ifndef" "else ifeq" "else ifneq" "else ifperl" | ||
| 312 | "else ifmakeperl" "else ifsys" "else ifnsys" "enddef" "load_makefile" | ||
| 313 | "ifperl" "ifmakeperl" "ifsys" "ifnsys" "_include" "makeperl" "makesub" | ||
| 314 | "no_implicit_load" "perl" "perl-begin" "perl_begin" "perl-end" "perl_end" | ||
| 315 | "prebuild" "or ifdef" "or ifndef" "or ifeq" "or ifneq" "or ifperl" | ||
| 316 | "or ifmakeperl" "or ifsys" "or ifnsys" "register_command_parser" | ||
| 317 | "register_scanner" "repository" "runtime" "signature" "sub" | ||
| 318 | ,@(nthcdr 4 makefile-gmake-statements)) | ||
| 319 | "List of keywords understood by gmake.") | ||
| 320 | |||
| 321 | (defconst makefile-bsdmake-statements | ||
| 322 | `(".elif" ".elifdef" ".elifmake" ".elifndef" ".elifnmake" ".else" ".endfor" | ||
| 323 | ".endif" ".for" ".if" ".ifdef" ".ifmake" ".ifndef" ".ifnmake" ".undef") | ||
| 324 | "List of keywords understood by BSD make.") | ||
| 325 | |||
| 326 | (defun makefile-make-font-lock-keywords (dependency action var keywords space | ||
| 327 | &optional negation | ||
| 328 | &rest font-lock-keywords) | ||
| 329 | `(;; Do macro assignments. These get the "variable-name" face. | ||
| 330 | (,makefile-macroassign-regex | ||
| 331 | (1 font-lock-variable-name-face) | ||
| 332 | ;; This is for after != | ||
| 333 | (2 'makefile-shell-face prepend t)) | ||
| 334 | |||
| 335 | ;; Do dependencies. | ||
| 336 | (,dependency 1 'makefile-targets-face prepend) | ||
| 337 | |||
| 338 | ;; Rule actions. | ||
| 339 | (,action | ||
| 340 | (1 font-lock-type-face) | ||
| 341 | (2 'makefile-shell-face prepend) | ||
| 342 | ;; Only makepp has builtin commands. | ||
| 343 | (3 font-lock-builtin-face prepend t)) | ||
| 344 | |||
| 345 | ;; Variable references even in targets/strings/comments. | ||
| 346 | (,var 1 font-lock-variable-name-face prepend) | ||
| 347 | |||
| 348 | ;; Automatic variable references and single character variable references, | ||
| 349 | ;; but not shell variables references. | ||
| 350 | ("[^$]\\$\\([@%<?^+*_]\\|[a-zA-Z0-9]\\>\\)" | ||
| 351 | 1 font-lock-constant-face prepend) | ||
| 352 | ("[^$]\\(\\$[@%*]\\)" | ||
| 353 | 1 'makefile-targets-face prepend) | ||
| 263 | 354 | ||
| 264 | ;; Do dependencies. These get the function name face. | 355 | ;; Fontify conditionals and includes. |
| 265 | (list makefile-dependency-regex 1 'font-lock-function-name-face) | 356 | ;; Note that plain `if' is an automake conditional, and not a bug. |
| 357 | (,(concat "^\\(?: [ \t]*\\)?" | ||
| 358 | (regexp-opt keywords t) | ||
| 359 | "\\>[ \t]*\\([^: \t\n#]*\\)") | ||
| 360 | (1 font-lock-keyword-face) (2 font-lock-variable-name-face)) | ||
| 266 | 361 | ||
| 267 | ;; Variable references even in targets/strings/comments. | 362 | ,(if negation |
| 268 | '("[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\|[@%<?^+*][FD]?\\)[}):]" | 363 | `(,negation (1 font-lock-negation-char-face prepend) |
| 269 | 1 font-lock-constant-face prepend) | 364 | (2 font-lock-negation-char-face prepend t))) |
| 270 | 365 | ||
| 271 | ;; Automatic variable references and single character variable references, | 366 | ,@(if space |
| 272 | ;; but not shell variables references. | 367 | '(;; Highlight lines that contain just whitespace. |
| 273 | '("[^$]\\$\\([@%<?^+*_]\\|[a-zA-Z0-9]\\>\\)" | 368 | ;; They can cause trouble, especially if they start with a tab. |
| 274 | 1 font-lock-constant-face prepend) | 369 | ("^[ \t]+$" . makefile-space-face) |
| 275 | 370 | ||
| 276 | ;; Fontify conditionals and includes. | 371 | ;; Highlight shell comments that Make treats as commands, |
| 277 | ;; Note that plain `if' is an automake conditional, and not a bug. | 372 | ;; since these can fool people. |
| 278 | (list | 373 | ("^\t+#" 0 makefile-space-face t) |
| 279 | (concat "^\\(?: [ \t]*\\)?" | ||
| 280 | (regexp-opt '("-include" "-sinclude" "include" "sinclude" "ifeq" | ||
| 281 | "if" "ifneq" "ifdef" "ifndef" "endif" "else" | ||
| 282 | "define" "endef" "override" | ||
| 283 | "export" "unexport" "vpath") t) | ||
| 284 | "\\>[ \t]*\\([^: \t\n#]*\\)") | ||
| 285 | '(1 font-lock-keyword-face) '(2 font-lock-variable-name-face)) | ||
| 286 | 374 | ||
| 287 | '("^\\(?: [ \t]*\\)?if\\(n\\)\\(?:def\\|eq\\)\\>" | 375 | ;; Highlight spaces that precede tabs. |
| 288 | 1 font-lock-negation-char-face prepend) | 376 | ;; They can make a tab fail to be effective. |
| 377 | ("^\\( +\\)\t" 1 makefile-space-face))) | ||
| 289 | 378 | ||
| 290 | ;; Highlight lines that contain just whitespace. | 379 | ,@font-lock-keywords)) |
| 291 | ;; They can cause trouble, especially if they start with a tab. | ||
| 292 | '("^[ \t]+$" . makefile-space-face) | ||
| 293 | 380 | ||
| 294 | ;; Highlight shell comments that Make treats as commands, | 381 | (defconst makefile-font-lock-keywords |
| 295 | ;; since these can fool people. | 382 | (makefile-make-font-lock-keywords |
| 296 | '("^\t+#" 0 makefile-space-face t) | 383 | makefile-dependency-regex |
| 384 | makefile-rule-action-regex | ||
| 385 | makefile-var-use-regex | ||
| 386 | makefile-statements | ||
| 387 | t)) | ||
| 388 | |||
| 389 | (defconst makefile-automake-font-lock-keywords | ||
| 390 | (makefile-make-font-lock-keywords | ||
| 391 | makefile-dependency-regex | ||
| 392 | makefile-rule-action-regex | ||
| 393 | makefile-var-use-regex | ||
| 394 | makefile-automake-statements | ||
| 395 | t)) | ||
| 396 | |||
| 397 | (defconst makefile-gmake-font-lock-keywords | ||
| 398 | (makefile-make-font-lock-keywords | ||
| 399 | makefile-dependency-regex | ||
| 400 | makefile-rule-action-regex | ||
| 401 | makefile-var-use-regex | ||
| 402 | makefile-gmake-statements | ||
| 403 | t | ||
| 404 | "^\\(?: [ \t]*\\)?if\\(n\\)\\(?:def\\|eq\\)\\>" | ||
| 405 | |||
| 406 | '("[^$]\\(\\$[({][@%*][DF][})]\\)" | ||
| 407 | 1 'makefile-targets-face prepend) | ||
| 408 | |||
| 409 | ;; $(function ...) ${function ...} | ||
| 410 | '("[^$]\\$[({]\\(\\S +\\s \\)" | ||
| 411 | 1 font-lock-function-name-face) | ||
| 412 | |||
| 413 | ;; $(shell ...) ${shell ...} | ||
| 414 | '("[^$]\\$\\([({]\\)shell[ \t]+" | ||
| 415 | makefile-match-function-end nil nil | ||
| 416 | (1 'makefile-shell-face prepend t)))) | ||
| 417 | |||
| 418 | (defconst makefile-makepp-font-lock-keywords | ||
| 419 | (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 | ||
| 424 | makefile-makepp-statements | ||
| 425 | nil | ||
| 426 | "^\\(?: [ \t]*\\)?\\(?:and[ \t]+\\|else[ \t]+\\|or[ \t]+\\)?if\\(n\\)\\(?:def\\|eq\\|sys\\)\\>" | ||
| 427 | |||
| 428 | '("[^$]\\(\\$[({]\\(?:target\\|output\\)s?[})]\\)" | ||
| 429 | 1 'makefile-targets-face prepend) | ||
| 430 | |||
| 431 | ;; Colon modifier keywords. | ||
| 432 | '(":\\s *\\(build_c\\(?:ache\\|heck\\)\\|env\\(?:ironment\\)?\\|foreach\\|signature\\|scanner\\|quickscan\\|smartscan\\)\\>" | ||
| 433 | 1 font-lock-keyword-face t) | ||
| 434 | |||
| 435 | ;; $(function ...) $((function ...)) ${function ...} ${{function ...}} | ||
| 436 | '("[^$]\\$\\(((?\\|{{?\\)\\(\\S +\\s \\)" | ||
| 437 | 2 font-lock-function-name-face) | ||
| 438 | |||
| 439 | ;; $(shell ...) $((shell ...)) ${shell ...} ${{shell ...}} | ||
| 440 | '("[^$]\\$\\(((?\\|{{?\\)shell\\(?:[-_]\\(?:global[-_]\\)?once\\)?[ \t]+" | ||
| 441 | makefile-match-function-end nil nil | ||
| 442 | (1 'makefile-shell-face prepend t)) | ||
| 443 | |||
| 444 | ;; $(perl ...) $((perl ...)) ${perl ...} ${{perl ...}} | ||
| 445 | '("[^$]\\$\\(((?\\|{{?\\)makeperl[ \t]+" | ||
| 446 | makefile-match-function-end nil nil | ||
| 447 | (1 'makefile-makepp-perl-face prepend t)) | ||
| 448 | '("[^$]\\$\\(((?\\|{{?\\)perl[ \t]+" | ||
| 449 | makefile-match-function-end nil nil | ||
| 450 | (1 'makefile-makepp-perl-face t t)) | ||
| 451 | |||
| 452 | ;; Can we unify these with (if (match-end 1) 'prepend t)? | ||
| 453 | '("ifmakeperl\\s +\\(.*\\)" 1 'makefile-makepp-perl-face prepend) | ||
| 454 | '("ifperl\\s +\\(.*\\)" 1 'makefile-makepp-perl-face t) | ||
| 455 | |||
| 456 | ;; Perl block single- or multiline, as statement or rule action. | ||
| 457 | ;; Don't know why the initial newline in 2nd variant of group 2 doesn't get skipped. | ||
| 458 | '("\\<make\\(?:perl\\|sub\\s +\\S +\\)\\s *\n?\\s *{\\(?:{\\s *\n?\\(\\(?:.*\n\\)+?\\)\\s *}\\|\\s *\\(\\(?:.*?\\|\n?\\(?:.*\n\\)+?\\)\\)\\)}" | ||
| 459 | (1 'makefile-makepp-perl-face prepend t) | ||
| 460 | (2 'makefile-makepp-perl-face prepend t)) | ||
| 461 | '("\\<\\(?:perl\\|sub\\s +\\S +\\)\\s *\n?\\s *{\\(?:{\\s *\n?\\(\\(?:.*\n\\)+?\\)\\s *}\\|\\s *\\(\\(?:.*?\\|\n?\\(?:.*\n\\)+?\\)\\)\\)}" | ||
| 462 | (1 'makefile-makepp-perl-face t t) | ||
| 463 | (2 'makefile-makepp-perl-face t t)) | ||
| 464 | |||
| 465 | ;; Statement style perl block. | ||
| 466 | '("perl[-_]begin\\s *\\(?:\\s #.*\\)?\n\\(\\(?:.*\n\\)+?\\)\\s *perl[-_]end\\>" | ||
| 467 | 1 'makefile-makepp-perl-face t))) | ||
| 468 | |||
| 469 | ;; A lot more could be done for variables here: | ||
| 470 | (defconst makefile-bsdmake-font-lock-keywords | ||
| 471 | (makefile-make-font-lock-keywords | ||
| 472 | "^ *\\(\\(?:\\$[({]\\(?:\\$[({][^\n#})]+?[})]\\|[^\n#]\\)+?[})]\\|[^\n#:=]\\)+?\\)[ \t]*[:!]\\(?:[ \t]*$\\|[^=\n].*$\\)" | ||
| 473 | "^\t[ \t]*\\([-+@]*\\)[ \t]*\\(.+\\)" | ||
| 474 | makefile-var-use-regex | ||
| 475 | makefile-bsdmake-statements | ||
| 476 | t | ||
| 477 | "^\\(?: [ \t]*\\)?\\.\\(?:el\\)?if\\(n?\\)\\(?:def\\|make\\)?\\>[ \t]*\\(!?\\)" | ||
| 478 | '("^[ \t]*\\.for[ \t].+[ \t]\\(in\\)\\>" 1 font-lock-keyword-face))) | ||
| 297 | 479 | ||
| 298 | ;; Highlight spaces that precede tabs. | ||
| 299 | ;; They can make a tab fail to be effective. | ||
| 300 | '("^\\( +\\)\t" 1 makefile-space-face))) | ||
| 301 | 480 | ||
| 302 | (defconst makefile-font-lock-syntactic-keywords | 481 | (defconst makefile-font-lock-syntactic-keywords |
| 303 | ;; From sh-script.el. | 482 | ;; From sh-script.el. |
| @@ -371,47 +550,50 @@ The function must satisfy this calling convention: | |||
| 371 | () | 550 | () |
| 372 | (define-abbrev-table 'makefile-mode-abbrev-table ())) | 551 | (define-abbrev-table 'makefile-mode-abbrev-table ())) |
| 373 | 552 | ||
| 374 | (defvar makefile-mode-map nil | 553 | (defvar makefile-mode-map |
| 554 | (let ((map (make-sparse-keymap))) | ||
| 555 | ;; set up the keymap | ||
| 556 | (define-key map "\C-c:" 'makefile-insert-target-ref) | ||
| 557 | (if makefile-electric-keys | ||
| 558 | (progn | ||
| 559 | (define-key map "$" 'makefile-insert-macro-ref) | ||
| 560 | (define-key map ":" 'makefile-electric-colon) | ||
| 561 | (define-key map "=" 'makefile-electric-equal) | ||
| 562 | (define-key map "." 'makefile-electric-dot))) | ||
| 563 | (define-key map "\C-c\C-f" 'makefile-pickup-filenames-as-targets) | ||
| 564 | (define-key map "\C-c\C-b" 'makefile-switch-to-browser) | ||
| 565 | (define-key map "\C-c\C-c" 'comment-region) | ||
| 566 | (define-key map "\C-c\C-p" 'makefile-pickup-everything) | ||
| 567 | (define-key map "\C-c\C-u" 'makefile-create-up-to-date-overview) | ||
| 568 | (define-key map "\C-c\C-i" 'makefile-insert-gmake-function) | ||
| 569 | (define-key map "\C-c\C-\\" 'makefile-backslash-region) | ||
| 570 | (define-key map "\C-c\C-m\C-a" 'makefile-automake-mode) | ||
| 571 | (define-key map "\C-c\C-m\C-b" 'makefile-bsdmake-mode) | ||
| 572 | (define-key map "\C-c\C-m\C-g" 'makefile-gmake-mode) | ||
| 573 | (define-key map "\C-c\C-m\C-m" 'makefile-mode) | ||
| 574 | (define-key map "\C-c\C-m\C-p" 'makefile-makepp-mode) | ||
| 575 | (define-key map "\M-p" 'makefile-previous-dependency) | ||
| 576 | (define-key map "\M-n" 'makefile-next-dependency) | ||
| 577 | (define-key map "\e\t" 'makefile-complete) | ||
| 578 | |||
| 579 | ;; Make menus. | ||
| 580 | (define-key map [menu-bar makefile-mode] | ||
| 581 | (cons "Makefile" (make-sparse-keymap "Makefile"))) | ||
| 582 | |||
| 583 | (define-key map [menu-bar makefile-mode browse] | ||
| 584 | '("Pop up Makefile Browser" . makefile-switch-to-browser)) | ||
| 585 | (define-key map [menu-bar makefile-mode complete] | ||
| 586 | '("Complete Target or Macro" . makefile-complete)) | ||
| 587 | (define-key map [menu-bar makefile-mode pickup] | ||
| 588 | '("Find Targets and Macros" . makefile-pickup-everything)) | ||
| 589 | |||
| 590 | (define-key map [menu-bar makefile-mode prev] | ||
| 591 | '("Move to Previous Dependency" . makefile-previous-dependency)) | ||
| 592 | (define-key map [menu-bar makefile-mode next] | ||
| 593 | '("Move to Next Dependency" . makefile-next-dependency)) | ||
| 594 | map) | ||
| 375 | "The keymap that is used in Makefile mode.") | 595 | "The keymap that is used in Makefile mode.") |
| 376 | 596 | ||
| 377 | (if makefile-mode-map | ||
| 378 | () | ||
| 379 | (setq makefile-mode-map (make-sparse-keymap)) | ||
| 380 | ;; set up the keymap | ||
| 381 | (define-key makefile-mode-map "\C-c:" 'makefile-insert-target-ref) | ||
| 382 | (if makefile-electric-keys | ||
| 383 | (progn | ||
| 384 | (define-key makefile-mode-map "$" 'makefile-insert-macro-ref) | ||
| 385 | (define-key makefile-mode-map ":" 'makefile-electric-colon) | ||
| 386 | (define-key makefile-mode-map "=" 'makefile-electric-equal) | ||
| 387 | (define-key makefile-mode-map "." 'makefile-electric-dot))) | ||
| 388 | (define-key makefile-mode-map "\C-c\C-f" 'makefile-pickup-filenames-as-targets) | ||
| 389 | (define-key makefile-mode-map "\C-c\C-b" 'makefile-switch-to-browser) | ||
| 390 | (define-key makefile-mode-map "\C-c\C-c" 'comment-region) | ||
| 391 | (define-key makefile-mode-map "\C-c\C-p" 'makefile-pickup-everything) | ||
| 392 | (define-key makefile-mode-map "\C-c\C-u" 'makefile-create-up-to-date-overview) | ||
| 393 | (define-key makefile-mode-map "\C-c\C-i" 'makefile-insert-gmake-function) | ||
| 394 | (define-key makefile-mode-map "\C-c\C-\\" 'makefile-backslash-region) | ||
| 395 | (define-key makefile-mode-map "\M-p" 'makefile-previous-dependency) | ||
| 396 | (define-key makefile-mode-map "\M-n" 'makefile-next-dependency) | ||
| 397 | (define-key makefile-mode-map "\e\t" 'makefile-complete) | ||
| 398 | |||
| 399 | ;; Make menus. | ||
| 400 | (define-key makefile-mode-map [menu-bar makefile-mode] | ||
| 401 | (cons "Makefile" (make-sparse-keymap "Makefile"))) | ||
| 402 | |||
| 403 | (define-key makefile-mode-map [menu-bar makefile-mode browse] | ||
| 404 | '("Pop up Makefile Browser" . makefile-switch-to-browser)) | ||
| 405 | (define-key makefile-mode-map [menu-bar makefile-mode complete] | ||
| 406 | '("Complete Target or Macro" . makefile-complete)) | ||
| 407 | (define-key makefile-mode-map [menu-bar makefile-mode pickup] | ||
| 408 | '("Find Targets and Macros" . makefile-pickup-everything)) | ||
| 409 | |||
| 410 | (define-key makefile-mode-map [menu-bar makefile-mode prev] | ||
| 411 | '("Move to Previous Dependency" . makefile-previous-dependency)) | ||
| 412 | (define-key makefile-mode-map [menu-bar makefile-mode next] | ||
| 413 | '("Move to Next Dependency" . makefile-next-dependency))) | ||
| 414 | |||
| 415 | (defvar makefile-browser-map nil | 597 | (defvar makefile-browser-map nil |
| 416 | "The keymap that is used in the macro- and target browser.") | 598 | "The keymap that is used in the macro- and target browser.") |
| 417 | (if makefile-browser-map | 599 | (if makefile-browser-map |
| @@ -504,8 +686,14 @@ The function must satisfy this calling convention: | |||
| 504 | 686 | ||
| 505 | ;;;###autoload | 687 | ;;;###autoload |
| 506 | (defun makefile-mode () | 688 | (defun makefile-mode () |
| 507 | "Major mode for editing Makefiles. | 689 | "Major mode for editing standard Makefiles. |
| 508 | This function ends by invoking the function(s) `makefile-mode-hook'. | 690 | |
| 691 | If you are editing a file for a different make, try one of the | ||
| 692 | variants `makefile-automake-mode', `makefile-gmake-mode', | ||
| 693 | `makefile-makepp-mode' or `makefile-bsdmake-mode'. All but the | ||
| 694 | last should be correctly chosen based on the file name, except if | ||
| 695 | it is *.mk. This function ends by invoking the function(s) | ||
| 696 | `makefile-mode-hook'. | ||
| 509 | 697 | ||
| 510 | \\{makefile-mode-map} | 698 | \\{makefile-mode-map} |
| 511 | 699 | ||
| @@ -645,6 +833,31 @@ Makefile mode can be configured by modifying the following variables: | |||
| 645 | (setq indent-tabs-mode t) | 833 | (setq indent-tabs-mode t) |
| 646 | (run-hooks 'makefile-mode-hook)) | 834 | (run-hooks 'makefile-mode-hook)) |
| 647 | 835 | ||
| 836 | ;; These should do more than just differentiate font-lock. | ||
| 837 | ;;;###autoload | ||
| 838 | (define-derived-mode makefile-automake-mode makefile-mode "Makefile.am" | ||
| 839 | "An adapted `makefile-mode' that knows about automake." | ||
| 840 | (setq font-lock-defaults | ||
| 841 | `(makefile-automake-font-lock-keywords ,@(cdr font-lock-defaults)))) | ||
| 842 | |||
| 843 | ;;;###autoload | ||
| 844 | (define-derived-mode makefile-gmake-mode makefile-mode "GNUmakefile" | ||
| 845 | "An adapted `makefile-mode' that knows about gmake." | ||
| 846 | (setq font-lock-defaults | ||
| 847 | `(makefile-gmake-font-lock-keywords ,@(cdr font-lock-defaults)))) | ||
| 848 | |||
| 849 | ;;;###autoload | ||
| 850 | (define-derived-mode makefile-makepp-mode makefile-mode "Makeppfile" | ||
| 851 | "An adapted `makefile-mode' that knows about makepp." | ||
| 852 | (setq font-lock-defaults | ||
| 853 | `(makefile-makepp-font-lock-keywords ,@(cdr font-lock-defaults)))) | ||
| 854 | |||
| 855 | ;;;###autoload | ||
| 856 | (define-derived-mode makefile-bsdmake-mode makefile-mode "BSDmakefile" | ||
| 857 | "An adapted `makefile-mode' that knows about BSD make." | ||
| 858 | (setq font-lock-defaults | ||
| 859 | `(makefile-bsdmake-font-lock-keywords ,@(cdr font-lock-defaults)))) | ||
| 860 | |||
| 648 | 861 | ||
| 649 | 862 | ||
| 650 | ;;; Motion code. | 863 | ;;; Motion code. |
| @@ -1453,6 +1666,16 @@ Then prompts for all required parameters." | |||
| 1453 | ;;; Utility functions | 1666 | ;;; Utility functions |
| 1454 | ;;; ------------------------------------------------------------ | 1667 | ;;; ------------------------------------------------------------ |
| 1455 | 1668 | ||
| 1669 | (defun makefile-match-function-end (end) | ||
| 1670 | "To be called as an anchored matcher by font-lock. | ||
| 1671 | The anchor must have matched the opening parens in the first group." | ||
| 1672 | (let ((s (match-string-no-properties 1))) | ||
| 1673 | (setq s (cond ((string= s "(") "\\(.*?\\)[ \t]*)") | ||
| 1674 | ((string= s "{") "\\(.*?\\)[ \t]*}") | ||
| 1675 | ((string= s "((") "\\(.*?\\)[ \t]*))") | ||
| 1676 | ((string= s "{{") "\\(.*?\\)[ \t]*}}"))) | ||
| 1677 | (if s (looking-at s)))) | ||
| 1678 | |||
| 1456 | (defun makefile-do-macro-insertion (macro-name) | 1679 | (defun makefile-do-macro-insertion (macro-name) |
| 1457 | "Insert a macro reference." | 1680 | "Insert a macro reference." |
| 1458 | (if (not (zerop (length macro-name))) | 1681 | (if (not (zerop (length macro-name))) |