aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/progmodes/make-mode.el378
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
92allow a larger variety of different macro assignments, so you 116allow a larger variety of different macro assignments, so you
93might prefer to use \" += \" or \" := \" .") 117might prefer to use \" += \" or \" := \" .")
94 118
119(defvar makefile-electric-keys nil
120 "If non-nil, install electric keybindings.
121Default 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.
97Set this variable to a non-nil value if you prefer curly braces 125Set 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 \".\"
153at the beginning of a line in makefile-mode.") 181at 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.
158If you insert a macro reference using makefile-insert-macro-ref, the name 186If you insert a macro reference using makefile-insert-macro-ref, the name
159of the macro is checked against this list. If it can be found its name will 187of the macro is checked against this list. If it can be found its name will
160not be enclosed in { } or ( ).") 188not 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:
342makefile-mode can be configured by modifying the following 404makefile-mode can be configured by modifying the following
343variables: 405variables:
344 406
345makefile-mode-name:
346 The \"pretty name\" of makefile-mode, as it
347 appears in the modeline.
348
349makefile-browser-buffer-name: 407makefile-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.
458Anywhere else just insert a dot." 542Only does electric insertion at beginning of line.
459 (interactive) 543Anywhere 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.
551Uses `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) 564Only does prompting if point is at beginning of line.
565Anywhere 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) 616Prompting only happens at beginning of line.
617Anywhere 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.
610See their documentation for what they do." 697See their documentation for what they do.
611 (interactive) 698Prefix 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
620against makefile-ignored-files-in-pickup-regex and add all qualifying 711against 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.
732Can complete variable and target names.
733The 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