summaryrefslogtreecommitdiffhomepage
path: root/lib/eos/jao-shell.el
blob: 8745492f9f73aedbe3d5de3712922767e36aa144 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
;;; jao-shell.el --- shell utils                     -*- lexical-binding: t; -*-

;; Copyright (C) 2022, 2026  jao

;; Author: jao <mail@jao.io>
;; 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 <https://www.gnu.org/licenses/>.

(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