Skip to content

ceblan/emacs-run-command

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MELPA

run-command

Leave Emacs less. Relocate those frequent shell commands to configurable, dynamic, context-sensitive lists, and run them at a fraction of the keystrokes via Helm or Ivy.

Table of Contents:

Demo

The screencast below shows using run-command to 1) create a project from a boilerplate, 2) execute a file on every save, and 3) start the test runner.

demo

Installing

Available from MELPA.

Configuring

By default, commands are run in compilation-mode. See Lightweight external command integration in Emacs via compilation mode for some notes on how to make the most of compilation-mode.

Alternatively (and experimentally), commands can be run in term-mode plus compilation-minor-mode, especially useful for commands with rich output such as colors, progress bars, and screen refreshes, while preserving compilation-mode functionality. Set run-command-run-method to term and please comment on issue #2 if you find issues.

The auto-completion framework is automatically detected. It can be set manually by customizing run-command-completion-method.

Quickstart

  1. Add a "command recipe" to your init file, for example:
(defun run-command-recipe-local ()
  (list
   (list :command-name "say-hello"
         :command-line "echo Hello, World!")
   (list :command-name "serve-http-dir"
         :command-line "python3 -m http.server 8000")
   (when (equal (buffer-name) "README.md")
     ;; uses https://github.com/joeyespo/grip
     (list :command-name "preview-github-readme"
           :command-line "grip --browser --norefresh"))))
  1. Customize run-command-recipes and add run-command-recipe-local to the list.

  2. Type M-x run-command RET.

Read more about configuration, invocation, and how to add commands, or check out some recipe examples.

Invoking

Type M-x run-command or bind run-command to a key:

(global-set-key (kbd "C-c c") 'run-command)

Or:

(use-package run-command
  :bind ("C-c c" . run-command)

When using Helm, you can edit a command before running it by typing C-u RET instead of RET. (See issue #1 if you can help bring that to Ivy.)

Tutorial: adding commands

Readable command names

To provide a more user-friendly name for a command, use the :display property:

(defun run-command-recipe-local ()
  (list
   (list :command-name "serve-http-dir"
         :command-line "python3 -m http.server 8000"
         :display "Serve directory over HTTP port 8000")))

Specifying the working directory

A command runs by default in the current buffer's directory. You can make it run in a different directory by setting :working-dir.

For example, you want to serve the current directory via HTTP, unless you're visiting a file that is somewhere below a public_html directory, in which case you want to serve public_html instead:

(defun run-command-recipe-local ()
  (list
   (list :command-name "serve-http-dir"
         :command-line "python3 -m http.server 8000"
         :display "Serve directory over HTTP port 8000"
         :working-dir (let ((project-dir
                             (locate-dominating-file default-directory "public_html")))
                        (if project-dir
                            (concat project-dir "public_html")
                          default-directory)))))

See the Hugo project recipe for a recipe that uses the project's directory for all commands.

Enabling and disabling depending on context

To disable a command in certain circumstances, make its recipe return nil in its place.

For example, you want to enable a command only when a buffer's file is executable:

(defun run-command-recipe-local ()
  (let* ((buffer-file (buffer-file-name))
         (executable-p (and buffer-file (file-executable-p buffer-file))))
    (list
     (if executable-p
         (list
          :command-name "run-buffer-file"
          :command-line buffer-file
          :display "Run this buffer's file")
       nil))))

See the executable file recipe for a variant that also re-runs the file on each save.

Generating commands on the fly

Recipes are plain old Lisp functions, so they generate commands based on e.g. project setup.

See the NPM project recipe, which uses a JavaScript's project package.json file to generate commands, and the Make project recipe, which does the same for Makefile projects.

About

Efficient and ergonomic external command invocation via Helm or Ivy.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Emacs Lisp 100.0%