about summary refs log tree commit diff
path: root/init/functions.el
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2018-05-01T14·02+0200
committerVincent Ambo <tazjin@gmail.com>2018-05-01T14·02+0200
commit456f692b88323575aacab137a1a016df88f76638 (patch)
treea792bc5fa0ec09d6edda0f41b073fb696c8a2a43 /init/functions.el
parent72a33b9156ac1b60703659c3ff204a501f67599f (diff)
feat(functions): Add ivy-run-external-command
Adds an ivy-based function akin to Helm's helm-run-external-command,
but without all the things I don't need/want.
Diffstat (limited to 'init/functions.el')
-rw-r--r--init/functions.el36
1 files changed, 36 insertions, 0 deletions
diff --git a/init/functions.el b/init/functions.el
index 726d40f25780..ed1cf9d2a472 100644
--- a/init/functions.el
+++ b/init/functions.el
@@ -134,4 +134,40 @@ Including indent-buffer, which should not be called automatically on save."
            (buffer-name)
            require-final-newline))
 
+;; Helm includes a command to run external applications, which does
+;; not seem to exist in ivy. This implementation uses some of the
+;; logic from Helm to provide similar functionality using ivy.
+(defun list-external-commands ()
+  "Creates a list of all external commands available on $PATH
+  while filtering NixOS wrappers."
+  (cl-loop
+   for dir in (split-string (getenv "PATH") path-separator)
+   when (and (file-exists-p dir) (file-accessible-directory-p dir))
+   for lsdir = (cl-loop for i in (directory-files dir t)
+                        for bn = (file-name-nondirectory i)
+                        when (and (not (s-contains? "-wrapped" i))
+                                  (not (member bn completions))
+                                  (not (file-directory-p i))
+                                  (file-executable-p i))
+                        collect bn)
+   append lsdir into completions
+   finally return (sort completions 'string-lessp)))
+
+(defun ivy-run-external-command ()
+  "Prompts the user with a list of all installed applications and
+  lets them select one to launch."
+
+  (interactive)
+  (let ((external-commands-list (list-external-commands)))
+    (ivy-read "Command:" external-commands-list
+              :require-match t
+              :history 'external-commands-history
+              :action (lambda (cmd)
+                        (message "Starting %s..." cmd)
+                        (set-process-sentinel
+                         (start-process-shell-command cmd nil cmd)
+                         (lambda (process event)
+                           (when (string= event "finished\n")
+                             (message "%s process finished." process))))))))
+
 (provide 'functions)