diff options
| -rw-r--r-- | lisp/progmodes/make-mode.el | 378 |
1 files changed, 310 insertions, 68 deletions
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el index 13dab564e6b..c569b5511f4 100644 --- a/lisp/progmodes/make-mode.el +++ b/lisp/progmodes/make-mode.el | |||
| @@ -8,16 +8,13 @@ | |||
| 8 | ;; Keywords: unix, tools | 8 | ;; Keywords: unix, tools |
| 9 | 9 | ||
| 10 | ;; RMS: | 10 | ;; RMS: |
| 11 | ;; This needs work. The electric characters are too obnoxious. | 11 | ;; This needs work. |
| 12 | ;; It should not define C-c LETTER. | ||
| 13 | ;; It should support knowing the list of existing macros and targets | ||
| 14 | ;; via M-TAB completion, not by preempting insertion of references. | ||
| 15 | ;; Also, the doc strings need fixing: the first line doesn't stand alone, | 12 | ;; Also, the doc strings need fixing: the first line doesn't stand alone, |
| 16 | ;; and other usage is not high quality. Symbol names don't have `...'. | 13 | ;; and other usage is not high quality. Symbol names don't have `...'. |
| 17 | 14 | ||
| 18 | ;; So, for the meantime, this is not the default mode for makefiles. | 15 | ;; So, for the meantime, this is not the default mode for makefiles. |
| 19 | 16 | ||
| 20 | ;; $Id: makefile.el,v 1.15 1994/04/22 20:20:49 rms Exp rms $ | 17 | ;; $Id: makefile.el,v 1.16 1994/05/22 22:10:39 rms Exp $ |
| 21 | 18 | ||
| 22 | ;; This file is part of GNU Emacs. | 19 | ;; This file is part of GNU Emacs. |
| 23 | 20 | ||
| @@ -47,7 +44,7 @@ | |||
| 47 | ;; automatically updated, if necessary, whenever you invoke one of | 44 | ;; automatically updated, if necessary, whenever you invoke one of |
| 48 | ;; these commands. You can force it to be updated with C-c C-p. | 45 | ;; these commands. You can force it to be updated with C-c C-p. |
| 49 | ;; | 46 | ;; |
| 50 | ;; The command C-c f adds certain filenames in the current directory | 47 | ;; The command C-c C-f adds certain filenames in the current directory |
| 51 | ;; as targets. You can filter out filenames by setting the variable | 48 | ;; as targets. You can filter out filenames by setting the variable |
| 52 | ;; makefile-ignored-files-in-pickup-regex. | 49 | ;; makefile-ignored-files-in-pickup-regex. |
| 53 | ;; | 50 | ;; |
| @@ -56,7 +53,7 @@ | |||
| 56 | ;; prerequisites, which targets are out-of-date, and which have no | 53 | ;; prerequisites, which targets are out-of-date, and which have no |
| 57 | ;; prerequisites. | 54 | ;; prerequisites. |
| 58 | ;; | 55 | ;; |
| 59 | ;; The command C-c b pops up a browser window listing all target and | 56 | ;; The command C-c C-b pops up a browser window listing all target and |
| 60 | ;; macro names. You can mark or unmark items wit C-c SPC, and insert | 57 | ;; macro names. You can mark or unmark items wit C-c SPC, and insert |
| 61 | ;; all marked items back in the Makefile with C-c TAB. | 58 | ;; all marked items back in the Makefile with C-c TAB. |
| 62 | ;; | 59 | ;; |
| @@ -65,17 +62,44 @@ | |||
| 65 | ;; | 62 | ;; |
| 66 | ;; There are numerous other customization variables. | 63 | ;; There are numerous other customization variables. |
| 67 | 64 | ||
| 65 | ;; | ||
| 66 | ;; To Do: | ||
| 67 | ;; | ||
| 68 | ;; * Eliminate electric stuff entirely. | ||
| 69 | ;; * It might be nice to highlight targets differently depending on | ||
| 70 | ;; whether they are up-to-date or not. Not sure how this would | ||
| 71 | ;; interact with font-lock. | ||
| 72 | ;; * Would be nice to edit the commands in ksh-mode and have | ||
| 73 | ;; indentation and slashification done automatically. Hard. | ||
| 74 | ;; * Consider removing browser mode. It seems useless. | ||
| 75 | ;; * ":" should notice when a new target is made and add it to the | ||
| 76 | ;; list (or at least set makefile-need-target-pickup). | ||
| 77 | ;; * Make browser into a mode. | ||
| 78 | ;; * Clean up macro insertion stuff. It is a mess. | ||
| 79 | ;; * Browser entry and exit is weird. Normalize. | ||
| 80 | ;; * Browser needs to be rewritten. Right now it is kind of a crock. | ||
| 81 | ;; Should at least: | ||
| 82 | ;; * Act more like dired/buffer menu/whatever. | ||
| 83 | ;; * Highlight as mouse traverses. | ||
| 84 | ;; * B2 inserts. | ||
| 85 | ;; * Update documentation above. | ||
| 86 | ;; * Update texinfo manual. | ||
| 87 | ;; * Update files.el. | ||
| 88 | |||
| 89 | |||
| 90 | |||
| 68 | ;;; Code: | 91 | ;;; Code: |
| 69 | 92 | ||
| 70 | (provide 'makefile) | 93 | (provide 'makefile) |
| 71 | 94 | ||
| 95 | ;; Sadly we need this for a macro. | ||
| 96 | (eval-when-compile | ||
| 97 | (require 'imenu)) | ||
| 98 | |||
| 72 | ;;; ------------------------------------------------------------ | 99 | ;;; ------------------------------------------------------------ |
| 73 | ;;; Configurable stuff | 100 | ;;; Configurable stuff |
| 74 | ;;; ------------------------------------------------------------ | 101 | ;;; ------------------------------------------------------------ |
| 75 | 102 | ||
| 76 | (defconst makefile-mode-name "Makefile" | ||
| 77 | "The \"pretty name\" of makefile-mode, as it appears in the modeline.") | ||
| 78 | |||
| 79 | (defvar makefile-browser-buffer-name "*Macros and Targets*" | 103 | (defvar makefile-browser-buffer-name "*Macros and Targets*" |
| 80 | "Name of the macro- and target browser buffer.") | 104 | "Name of the macro- and target browser buffer.") |
| 81 | 105 | ||
| @@ -92,6 +116,10 @@ standard make expects. However, newer makes such as dmake | |||
| 92 | allow a larger variety of different macro assignments, so you | 116 | allow a larger variety of different macro assignments, so you |
| 93 | might prefer to use \" += \" or \" := \" .") | 117 | might prefer to use \" += \" or \" := \" .") |
| 94 | 118 | ||
| 119 | (defvar makefile-electric-keys nil | ||
| 120 | "If non-nil, install electric keybindings. | ||
| 121 | Default is nil.") | ||
| 122 | |||
| 95 | (defvar makefile-use-curly-braces-for-macros-p nil | 123 | (defvar makefile-use-curly-braces-for-macros-p nil |
| 96 | "Controls the style of generated macro references. | 124 | "Controls the style of generated macro references. |
| 97 | Set this variable to a non-nil value if you prefer curly braces | 125 | Set this variable to a non-nil value if you prefer curly braces |
| @@ -153,24 +181,39 @@ on one of those in the minibuffer whenever you enter a \".\" | |||
| 153 | at the beginning of a line in makefile-mode.") | 181 | at the beginning of a line in makefile-mode.") |
| 154 | 182 | ||
| 155 | (defvar makefile-runtime-macros-list | 183 | (defvar makefile-runtime-macros-list |
| 156 | '(("@") ("&") (">") ("<") ("*") ("^") ("?") ("%")) | 184 | '(("@") ("&") (">") ("<") ("*") ("^") ("?") ("%") ("$")) |
| 157 | "List of macros that are resolved by make at runtime. | 185 | "List of macros that are resolved by make at runtime. |
| 158 | If you insert a macro reference using makefile-insert-macro-ref, the name | 186 | If you insert a macro reference using makefile-insert-macro-ref, the name |
| 159 | of the macro is checked against this list. If it can be found its name will | 187 | of the macro is checked against this list. If it can be found its name will |
| 160 | not be enclosed in { } or ( ).") | 188 | not be enclosed in { } or ( ).") |
| 161 | 189 | ||
| 190 | ;; Note that the first big subexpression is used by font lock. Note | ||
| 191 | ;; that if you change this regexp you must fix the imenu index | ||
| 192 | ;; function defined at the end of the file. | ||
| 162 | (defconst makefile-dependency-regex | 193 | (defconst makefile-dependency-regex |
| 163 | "^[^ \t#:]+\\([ \t]+[^ \t#:]+\\)*[ \t]*:\\([ \t]*$\\|\\([^=\n].*$\\)\\)" | 194 | "^\\([^ \n\t#:]+\\([ \t]+[^ \t\n#:]+\\)*\\)[ \t]*:\\([ \t]*$\\|\\([^=\n].*$\\)\\)" |
| 164 | "Regex used to find dependency lines in a makefile.") | 195 | "Regex used to find dependency lines in a makefile.") |
| 165 | 196 | ||
| 197 | ;; Note that the first subexpression is used by font lock. Note that | ||
| 198 | ;; if you change this regexp you must fix the imenu index function | ||
| 199 | ;; defined at the end of the file. | ||
| 166 | (defconst makefile-macroassign-regex | 200 | (defconst makefile-macroassign-regex |
| 167 | "^[^ \t][^:#=]*[\\*:\\+]?:?=.*$" | 201 | "^\\([^ \n\t][^:#=\n]*\\)[ \t]*[*:+]?:?=" |
| 168 | "Regex used to find macro assignment lines in a makefile.") | 202 | "Regex used to find macro assignment lines in a makefile.") |
| 169 | 203 | ||
| 170 | (defconst makefile-ignored-files-in-pickup-regex | 204 | (defconst makefile-ignored-files-in-pickup-regex |
| 171 | "\\(^\\..*\\)\\|\\(.*~$\\)\\|\\(.*,v$\\)\\|\\(\\.[chy]\\)" | 205 | "\\(^\\..*\\)\\|\\(.*~$\\)\\|\\(.*,v$\\)\\|\\(\\.[chy]\\)" |
| 172 | "Regex for filenames that will NOT be included in the target list.") | 206 | "Regex for filenames that will NOT be included in the target list.") |
| 173 | 207 | ||
| 208 | (defconst makefile-font-lock-keywords | ||
| 209 | (list | ||
| 210 | ;; Do macro assignments. These get the "type" face rather | ||
| 211 | ;; arbitrarily. | ||
| 212 | (list makefile-macroassign-regex 1 'font-lock-type-face) | ||
| 213 | |||
| 214 | ;; Do dependencies. These get the function name face. | ||
| 215 | (list makefile-dependency-regex 1 'font-lock-function-name-face))) | ||
| 216 | |||
| 174 | ;;; ------------------------------------------------------------ | 217 | ;;; ------------------------------------------------------------ |
| 175 | ;;; The following configurable variables are used in the | 218 | ;;; The following configurable variables are used in the |
| 176 | ;;; up-to-date overview . | 219 | ;;; up-to-date overview . |
| @@ -221,18 +264,37 @@ interface: | |||
| 221 | () | 264 | () |
| 222 | (setq makefile-mode-map (make-sparse-keymap)) | 265 | (setq makefile-mode-map (make-sparse-keymap)) |
| 223 | ;; set up the keymap | 266 | ;; set up the keymap |
| 224 | (define-key makefile-mode-map "$" 'makefile-insert-macro-ref) | 267 | (define-key makefile-mode-map "\C-c:" 'makefile-insert-target-ref) |
| 225 | (define-key makefile-mode-map "\C-c:" 'makefile-insert-target-ref) | 268 | (if makefile-electric-keys |
| 226 | (define-key makefile-mode-map ":" 'makefile-electric-colon) | 269 | (progn |
| 227 | (define-key makefile-mode-map "=" 'makefile-electric-equal) | 270 | (define-key makefile-mode-map "$" 'makefile-insert-macro-ref) |
| 228 | (define-key makefile-mode-map "." 'makefile-electric-dot) | 271 | (define-key makefile-mode-map ":" 'makefile-electric-colon) |
| 272 | (define-key makefile-mode-map "=" 'makefile-electric-equal) | ||
| 273 | (define-key makefile-mode-map "." 'makefile-electric-dot))) | ||
| 229 | (define-key makefile-mode-map "\C-c\C-f" 'makefile-pickup-filenames-as-targets) | 274 | (define-key makefile-mode-map "\C-c\C-f" 'makefile-pickup-filenames-as-targets) |
| 230 | (define-key makefile-mode-map "\C-c\C-b" 'makefile-switch-to-browser) | 275 | (define-key makefile-mode-map "\C-c\C-b" 'makefile-switch-to-browser) |
| 231 | (define-key makefile-mode-map "\C-c\C-p" 'makefile-pickup-everything) | 276 | (define-key makefile-mode-map "\C-c\C-p" 'makefile-pickup-everything) |
| 232 | (define-key makefile-mode-map "\C-c\C-u" 'makefile-create-up-to-date-overview) | 277 | (define-key makefile-mode-map "\C-c\C-u" 'makefile-create-up-to-date-overview) |
| 233 | (define-key makefile-mode-map "\C-c\C-i" 'makefile-insert-gmake-function) | 278 | (define-key makefile-mode-map "\C-c\C-i" 'makefile-insert-gmake-function) |
| 234 | (define-key makefile-mode-map "\M-p" 'makefile-previous-dependency) | 279 | (define-key makefile-mode-map "\M-p" 'makefile-previous-dependency) |
| 235 | (define-key makefile-mode-map "\M-n" 'makefile-next-dependency)) | 280 | (define-key makefile-mode-map "\M-n" 'makefile-next-dependency) |
| 281 | (define-key makefile-mode-map "\e\t" 'makefile-complete) | ||
| 282 | |||
| 283 | ;; Make menus. | ||
| 284 | (define-key makefile-mode-map [menu-bar makefile-mode] | ||
| 285 | (cons "Makefile" (make-sparse-keymap "Makefile"))) | ||
| 286 | |||
| 287 | (define-key makefile-mode-map [menu-bar makefile-mode browse] | ||
| 288 | '("Pop up Makefile browser" . makefile-switch-to-browser)) | ||
| 289 | (define-key makefile-mode-map [menu-bar makefile-mode complete] | ||
| 290 | '("Complete target or macro" . makefile-complete)) | ||
| 291 | (define-key makefile-mode-map [menu-bar makefile-mode pickup] | ||
| 292 | '("Find targets and macros" . makefile-pickup-everything)) | ||
| 293 | |||
| 294 | (define-key makefile-mode-map [menu-bar makefile-mode prev] | ||
| 295 | '("Move to previous dependency" . makefile-previous-dependency)) | ||
| 296 | (define-key makefile-mode-map [menu-bar makefile-mode next] | ||
| 297 | '("Move to next dependency" . makefile-next-dependency))) | ||
| 236 | 298 | ||
| 237 | (defvar makefile-browser-map nil | 299 | (defvar makefile-browser-map nil |
| 238 | "The keymap that is used in the macro- and target browser.") | 300 | "The keymap that is used in the macro- and target browser.") |
| @@ -266,8 +328,8 @@ interface: | |||
| 266 | (modify-syntax-entry ?\} "){ " makefile-mode-syntax-table) | 328 | (modify-syntax-entry ?\} "){ " makefile-mode-syntax-table) |
| 267 | (modify-syntax-entry ?# "< " makefile-mode-syntax-table) | 329 | (modify-syntax-entry ?# "< " makefile-mode-syntax-table) |
| 268 | (modify-syntax-entry ?\n "> " makefile-mode-syntax-table)) | 330 | (modify-syntax-entry ?\n "> " makefile-mode-syntax-table)) |
| 269 | 331 | ||
| 270 | 332 | ||
| 271 | ;;; ------------------------------------------------------------ | 333 | ;;; ------------------------------------------------------------ |
| 272 | ;;; Internal variables. | 334 | ;;; Internal variables. |
| 273 | ;;; You don't need to configure below this line. | 335 | ;;; You don't need to configure below this line. |
| @@ -342,10 +404,6 @@ In the browser, use the following keys: | |||
| 342 | makefile-mode can be configured by modifying the following | 404 | makefile-mode can be configured by modifying the following |
| 343 | variables: | 405 | variables: |
| 344 | 406 | ||
| 345 | makefile-mode-name: | ||
| 346 | The \"pretty name\" of makefile-mode, as it | ||
| 347 | appears in the modeline. | ||
| 348 | |||
| 349 | makefile-browser-buffer-name: | 407 | makefile-browser-buffer-name: |
| 350 | Name of the macro- and target browser buffer. | 408 | Name of the macro- and target browser buffer. |
| 351 | 409 | ||
| @@ -407,6 +465,7 @@ makefile-special-targets-list: | |||
| 407 | List of special targets. You will be offered to complete | 465 | List of special targets. You will be offered to complete |
| 408 | on one of those in the minibuffer whenever you enter a \".\" | 466 | on one of those in the minibuffer whenever you enter a \".\" |
| 409 | at the beginning of a line in makefile-mode." | 467 | at the beginning of a line in makefile-mode." |
| 468 | |||
| 410 | (interactive) | 469 | (interactive) |
| 411 | (kill-all-local-variables) | 470 | (kill-all-local-variables) |
| 412 | (make-local-variable 'local-write-file-hooks) | 471 | (make-local-variable 'local-write-file-hooks) |
| @@ -417,20 +476,44 @@ makefile-special-targets-list: | |||
| 417 | (make-local-variable 'makefile-has-prereqs) | 476 | (make-local-variable 'makefile-has-prereqs) |
| 418 | (make-local-variable 'makefile-need-target-pickup) | 477 | (make-local-variable 'makefile-need-target-pickup) |
| 419 | (make-local-variable 'makefile-need-macro-pickup) | 478 | (make-local-variable 'makefile-need-macro-pickup) |
| 479 | |||
| 480 | ;; Font lock. | ||
| 481 | (make-local-variable 'font-lock-keywords) | ||
| 482 | (setq font-lock-keywords makefile-font-lock-keywords) | ||
| 483 | (make-local-variable 'font-lock-keywords-case-fold-search) | ||
| 484 | (setq font-lock-keywords-case-fold-search t) | ||
| 485 | |||
| 486 | ;; Add-log. | ||
| 487 | (make-local-variable 'add-log-current-defun-function) | ||
| 488 | (setq add-log-current-defun-function 'makefile-add-log-defun) | ||
| 489 | |||
| 490 | ;; Imenu. | ||
| 491 | (make-local-variable 'imenu-create-index-function) | ||
| 492 | (setq imenu-create-index-function 'makefile-menu-index-function) | ||
| 493 | |||
| 494 | ;; Comment stuff. | ||
| 420 | (make-local-variable 'comment-start) | 495 | (make-local-variable 'comment-start) |
| 421 | (make-local-variable 'comment-end) | ||
| 422 | (make-local-variable 'comment-start-skip) | ||
| 423 | (setq comment-start "#") | 496 | (setq comment-start "#") |
| 497 | (make-local-variable 'comment-end) | ||
| 424 | (setq comment-end "") | 498 | (setq comment-end "") |
| 425 | (setq comment-start-skip "#[ \t]*") | 499 | (make-local-variable 'comment-start-skip) |
| 500 | (setq comment-start-skip "#+[ \t]*") | ||
| 501 | |||
| 426 | ;; become the current major mode | 502 | ;; become the current major mode |
| 427 | (setq major-mode 'makefile-mode) | 503 | (setq major-mode 'makefile-mode) |
| 428 | (setq mode-name makefile-mode-name) | 504 | (setq mode-name "Makefile") |
| 429 | ;; activate keymap | 505 | |
| 506 | ;; Activate keymap and syntax table. | ||
| 430 | (use-local-map makefile-mode-map) | 507 | (use-local-map makefile-mode-map) |
| 431 | (set-syntax-table makefile-mode-syntax-table) | 508 | (set-syntax-table makefile-mode-syntax-table) |
| 432 | (setq indent-tabs-mode t) ;real TABs are important in makefiles | 509 | |
| 433 | (run-hooks 'makefile-mode-hook)) | 510 | ;; Real TABs are important in makefiles |
| 511 | (setq indent-tabs-mode t) | ||
| 512 | (run-hooks 'makefile-mode-hook)) | ||
| 513 | |||
| 514 | |||
| 515 | |||
| 516 | ;;; Motion code. | ||
| 434 | 517 | ||
| 435 | (defun makefile-next-dependency () | 518 | (defun makefile-next-dependency () |
| 436 | "Move (point) to the beginning of the next dependency line below (point)." | 519 | "Move (point) to the beginning of the next dependency line below (point)." |
| @@ -440,7 +523,7 @@ makefile-special-targets-list: | |||
| 440 | (if (re-search-forward makefile-dependency-regex (point-max) t) | 523 | (if (re-search-forward makefile-dependency-regex (point-max) t) |
| 441 | (progn (beginning-of-line) t) ; indicate success | 524 | (progn (beginning-of-line) t) ; indicate success |
| 442 | (goto-char here) nil))) | 525 | (goto-char here) nil))) |
| 443 | 526 | ||
| 444 | (defun makefile-previous-dependency () | 527 | (defun makefile-previous-dependency () |
| 445 | "Move (point) to the beginning of the next dependency line above (point)." | 528 | "Move (point) to the beginning of the next dependency line above (point)." |
| 446 | (interactive) | 529 | (interactive) |
| @@ -450,37 +533,41 @@ makefile-special-targets-list: | |||
| 450 | (progn (beginning-of-line) t) ; indicate success | 533 | (progn (beginning-of-line) t) ; indicate success |
| 451 | (goto-char here) nil))) | 534 | (goto-char here) nil))) |
| 452 | 535 | ||
| 536 | |||
| 453 | 537 | ||
| 454 | ;;; Stuff below here depends on the pickup state | 538 | ;;; Electric keys. Blech. |
| 455 | 539 | ||
| 456 | (defun makefile-electric-dot () | 540 | (defun makefile-electric-dot (arg) |
| 457 | "At (bol), offer completion on makefile-special-targets-list. | 541 | "Prompt for the name of a special target to insert. |
| 458 | Anywhere else just insert a dot." | 542 | Only does electric insertion at beginning of line. |
| 459 | (interactive) | 543 | Anywhere else just self-inserts." |
| 544 | (interactive "p") | ||
| 460 | (if (bolp) | 545 | (if (bolp) |
| 461 | (makefile-insert-special-target) | 546 | (makefile-insert-special-target) |
| 462 | (insert "."))) | 547 | (self-insert-command arg))) |
| 463 | 548 | ||
| 464 | (defun makefile-insert-special-target () | 549 | (defun makefile-insert-special-target () |
| 465 | "Complete on makefile-special-targets-list, insert result at (point)." | 550 | "Propmt for and insert a special target name. |
| 551 | Uses `makefile-special-targets' list." | ||
| 466 | (interactive) | 552 | (interactive) |
| 467 | (makefile-pickup-targets) | 553 | (makefile-pickup-targets) |
| 468 | (let | 554 | (let ((special-target |
| 469 | ((special-target | 555 | (completing-read "Special target: " |
| 470 | (completing-read "Special target: " | 556 | makefile-special-targets-list nil nil nil))) |
| 471 | makefile-special-targets-list nil nil nil))) | ||
| 472 | (if (zerop (length special-target)) | 557 | (if (zerop (length special-target)) |
| 473 | () | 558 | () |
| 474 | (insert (format ".%s:" special-target)) | 559 | (insert "." special-target ":") |
| 475 | (makefile-forward-after-target-colon)))) | 560 | (makefile-forward-after-target-colon)))) |
| 476 | 561 | ||
| 477 | (defun makefile-electric-equal () | 562 | (defun makefile-electric-equal (arg) |
| 478 | "At (bol) do makefile-insert-macro. Anywhere else just self-insert." | 563 | "Prompt for name of a macro to insert. |
| 479 | (interactive) | 564 | Only does prompting if point is at beginning of line. |
| 565 | Anywhere else just self-inserts." | ||
| 566 | (interactive "p") | ||
| 480 | (makefile-pickup-macros) | 567 | (makefile-pickup-macros) |
| 481 | (if (bolp) | 568 | (if (bolp) |
| 482 | (call-interactively 'makefile-insert-macro) | 569 | (call-interactively 'makefile-insert-macro) |
| 483 | (insert "="))) | 570 | (self-insert-command arg))) |
| 484 | 571 | ||
| 485 | (defun makefile-insert-macro (macro-name) | 572 | (defun makefile-insert-macro (macro-name) |
| 486 | "Prepare definition of a new macro." | 573 | "Prepare definition of a new macro." |
| @@ -489,7 +576,7 @@ Anywhere else just insert a dot." | |||
| 489 | (if (not (zerop (length macro-name))) | 576 | (if (not (zerop (length macro-name))) |
| 490 | (progn | 577 | (progn |
| 491 | (beginning-of-line) | 578 | (beginning-of-line) |
| 492 | (insert (format "%s%s" macro-name makefile-macro-assign)) | 579 | (insert macro-name makefile-macro-assign) |
| 493 | (setq makefile-need-macro-pickup t) | 580 | (setq makefile-need-macro-pickup t) |
| 494 | (makefile-remember-macro macro-name)))) | 581 | (makefile-remember-macro macro-name)))) |
| 495 | 582 | ||
| @@ -500,10 +587,7 @@ Anywhere else just insert a dot." | |||
| 500 | (progn | 587 | (progn |
| 501 | (makefile-pickup-macros) | 588 | (makefile-pickup-macros) |
| 502 | (completing-read "Refer to macro: " makefile-macro-table nil nil nil)))) | 589 | (completing-read "Refer to macro: " makefile-macro-table nil nil nil)))) |
| 503 | (if (not (zerop (length macro-name))) | 590 | (makefile-do-macro-insertion macro-name)) |
| 504 | (if (assoc macro-name makefile-runtime-macros-list) | ||
| 505 | (insert (format "$%s" macro-name)) | ||
| 506 | (insert (makefile-format-macro-ref macro-name))))) | ||
| 507 | 591 | ||
| 508 | (defun makefile-insert-target (target-name) | 592 | (defun makefile-insert-target (target-name) |
| 509 | "Prepare definition of a new target (dependency line)." | 593 | "Prepare definition of a new target (dependency line)." |
| @@ -511,7 +595,7 @@ Anywhere else just insert a dot." | |||
| 511 | (if (not (zerop (length target-name))) | 595 | (if (not (zerop (length target-name))) |
| 512 | (progn | 596 | (progn |
| 513 | (beginning-of-line) | 597 | (beginning-of-line) |
| 514 | (insert (format "%s%s" target-name makefile-target-colon)) | 598 | (insert target-name makefile-target-colon) |
| 515 | (makefile-forward-after-target-colon) | 599 | (makefile-forward-after-target-colon) |
| 516 | (end-of-line) | 600 | (end-of-line) |
| 517 | (setq makefile-need-target-pickup t) | 601 | (setq makefile-need-target-pickup t) |
| @@ -525,15 +609,18 @@ Anywhere else just insert a dot." | |||
| 525 | (makefile-pickup-targets) | 609 | (makefile-pickup-targets) |
| 526 | (completing-read "Refer to target: " makefile-target-table nil nil nil)))) | 610 | (completing-read "Refer to target: " makefile-target-table nil nil nil)))) |
| 527 | (if (not (zerop (length target-name))) | 611 | (if (not (zerop (length target-name))) |
| 528 | (progn | 612 | (insert target-name " "))) |
| 529 | (insert (format "%s " target-name))))) | ||
| 530 | 613 | ||
| 531 | (defun makefile-electric-colon () | 614 | (defun makefile-electric-colon (arg) |
| 532 | "At (bol) defines a new target, anywhere else just self-insert ." | 615 | "Prompt for name of new target. |
| 533 | (interactive) | 616 | Prompting only happens at beginning of line. |
| 617 | Anywhere else just self-inserts." | ||
| 618 | (interactive "p") | ||
| 534 | (if (bolp) | 619 | (if (bolp) |
| 535 | (call-interactively 'makefile-insert-target) | 620 | (call-interactively 'makefile-insert-target) |
| 536 | (insert ":"))) | 621 | (self-insert-command arg))) |
| 622 | |||
| 623 | |||
| 537 | 624 | ||
| 538 | ;;; ------------------------------------------------------------ | 625 | ;;; ------------------------------------------------------------ |
| 539 | ;;; Extracting targets and macros from an existing makefile | 626 | ;;; Extracting targets and macros from an existing makefile |
| @@ -605,16 +692,20 @@ and add them to the list of known macros." | |||
| 605 | (message "Picked up macro \"%s\" from line %d" | 692 | (message "Picked up macro \"%s\" from line %d" |
| 606 | macro-name line-number)))))) | 693 | macro-name line-number)))))) |
| 607 | 694 | ||
| 608 | (defun makefile-pickup-everything () | 695 | (defun makefile-pickup-everything (arg) |
| 609 | "Calls makefile-pickup-targets and makefile-pickup-macros. | 696 | "Calls makefile-pickup-targets and makefile-pickup-macros. |
| 610 | See their documentation for what they do." | 697 | See their documentation for what they do. |
| 611 | (interactive) | 698 | Prefix arg means force pickups to be redone." |
| 699 | (interactive "P") | ||
| 700 | (if arg | ||
| 701 | (progn | ||
| 702 | (setq makefile-need-target-pickup t) | ||
| 703 | (setq makefile-need-macro-pickup t))) | ||
| 612 | (makefile-pickup-macros) | 704 | (makefile-pickup-macros) |
| 613 | (makefile-pickup-targets) | 705 | (makefile-pickup-targets) |
| 614 | (if makefile-pickup-everything-picks-up-filenames-p | 706 | (if makefile-pickup-everything-picks-up-filenames-p |
| 615 | (makefile-pickup-filenames-as-targets))) | 707 | (makefile-pickup-filenames-as-targets))) |
| 616 | 708 | ||
| 617 | |||
| 618 | (defun makefile-pickup-filenames-as-targets () | 709 | (defun makefile-pickup-filenames-as-targets () |
| 619 | "Scan the current directory for filenames, check each filename | 710 | "Scan the current directory for filenames, check each filename |
| 620 | against makefile-ignored-files-in-pickup-regex and add all qualifying | 711 | against makefile-ignored-files-in-pickup-regex and add all qualifying |
| @@ -632,8 +723,105 @@ names to the list of known targets." | |||
| 632 | (message "Picked up file \"%s\" as target" name)))) | 723 | (message "Picked up file \"%s\" as target" name)))) |
| 633 | raw-filename-list))) | 724 | raw-filename-list))) |
| 634 | 725 | ||
| 726 | |||
| 727 | |||
| 728 | ;;; Completion. | ||
| 729 | |||
| 730 | (defun makefile-complete () | ||
| 731 | "Perform completion on Makefile construct preceding point. | ||
| 732 | Can complete variable and target names. | ||
| 733 | The context determines which are considered." | ||
| 734 | (interactive) | ||
| 735 | (let* ((beg (save-excursion | ||
| 736 | (skip-chars-backward "^$(){}:#= \t\n") | ||
| 737 | (point))) | ||
| 738 | (try (buffer-substring beg (point))) | ||
| 739 | (do-macros nil) | ||
| 740 | (paren nil)) | ||
| 741 | |||
| 742 | (save-excursion | ||
| 743 | (goto-char beg) | ||
| 744 | (let ((pc (preceding-char))) | ||
| 745 | (cond | ||
| 746 | ;; Beginning of line means anything. | ||
| 747 | ((bolp) | ||
| 748 | ()) | ||
| 749 | |||
| 750 | ;; Preceding "$" means macros only. | ||
| 751 | ((= pc ?$) | ||
| 752 | (setq do-macros t)) | ||
| 753 | |||
| 754 | ;; Preceding "$(" or "${" means macros only. | ||
| 755 | ((and (or (= pc ?{) | ||
| 756 | (= pc ?\()) | ||
| 757 | (progn | ||
| 758 | (setq paren pc) | ||
| 759 | (backward-char) | ||
| 760 | (and (not (bolp)) | ||
| 761 | (= (preceding-char) ?$)))) | ||
| 762 | (setq do-macros t))))) | ||
| 763 | |||
| 764 | ;; Try completion. | ||
| 765 | (let* ((table (append (if do-macros | ||
| 766 | '() | ||
| 767 | makefile-target-table) | ||
| 768 | makefile-macro-table)) | ||
| 769 | (completion (try-completion try table))) | ||
| 770 | (cond | ||
| 771 | ;; Exact match, so insert closing paren or colon. | ||
| 772 | ((eq completion t) | ||
| 773 | (insert (if do-macros | ||
| 774 | (if (eq paren ?{) | ||
| 775 | ?} | ||
| 776 | ?\)) | ||
| 777 | (if (save-excursion | ||
| 778 | (goto-char beg) | ||
| 779 | (bolp)) | ||
| 780 | ":" | ||
| 781 | " ")))) | ||
| 782 | |||
| 783 | ;; No match. | ||
| 784 | ((null completion) | ||
| 785 | (message "Can't find completion for \"%s\"" try) | ||
| 786 | (ding)) | ||
| 787 | |||
| 788 | ;; Partial completion. | ||
| 789 | ((not (string= try completion)) | ||
| 790 | ;; FIXME it would be nice to supply the closing paren if an | ||
| 791 | ;; exact, unambiguous match were found. That is not possible | ||
| 792 | ;; right now. Ditto closing ":" for targets. | ||
| 793 | (delete-region beg (point)) | ||
| 794 | |||
| 795 | ;; DO-MACROS means doing macros only. If not that, then check | ||
| 796 | ;; to see if this completion is a macro. Special insertion | ||
| 797 | ;; must be done for macros. | ||
| 798 | (if (or do-macros | ||
| 799 | (assoc completion makefile-macro-table)) | ||
| 800 | (let ((makefile-use-curly-braces-for-macros-p | ||
| 801 | (or (eq paren ?{) | ||
| 802 | makefile-use-curly-braces-for-macros-p))) | ||
| 803 | (delete-backward-char 2) | ||
| 804 | (makefile-do-macro-insertion completion) | ||
| 805 | (delete-backward-char 1)) | ||
| 806 | |||
| 807 | ;; Just insert targets. | ||
| 808 | (insert completion))) | ||
| 809 | |||
| 810 | ;; Can't complete any more, so make completion list. FIXME | ||
| 811 | ;; this doesn't do the right thing when the completion is | ||
| 812 | ;; actually inserted. I don't think there is an easy way to do | ||
| 813 | ;; that. | ||
| 814 | (t | ||
| 815 | (message "Making completion list...") | ||
| 816 | (let ((list (all-completions try table))) | ||
| 817 | (with-output-to-temp-buffer "*Completions*" | ||
| 818 | (display-completion-list list))) | ||
| 819 | (message "Making completion list...done")))))) | ||
| 820 | |||
| 821 | |||
| 822 | |||
| 635 | ;;; ------------------------------------------------------------ | 823 | ;;; ------------------------------------------------------------ |
| 636 | ;;; The browser window | 824 | ;;; Browser mode. |
| 637 | ;;; ------------------------------------------------------------ | 825 | ;;; ------------------------------------------------------------ |
| 638 | 826 | ||
| 639 | (defun makefile-browser-format-target-line (target selected) | 827 | (defun makefile-browser-format-target-line (target selected) |
| @@ -812,6 +1000,7 @@ Insertion takes place at (point)." | |||
| 812 | (makefile-pickup-macros) | 1000 | (makefile-pickup-macros) |
| 813 | (makefile-browse makefile-target-table makefile-macro-table)) | 1001 | (makefile-browse makefile-target-table makefile-macro-table)) |
| 814 | 1002 | ||
| 1003 | |||
| 815 | 1004 | ||
| 816 | ;;; ------------------------------------------------------------ | 1005 | ;;; ------------------------------------------------------------ |
| 817 | ;;; Up-to-date overview buffer | 1006 | ;;; Up-to-date overview buffer |
| @@ -911,6 +1100,8 @@ and generates the overview, one line per target name." | |||
| 911 | (defun makefile-query-by-make-minus-q (target &optional filename) | 1100 | (defun makefile-query-by-make-minus-q (target &optional filename) |
| 912 | (not (zerop (call-process makefile-brave-make nil nil nil "-f" filename "-q" target)))) | 1101 | (not (zerop (call-process makefile-brave-make nil nil nil "-f" filename "-q" target)))) |
| 913 | 1102 | ||
| 1103 | |||
| 1104 | |||
| 914 | ;;; ------------------------------------------------------------ | 1105 | ;;; ------------------------------------------------------------ |
| 915 | ;;; Continuation cleanup | 1106 | ;;; Continuation cleanup |
| 916 | ;;; ------------------------------------------------------------ | 1107 | ;;; ------------------------------------------------------------ |
| @@ -945,6 +1136,7 @@ and generates the overview, one line per target name." | |||
| 945 | line-nr)))))))) | 1136 | line-nr)))))))) |
| 946 | dont-save)) | 1137 | dont-save)) |
| 947 | 1138 | ||
| 1139 | |||
| 948 | 1140 | ||
| 949 | ;;; ------------------------------------------------------------ | 1141 | ;;; ------------------------------------------------------------ |
| 950 | ;;; GNU make function support | 1142 | ;;; GNU make function support |
| @@ -981,12 +1173,19 @@ powerful GNU make feature." | |||
| 981 | prompt-list | 1173 | prompt-list |
| 982 | ",")) | 1174 | ",")) |
| 983 | 1175 | ||
| 984 | 1176 | ||
| 985 | 1177 | ||
| 986 | ;;; ------------------------------------------------------------ | 1178 | ;;; ------------------------------------------------------------ |
| 987 | ;;; Utility functions | 1179 | ;;; Utility functions |
| 988 | ;;; ------------------------------------------------------------ | 1180 | ;;; ------------------------------------------------------------ |
| 989 | 1181 | ||
| 1182 | (defun makefile-do-macro-insertion (macro-name) | ||
| 1183 | "Insert a macro reference." | ||
| 1184 | (if (not (zerop (length macro-name))) | ||
| 1185 | (if (assoc macro-name makefile-runtime-macros-list) | ||
| 1186 | (insert "$" macro-name) | ||
| 1187 | (insert (makefile-format-macro-ref macro-name))))) | ||
| 1188 | |||
| 990 | (defun makefile-remember-target (target-name &optional has-prereqs) | 1189 | (defun makefile-remember-target (target-name &optional has-prereqs) |
| 991 | "Remember a given target if it is not already remembered for this buffer." | 1190 | "Remember a given target if it is not already remembered for this buffer." |
| 992 | (if (not (zerop (length target-name))) | 1191 | (if (not (zerop (length target-name))) |
| @@ -1070,4 +1269,47 @@ configuration variable makefile-use-curly-braces-for-macros-p ." | |||
| 1070 | (defun makefile-first-line-p () | 1269 | (defun makefile-first-line-p () |
| 1071 | (= (makefile-beginning-of-line-point) (point-min))) | 1270 | (= (makefile-beginning-of-line-point) (point-min))) |
| 1072 | 1271 | ||
| 1073 | ;; makefile.el ends here | 1272 | |
| 1273 | |||
| 1274 | ;;; Support for other packages, like add-log and imenu. | ||
| 1275 | |||
| 1276 | (defun makefile-add-log-defun () | ||
| 1277 | "Return name of target or macro point is in, or nil." | ||
| 1278 | (save-excursion | ||
| 1279 | (beginning-of-line) | ||
| 1280 | (cond | ||
| 1281 | ((looking-at makefile-macroassign-regex) | ||
| 1282 | (buffer-substring (match-beginning 1) | ||
| 1283 | (match-end 1))) | ||
| 1284 | ((progn | ||
| 1285 | (forward-char) | ||
| 1286 | (re-search-backward makefile-dependency-regex nil t)) | ||
| 1287 | (buffer-substring (match-beginning 1) | ||
| 1288 | (match-end 1))) | ||
| 1289 | (t nil)))) | ||
| 1290 | |||
| 1291 | ;; FIXME it might be nice to have them separated by macro vs target. | ||
| 1292 | (defun makefile-menu-index-function () | ||
| 1293 | "Generate alist of indices for imenu." | ||
| 1294 | (let (alist | ||
| 1295 | stupid | ||
| 1296 | (re (concat makefile-dependency-regex | ||
| 1297 | "\\|" | ||
| 1298 | makefile-macroassign-regex))) | ||
| 1299 | (imenu-progress-message stupid 0) | ||
| 1300 | (goto-char (point-min)) | ||
| 1301 | (while (re-search-forward re nil t) | ||
| 1302 | (imenu-progress-message stupid) | ||
| 1303 | (setq zardoz (list (match-beginning 0) (match-end 0) | ||
| 1304 | (match-beginning 1) (match-end 1) | ||
| 1305 | )) | ||
| 1306 | (let ((n (if (match-beginning 1) 1 5))) | ||
| 1307 | (setq alist (cons | ||
| 1308 | (cons (buffer-substring (match-beginning n) | ||
| 1309 | (match-end n)) | ||
| 1310 | (match-beginning n)) | ||
| 1311 | alist)))) | ||
| 1312 | (imenu-progress-message stupid 100) | ||
| 1313 | (nreverse alist))) | ||
| 1314 | |||
| 1315 | ;;; makefile.el ends here | ||