Skip to content

Instantly share code, notes, and snippets.

@tototoshi
Created August 30, 2026 23:56
Show Gist options
  • Select an option

  • Save tototoshi/c250c392afe5c9edc5870ece55cf379b to your computer and use it in GitHub Desktop.

Select an option

Save tototoshi/c250c392afe5c9edc5870ece55cf379b to your computer and use it in GitHub Desktop.
Emacs make-process wrapper
;; -*- lexical-binding: t; -*-
(require 'cl-lib)
(require 'vertico)
(defvar *my/cmd-history-limit* 100)
(defvar *my/cmd-history* (make-hash-table :test 'equal))
(defun my/cmd (&rest args)
(let ((kill-buffer-after-process (plist-get args :kill-buffer))
(output (plist-get args :output))
(on-success (or (plist-get args :on-success) (lambda (output) nil)))
(buffer-lines-limit 9999))
(cl-labels ((setup-buffer (buffer)
(with-current-buffer buffer
(prefer-coding-system 'utf-8-dos))
buffer)
(apply-ansi-color (proc string)
(with-current-buffer (process-buffer proc)
(goto-char (point-max))
(let ((start (point-max)))
(insert string)
(delete-trailing-whitespace start (point-max))
(ansi-color-apply-on-region start (point-max))
(goto-char (point-max))
(when (> (line-number-at-pos) buffer-lines-limit)
(save-excursion
(goto-line (- (line-number-at-pos) buffer-lines-limit))
(delete-region (point-min) (point)))))))
(process-output-string (proc)
(with-current-buffer (process-buffer proc)
(buffer-string)))
(notify-finished (proc string)
(cond ((equal "finished\n" string)
(cond ((eq output 'string)
(let ((bs (process-output-string proc)))
(when kill-buffer-after-process (kill-buffer (process-buffer proc)))
(funcall on-success (message bs))))
((eq output 'buffer)
(funcall on-success (process-buffer proc)))))
(t (error string))))
(expand-command-name (command)
(if (string-match "\\.+/" (car command))
(cons (expand-file-name (car command)) (cdr command))
command))
(cmd-name (command)
(string-join command "-"))
(generate-history-hash-key (args)
(string-join (plist-get args :command) " "))
(add-command-to-history (args)
(puthash
(generate-history-hash-key args)
args
*my/cmd-history*)))
(let* ((default-directory (or (plist-get args :dir) default-directory))
(buffer (setup-buffer
(get-buffer-create (or (plist-get args :buffer) (generate-new-buffer-name "my/cmd")))))
(command (plist-get args :command))
(name (or (plist-get args :name) (cmd-name command)))
(p (make-process :name name
:buffer buffer
:filter (or (plist-get args :filter) #'apply-ansi-color)
:command (expand-command-name command)
:sentinel (or (plist-get args :sentinel) #'notify-finished))))
(add-command-to-history args)
(when (eq output 'buffer) (pop-to-buffer buffer))
p))))
(defun my/cmd-select ()
(interactive)
(vertico-mode)
(let* ((c (completing-read "Command: "
(cl-loop for k being the hash-key of *my/cmd-history*
collect k)))
(args (gethash c *my/cmd-history*)))
(when args
(apply #'my/cmd args))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment