From: Stephen Leake Date: Thu, 19 Sep 2019 00:42:30 +0000 (-0700) Subject: Enhance 'pcomplete/make' to complete on targets in included makefiles X-Git-Tag: emacs-27.0.90~1552 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=b478444099655f36f7b243e21e8f98051299ca8f;p=emacs.git Enhance 'pcomplete/make' to complete on targets in included makefiles * 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. --- diff --git a/etc/NEWS b/etc/NEWS index 87666740df6..c1487aa3215 100644 --- 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 --- diff --git a/lisp/pcmpl-gnu.el b/lisp/pcmpl-gnu.el index 391441bd79c..8ec5d93a68a 100644 --- a/lisp/pcmpl-gnu.el +++ b/lisp/pcmpl-gnu.el @@ -40,6 +40,13 @@ :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 @@ -108,8 +115,41 @@ "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 @@ -119,12 +159,7 @@ 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