;;; jao-shell.el --- shell utils -*- lexical-binding: t; -*- ;; Copyright (C) 2022, 2026 jao ;; Author: jao ;; Keywords: shell ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . (require 'term) ;;; term ;;;###autoload (defvar jao-use-vterm nil) ;;;###autoload (defvar jao-use-eat nil) (defvar-local jao-term--cmd nil) (defvar-local jao-term--cmd nil) (defun jao-term--find (cmd) (seq-find (lambda (b) (with-current-buffer b (and (derived-mode-p 'eat-mode 'term-mode 'vterm-mode) (string= (or jao-term--cmd "") cmd)))) (buffer-list))) (declare-function vterm nil) (declare-function vterm-mode nil) (defvar vterm-shell) (defvar vterm-kill-buffer-on-exit) (defun jao-exec-in-vterm (cmd bname &optional no-kill) (if (string-blank-p (or cmd "")) (vterm) (let ((vterm-shell cmd) (vterm-kill-buffer-on-exit (not no-kill)) (buff (generate-new-buffer bname))) (switch-to-buffer buff) (vterm-mode)))) ;;;###autoload (defun jao-exec-in-term (cmd &optional name no-kill) (interactive "SCommand") (require 'eat nil t) (cond ((and jao-use-vterm (fboundp 'jao-exec-in-vterm)) (jao-exec-in-vterm cmd name no-kill)) ((and jao-use-eat (fboundp 'eat)) (let ((eat-term-name "xterm-256color")) (with-current-buffer (eat cmd t) (setq-local jao-term--cmd cmd)))) (t (ansi-term "bash" name) (unless no-kill (set-process-sentinel (get-buffer-process (current-buffer)) (lambda (process event) (when (string= event "finished\n") (kill-buffer (process-buffer process)))))) (setq-local jao-term--cmd cmd) (term-send-string nil (format "%s%s\n" cmd (if no-kill "" ";exit")))))) ;;;###autoload (defmacro jao-def-exec-in-term (name cmd &rest prelude) `(defun ,(intern (format "jao-term-%s" name)) (&optional term) (interactive "P") ,@prelude (let ((jao-use-vterm (if term (not jao-use-vterm) jao-use-vterm))) (if-let* ((b (jao-term--find ,cmd))) (pop-to-buffer b) (jao-exec-in-term ,cmd ,(format "*%s*" name)))))) ;;; shell (defun jao-shell-cmd-lines (cmd &rest args) (let ((cmd (concat cmd " " (combine-and-quote-strings args)))) (split-string (shell-command-to-string cmd) "\n" t))) (defun jao-shell-string (cmd &rest args) (string-trim (or (car (apply #'jao-shell-cmd-lines cmd args)) ""))) (defun jao-shell-exec (command &optional wait) (interactive (list (read-shell-command "$ " (if current-prefix-arg (cons (concat " " (buffer-file-name)) 0) "")))) (if wait (call-process-shell-command command) (start-process-shell-command command nil command))) (defun jao-shell-exec* (command-or-wait &rest args) (let ((wait (and (not (stringp command-or-wait)) command-or-wait)) (args (if (stringp command-or-wait) (cons command-or-wait args) args))) (jao-shell-exec (combine-and-quote-strings args) wait))) (defun jao-shell-exec-p (command) (eq 0 (jao-shell-exec command t))) (defmacro jao-shell-def-exec (name &rest args) `(defun ,name (&rest other-args) (interactive) (start-process-shell-command ,(car args) "*jao-exec - console*" (string-join (append (list ,@args) other-args) " ")))) (defun jao-shell-output (cmd handler) (with-temp-buffer (call-process-shell-command cmd nil (current-buffer)) (goto-char (point-min)) (funcall handler))) (defun jao-shell-running-p (pr) (eq 0 (jao-shell-exec* t "pidof" pr))) (defun jao-shell-kill-p (pr) (eq 0 (jao-shell-exec* t "killall" pr))) (provide 'jao-shell) ;;; jao-shell.el ends here