branch: master commit b180abf2cb8149047245df8b35ac8ae2f9c5b9f0 Author: Alex Bennée <alex.ben...@linaro.org> Commit: Oleh Krehel <ohwoeo...@gmail.com>
counsel.el (counsel-compile): clean-up get-make-targets The original code called a pipeline of shell functions to get the list of PHONY targets. One of the consequence of this is we picked up a bunch of noise if the make crapped out with an error. To avoid this we bring all the text extraction into emacs with a temp buffer and only process it if make is happy. This is also a first step towards what we would need if we wanted to use counsel--async-command to gather stuff and update the targets dynamically. --- v2 - use bare form of (rx) for phony macro - tweak wording in comments - push/nconc/sort the results - revert de-hyphenating - let*->let Fixes #1972 --- counsel.el | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/counsel.el b/counsel.el index 27eeb1e..bbe6884 100644 --- a/counsel.el +++ b/counsel.el @@ -5196,32 +5196,48 @@ N in your system." "List of potential build subdirectory names to check for." :type '(repeat directory)) +(defvar counsel-compile-phony-pattern + (rx bol ".PHONY:" space (group (+ print)) eol) + "Regexp for extracting phony targets from Makefiles.") + ;; This is loosely based on the Bash Make completion code +(defun counsel-compile--probe-make-targets (dir) + "Return a list of Make targets for DIR. + +Return an empty list is Make exits with an error. This might +happen because some sort of configuration needs to be done first +or the source tree is pristine and being used for multiple build +trees." + (let ((default-directory dir) + (targets)) + (with-temp-buffer + ;; 0 = no-rebuild, -q & 1 needs rebuild, 2 error (for GNUMake at + ;; least) + (when (> 2 (call-process "make" nil t nil "-nqp")) + (goto-char (point-min)) + (while (re-search-forward counsel-compile-phony-pattern nil t) + (push (split-string (match-string-no-properties 1)) + targets)))) + (sort (apply #'nconc targets) 'string-lessp))) + (defun counsel--compile-get-make-targets (srcdir &optional blddir) "Return a list of Make targets for a given SRCDIR/BLDDIR combination. We search the Makefile for a list of phony targets which are -generally the top-level targets a Make system provides. +generally the top level targets a Make system provides. The resulting strings are tagged with properties that `counsel-compile-history' can use for filtering results." - (let* ((default-directory (or blddir srcdir)) - (fmt (format (propertize "make %s %%s" 'cmd t) - counsel-compile-make-args)) - (suffix (and blddir - (concat (propertize " in " 'face 'font-lock-warning-face) - (propertize blddir 'face 'dired-directory)))) - (props `(srcdir ,srcdir blddir ,default-directory))) + (let ((fmt (format (propertize "make %s %%s" 'cmd t) + counsel-compile-make-args)) + (suffix (and blddir + (concat (propertize " in " 'face 'font-lock-warning-face) + (propertize blddir 'face 'dired-directory)))) + (props `(srcdir ,srcdir blddir ,default-directory))) (mapcar (lambda (target) (setq target (concat (format fmt target) suffix)) (add-text-properties 0 (length target) props target) target) - (split-string (shell-command-to-string "\ -make -nqp |\ - grep -B 1 PHONY |\ - grep ':' |\ - cut -d ':' -f 1 |\ - sort") - "\n")))) + (counsel-compile--probe-make-targets (or blddir srcdir))))) (defun counsel-compile-get-make-invocation (&optional blddir) "Have a look in the root directory for any build control files.