blob: 9625a13688d16d04cd3c1c6d383497e3e9aae255 (
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
|
(require 'cl-lib)
(require 'eshell)
(defun prot-eshell--cd (dir)
"Routine to cd into DIR."
(delete-region eshell-last-output-end (point-max))
(when (> eshell-last-output-end (point))
(goto-char eshell-last-output-end))
(insert-and-inherit "cd " (eshell-quote-argument dir))
(eshell-send-input))
(defun prot-eshell-complete-recent-dir (dir &optional arg)
"Switch to a recent Eshell directory.
When called interactively, DIR is selected with completion from
the elements of `eshell-last-dir-ring'.
With optional ARG prefix argument (\\[universal-argument]) also
open the directory in a `dired' buffer."
(interactive
(list
(if-let ((dirs (ring-elements eshell-last-dir-ring)))
(completing-read "Switch to recent dir: " dirs nil t)
(user-error "There is no Eshell history for recent directories"))
current-prefix-arg))
(prot-eshell--cd dir)
;; UPDATE 2022-01-04 10:48 +0200: The idea for `dired-other-window'
;; was taken from Sean Whitton's `spw/eshell-cd-recent-dir'. Check
;; Sean's dotfiles: <https://git.spwhitton.name/dotfiles>.
(when arg
(dired-other-window dir)))
(defun bard/eshell-find-file-at-point ()
"Run `find-file` to find file"
(interactive)
(let ((file (ffap-file-at-point)))
(if file
(find-file file)
(user-error "No file at point"))))
(defcustom prot-eshell-output-buffer "*Exported Eshell output*"
"Name of buffer with the last output of Eshell command.
Used by `prot-eshell-export'."
:type 'string
:group 'prot-eshell)
(defcustom prot-eshell-output-delimiter "* * *"
"Delimiter for successive `prot-eshell-export' outputs.
This is formatted internally to have newline characters before
and after it."
:type 'string
:group 'prot-eshell)
(defun prot-eshell--command-prompt-output ()
"Capture last command prompt and its output."
(let ((beg (save-excursion
(goto-char (eshell-beginning-of-input))
(goto-char (point-at-bol)))))
(when (derived-mode-p 'eshell-mode)
(buffer-substring-no-properties beg (eshell-end-of-output)))))
;;;###autoload
(defun prot-eshell-export ()
"Produce a buffer with output of the last Eshell command.
If `prot-eshell-output-buffer' does not exist, create it. Else
append to it, while separating multiple outputs with
`prot-eshell-output-delimiter'."
(interactive)
(let ((eshell-output (prot-eshell--command-prompt-output)))
(with-current-buffer (get-buffer-create prot-eshell-output-buffer)
(let ((inhibit-read-only t))
(goto-char (point-max))
(unless (eq (point-min) (point-max))
(insert (format "\n%s\n\n" prot-eshell-output-delimiter)))
(goto-char (point-at-bol))
(insert eshell-output)
(switch-to-buffer-other-window (current-buffer))))))
(defgroup bard-eshell-faces nil
"Faces for my custom modeline."
:group 'prot-eshell-faces)
(defface bard-eshell-highlight-yellow-bg
'((default :inherit (bold prot-modeline-indicator-button))
(((class color) (min-colors 88) (background light))
:background "#805000" :foreground "white")
(((class color) (min-colors 88) (background dark))
:background "#ffc800" :foreground "black")
(t :background "yellow" :foreground "black"))
"Face for modeline indicators with a background."
:group 'bard-eshell-faces)
(defun prot-eshell-narrow-output-highlight-regexp (regexp)
"Narrow to last command output and highlight REGEXP."
(interactive
(list (read-regexp "Regexp to highlight" nil 'prot-eshell--output-highlight-history)))
(narrow-to-region (eshell-beginning-of-output)
(eshell-end-of-output))
(goto-char (point-min))
(highlight-regexp regexp 'prot-eshell-highlight-yellow-bg)
(message "%s to last output and highlighted '%s'"
(propertize "Narrowed" 'face 'bold)
(propertize regexp 'face 'italic)))
(defun select-or-create (arg)
"Commentary ARG."
(if (string= arg "New eshell")
(eshell t)
(switch-to-buffer arg)))
(defun eshell-switcher (&optional arg)
"Commentary ARG."
(interactive)
(let* (
(buffers (cl-remove-if-not (lambda (n) (eq (buffer-local-value 'major-mode n) 'eshell-mode)) (buffer-list)) )
(names (mapcar (lambda (n) (buffer-name n)) buffers))
(num-buffers (length buffers) )
(in-eshellp (eq major-mode 'eshell-mode)))
(cond ((eq num-buffers 0) (eshell (or arg t)))
((not in-eshellp) (switch-to-buffer (car buffers)))
(t (select-or-create (completing-read "Select Shell:" (cons "New eshell" names)))))))
(provide 'bard-eshell)
|