Merge from emacs-24; up to 2012-12-22T19:09:52Z!rgm@gnu.org
[bpt/emacs.git] / lisp / progmodes / make-mode.el
index aa58c67..2067386 100644 (file)
@@ -1,7 +1,6 @@
-;;; make-mode.el --- makefile editing commands for Emacs
+;;; make-mode.el --- makefile editing commands for Emacs -*- lexical-binding:t -*-
 
-;; Copyright (C) 1992, 1994, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-;;   2006, 2007, 2008, 2009, 2010, 2011, 2012  Free Software Foundation, Inc.
+;; Copyright (C) 1992, 1994, 1999-2013 Free Software Foundation, Inc.
 
 ;; Author: Thomas Neumann <tom@smart.bo.open.de>
 ;;     Eric S. Raymond <esr@snark.thyrsus.com>
   :version "22.1")
 
 (defcustom makefile-browser-buffer-name "*Macros and Targets*"
-  "*Name of the macro- and target browser buffer."
+  "Name of the macro- and target browser buffer."
   :type 'string
   :group 'makefile)
 
 (defcustom makefile-target-colon ":"
-  "*String to append to all target names inserted by `makefile-insert-target'.
+  "String to append to all target names inserted by `makefile-insert-target'.
 \":\" or \"::\" are common values."
   :type 'string
   :group 'makefile)
 
 (defcustom makefile-macro-assign " = "
-  "*String to append to all macro names inserted by `makefile-insert-macro'.
+  "String to append to all macro names inserted by `makefile-insert-macro'.
 The normal value should be \" = \", since this is what
 standard make expects.  However, newer makes such as dmake
 allow a larger variety of different macro assignments, so you
@@ -150,69 +149,69 @@ might prefer to use \" += \" or \" := \" ."
   :group 'makefile)
 
 (defcustom makefile-electric-keys nil
-  "*If non-nil, Makefile mode should install electric keybindings.
+  "If non-nil, Makefile mode should install electric keybindings.
 Default is nil."
   :type 'boolean
   :group 'makefile)
 
 (defcustom makefile-use-curly-braces-for-macros-p nil
-  "*Controls the style of generated macro references.
+  "Controls the style of generated macro references.
 Non-nil means macro references should use curly braces, like `${this}'.
 nil means use parentheses, like `$(this)'."
   :type 'boolean
   :group 'makefile)
 
 (defcustom makefile-tab-after-target-colon t
-  "*If non-nil, insert a TAB after a target colon.
+  "If non-nil, insert a TAB after a target colon.
 Otherwise, a space is inserted.
 The default is t."
   :type 'boolean
   :group 'makefile)
 
 (defcustom makefile-browser-leftmost-column 10
-  "*Number of blanks to the left of the browser selection mark."
+  "Number of blanks to the left of the browser selection mark."
   :type 'integer
   :group 'makefile)
 
 (defcustom makefile-browser-cursor-column 10
-  "*Column the cursor goes to when it moves up or down in the Makefile browser."
+  "Column the cursor goes to when it moves up or down in the Makefile browser."
   :type 'integer
   :group 'makefile)
 
 (defcustom makefile-backslash-column 48
-  "*Column in which `makefile-backslash-region' inserts backslashes."
+  "Column in which `makefile-backslash-region' inserts backslashes."
   :type 'integer
   :group 'makefile)
 
 (defcustom makefile-backslash-align t
-  "*If non-nil, `makefile-backslash-region' will align backslashes."
+  "If non-nil, `makefile-backslash-region' will align backslashes."
   :type 'boolean
   :group 'makefile)
 
 (defcustom makefile-browser-selected-mark "+  "
-  "*String used to mark selected entries in the Makefile browser."
+  "String used to mark selected entries in the Makefile browser."
   :type 'string
   :group 'makefile)
 
 (defcustom makefile-browser-unselected-mark "   "
-  "*String used to mark unselected entries in the Makefile browser."
+  "String used to mark unselected entries in the Makefile browser."
   :type 'string
   :group 'makefile)
 
 (defcustom makefile-browser-auto-advance-after-selection-p t
-  "*If non-nil, cursor will move after item is selected in Makefile browser."
+  "If non-nil, cursor will move after item is selected in Makefile browser."
   :type 'boolean
   :group 'makefile)
 
 (defcustom makefile-pickup-everything-picks-up-filenames-p nil
-  "*If non-nil, `makefile-pickup-everything' picks up filenames as targets.
+  "If non-nil, `makefile-pickup-everything' picks up filenames as targets.
 This means it calls `makefile-pickup-filenames-as-targets'.
 Otherwise filenames are omitted."
   :type 'boolean
   :group 'makefile)
 
 (defcustom makefile-cleanup-continuations nil
-  "*If non-nil, automatically clean up continuation lines when saving.
+  "If non-nil, automatically clean up continuation lines when saving.
 A line is cleaned up by removing all whitespace following a trailing
 backslash.  This is done silently.
 IMPORTANT: Please note that enabling this option causes Makefile mode
@@ -221,7 +220,7 @@ to MODIFY A FILE WITHOUT YOUR CONFIRMATION when \"it seems necessary\"."
   :group 'makefile)
 
 (defcustom makefile-mode-hook nil
-  "*Normal hook run by `makefile-mode'."
+  "Normal hook run by `makefile-mode'."
   :type 'hook
   :group 'makefile)
 
@@ -248,7 +247,7 @@ you enter a \".\" at the beginning of a line in `makefile-mode'."
 
 (defcustom makefile-runtime-macros-list
   '(("@") ("&") (">") ("<") ("*") ("^") ("+") ("?") ("%") ("$"))
-  "*List of macros that are resolved by make at runtime.
+  "List of macros that are resolved by make at runtime.
 If you insert a macro reference using `makefile-insert-macro-ref', the name
 of the macro is checked against this list.  If it can be found its name will
 not be enclosed in { } or ( )."
@@ -281,8 +280,7 @@ not be enclosed in { } or ( )."
   "Regex used to highlight makepp rule action lines in font lock mode.")
 
 (defconst makefile-bsdmake-rule-action-regex
-  (progn (string-match "-@" makefile-rule-action-regex)
-        (replace-match "-+@" t t makefile-rule-action-regex))
+  (replace-regexp-in-string "-@" "-+@" makefile-rule-action-regex)
   "Regex used to highlight BSD rule action lines in font lock mode.")
 
 ;; Note that the first and second subexpression is used by font lock.  Note
@@ -317,25 +315,32 @@ not be enclosed in { } or ( )."
   "List of keywords understood by automake.")
 
 (defconst makefile-gmake-statements
-  `("-sinclude" "sinclude" "vpath"     ; makefile-makepp-statements takes rest
+  `("-sinclude" "sinclude"             ; makefile-makepp-statements takes rest
     "ifdef" "ifndef" "ifeq" "ifneq" "-include" "define" "endef" "export"
-    "override define" "override" "unexport"
+    "override define" "override" "unexport" "vpath"
     ,@(cdr makefile-automake-statements))
   "List of keywords understood by gmake.")
 
-;; These are even more silly, because you can have more spaces in between.
 (defconst makefile-makepp-statements
-  `("and ifdef" "and ifndef" "and ifeq" "and ifneq" "and ifperl"
-    "and ifmakeperl" "and ifsys" "and ifnsys" "build_cache" "build_check"
+  `(t                                  ; - alternately means _
+    ;; todo: take if* out of these lists, and let the negation regexp do it all
+    "ifperl" "ifmakeperl" "ifsys" "ifnsys" "iftrue" "ifntrue"
+    "and ifdef" "and ifndef" "and ifeq" "and ifneq" "and ifperl"
+    "and ifmakeperl" "and ifsys" "and ifnsys" "and iftrue" "and ifntrue"
     "else ifdef" "else ifndef" "else ifeq" "else ifneq" "else ifperl"
-    "else ifmakeperl" "else ifsys" "else ifnsys" "enddef" "global"
-    "load_makefile" "ifperl" "ifmakeperl" "ifsys" "ifnsys" "_include"
-    "makeperl" "makesub" "no_implicit_load" "perl" "perl-begin" "perl_begin"
-    "perl-end" "perl_end" "prebuild" "or ifdef" "or ifndef" "or ifeq"
-    "or ifneq" "or ifperl" "or ifmakeperl" "or ifsys" "or ifnsys"
-    "override export" "override global" "register_command_parser"
-    "register_scanner" "repository" "runtime" "signature" "sub"
-    ,@(nthcdr 3 makefile-gmake-statements))
+    "else ifmakeperl" "else ifsys" "else ifnsys" "else iftrue" "else ifntrue"
+    "or ifdef" "or ifndef" "or ifeq" "or ifneq" "or ifperl"
+    "or ifmakeperl" "or ifsys" "or ifnsys" "or iftrue" "or ifntrue"
+
+    "autoload" "build-cache" "build-check" "enddef" "export define"
+    "global" "global build-cache" "global build-check" "global define"
+    "global signature" "global override signature" "load-makefile"
+    "make" "makeperl" "makesub" "no-implicit-load" "perl" "perl-begin"
+    "perl-end" "prebuild" "override export" "override global" "register-parser"
+    "register-command-parser" "register-input-suffix"
+    "register-scanner" "repository" "runtime" "signature" "sub"
+
+    ,@(nthcdr 2 makefile-gmake-statements))
   "List of keywords understood by gmake.")
 
 (defconst makefile-bsdmake-statements
@@ -345,7 +350,7 @@ not be enclosed in { } or ( )."
 
 (defun makefile-make-font-lock-keywords (var keywords space
                                             &optional negation
-                                            &rest font-lock-keywords)
+                                            &rest fl-keywords)
   `(;; Do macro assignments.  These get the "variable-name" face.
     (,makefile-macroassign-regex
      (1 font-lock-variable-name-face)
@@ -374,7 +379,12 @@ not be enclosed in { } or ( )."
 
     ;; Fontify conditionals and includes.
     (,(concat "^\\(?: [ \t]*\\)?"
-             (regexp-opt keywords t)
+             (replace-regexp-in-string
+              " " "[ \t]+"
+              (if (eq (car keywords) t)
+                  (replace-regexp-in-string "-" "[_-]"
+                                             (regexp-opt (cdr keywords) t))
+                (regexp-opt keywords t)))
              "\\>[ \t]*\\([^: \t\n#]*\\)")
      (1 font-lock-keyword-face) (2 font-lock-variable-name-face))
 
@@ -395,7 +405,7 @@ not be enclosed in { } or ( )."
            ;; They can make a tab fail to be effective.
            ("^\\( +\\)\t" 1 makefile-space)))
 
-    ,@font-lock-keywords
+    ,@fl-keywords
 
     ;; Do dependencies.
     (makefile-match-dependency
@@ -438,7 +448,7 @@ not be enclosed in { } or ( )."
    makefile-var-use-regex
    makefile-makepp-statements
    nil
-   "^\\(?: [ \t]*\\)?\\(?:and[ \t]+\\|else[ \t]+\\|or[ \t]+\\)?if\\(n\\)\\(?:def\\|eq\\|sys\\)\\>"
+   "^\\(?: [ \t]*\\)?\\(?:and[ \t]+\\|else[ \t]+\\|or[ \t]+\\)?if\\(n\\)\\(?:def\\|eq\\|sys\\|true\\)\\>"
 
    '("[^$]\\(\\$[({]\\(?:output\\|stem\\|target\\)s?\\_>.*?[})]\\)"
      1 'makefile-targets append)
@@ -449,17 +459,17 @@ not be enclosed in { } or ( )."
      (2 font-lock-keyword-face t)
      (3 font-lock-variable-name-face t))
 
-   ;; $(function ...) $((function ...)) ${function ...} ${{function ...}}
-   '("[^$]\\$\\(?:((?\\|{{?\\)\\([-a-zA-Z0-9_.]+\\s \\)"
+   ;; $(function ...) $((function ...)) ${...} ${{...}} $[...] $[[...]]
+   '("[^$]\\$\\(?:((?\\|{{?\\|\\[\\[?\\)\\([-a-zA-Z0-9_.]+\\s \\)"
      1 font-lock-function-name-face prepend)
 
-   ;; $(shell ...) $((shell ...)) ${shell ...} ${{shell ...}}
-   '("[^$]\\$\\(((?\\|{{?\\)shell\\(?:[-_]\\(?:global[-_]\\)?once\\)?[ \t]+"
+   ;; $(shell ...) $((shell ...)) ${...} ${{...}} $[...] $[[...]]
+   '("[^$]\\$\\(((?\\|{{?\\|\\[\\[?\\)shell\\(?:[-_]\\(?:global[-_]\\)?once\\)?[ \t]+"
      makefile-match-function-end nil nil
      (1 'makefile-shell prepend t))
 
-   ;; $(perl ...) $((perl ...)) ${perl ...} ${{perl ...}}
-   '("[^$]\\$\\(((?\\|{{?\\)makeperl[ \t]+"
+   ;; $(perl ...) $((perl ...)) ${...} ${{...}} $[...] $[[...]]
+   '("[^$]\\$\\(((?\\|{{?\\|\\[\\[?\\)makeperl[ \t]+"
      makefile-match-function-end nil nil
      (1 'makefile-makepp-perl prepend t))
    '("[^$]\\$\\(((?\\|{{?\\)perl[ \t]+"
@@ -493,7 +503,7 @@ not be enclosed in { } or ( )."
    '("^[ \t]*\\.for[ \t].+[ \t]\\(in\\)\\>" 1 font-lock-keyword-face)))
 
 (defconst makefile-imake-font-lock-keywords
-  (append 
+  (append
    (makefile-make-font-lock-keywords
     makefile-var-use-regex
     makefile-statements
@@ -506,50 +516,51 @@ not be enclosed in { } or ( )."
    cpp-font-lock-keywords))
 
 
-(defconst makefile-font-lock-syntactic-keywords
-  ;; From sh-script.el.
-  ;; A `#' begins a comment in sh when it is unquoted and at the beginning
-  ;; of a word.  In the shell, words are separated by metacharacters.
-  ;; The list of special chars is taken from the single-unix spec of the
-  ;; shell command language (under `quoting') but with `$' removed.
-  '(("[^|&;<>()`\\\"' \t\n]\\(#+\\)" 1 "_")
-    ;; Change the syntax of a quoted newline so that it does not end a comment.
-    ("\\\\\n" 0 ".")))
+(defconst makefile-syntax-propertize-function
+  (syntax-propertize-rules
+   ;; From sh-script.el.
+   ;; A `#' begins a comment in sh when it is unquoted and at the beginning
+   ;; of a word.  In the shell, words are separated by metacharacters.
+   ;; The list of special chars is taken from the single-unix spec of the
+   ;; shell command language (under `quoting') but with `$' removed.
+   ("[^|&;<>()`\\\"' \t\n]\\(#+\\)" (1 "_"))
+   ;; Change the syntax of a quoted newline so that it does not end a comment.
+   ("\\\\\n" (0 "."))))
 
 (defvar makefile-imenu-generic-expression
   `(("Dependencies" makefile-previous-dependency 1)
     ("Macro Assignment" ,makefile-macroassign-regex 1))
   "Imenu generic expression for Makefile mode.  See `imenu-generic-expression'.")
 
-;;; ------------------------------------------------------------
-;;; The following configurable variables are used in the
-;;; up-to-date overview .
-;;; The standard configuration assumes that your `make' program
-;;; can be run in question/query mode using the `-q' option, this
-;;; means that the command
-;;;
-;;;    make -q foo
-;;;
-;;; should return an exit status of zero if the target `foo' is
-;;; up to date and a nonzero exit status otherwise.
-;;; Many makes can do this although the docs/manpages do not mention
-;;; it. Try it with your favourite one.  GNU make, System V make, and
-;;; Dennis Vadura's DMake have no problems.
-;;; Set the variable `makefile-brave-make' to the name of the
-;;; make utility that does this on your system.
-;;; To understand what this is all about see the function definition
-;;; of `makefile-query-by-make-minus-q' .
-;;; ------------------------------------------------------------
+;; ------------------------------------------------------------
+;; The following configurable variables are used in the
+;; up-to-date overview .
+;; The standard configuration assumes that your `make' program
+;; can be run in question/query mode using the `-q' option, this
+;; means that the command
+;;
+;;    make -q foo
+;;
+;; should return an exit status of zero if the target `foo' is
+;; up to date and a nonzero exit status otherwise.
+;; Many makes can do this although the docs/manpages do not mention
+;; it. Try it with your favorite one.  GNU make, System V make, and
+;; Dennis Vadura's DMake have no problems.
+;; Set the variable `makefile-brave-make' to the name of the
+;; make utility that does this on your system.
+;; To understand what this is all about see the function definition
+;; of `makefile-query-by-make-minus-q' .
+;; ------------------------------------------------------------
 
 (defcustom makefile-brave-make "make"
-  "*How to invoke make, for `makefile-query-targets'.
+  "How to invoke make, for `makefile-query-targets'.
 This should identify a `make' command that can handle the `-q' option."
   :type 'string
   :group 'makefile)
 
 (defcustom makefile-query-one-target-method-function
   'makefile-query-by-make-minus-q
-  "*Function to call to determine whether a make target is up to date.
+  "Function to call to determine whether a make target is up to date.
 The function must satisfy this calling convention:
 
 * As its first argument, it must accept the name of the target to
@@ -568,17 +579,14 @@ The function must satisfy this calling convention:
   'makefile-query-one-target-method-function)
 
 (defcustom makefile-up-to-date-buffer-name "*Makefile Up-to-date overview*"
-  "*Name of the Up-to-date overview buffer."
+  "Name of the Up-to-date overview buffer."
   :type 'string
   :group 'makefile)
 
 ;;; --- end of up-to-date-overview configuration ------------------
 
-(defvar makefile-mode-abbrev-table nil
+(define-abbrev-table 'makefile-mode-abbrev-table ()
   "Abbrev table in use in Makefile buffers.")
-(if makefile-mode-abbrev-table
-    ()
-  (define-abbrev-table 'makefile-mode-abbrev-table ()))
 
 (defvar makefile-mode-map
   (let ((map (make-sparse-keymap))
@@ -606,7 +614,7 @@ The function must satisfy this calling convention:
     (define-key map "\C-c\C-m\C-p" 'makefile-makepp-mode)
     (define-key map "\M-p"     'makefile-previous-dependency)
     (define-key map "\M-n"     'makefile-next-dependency)
-    (define-key map "\e\t"     'makefile-complete)
+    (define-key map "\e\t"     'completion-at-point)
 
     ;; Make menus.
     (define-key map [menu-bar makefile-mode]
@@ -657,7 +665,7 @@ The function must satisfy this calling convention:
       '(menu-item "Find Targets and Macros" makefile-pickup-everything
                  :help "Notice names of all macros and targets in Makefile"))
     (define-key map [menu-bar makefile-mode complete]
-      '(menu-item "Complete Target or Macro" makefile-complete
+      '(menu-item "Complete Target or Macro" completion-at-point
                  :help "Perform completion on Makefile construct preceding point"))
     (define-key map [menu-bar makefile-mode backslash]
       '(menu-item "Backslash Region" makefile-backslash-region
@@ -706,15 +714,13 @@ The function must satisfy this calling convention:
     (modify-syntax-entry ?\n ">     " st)
     st))
 
-(defvar makefile-imake-mode-syntax-table (copy-syntax-table
-                                         makefile-mode-syntax-table))
-(if makefile-imake-mode-syntax-table
-    ()
-  (modify-syntax-entry ?/  ". 14" makefile-imake-mode-syntax-table)
-  (modify-syntax-entry ?*  ". 23" makefile-imake-mode-syntax-table)
-  (modify-syntax-entry ?#  "'" makefile-imake-mode-syntax-table)
-  (modify-syntax-entry ?\n ". b" makefile-imake-mode-syntax-table))
-
+(defvar makefile-imake-mode-syntax-table
+  (let ((st (make-syntax-table makefile-mode-syntax-table)))
+    (modify-syntax-entry ?/  ". 14" st)
+    (modify-syntax-entry ?*  ". 23" st)
+    (modify-syntax-entry ?#  "'"    st)
+    (modify-syntax-entry ?\n ". b"  st)
+    st))
 
 ;;; ------------------------------------------------------------
 ;;; Internal variables.
@@ -774,7 +780,7 @@ The function must satisfy this calling convention:
 ;;; ------------------------------------------------------------
 
 ;;;###autoload
-(defun makefile-mode ()
+(define-derived-mode makefile-mode prog-mode "Makefile"
   "Major mode for editing standard Makefiles.
 
 If you are editing a file for a different make, try one of the
@@ -858,9 +864,8 @@ Makefile mode can be configured by modifying the following variables:
    List of special targets. You will be offered to complete
    on one of those in the minibuffer whenever you enter a `.'.
    at the beginning of a line in Makefile mode."
-
-  (interactive)
-  (kill-all-local-variables)
+  (add-hook 'completion-at-point-functions
+            #'makefile-completions-at-point nil t)
   (add-hook 'write-file-functions
            'makefile-warn-suspicious-lines nil t)
   (add-hook 'write-file-functions
@@ -874,59 +879,45 @@ Makefile mode can be configured by modifying the following variables:
   (make-local-variable 'makefile-need-macro-pickup)
 
   ;; Font lock.
-  (make-local-variable 'font-lock-defaults)
-  (setq font-lock-defaults
-       ;; SYNTAX-BEGIN set to backward-paragraph to avoid slow-down
-       ;; near the end of a large buffer, due to parse-partial-sexp's
-       ;; trying to parse all the way till the beginning of buffer.
-       '(makefile-font-lock-keywords
-         nil nil
-         ((?$ . "."))
-         backward-paragraph
-         (font-lock-syntactic-keywords
-          . makefile-font-lock-syntactic-keywords)))
+  (setq-local font-lock-defaults
+             ;; Set SYNTAX-BEGIN to backward-paragraph to avoid
+             ;; slow-down near the end of a large buffer, due to
+             ;; `parse-partial-sexp' trying to parse all the way till
+             ;; the beginning of buffer.
+             '(makefile-font-lock-keywords
+               nil nil
+               ((?$ . "."))
+               backward-paragraph))
+  (setq-local syntax-propertize-function
+             makefile-syntax-propertize-function)
 
   ;; Add-log.
-  (make-local-variable 'add-log-current-defun-function)
-  (setq add-log-current-defun-function 'makefile-add-log-defun)
+  (setq-local add-log-current-defun-function
+             'makefile-add-log-defun)
 
   ;; Imenu.
-  (make-local-variable 'imenu-generic-expression)
-  (setq imenu-generic-expression makefile-imenu-generic-expression)
+  (setq-local imenu-generic-expression
+             makefile-imenu-generic-expression)
 
   ;; Dabbrev.
-  (make-local-variable 'dabbrev-abbrev-skip-leading-regexp)
-  (setq dabbrev-abbrev-skip-leading-regexp "\\$")
+  (setq-local dabbrev-abbrev-skip-leading-regexp "\\$")
 
   ;; Other abbrevs.
   (setq local-abbrev-table makefile-mode-abbrev-table)
 
   ;; Filling.
-  (make-local-variable 'fill-paragraph-function)
-  (setq fill-paragraph-function 'makefile-fill-paragraph)
+  (setq-local fill-paragraph-function 'makefile-fill-paragraph)
 
   ;; Comment stuff.
-  (make-local-variable 'comment-start)
-  (setq comment-start "#")
-  (make-local-variable 'comment-end)
-  (setq comment-end "")
-  (make-local-variable 'comment-start-skip)
-  (setq comment-start-skip "#+[ \t]*")
+  (setq-local comment-start "#")
+  (setq-local comment-end "")
+  (setq-local comment-start-skip "#+[ \t]*")
 
   ;; Make sure TAB really inserts \t.
-  (set (make-local-variable 'indent-line-function) 'indent-to-left-margin)
-
-  ;; become the current major mode
-  (setq major-mode 'makefile-mode)
-  (setq mode-name "Makefile")
-
-  ;; Activate keymap and syntax table.
-  (use-local-map makefile-mode-map)
-  (set-syntax-table makefile-mode-syntax-table)
+  (setq-local indent-line-function 'indent-to-left-margin)
 
   ;; Real TABs are important in makefiles
-  (setq indent-tabs-mode t)
-  (run-mode-hooks 'makefile-mode-hook))
+  (setq indent-tabs-mode t))
 
 ;; These should do more than just differentiate font-lock.
 ;;;###autoload
@@ -944,8 +935,7 @@ Makefile mode can be configured by modifying the following variables:
 ;;;###autoload
 (define-derived-mode makefile-makepp-mode makefile-mode "Makeppfile"
   "An adapted `makefile-mode' that knows about makepp."
-  (set (make-local-variable 'makefile-rule-action-regex)
-       makefile-makepp-rule-action-regex)
+  (setq-local makefile-rule-action-regex makefile-makepp-rule-action-regex)
   (setq font-lock-defaults
        `(makefile-makepp-font-lock-keywords ,@(cdr font-lock-defaults))
        imenu-generic-expression
@@ -955,11 +945,9 @@ Makefile mode can be configured by modifying the following variables:
 ;;;###autoload
 (define-derived-mode makefile-bsdmake-mode makefile-mode "BSDmakefile"
   "An adapted `makefile-mode' that knows about BSD make."
-  (set (make-local-variable 'makefile-dependency-regex)
-       makefile-bsdmake-dependency-regex)
-  (set (make-local-variable 'makefile-dependency-skip) "^:!")
-  (set (make-local-variable 'makefile-rule-action-regex)
-       makefile-bsdmake-rule-action-regex)
+  (setq-local makefile-dependency-regex makefile-bsdmake-dependency-regex)
+  (setq-local makefile-dependency-skip "^:!")
+  (setq-local makefile-rule-action-regex makefile-bsdmake-rule-action-regex)
   (setq font-lock-defaults
        `(makefile-bsdmake-font-lock-keywords ,@(cdr font-lock-defaults))))
 
@@ -967,15 +955,9 @@ Makefile mode can be configured by modifying the following variables:
 (define-derived-mode makefile-imake-mode makefile-mode "Imakefile"
   "An adapted `makefile-mode' that knows about imake."
   :syntax-table makefile-imake-mode-syntax-table
-  (let ((base `(makefile-imake-font-lock-keywords ,@(cdr font-lock-defaults)))
-       new)
-    ;; Remove `font-lock-syntactic-keywords' entry from font-lock-defaults.
-    (mapc (lambda (elt)
-           (unless (and (consp elt)
-                        (eq (car elt) 'font-lock-syntactic-keywords))
-             (setq new (cons elt new))))
-         base)
-    (setq font-lock-defaults (nreverse new))))
+  (setq-local syntax-propertize-function nil)
+  (setq font-lock-defaults
+        `(makefile-imake-font-lock-keywords ,@(cdr font-lock-defaults))))
 
 \f
 
@@ -1177,15 +1159,10 @@ and adds all qualifying names to the list of known targets."
 
 ;;; Completion.
 
-(defun makefile-complete ()
-  "Perform completion on Makefile construct preceding point.
-Can complete variable and target names.
-The context determines which are considered."
-  (interactive)
+(defun makefile-completions-at-point ()
   (let* ((beg (save-excursion
                (skip-chars-backward "^$(){}:#= \t\n")
                (point)))
-        (try (buffer-substring beg (point)))
         (paren nil)
         (do-macros
           (save-excursion
@@ -1199,22 +1176,26 @@ The context determines which are considered."
                ;; Preceding "$(" or "${" means macros only.
                ((and (memq pc '(?\{ ?\())
                      (progn
-                       (setq paren (if (eq paren ?\{) ?\} ?\)))
+                       (setq paren (if (eq pc ?\{) ?\} ?\)))
                        (backward-char)
                        (= (preceding-char) ?$)))
                 t)))))
-
-         (table (apply-partially 'completion-table-with-terminator
-                                   (cond
-                                    (do-macros (or paren ""))
-                                    ((save-excursion (goto-char beg) (bolp)) ":")
-                                    (t " "))
-                                   (append (if do-macros
-                                               '()
-                                             makefile-target-table)
-                                           makefile-macro-table))))
-    (completion-in-region beg (point) table)))
-
+         (suffix (cond
+                  (do-macros (if paren (string paren)))
+                  ((save-excursion (goto-char beg) (bolp)) ":")
+                  (t " "))))
+    (list beg (point)
+          (append (if do-macros '() makefile-target-table)
+                  makefile-macro-table)
+          :exit-function
+          (if suffix
+              (lambda (_s finished)
+                (when (memq finished '(sole finished))
+                  (if (looking-at (regexp-quote suffix))
+                      (goto-char (match-end 0))
+                    (insert suffix))))))))
+
+(define-obsolete-function-alias 'makefile-complete 'completion-at-point "24.1")
 \f
 
 ;; Backslashification.  Stolen from cc-mode.el.
@@ -1232,26 +1213,23 @@ definition and conveniently use this command."
   (save-excursion
     (goto-char from)
     (let ((column makefile-backslash-column)
-          (endmark (make-marker)))
-      (move-marker endmark to)
+          (endmark (copy-marker to)))
       ;; Compute the smallest column number past the ends of all the lines.
-      (if makefile-backslash-align
-         (progn
-           (if (not delete-flag)
-               (while (< (point) to)
-                 (end-of-line)
-                 (if (= (preceding-char) ?\\)
-                     (progn (forward-char -1)
-                            (skip-chars-backward " \t")))
-                 (setq column (max column (1+ (current-column))))
-                 (forward-line 1)))
-           ;; Adjust upward to a tab column, if that doesn't push
-           ;; past the margin.
-           (if (> (% column tab-width) 0)
-               (let ((adjusted (* (/ (+ column tab-width -1) tab-width)
-                                  tab-width)))
-                 (if (< adjusted (window-width))
-                     (setq column adjusted))))))
+      (when (and makefile-backslash-align (not delete-flag))
+        (while (< (point) to)
+          (end-of-line)
+          (if (= (preceding-char) ?\\)
+              (progn (forward-char -1)
+                     (skip-chars-backward " \t")))
+          (setq column (max column (1+ (current-column))))
+         (forward-line 1))
+        ;; Adjust upward to a tab column, if that doesn't push
+        ;; past the margin.
+        (if (> (% column tab-width) 0)
+            (let ((adjusted (* (/ (+ column tab-width -1) tab-width)
+                               tab-width)))
+              (if (< adjusted (window-width))
+                 (setq column adjusted)))))
       ;; Don't modify blank lines at start of region.
       (goto-char from)
       (while (and (< (point) endmark) (eolp))
@@ -1292,9 +1270,9 @@ definition and conveniently use this command."
 
 ;; Filling
 
-(defun makefile-fill-paragraph (arg)
-  ;; Fill comments, backslashed lines, and variable definitions
-  ;; specially.
+(defun makefile-fill-paragraph (_justify)
+  "Function used for `fill-paragraph-function' in Makefile mode.
+Fill comments, backslashed lines, and variable definitions specially."
   (save-excursion
     (beginning-of-line)
     (cond
@@ -1307,15 +1285,17 @@ definition and conveniently use this command."
      ((or (eq (char-before (line-end-position 1)) ?\\)
          (eq (char-before (line-end-position 0)) ?\\))
       ;; A backslash region.  Find beginning and end, remove
-      ;; backslashes, fill, and then reapply backslahes.
+      ;; backslashes, fill, and then reapply backslashes.
       (end-of-line)
       (let ((beginning
             (save-excursion
               (end-of-line 0)
               (while (= (preceding-char) ?\\)
                 (end-of-line 0))
-              (forward-char)
-              (point)))
+              ;; Maybe we hit bobp, in which case we are not at EOL.
+              (if (eolp)
+                  (1+ (point))
+                 (point))))
            (end
             (save-excursion
               (while (= (preceding-char) ?\\)
@@ -1324,6 +1304,12 @@ definition and conveniently use this command."
        (save-restriction
          (narrow-to-region beginning end)
          (makefile-backslash-region (point-min) (point-max) t)
+         ;; Backslashed newlines are marked as punctuation, so when
+         ;; fill-delete-newlines turns the LF into SPC, we end up with spaces
+         ;; which back-to-indentation (called via fill-newline ->
+         ;; fill-indent-to-left-margin -> indent-line-to) thinks are real code
+         ;; (bug#13179).
+         (remove-text-properties (point-min) (point-max) '(syntax-table))
          (let ((fill-paragraph-function nil)
                 ;; Adjust fill-column to allow space for the backslash.
                 (fill-column (- fill-column 1)))
@@ -1510,7 +1496,6 @@ Insertion takes place at point."
   (setq buffer-read-only t))
 
 (defun makefile-browse (targets macros)
-  (interactive)
   (if (zerop (+ (length targets) (length macros)))
       (progn
        (beep)
@@ -1519,8 +1504,8 @@ Insertion takes place at point."
        (pop-to-buffer browser-buffer)
        (makefile-browser-fill targets macros)
        (shrink-window-if-larger-than-buffer)
-       (set (make-local-variable 'makefile-browser-selection-vector)
-            (make-vector (+ (length targets) (length macros)) nil))
+       (setq-local makefile-browser-selection-vector
+                   (make-vector (+ (length targets) (length macros)) nil))
        (makefile-browser-start-interaction))))
 
 (defun makefile-switch-to-browser ()
@@ -1710,15 +1695,17 @@ Then prompts for all required parameters."
 ;;; Utility functions
 ;;; ------------------------------------------------------------
 
-(defun makefile-match-function-end (end)
+(defun makefile-match-function-end (_end)
   "To be called as an anchored matcher by font-lock.
 The anchor must have matched the opening parens in the first group."
   (let ((s (match-string-no-properties 1)))
     ;; FIXME forward-sexp or somesuch would be better?
     (if (setq s (cond ((string= s "(") ")")
                      ((string= s "{") "}")
+                     ((string= s "[") "]")
                      ((string= s "((") "))")
-                     ((string= s "{{") "}}")))
+                     ((string= s "{{") "}}")
+                     ((string= s "[[") "]]")))
        (re-search-forward (concat "\\(.*\\)[ \t]*" s) (line-end-position) t))))
 
 (defun makefile-match-dependency (bound)
@@ -1868,5 +1855,4 @@ If it isn't in one, return nil."
 
 (provide 'make-mode)
 
-;; arch-tag: bd23545a-de91-44fb-b1b2-feafbb2635a0
 ;;; make-mode.el ends here