Changes to ebb/flow for a better UI

This commit is contained in:
Howard Abrams 2023-09-09 22:11:29 -07:00
parent 1e2f016c5f
commit 549887bce5

View file

@ -402,7 +402,8 @@ This buffer has a minor-mode that binds ~C-c C-q~ to close the window and return
(defun ha-eshell-ebbflow-return () (defun ha-eshell-ebbflow-return ()
"Close the ebb-flow window and return to Eshell session." "Close the ebb-flow window and return to Eshell session."
(interactive) (interactive)
(if (boundp 'ha-eshell-ebbflow-return-buffer) (if (and (boundp 'ha-eshell-ebbflow-return-buffer)
(bufferp 'ha-eshell-ebbflow-return-buffer))
(pop-to-buffer ha-eshell-ebbflow-return-buffer) (pop-to-buffer ha-eshell-ebbflow-return-buffer)
(bury-buffer))) (bury-buffer)))
@ -415,7 +416,7 @@ This buffer has a minor-mode that binds ~C-c C-q~ to close the window and return
#+end_src #+end_src
Since I use Evil, I also add ~Q~ to call this function: Since I use Evil, I also add ~Q~ to call this function:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(evil-define-key 'normal ebbflow-mode-map (kbd "Q") 'ha-eshell-ebbflow-return) (evil-define-key 'normal ebbflow-mode-map "Q" 'ha-eshell-ebbflow-return)
#+end_src #+end_src
*** flow (or Buffer Cat) *** flow (or Buffer Cat)
Eshell can send the output of a command sequence to a buffer: Eshell can send the output of a command sequence to a buffer:
@ -492,6 +493,9 @@ Straight-forward to acquire the contents of a buffer :
(defalias 'eshell/bcat 'eshell/flow) (defalias 'eshell/bcat 'eshell/flow)
#+end_src #+end_src
*** ebb: Bump Data to a Buffer *** ebb: Bump Data to a Buffer
The =ebb= function puts content /into/ the /ebbflow buffer/. Any content given to it on the command line is placed into the buffer, for instance:
- =ebb foobar= :: replaces the contents of the buffer with the text, =foobar=
- =ebb -p foobar= :: adds the text at the beginning
We have three separate use-cases: We have three separate use-cases:
1. Execute a command, inserting the output into the buffer (good if we know the output will be long, complicated, or needing manipulation) 1. Execute a command, inserting the output into the buffer (good if we know the output will be long, complicated, or needing manipulation)
2. Insert one or more files into the buffer (this assumes the files are data) 2. Insert one or more files into the buffer (this assumes the files are data)
@ -499,17 +503,22 @@ We have three separate use-cases:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defun eshell/ebb (&rest args) (defun eshell/ebb (&rest args)
"Run command with output into a buffer, or output of last command. "Insert text content into *eshell-edit* buffer, or if not text is given, the output of last command.
Usage: ebb [OPTION] [COMMAND] [FILE ...] Usage: ebb [OPTION] [text content]
-h, --help show this usage screen -h, --help show this usage screen
-a, --append add command output to the *eshell-edit* buffer -m, --mode specify the major-mode for the *eshell-edit* buffer, e.g. json
-p, --prepend add command output to the end of *eshell-edit* buffer -n, --newline separate the text contents by newlines (this is default)
-i, --insert add command output to *eshell-edit* at point" -s, --spaces separate the text contents by spaces, instead of newlines
(let* ((options (eshell-getopts '((:name insert :short "i" :long "insert") -b, --begin add text content to the beginning of the *eshell-edit* buffer
(:name append :short "a" :long "append") -e, --end add text content to the end of *eshell-edit* buffer
(:name prepend :short "p" :long "prepend") -i, --insert add text content to *eshell-edit* at point"
(:name mode :short "m" :long "mode" :parameter string) (let* ((options (eshell-getopts '((:name insert :short "i" :long "insert")
(:name help :short "h" :long "help" (:name append :short "e" :long "end")
(:name prepend :short "b" :long "begin")
(:name newline :short "n" :long "newline")
(:name spaces :short "s" :long "spaces")
(:name mode-option :short "m" :long "mode" :parameter string)
(:name help :short "h" :long "help"
:help eshell/ebb)) :help eshell/ebb))
args)) args))
(location (cond (location (cond
@ -518,19 +527,19 @@ We have three separate use-cases:
((gethash 'prepend options) :prepend) ((gethash 'prepend options) :prepend)
(t :replace))) (t :replace)))
(params (gethash 'parameters options))) (params (gethash 'parameters options)))
(cond
((seq-empty-p params) (ha-eshell-ebb-output location)) (if (seq-empty-p params)
((file-exists-p (car params)) (ha-eshell-ebb-files location params)) ((ha-eshell-ebb-output location))
(t (ha-eshell-ebb-command location params))) (ha-eshell-ebb-string location (gethash 'spaces options) params))
;; At this point, we are in the `ha-eshell-ebbflow-buffername', and ;; At this point, we are in the `ha-eshell-ebbflow-buffername', and
;; the buffer contains the inserted data. Did we specify a major-mode? ;; the buffer contains the inserted data. Did we specify a major-mode?
(let ((mode (gethash 'mode options))) (when-let ((mode-option (gethash 'mode-option options)))
(if (s-starts-with? "js" mode) (if (s-starts-with? "js" mode-option)
(js-json-mode) ; Or should we just go to json-ts-mode? (js-json-mode) ; Or should we just go to json-ts-mode?
(funcall (concat mode "-mode")))) (funcall (intern (concat mode-option "-mode")))))
;; Flip on the minor mode so we can close the window later on: ;; Flip on the minor mode-option so we can close the window later on:
(ebbflow-mode +1) (ebbflow-mode +1)
(goto-char (point-min))) (goto-char (point-min)))
@ -558,6 +567,19 @@ Each of the use-case functions described needs to switch to the =*eshell-edit*=
(:replace (delete-region (point-min) (point-max)))))) (:replace (delete-region (point-min) (point-max))))))
#+end_src #+end_src
One way to call =ebb= is with a command wrapped in braces, e.g. =ebb { ls -1 }=, which calls this function, as the output from the ={ … }= /sub-shell/ is passed as arguments to the =ebb= command, and appears as =command-results=:
#+begin_src emacs-lisp
(defun ha-eshell-ebb-string (insert-location space-separator-p command-results)
"Insert the COMMAND-RESULTS into the `ha-eshell-ebbflow-buffername`.
Contents are placed based on INSERT-LOCATION and, if given, separated
by SEPARATOR (which defaults to a space)."
(let* ((sep (if space-separator-p " " "\n"))
(str (string-join (-flatten command-results) sep)))
(ha-eshell-ebb-switch-to-buffer insert-location)
(insert str)))
#+end_src
Command string passed to [[help:eshell-command][eshell-command]]: Command string passed to [[help:eshell-command][eshell-command]]:
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defun ha-eshell-ebb-command (insert-location command-parts) (defun ha-eshell-ebb-command (insert-location command-parts)
@ -1353,7 +1375,31 @@ Whenever I open a shell, I instinctively type =ls= … so why not do that automa
#+begin_src emacs-lisp #+begin_src emacs-lisp
(defun ha-eshell-banner () (defun ha-eshell-banner ()
"Return a string containing the files in the current directory." "Return a string containing the files in the current directory."
(eshell/lsd)) (let ((fg (face-attribute 'default :background))
(bg (face-attribute 'default :foreground))
(bg "#c09644")
(dd (thread-last default-directory
(replace-regexp-in-string (getenv "HOME") "~")))
(gs (thread-last "git status --short --branch --ahead-behind 2>/dev/null"
(shell-command-to-list)
(first)
(replace-regexp-in-string
(rx "## "
(group (zero-or-more not-newline))
(zero-or-more anychar))
"\\1")
(replace-regexp-in-string
(rx "...") " → "))))
(ignore-errors
(concat
;; Line 1
(propertize
(format " %s • ⑆ %s " dd gs)
'face `(:background ,bg :foreground ,fg))
"\n"
;; Line 2
(ha-dad-joke)
"\n\n"))))
#+end_src #+end_src
* Shell Windows * Shell Windows
Now that I often need to pop into remote systems to run a shell or commands, I create helper functions to create those buffer windows. Each buffer begins with =eshell=: allowing me to have more than one eshells, typically, one per project. Now that I often need to pop into remote systems to run a shell or commands, I create helper functions to create those buffer windows. Each buffer begins with =eshell=: allowing me to have more than one eshells, typically, one per project.