;;; jao-eshell-here.el --- Easy opening of eshell buffers -*- lexical-binding: t; -*- ;; Copyright (C) 2021 jao ;; Author: jao ;; Keywords: eshell ;; 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 . ;;; Commentary: ;; Commands for toggling eshell buffers below the current one. ;;; Code: (require 'eshell) (defvar jao-eshell-here-display-buffer-alist '(("^\\*eshell" (display-buffer-reuse-window display-buffer-below-selected) (window-height . 0.5))) "Value to use for `display-buffer-alist' when displaying the eshell buffer.") (defun jao-eshell-here--find-window (b) (when-let (w (seq-find (lambda (w) (eq (window-buffer w) b)) (window-list))) (select-window w))) (defun jao-eshell-here--frame-buffer (&optional b) (let ((p 'jao-eshell-buffer)) (if b (set-frame-parameter nil p b) (frame-parameter nil p)))) (defun jao-eshell--cd-here (&optional dir) (eshell-kill-input) (eshell/cd (or dir default-directory)) (insert "\n") (eshell-send-input)) (defun jao-eshell-here (stay &optional force-new) "Open an eshell buffer below current buffer. Buffers are reused (per frame) unless FORCE-NEW is t. With prefix STAY (C-u), open at project's root, and with double prefix (C-u C-u) open in the current's buffer default dir." (interactive "p") (let ((b (unless force-new (jao-eshell-here--frame-buffer))) (dir (cond ((> stay 4) default-directory) ((> stay 1) (project-root (or (project-current) `(transient . ,default-directory)))))) (display-buffer-alist (append display-buffer-alist jao-eshell-here-display-buffer-alist))) (jao-with-attached-buffer "^\\*eshell" 0.5 (if (buffer-live-p b) (progn (pop-to-buffer b nil t) (eshell-save-some-history) (when dir (jao-eshell--cd-here dir))) (let ((default-directory (or dir default-directory))) (eshell (when force-new 4))) (unless force-new (jao-eshell-here--frame-buffer (current-buffer))))))) ;;;###autoload (defun eshell/x () (when (derived-mode-p 'eshell-mode) (when (fboundp 'eshell-autojump-save) (eshell-autojump-save)) (eshell-save-some-history) (if (> (frame-height) (window-height)) (delete-window) (bury-buffer)))) ;;;###autoload (defun jao-eshell-here-toggle (stay &optional force-new) "Open or close an eshell buffer, using `jao-eshell-here'." (interactive "p") (if (or (and force-new (derived-mode-p 'eshell-mode)) (eq (current-buffer) (jao-eshell-here--frame-buffer))) (eshell/x) (jao-eshell-here stay force-new))) ;;;###autoload (defun jao-eshell-here-toggle-new (stay) "Open or close a new eshell buffer, using `jao-eshell-here'." (interactive "p") (jao-eshell-here-toggle stay t)) (provide 'jao-eshell-here) ;;; jao-eshell-here.el ends here