1 |
;;; make-mode.el --- makefile editing commands for Emacs |
;;; make-mode.el --- makefile editing commands for Emacs |
2 |
|
|
3 |
;; Copyright (C) 1992,94,99,2000,2001 Free Software Foundation, Inc. |
;; Copyright (C) 1992,94,99,2000,2001, 2002, 2003 Free Software Foundation, Inc. |
4 |
|
|
5 |
;; Author: Thomas Neumann <tom@smart.bo.open.de> |
;; Author: Thomas Neumann <tom@smart.bo.open.de> |
6 |
;; Eric S. Raymond <esr@snark.thyrsus.com> |
;; Eric S. Raymond <esr@snark.thyrsus.com> |
108 |
(t (:reverse-video t))) |
(t (:reverse-video t))) |
109 |
"Face to use for highlighting leading spaces in Font-Lock mode." |
"Face to use for highlighting leading spaces in Font-Lock mode." |
110 |
:group 'faces |
:group 'faces |
111 |
:group 'makemode) |
:group 'makefile) |
112 |
|
|
113 |
(defcustom makefile-browser-buffer-name "*Macros and Targets*" |
(defcustom makefile-browser-buffer-name "*Macros and Targets*" |
114 |
"*Name of the macro- and target browser buffer." |
"*Name of the macro- and target browser buffer." |
192 |
:type 'boolean |
:type 'boolean |
193 |
:group 'makefile) |
:group 'makefile) |
194 |
|
|
195 |
(defcustom makefile-cleanup-continuations-p t |
(defcustom makefile-cleanup-continuations nil |
196 |
"*If non-nil, automatically clean up continuation lines when saving. |
"*If non-nil, automatically clean up continuation lines when saving. |
197 |
A line is cleaned up by removing all whitespace following a trailing |
A line is cleaned up by removing all whitespace following a trailing |
198 |
backslash. This is done silently. |
backslash. This is done silently. |
210 |
|
|
211 |
;; |
;; |
212 |
;; Special targets for DMake, Sun's make ... |
;; Special targets for DMake, Sun's make ... |
213 |
;; |
;; |
214 |
(defcustom makefile-special-targets-list |
(defcustom makefile-special-targets-list |
215 |
'(("DEFAULT") ("DONE") ("ERROR") ("EXPORT") |
'(("DEFAULT") ("DONE") ("ERROR") ("EXPORT") |
216 |
("FAILED") ("GROUPEPILOG") ("GROUPPROLOG") ("IGNORE") |
("FAILED") ("GROUPEPILOG") ("GROUPPROLOG") ("IGNORE") |
268 |
;; Do dependencies. These get the function name face. |
;; Do dependencies. These get the function name face. |
269 |
(list makefile-dependency-regex 1 'font-lock-function-name-face) |
(list makefile-dependency-regex 1 'font-lock-function-name-face) |
270 |
|
|
271 |
;; Variable references even in targets/strings/comments: |
;; Variable references even in targets/strings/comments. |
272 |
'("\\$[({]\\([-a-zA-Z0-9_.]+\\)[}):]" 1 font-lock-constant-face prepend) |
'("[^$]\\$[({]\\([-a-zA-Z0-9_.]+\\|[@%<?^+*][FD]?\\)[}):]" |
273 |
|
1 font-lock-constant-face prepend) |
274 |
;; Automatic variable references. |
|
275 |
'("\\$\\([@%<?^+*]\\)" 1 font-lock-reference-face prepend) |
;; Automatic variable references and single character variable references, |
276 |
|
;; but not shell variables references. |
277 |
|
'("[^$]\\$\\([@%<?^+*_]\\|[a-zA-Z0-9]\\>\\)" |
278 |
|
1 font-lock-constant-face prepend) |
279 |
|
|
280 |
;; Fontify conditionals and includes. |
;; Fontify conditionals and includes. |
281 |
;; Note that plain `if' is an automake conditional, and not a bug. |
;; Note that plain `if' is an automake conditional, and not a bug. |
282 |
(list |
(list |
283 |
(concat "^\\(?: [ \t]*\\)?" |
(concat "^\\(?: [ \t]*\\)?" |
284 |
(regexp-opt '("-include" "-sinclude" "include" "sinclude" "ifeq" |
(regexp-opt '("-include" "-sinclude" "include" "sinclude" "ifeq" |
285 |
"if" "ifneq" "ifdef" "ifndef" "endif" "else") t) |
"if" "ifneq" "ifdef" "ifndef" "endif" "else" |
286 |
|
"define" "endef" "override" |
287 |
|
"export" "unexport" "vpath") t) |
288 |
"\\>[ \t]*\\([^: \t\n#]*\\)") |
"\\>[ \t]*\\([^: \t\n#]*\\)") |
289 |
'(1 font-lock-keyword-face) '(2 font-lock-variable-name-face)) |
'(1 font-lock-keyword-face) '(2 font-lock-variable-name-face)) |
290 |
|
|
300 |
;; They can make a tab fail to be effective. |
;; They can make a tab fail to be effective. |
301 |
'("^\\( +\\)\t" 1 makefile-space-face))) |
'("^\\( +\\)\t" 1 makefile-space-face))) |
302 |
|
|
303 |
|
(defconst makefile-font-lock-syntactic-keywords |
304 |
|
(list |
305 |
|
;; Change the syntax of a quoted newline so that it does not end a comment. |
306 |
|
'("\\\\\n" 0 " "))) |
307 |
|
|
308 |
(defvar makefile-imenu-generic-expression |
(defvar makefile-imenu-generic-expression |
309 |
(list |
(list |
310 |
(list "Dependencies" makefile-dependency-regex 1) |
(list "Dependencies" makefile-dependency-regex 1) |
555 |
(i.e. it calls `makefile-pickup-filenames-as-targets'), otherwise |
(i.e. it calls `makefile-pickup-filenames-as-targets'), otherwise |
556 |
filenames are omitted. |
filenames are omitted. |
557 |
|
|
558 |
`makefile-cleanup-continuations-p': |
`makefile-cleanup-continuations': |
559 |
If this variable is set to a non-nil value then Makefile mode |
If this variable is set to a non-nil value then Makefile mode |
560 |
will assure that no line in the file ends with a backslash |
will assure that no line in the file ends with a backslash |
561 |
(the continuation character) followed by any whitespace. |
(the continuation character) followed by any whitespace. |
575 |
|
|
576 |
(interactive) |
(interactive) |
577 |
(kill-all-local-variables) |
(kill-all-local-variables) |
578 |
(make-local-variable 'local-write-file-hooks) |
(add-hook 'write-file-functions |
579 |
(setq local-write-file-hooks |
'makefile-warn-suspicious-lines nil t) |
580 |
'(makefile-cleanup-continuations makefile-warn-suspicious-lines)) |
(add-hook 'write-file-functions |
581 |
|
'makefile-warn-continuations nil t) |
582 |
|
(add-hook 'write-file-functions |
583 |
|
'makefile-cleanup-continuations nil t) |
584 |
(make-local-variable 'makefile-target-table) |
(make-local-variable 'makefile-target-table) |
585 |
(make-local-variable 'makefile-macro-table) |
(make-local-variable 'makefile-macro-table) |
586 |
(make-local-variable 'makefile-has-prereqs) |
(make-local-variable 'makefile-has-prereqs) |
593 |
;; SYNTAX-BEGIN set to backward-paragraph to avoid slow-down |
;; SYNTAX-BEGIN set to backward-paragraph to avoid slow-down |
594 |
;; near the end of a large buffer, due to parse-partial-sexp's |
;; near the end of a large buffer, due to parse-partial-sexp's |
595 |
;; trying to parse all the way till the beginning of buffer. |
;; trying to parse all the way till the beginning of buffer. |
596 |
'(makefile-font-lock-keywords nil nil nil backward-paragraph)) |
'(makefile-font-lock-keywords |
597 |
|
nil nil |
598 |
|
((?$ . ".")) |
599 |
|
backward-paragraph |
600 |
|
(font-lock-syntactic-keywords . makefile-font-lock-syntactic-keywords))) |
601 |
|
|
602 |
;; Add-log. |
;; Add-log. |
603 |
(make-local-variable 'add-log-current-defun-function) |
(make-local-variable 'add-log-current-defun-function) |
766 |
(setq makefile-has-prereqs nil) |
(setq makefile-has-prereqs nil) |
767 |
(save-excursion |
(save-excursion |
768 |
(goto-char (point-min)) |
(goto-char (point-min)) |
769 |
(while (re-search-forward makefile-dependency-regex (point-max) t) |
(while (re-search-forward makefile-dependency-regex nil t) |
770 |
(makefile-add-this-line-targets))) |
(makefile-add-this-line-targets))) |
771 |
(message "Read targets OK."))) |
(message "Read targets OK."))) |
772 |
|
|
800 |
(setq makefile-macro-table nil) |
(setq makefile-macro-table nil) |
801 |
(save-excursion |
(save-excursion |
802 |
(goto-char (point-min)) |
(goto-char (point-min)) |
803 |
(while (re-search-forward makefile-macroassign-regex (point-max) t) |
(while (re-search-forward makefile-macroassign-regex nil t) |
804 |
(makefile-add-this-line-macro) |
(makefile-add-this-line-macro) |
805 |
(forward-line 1))) |
(forward-line 1))) |
806 |
(message "Read macros OK."))) |
(message "Read macros OK."))) |
809 |
(save-excursion |
(save-excursion |
810 |
(beginning-of-line) |
(beginning-of-line) |
811 |
(skip-chars-forward " \t") |
(skip-chars-forward " \t") |
812 |
(if (not (eolp)) |
(unless (eolp) |
813 |
(let* ((start-of-macro-name (point)) |
(let* ((start-of-macro-name (point)) |
814 |
(line-number (1+ (count-lines (point-min) (point)))) |
(line-number (1+ (count-lines (point-min) (point)))) |
815 |
(macro-name (progn |
(macro-name (progn |
816 |
(skip-chars-forward "^ \t:#=*") |
(skip-chars-forward "^ \t:#=*") |
817 |
(buffer-substring start-of-macro-name (point))))) |
(buffer-substring start-of-macro-name (point))))) |
818 |
(if (makefile-remember-macro macro-name) |
(if (makefile-remember-macro macro-name) |
819 |
(message "Picked up macro \"%s\" from line %d" |
(message "Picked up macro \"%s\" from line %d" |
820 |
macro-name line-number)))))) |
macro-name line-number)))))) |
821 |
|
|
822 |
(defun makefile-pickup-everything (arg) |
(defun makefile-pickup-everything (arg) |
823 |
"Notice names of all macros and targets in Makefile. |
"Notice names of all macros and targets in Makefile. |
1028 |
(beginning-of-line) |
(beginning-of-line) |
1029 |
(cond |
(cond |
1030 |
((looking-at "^#+ ") |
((looking-at "^#+ ") |
1031 |
;; Found a comment. Set the fill prefix and then fill. |
;; Found a comment. Set the fill prefix, and find the paragraph |
1032 |
(let ((fill-prefix (buffer-substring-no-properties (match-beginning 0) |
;; boundaries by searching for lines that look like comment-only |
1033 |
(match-end 0))) |
;; lines. |
1034 |
|
(let ((fill-prefix (match-string-no-properties 0)) |
1035 |
(fill-paragraph-function nil)) |
(fill-paragraph-function nil)) |
1036 |
(fill-paragraph nil) |
(save-excursion |
1037 |
t)) |
(save-restriction |
1038 |
|
(narrow-to-region |
1039 |
|
;; Search backwards. |
1040 |
|
(save-excursion |
1041 |
|
(while (and (zerop (forward-line -1)) |
1042 |
|
(looking-at "^#"))) |
1043 |
|
;; We may have gone too far. Go forward again. |
1044 |
|
(or (looking-at "^#") |
1045 |
|
(forward-line 1)) |
1046 |
|
(point)) |
1047 |
|
;; Search forwards. |
1048 |
|
(save-excursion |
1049 |
|
(while (looking-at "^#") |
1050 |
|
(forward-line)) |
1051 |
|
(point))) |
1052 |
|
(fill-paragraph nil) |
1053 |
|
t)))) |
1054 |
|
|
1055 |
;; Must look for backslashed-region before looking for variable |
;; Must look for backslashed-region before looking for variable |
1056 |
;; assignment. |
;; assignment. |
1057 |
((save-excursion |
((or (eq (char-before (line-end-position 1)) ?\\) |
1058 |
(end-of-line) |
(eq (char-before (line-end-position 0)) ?\\)) |
|
(or |
|
|
(= (preceding-char) ?\\) |
|
|
(progn |
|
|
(end-of-line -1) |
|
|
(= (preceding-char) ?\\)))) |
|
1059 |
;; A backslash region. Find beginning and end, remove |
;; A backslash region. Find beginning and end, remove |
1060 |
;; backslashes, fill, and then reapply backslahes. |
;; backslashes, fill, and then reapply backslahes. |
1061 |
(end-of-line) |
(end-of-line) |
1381 |
|
|
1382 |
(defun makefile-cleanup-continuations () |
(defun makefile-cleanup-continuations () |
1383 |
(if (eq major-mode 'makefile-mode) |
(if (eq major-mode 'makefile-mode) |
1384 |
(if (and makefile-cleanup-continuations-p |
(if (and makefile-cleanup-continuations |
1385 |
(not buffer-read-only)) |
(not buffer-read-only)) |
1386 |
(save-excursion |
(save-excursion |
1387 |
(goto-char (point-min)) |
(goto-char (point-min)) |
1388 |
(while (re-search-forward "\\\\[ \t]+$" (point-max) t) |
(while (re-search-forward "\\\\[ \t]+$" nil t) |
1389 |
(replace-match "\\" t t)))))) |
(replace-match "\\" t t)))))) |
1390 |
|
|
1391 |
|
|
1400 |
(goto-char (point-min)) |
(goto-char (point-min)) |
1401 |
(if (re-search-forward "^\\(\t+$\\| +\t\\)" nil t) |
(if (re-search-forward "^\\(\t+$\\| +\t\\)" nil t) |
1402 |
(not (y-or-n-p |
(not (y-or-n-p |
1403 |
(format "Suspicious line %d. Save anyway " |
(format "Suspicious line %d. Save anyway? " |
1404 |
|
(count-lines (point-min) (point))))))))) |
1405 |
|
|
1406 |
|
(defun makefile-warn-continuations () |
1407 |
|
(if (eq major-mode 'makefile-mode) |
1408 |
|
(save-excursion |
1409 |
|
(goto-char (point-min)) |
1410 |
|
(if (re-search-forward "\\\\[ \t]+$" nil t) |
1411 |
|
(not (y-or-n-p |
1412 |
|
(format "Suspicious continuation in line %d. Save anyway? " |
1413 |
(count-lines (point-min) (point))))))))) |
(count-lines (point-min) (point))))))))) |
|
|
|
1414 |
|
|
1415 |
|
|
1416 |
;;; ------------------------------------------------------------ |
;;; ------------------------------------------------------------ |
1541 |
;; Scan back line by line, noticing when we come to a |
;; Scan back line by line, noticing when we come to a |
1542 |
;; variable or rule definition, and giving up when we see |
;; variable or rule definition, and giving up when we see |
1543 |
;; a line that is not part of either of those. |
;; a line that is not part of either of those. |
1544 |
(while (not found) |
(while (not (or (setq found |
1545 |
(cond |
(when (or (looking-at makefile-macroassign-regex) |
1546 |
((looking-at makefile-macroassign-regex) |
(looking-at makefile-dependency-regex)) |
1547 |
(setq found (buffer-substring-no-properties (match-beginning 1) |
(match-string-no-properties 1))) |
1548 |
(match-end 1)))) |
;; Don't keep looking across a blank line or comment. |
1549 |
((looking-at makefile-dependency-regex) |
(looking-at "$\\|#") |
1550 |
(setq found (buffer-substring-no-properties (match-beginning 1) |
(not (zerop (forward-line -1)))))) |
1551 |
(match-end 1)))) |
found))) |
|
;; Don't keep looking across a blank line or comment. Give up. |
|
|
((looking-at "$\\|#") |
|
|
(setq found 'bobp)) |
|
|
((bobp) |
|
|
(setq found 'bobp))) |
|
|
(or found |
|
|
(forward-line -1))) |
|
|
(if (stringp found) found)))) |
|
1552 |
|
|
1553 |
(provide 'make-mode) |
(provide 'make-mode) |
1554 |
|
|