]> git.eshelyaron.com Git - emacs.git/commitdiff
Enhance 'pcomplete/make' to complete on targets in included makefiles
authorStephen Leake <stephen_leake@stephe-leake.org>
Thu, 19 Sep 2019 00:42:30 +0000 (17:42 -0700)
committerStephen Leake <stephen_leake@stephe-leake.org>
Thu, 19 Sep 2019 00:42:30 +0000 (17:42 -0700)
* lisp/pcmpl-gnu.el (pcmpl-gnu-makefile-includes): New.
(pcmpl-gnu-make-targets): New, factored out of pcmpl-gnu-make-all-targets.
(pcmpl-gnu-make-includes): New.
(pcmpl-gnu-make-all-targets): Use new functions.

etc/NEWS
lisp/pcmpl-gnu.el

index 87666740df663d95dee20d24bb2eaab725818b60..c1487aa32152ee32686a0299b3892ff8193eb7ca 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1456,6 +1456,11 @@ available for output of asynchronous shell commands.
 *** The function 'pcomplete-uniquify-list' has been renamed from
 'pcomplete-uniqify-list'.
 
+---
+*** 'pcomplete/make' now completes on targets in included files, recursively.
+To recover the previous behavior, set new user option
+`pcmpl-gnu-makefile-includes' to nil.
+
 ** Auth-source
 
 ---
index 391441bd79c5bc1a373d88cbee8c8cea107c8091..8ec5d93a68a1d5f8f2e334a24d7d4e8ef98f99a1 100644 (file)
   :type '(repeat regexp)
   :group 'pcmpl-gnu)
 
+(defcustom pcmpl-gnu-makefile-includes t
+  "If non-nil, `pcomplete/make' completes on targets in included files."
+  :type 'boolean
+  :group 'pcmpl-gnu
+  :version 27.1
+  :safe 'booleanp)
+
 ;; Functions:
 
 ;;;###autoload
   "Return a list of possible makefile names."
   (pcomplete-entries (mapconcat 'identity pcmpl-gnu-makefile-regexps "\\|")))
 
+(defun pcmpl-gnu-make-targets (targets)
+  "Add to TARGETS the list of makefile targets in the current buffer.
+Return the new list."
+  (goto-char (point-min))
+  (while (re-search-forward
+         "^\\s-*\\([^\n#%.$][^:=\n]*\\)\\s-*:[^=]" nil t)
+    (setq targets (nconc (split-string (match-string-no-properties 1))
+                         targets)))
+  targets)
+
+(defun pcmpl-gnu-make-includes ()
+  "Return a list of all included file names in the current buffer."
+  (let (filenames)
+    (goto-char (point-min))
+    (while (search-forward-regexp "^include +\\(.*\\)$" nil t)
+      (push (match-string-no-properties 1) filenames))
+    filenames))
+
+(defun pcmpl-gnu-make-all-targets (makefile targets)
+  "Add to TARGETS the list of target names in MAKEFILE and files it includes.
+Return the new list."
+  (with-temp-buffer
+    (with-demoted-errors                       ;Could be a directory or something.
+        (insert-file-contents makefile))
+
+    (let ((filenames (when pcmpl-gnu-makefile-includes (pcmpl-gnu-make-includes))))
+      (setq targets (pcmpl-gnu-make-targets targets))
+      (dolist (file filenames)
+        (when (file-readable-p file)
+         (setq targets (pcmpl-gnu-make-all-targets file targets))))
+      ))
+  targets)
+
 (defun pcmpl-gnu-make-rule-names ()
-  "Return a list of possible make rule names in MAKEFILE."
+  "Return a list of possible make targets in a makefile in the current directory."
   (let* ((minus-f (member "-f" pcomplete-args))
         (makefile (or (cadr minus-f)
                       (cond
         rules)
     (if (not (file-readable-p makefile))
        (unless minus-f (list "-f"))
-      (with-temp-buffer
-       (ignore-errors                  ;Could be a directory or something.
-         (insert-file-contents makefile))
-       (while (re-search-forward
-               (concat "^\\s-*\\([^\n#%.$][^:=\n]*\\)\\s-*:[^=]") nil t)
-         (setq rules (append (split-string (match-string 1)) rules))))
+      (setq rules (pcmpl-gnu-make-all-targets makefile rules))
       (pcomplete-uniquify-list rules))))
 
 (defcustom pcmpl-gnu-tarfile-regexp