diff options
-rwxr-xr-x | emacs.org | 162 |
1 files changed, 161 insertions, 1 deletions
@@ -880,9 +880,169 @@ Create function to watch videos using ~mpv~ (setq eshell-highlight-prompt t) #+end_src +** Multi Eshell +#+begin_src emacs-lisp + (defun if-void (arg default) + (if (boundp arg) + (eval arg) + default + )) + + (defgroup multi-eshell nil + "Simple support for having multiple shells open." + :group 'languages) + + (defcustom multi-eshell-shell-function '(eshell) + "Command called to create shell" + :group 'multi-eshell) + + (defcustom multi-eshell-name "*eshell*" "The name of the buffer opened by the shell command." + :type 'string + :group 'multi-eshell) + + (defun multi-eshell-function () "This function opens the appropriate shell." (eval multi-eshell-shell-function) ) + ;;;(defvar multi-eshell-function `(shell) ) ;;; Defines the shell. ('shell) or ('eshell) + ;(defvar multi-eshell-name "*eshell*") ;;; Name of default shell or eshell buffer + + (defvar multi-eshell-ring (make-ring 100) "This stores a bunch of buffers, which are shells created by multi-eshell." ) + (setq multi-eshell-index 0 ) + (defvar multi-eshell-last-buffer nil) + + (defun multi-eshell-is-current-buffer-current-multi-eshell (&optional ignored) + "Checks if current buffer is the current multi-eshell." + (eq (current-buffer) (ring-ref multi-eshell-ring multi-eshell-index)) + ) + + (defun multi-eshell-switch-to-current-shell (&optional ignored) + "Switch to shell buffer." + (if (buffer-live-p (ring-ref multi-eshell-ring multi-eshell-index)) + (switch-to-buffer (ring-ref multi-eshell-ring multi-eshell-index)) + ) + ) + + (defun multi-eshell-current-shell (&optional ignored) + "Returns the current multi-eshell." + (ring-ref multi-eshell-ring multi-eshell-index) + ) + + (defun multi-eshell-switch-to-next-live-shell (&optional ignored) + "Switches to the next live shell. Creates one if none exists." + (interactive "p") + (let ((still-looking t) + (empty nil)) + (while (and still-looking (not empty)) + (if (ring-empty-p multi-eshell-ring) + (progn + (setq empty t) + (multi-eshell 1) + ) + (progn + (if (buffer-live-p (ring-ref multi-eshell-ring multi-eshell-index)) + (progn + (setq multi-eshell-index (+ multi-eshell-index 1)) + (switch-to-buffer (ring-ref multi-eshell-ring multi-eshell-index)) + (setq still-looking nil) + ) + (ring-remove multi-eshell-ring multi-eshell-index) + ) + ) + ) + ) + ) + ) + + ;;;###autoload + (defun multi-eshell-go-back (&optional ignored) + "Switch to buffer multi-eshell-last-buffer." + (interactive "p") + (if (buffer-live-p multi-eshell-last-buffer) + (switch-to-buffer multi-eshell-last-buffer) + (message "Last buffer visited before multi-eshell is gone. Nothing to go back to..") + )) + + + ;;;###autoload + (defun multi-eshell-switch (&optional ignored) + "If current buffer is not an multi-eshell, switch to current multi-eshell buffer. Otherwise, switch to next multi-eshell buffer." + (interactive "p") + (progn + (setq multi-eshell-last-buffer (current-buffer)) + (let ((still-looking t) + (empty nil)) + (if (ring-empty-p multi-eshell-ring) + (multi-eshell 1) + (if (and (buffer-live-p (multi-eshell-current-shell) ) + (not (eq (multi-eshell-current-shell) (current-buffer)))) + (switch-to-buffer (multi-eshell-current-shell)) + (multi-eshell-switch-to-next-live-shell) + ) + ) + ))) + + ;;;###autoload + (defun multi-eshell (&optional numshells) + "Creates a shell buffer. If one already exists, this creates a new buffer, with the name '*shell*<n>', where n is chosen by the function generate-new-buffer-name." + (interactive "p") + (progn + (setq multi-eshell-last-buffer (current-buffer)) + (dotimes (i (if-void 'numshells 1) nil) + (let ( (tempname (generate-new-buffer-name "*tempshell*")) + (new-buff-name (generate-new-buffer-name multi-eshell-name)) + (localdir default-directory) + ) + (if (eq (get-buffer multi-eshell-name) nil) ;If a + (progn + (multi-eshell-function) + ;(process-send-string (get-buffer-process new-buff-name) (concat "cd " localdir "\n")) + (ring-insert multi-eshell-ring (current-buffer) ) + (setq multi-eshell-index (+ multi-eshell-index 1)) + ) + (progn + (interactive) + (multi-eshell-function) + (rename-buffer tempname) + (multi-eshell-function) + (rename-buffer new-buff-name ) + (switch-to-buffer tempname) + (rename-buffer multi-eshell-name) + (switch-to-buffer new-buff-name) + ;(process-send-string (get-buffer-process new-buff-name) (concat "cd " localdir "\n")) + (ring-insert multi-eshell-ring (current-buffer) ) + (setq multi-eshell-index (+ multi-eshell-index 1)) + ) + ) + ) + ) + ) + ) + + (defun shell-with-name (name) + "Creates a shell with name given by the first argument, and switches to it. If a buffer with name already exists, we simply switch to it." + (let ((buffer-of-name (get-buffer name)) + (tempname (generate-new-buffer-name "*tempshell*") ) ) + (cond ((bufferp buffer-of-name) ;If the buffer exists, switch to it (assume it is a shell) + (switch-to-buffer name)) + ( (bufferp (get-buffer multi-eshell-name)) + (progn + (multi-eshell-function) + (rename-buffer tempname) + (multi-eshell-function) + (rename-buffer name) + (switch-to-buffer tempname) + (rename-buffer multi-eshell-name) + (switch-to-buffer name))) + ( t + (progn + (multi-eshell-function) + (rename-buffer name)))))) +#+end_src ** Keybindings #+begin_src emacs-lisp - (global-set-key (kbd "C-c e") 'eshell) + (define-prefix-command 'thanos/eshell-map) + (global-set-key (kbd "C-c e") 'thanos/eshell-map) + + (define-key thanos/eshell-map (kbd "o") 'multi-eshell) + (define-key thanos/eshell-map (kbd "n") 'multi-eshell-switch) #+end_src * Misc ** Random functions |