Skip to content

Commit

Permalink
[Fix #1044] Prefer call-process to shell-command-to-string
Browse files Browse the repository at this point in the history
This change makes it so that a direct `call-process` invocation is used
when it is possible to determine what binary should be used for the
command. This avoids the cost of shell startup time that is incurred
when `shell-command-to-string` is invoked instead.
  • Loading branch information
colonelpanic8 committed Aug 16, 2016
1 parent 8082637 commit 8490928
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
* [#576](https://github.com/bbatsov/projectile/issues/576): `projectile-replace` stomps regular expressions.
* [#957](https://github.com/bbatsov/projectile/pull/957): When opening a specified file from the terminal, do not error inside of `projectile-cache-current-file`.
* [#984](https://github.com/bbatsov/projectile/pull/984): Error when a project is a symlink that changes target.
* [#1044](https://github.com/bbatsov/projectile/issues/1044): Replace `shell-command-to-string` invocations with `call-process` invocations where possible to avoid shell startup cost.

## 0.13.0 (2015-10-21)

Expand Down
3 changes: 2 additions & 1 deletion Cask
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
(development
(depends-on "noflet")
(depends-on "helm")
(depends-on "ag"))
(depends-on "ag")
(depends-on "el-mock"))
24 changes: 19 additions & 5 deletions projectile.el
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@
;;
;;; Code:

(require 'thingatpt)
(require 'dash)
(require 'ibuffer)
(require 'ibuf-ext)
(require 'compile)
(require 'dash)
(require 'eshell)
(require 'grep)
(require 'ibuf-ext)
(require 'ibuffer)
(require 'thingatpt)

(eval-when-compile
(defvar ag-ignore-list)
Expand Down Expand Up @@ -1018,9 +1019,22 @@ they are excluded from the results of this function."
(let ((cmd (projectile-get-ext-ignored-command)))
(projectile-files-via-ext-command cmd)))

(defun projectile-call-process-to-string (program &rest args)
(with-temp-buffer
(apply 'call-process program nil (current-buffer) nil args)
(buffer-string)))

(defun projectile-shell-command-to-string (command)
(cl-destructuring-bind
(the-command . args) (split-string command " ")
(let ((binary-path (eshell-search-path the-command)))
(if binary-path
(apply 'projectile-call-process-to-string binary-path args)
(shell-command-to-string command)))))

(defun projectile-files-via-ext-command (command)
"Get a list of relative file names in the project root by executing COMMAND."
(split-string (shell-command-to-string command) "\0" t))
(split-string (projectile-shell-command-to-string command) "\0" t))

(defun projectile-index-directory (directory patterns progress-reporter)
"Index DIRECTORY taking into account PATTERNS.
Expand Down
22 changes: 21 additions & 1 deletion test/projectile-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@
"include2/test1.service.spec.js"
"include1/test2.js"
"include2/test2.js")))

(should (equal '("include1/test1.h" "include2/test1.h")
(projectile-get-other-files "src/test1.c" source-tree)))
(should (equal '("include1/test1.h" "include2/test1.h" "include1/test1.hpp")
Expand Down Expand Up @@ -719,6 +719,26 @@
(should (equal (list (expand-file-name "vendor/client-submodule/" project))
(projectile-get-all-sub-projects project)))))))

(ert-deftest projectile-test-projectile-shell-command-to-string-fallback ()
(let ((command "command arg1 arg2")
(command-path "/path/to/command")
shell-command-args call-process-args)
(noflet ((shell-command-to-string (&rest args)
(setq shell-command-args args))
(call-process-called (&rest args)
(setq call-process-args args)))
(noflet ((eshell-search-path (_command) nil))
(projectile-files-via-ext-command command)
(should (equal shell-command-args command))
(should (equal call-process-args nil)))
(setq shell-command-args nil
call-process-args nil)
(noflet ((eshell-search-path (_command-name) command-path))
(projectile-files-via-ext-command command)
(should (equal shell-command-args nil))
(should (equal call-process-args
(cons command-path (cdr (split-string command " ")))))))))

;; Local Variables:
;; indent-tabs-mode: nil
;; End:

0 comments on commit 8490928

Please sign in to comment.