Add :term shell module
This commit is contained in:
parent
b57dccf825
commit
4ebd3fad7f
5 changed files with 113 additions and 0 deletions
|
@ -64,6 +64,7 @@
|
||||||
|
|
||||||
:term
|
:term
|
||||||
;;eshell ; a consistent, cross-platform shell (WIP)
|
;;eshell ; a consistent, cross-platform shell (WIP)
|
||||||
|
;;shell ; a terminal REPL for Emacs
|
||||||
;;term ; terminals in Emacs
|
;;term ; terminals in Emacs
|
||||||
;;vterm ; another terminals in Emacs
|
;;vterm ; another terminals in Emacs
|
||||||
|
|
||||||
|
|
99
modules/term/shell/autoload.el
Normal file
99
modules/term/shell/autoload.el
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
;;; term/shell/autoload.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(defun +shell-idle-p (buf)
|
||||||
|
"Return t if the shell in BUF is not running something.
|
||||||
|
When available, use process hierarchy information via pstree for
|
||||||
|
local shells. Otherwise, we ask comint if the point is after a
|
||||||
|
prompt."
|
||||||
|
(with-current-buffer buf
|
||||||
|
(let ((comint-says-idle (and
|
||||||
|
(> (point) 1) ;; if point > 1
|
||||||
|
;; see if previous char has the prompt face
|
||||||
|
(equal '(comint-highlight-prompt)
|
||||||
|
(get-text-property
|
||||||
|
(- (point) 1) 'font-lock-face)))))
|
||||||
|
(if (file-remote-p default-directory)
|
||||||
|
;; for remote shells we have to rely on comint
|
||||||
|
comint-says-idle
|
||||||
|
;; for local shells, we can potentially do better using pgrep
|
||||||
|
(condition-case nil
|
||||||
|
(case (call-process ;; look at the exit code of pgrep -P <pid>
|
||||||
|
"pgrep" nil nil nil "-P"
|
||||||
|
(number-to-string (process-id (get-buffer-process buf))))
|
||||||
|
(0 nil) ;; child procxesses found, not idle
|
||||||
|
(1 t) ;; not running any child processes, it's idle
|
||||||
|
(t comint-says-idle)) ;; anything else, fall back on comint.
|
||||||
|
(error comint-says-idle)))))) ;; comint fallback if execution failed
|
||||||
|
|
||||||
|
(defun +shell-unused-buffer ()
|
||||||
|
"TODO"
|
||||||
|
(or (cl-find-if #'+shell-idle-p (doom-buffers-in-mode 'shell-mode))
|
||||||
|
(generate-new-buffer "*doom:shell*")))
|
||||||
|
|
||||||
|
(defun +shell-tramp-hosts ()
|
||||||
|
"Ask tramp for a list of hosts that we can reach through ssh."
|
||||||
|
(cl-reduce #'append
|
||||||
|
(mapcar (lambda (x)
|
||||||
|
(delq nil (mapcar #'cadr (apply (car x) (cdr x)))))
|
||||||
|
(tramp-get-completion-function "scp"))))
|
||||||
|
|
||||||
|
(defun +shell--sentinel (process _event)
|
||||||
|
(when (memq (process-status process) '(exit stop))
|
||||||
|
(kill-buffer (process-buffer process))))
|
||||||
|
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +shell/toggle (&optional command)
|
||||||
|
"Toggle a persistent terminal popup window.
|
||||||
|
|
||||||
|
If popup is visible but unselected, selected it.
|
||||||
|
If popup is focused, kill it."
|
||||||
|
(interactive)
|
||||||
|
(let* ((buffer-name
|
||||||
|
(get-buffer-create
|
||||||
|
(format "*doom:shell-popup:%s*"
|
||||||
|
(if (bound-and-true-p persp-mode)
|
||||||
|
(safe-persp-name (get-current-persp))
|
||||||
|
"main")))))
|
||||||
|
(if-let (win (get-buffer-window buffer))
|
||||||
|
(if (eq (selected-window) win)
|
||||||
|
(let (confirm-kill-processes)
|
||||||
|
(set-process-query-on-exit-flag (get-buffer-process buffer) nil)
|
||||||
|
(delete-window win)
|
||||||
|
(ignore-errors (kill-buffer buffer)))
|
||||||
|
(select-window win)
|
||||||
|
(when (bound-and-true-p evil-local-mode)
|
||||||
|
(evil-change-to-initial-state))
|
||||||
|
(goto-char (point-max)))
|
||||||
|
(with-current-buffer (pop-to-buffer buffer)
|
||||||
|
(if (not (eq major-mode 'shell-mode))
|
||||||
|
(shell buffer)
|
||||||
|
(erase-buffer)
|
||||||
|
(cd dir))
|
||||||
|
(let ((process (get-buffer-process (current-buffer))))
|
||||||
|
(set-process-sentinel process #'+shell--sentinel)
|
||||||
|
(when command
|
||||||
|
(comint-send-string process command)))))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun +shell/here (&optional command)
|
||||||
|
"Open a terminal buffer in the current window.
|
||||||
|
|
||||||
|
If already in a shell buffer, clear it and cd into the current directory."
|
||||||
|
(interactive)
|
||||||
|
(let ((buffer (+shell-unused-buffer))
|
||||||
|
(dir default-directory))
|
||||||
|
(with-current-buffer (switch-to-buffer buffer)
|
||||||
|
(if (not (eq major-mode 'shell-mode))
|
||||||
|
(shell buffer)
|
||||||
|
(erase-buffer)
|
||||||
|
(cd dir))
|
||||||
|
(let ((process (get-buffer-process (current-buffer))))
|
||||||
|
(set-process-sentinel process #'+shell--sentinel)
|
||||||
|
(when command
|
||||||
|
(comint-send-string process command))))
|
||||||
|
buffer))
|
||||||
|
|
||||||
|
|
||||||
|
;; TODO +shell/frame -- dedicate current frame to shell buffers
|
||||||
|
;; TODO +shell/frame-quite -- revert frame to before +term/frame
|
5
modules/term/shell/config.el
Normal file
5
modules/term/shell/config.el
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
;;; term/shell/config.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
;;;###package shell
|
||||||
|
(add-hook 'shell-mode-hook #'doom|mark-buffer-as-real)
|
||||||
|
(add-hook 'shell-mode-hook #'hide-mode-line-mode)
|
4
modules/term/shell/packages.el
Normal file
4
modules/term/shell/packages.el
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
;; -*- no-byte-compile: t; -*-
|
||||||
|
;;; term/shell/packages.el
|
||||||
|
|
||||||
|
(package! shell :built-in t)
|
|
@ -53,3 +53,7 @@ If prefix ARG, recreate the term buffer."
|
||||||
;; before `switch-to-buffer', the hooks don't trigger, so we use this
|
;; before `switch-to-buffer', the hooks don't trigger, so we use this
|
||||||
;; roundabout way to trigger them properly.
|
;; roundabout way to trigger them properly.
|
||||||
(switch-to-buffer (save-window-excursion (multi-term))))
|
(switch-to-buffer (save-window-excursion (multi-term))))
|
||||||
|
|
||||||
|
|
||||||
|
;; TODO +term/frame -- dedicate current frame to term buffers
|
||||||
|
;; TODO +term/frame-quite -- revert frame to before +term/frame
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue