summary refs log tree commit diff
path: root/emacs/custom/my-eshell.el
blob: c5a4a2740678e8c6538f0b56747031a81af4d61b (plain) (blame)
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
;;; my-eshell.el --- Configure eshell -*- lexical-binding: t -*-

;;; Commentary:

;;; Code:

(require 'cl-seq)
(require 'vc)
(require 'eshell)
(require 'esh-mode)
(require 'esh-module)

(setq eshell-modules-list
      '(eshell-alias
        eshell-basic
        eshell-cmpl
        eshell-dirs
        eshell-glob
        eshell-hist
        eshell-ls
        eshell-pred
        eshell-prompt
        eshell-script
        eshell-term
        eshell-tramp
        eshell-unix))

(require 'em-alias)
(require 'em-basic)
(require 'em-dirs)
(require 'em-glob)
(require 'em-hist)
(require 'em-term)
(require 'em-tramp)
(require 'em-prompt)

(defun my/eshell-mode-setup ()
  "Configures various aliases for eshell."
  (eshell/alias "e" "find-file $1")
  (eshell/alias "emacs" "find-file $1")
  (eshell/alias "ee" "find-file-other-window $1")
  (eshell/alias "ll" "ls -l")
  (eshell/alias "lla" "ls -la")
  (eshell/alias "d" "dired $1")
  (eshell/alias "gs" "vc-diff")
  (eshell/alias "cal" "calendar")
  (eshell/alias "agenda" "org-agenda"))

(defvar-local my/eshell-output-buffer "*Exported eshell output*"
  "Name of buffer with the last output of Eshell command.")

(defvar-local my/eshell-output-delimiter "---"
  "Delimiter for successive `prot-eshell-export' outputs.")

(defun my/eshell--command-prompt-output ()
  "Capture last command prompt and its output."
  (let ((beg (save-excursion
               (goto-char (eshell-beginning-of-input))
               (goto-char (pos-bol)))))
  (when (derived-mode-p 'eshell-mode)
    (buffer-substring-no-properties beg (eshell-end-of-output)))))

;; https://gitlab.com/protesilaos/dotfiles/-/blob/master/emacs/.emacs.d/prot-lisp/prot-eshell.el#L114
(defun my/eshell-export ()
  "Produce a buffer with output of the last Eshell command.
If `my/eshell-output-buffer' does not exist, create it.  Else
append to it, while separating multiple outputs with
`my/eshell-output-delimiter'."
  (interactive)
  (let ((eshell-output (my/eshell--command-prompt-output)))
    (with-current-buffer (get-buffer-create my/eshell-output-buffer)
      (goto-char (point-max))
      (unless (eq (point-min) (point-max))
        (insert (format "\n%s\n\n" my/eshell-output-delimiter)))
      (goto-char (pos-bol))
      (insert eshell-output)
      (switch-to-buffer-other-window (current-buffer)))))

(defun my/short-pwd (path)
  "Turn a PATH of the form /foo/bar/baz into /f/b/baz, like fish shell."
  (let* ((home-path (replace-regexp-in-string (expand-file-name "~")
                                          "~"
                                          path))
         (current-dir (split-string home-path "/"))
         (cdir (last current-dir))
         (head (butlast current-dir)))
    (concat (mapconcat (lambda (s)
                         (if (string= "" s) nil
                           (substring s 0 1)))
                       head
                       "/")
            (if head "/" nil)
            (car cdir))))

(defmacro with-face (str &rest properties)
  "Set the PROPERTIES for the given STR."
  `(propertize ,str 'face (list ,@properties)))

(define-key eshell-mode-map (kbd "C-c e e") 'my/eshell-export)

(customize-set-variable 'eshell-scroll-to-bottom-on-input 'all)
(customize-set-variable 'eshell-error-if-no-glob t)
(customize-set-variable 'eshell-hist-ignoredups t)
(customize-set-variable 'eshell-save-history-on-exit t)
(customize-set-variable 'eshell-cd-on-directory t)
(customize-set-variable 'eshell-prefer-lisp-functions nil)
(customize-set-variable 'eshell-destroy-buffer-when-process-dies t)

(add-hook 'eshell-mode-hook 'my/eshell-mode-setup)

(provide 'my-eshell)

;;; my-eshell.el ends here