comparison lisp/progmodes/make-mode.el @ 62276:c1e4bf9803aa

(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.
author Daniel Pfeiffer <occitan@esperanto.org>
date Fri, 13 May 2005 07:51:15 +0000
parents 2805978983d8
children 6ac7ed8e212b
comparison
equal deleted inserted replaced
62275:93b464c181e6 62276:c1e4bf9803aa
98 "Makefile editing commands for Emacs." 98 "Makefile editing commands for Emacs."
99 :group 'tools 99 :group 'tools
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
107 :group 'makefile)
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."
106 :group 'faces 129 :group 'faces
107 :group 'makefile) 130 :group 'makefile)
108 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."
233 256
234 ;; 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
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.")
277
278 (defconst makefile-var-use-regex
279 "[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\|[@%<?^+*][FD]?\\)[}):]"
280 "Regex used to find $(macro) uses in a makefile.")
247 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.")
251 285
252 (if (fboundp 'facemenu-unlisted-faces) 286 (if (fboundp 'facemenu-unlisted-faces)
253 (add-to-list 'facemenu-unlisted-faces 'makefile-space-face)) 287 (add-to-list 'facemenu-unlisted-faces 'makefile-space-face))
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
291 ;; These lists were inspired by the old solution. But they are silly, because
292 ;; you can't differentiate what follows. They need to be split up.
293 (defconst makefile-statements '("include")
294 "List of keywords understood by standard make.")
295
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)
354
355 ;; Fontify conditionals and includes.
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))
361
362 ,(if negation
363 `(,negation (1 font-lock-negation-char-face prepend)
364 (2 font-lock-negation-char-face prepend t)))
365
366 ,@(if space
367 '(;; Highlight lines that contain just whitespace.
368 ;; They can cause trouble, especially if they start with a tab.
369 ("^[ \t]+$" . makefile-space-face)
370
371 ;; Highlight shell comments that Make treats as commands,
372 ;; since these can fool people.
373 ("^\t+#" 0 makefile-space-face t)
374
375 ;; Highlight spaces that precede tabs.
376 ;; They can make a tab fail to be effective.
377 ("^\\( +\\)\t" 1 makefile-space-face)))
378
379 ,@font-lock-keywords))
380
257 (defconst makefile-font-lock-keywords 381 (defconst makefile-font-lock-keywords
258 (list 382 (makefile-make-font-lock-keywords
259 383 makefile-dependency-regex
260 ;; Do macro assignments. These get the "variable-name" face rather 384 makefile-rule-action-regex
261 ;; arbitrarily. 385 makefile-var-use-regex
262 (list makefile-macroassign-regex 1 'font-lock-variable-name-face) 386 makefile-statements
263 387 t))
264 ;; Do dependencies. These get the function name face. 388
265 (list makefile-dependency-regex 1 'font-lock-function-name-face) 389 (defconst makefile-automake-font-lock-keywords
266 390 (makefile-make-font-lock-keywords
267 ;; Variable references even in targets/strings/comments. 391 makefile-dependency-regex
268 '("[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\|[@%<?^+*][FD]?\\)[}):]" 392 makefile-rule-action-regex
269 1 font-lock-constant-face prepend) 393 makefile-var-use-regex
270 394 makefile-automake-statements
271 ;; Automatic variable references and single character variable references, 395 t))
272 ;; but not shell variables references. 396
273 '("[^$]\\$\\([@%<?^+*_]\\|[a-zA-Z0-9]\\>\\)" 397 (defconst makefile-gmake-font-lock-keywords
274 1 font-lock-constant-face prepend) 398 (makefile-make-font-lock-keywords
275 399 makefile-dependency-regex
276 ;; Fontify conditionals and includes. 400 makefile-rule-action-regex
277 ;; Note that plain `if' is an automake conditional, and not a bug. 401 makefile-var-use-regex
278 (list 402 makefile-gmake-statements
279 (concat "^\\(?: [ \t]*\\)?" 403 t
280 (regexp-opt '("-include" "-sinclude" "include" "sinclude" "ifeq" 404 "^\\(?: [ \t]*\\)?if\\(n\\)\\(?:def\\|eq\\)\\>"
281 "if" "ifneq" "ifdef" "ifndef" "endif" "else" 405
282 "define" "endef" "override" 406 '("[^$]\\(\\$[({][@%*][DF][})]\\)"
283 "export" "unexport" "vpath") t) 407 1 'makefile-targets-face prepend)
284 "\\>[ \t]*\\([^: \t\n#]*\\)") 408
285 '(1 font-lock-keyword-face) '(2 font-lock-variable-name-face)) 409 ;; $(function ...) ${function ...}
286 410 '("[^$]\\$[({]\\(\\S +\\s \\)"
287 '("^\\(?: [ \t]*\\)?if\\(n\\)\\(?:def\\|eq\\)\\>" 411 1 font-lock-function-name-face)
288 1 font-lock-negation-char-face prepend) 412
289 413 ;; $(shell ...) ${shell ...}
290 ;; Highlight lines that contain just whitespace. 414 '("[^$]\\$\\([({]\\)shell[ \t]+"
291 ;; They can cause trouble, especially if they start with a tab. 415 makefile-match-function-end nil nil
292 '("^[ \t]+$" . makefile-space-face) 416 (1 'makefile-shell-face prepend t))))
293 417
294 ;; Highlight shell comments that Make treats as commands, 418 (defconst makefile-makepp-font-lock-keywords
295 ;; since these can fool people. 419 (makefile-make-font-lock-keywords
296 '("^\t+#" 0 makefile-space-face t) 420 makefile-dependency-regex
297 421 ;; Don't care about initial tab, but I don't know how to font-lock correctly without.
298 ;; Highlight spaces that precede tabs. 422 "^\t[ \t]*\\(\\(?:[ \t]*noecho\\>\\|[ \t]*ignore[-_]error\\>\\|[ \t]*[-@]+\\)*\\)[ \t]*\\(\\(&\\S +\\)?.+\\)"
299 ;; They can make a tab fail to be effective. 423 makefile-var-use-regex
300 '("^\\( +\\)\t" 1 makefile-space-face))) 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)))
479
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.
304 ;; A `#' begins a comment in sh when it is unquoted and at the beginning 483 ;; A `#' begins a comment in sh when it is unquoted and at the beginning
305 ;; of a word. In the shell, words are separated by metacharacters. 484 ;; of a word. In the shell, words are separated by metacharacters.
369 "Abbrev table in use in Makefile buffers.") 548 "Abbrev table in use in Makefile buffers.")
370 (if makefile-mode-abbrev-table 549 (if makefile-mode-abbrev-table
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
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 596
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
418 () 600 ()
502 ;;; The mode function itself. 684 ;;; The mode function itself.
503 ;;; ------------------------------------------------------------ 685 ;;; ------------------------------------------------------------
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
512 In the browser, use the following keys: 700 In the browser, use the following keys:
513 701
642 (set-syntax-table makefile-mode-syntax-table) 830 (set-syntax-table makefile-mode-syntax-table)
643 831
644 ;; Real TABs are important in makefiles 832 ;; Real TABs are important in makefiles
645 (setq indent-tabs-mode t) 833 (setq indent-tabs-mode t)
646 (run-hooks 'makefile-mode-hook)) 834 (run-hooks 'makefile-mode-hook))
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))))
647 860
648 861
649 862
650 ;;; Motion code. 863 ;;; Motion code.
651 864
1451 1664
1452 ;;; ------------------------------------------------------------ 1665 ;;; ------------------------------------------------------------
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)))
1459 (if (assoc macro-name makefile-runtime-macros-list) 1682 (if (assoc macro-name makefile-runtime-macros-list)
1460 (insert "$" macro-name) 1683 (insert "$" macro-name)