Fix some bugs based in eshell and vterm

After making my presentation on eshell, I encountered some bugs that
needed addressing.
This commit is contained in:
Howard Abrams 2022-11-24 23:10:38 -08:00
parent 4df8279e20
commit 6a74607b85
2 changed files with 98 additions and 57 deletions

View file

@ -426,7 +426,7 @@ Im calling the ability to get a buffer contents, /flow/ (Fetch contents as Li
:help eshell/flow))
args))
(buffers (gethash 'parameters options))
(content (thread-last parameters
(content (thread-last buffers
(-map 'eshell-flow-buffer-contents)
(s-join "\n"))))
(if (gethash 'help options)
@ -699,6 +699,7 @@ The [[https://github.com/joddie/pcre2el][pcre2el]] project can convert from a Li
(regexp "[0-9]\\{1,2\\}")))
(ipaddr (seq b256 "." b256 "." b256 "." b256))
(time (seq digit (optional digit) ":" (= 2 digit) (optional ":" (= 2 digit))))
(email (seq (1+ (regexp "[^,< ]")) "@" (1+ (seq (1+ (any alnum "-"))) ".") (1+ alnum)))
(date (seq (= 2 digit) (or "/" "-") (= 2 digit) (or "/" "-") (= 4 digit)))
(ymd (seq (= 4 digit) (or "/" "-") (= 2 digit) (or "/" "-") (= 2 digit)))
(uuid (seq (= 8 hex) "-" (= 3 (seq (= 4 hex) "-")) (= 12 hex)))
@ -1028,8 +1029,8 @@ This requires capture templates that dont do any formatting. I will reused =c
(defun ha-eshell-engineering-capture (capture-template comment cmd out)
"Capture formatted string in CAPTURE-TEMPLATE.
Base the string created on COMMENT, CMD, and OUT. Return OUTPUT."
(let* ((command (s-trim cmd))
(output (s-trim out))
(let* ((command (when cmd (s-trim cmd)))
(output (when out (s-trim out)))
(results (concat
(when comment (format "%s\n\n" comment))
(when command (format "#+begin_src shell\n %s\n#+end_src\n\n" command))
@ -1061,6 +1062,21 @@ This function simply calls [[help-org-capture][org-capture]] with [[info:org#Tem
"Call `org-capture' with the `ee' template to enter text into the engineering notebook."
(org-capture nil "ee"))
#+end_src
#+begin_src emacs-lisp
(defun ha-eshell-target-engineering-notebook (output)
"Write OUTPUT into the engineering notebook via `org-capture'."
(ha-eshell-engineering-capture "ef" nil nil output))
(defun ha-eshell-target-clocked-in-task (output)
"Write OUTPUT into the current clocked in task via `org-capture'."
(ha-eshell-engineering-capture "cc" nil nil output))
#+end_src
And finally, add our new functions to [[elisp(describe-variable 'eshell-virtual-targets)][eshell-virtual-targets]]:
#+begin_src emacs-lisp
(add-to-list 'eshell-virtual-targets '("/dev/e" ha-eshell-target-engineering-notebook nil))
(add-to-list 'eshell-virtual-targets '("/dev/c" ha-eshell-target-engineering-notebook nil))
#+end_src
* Special Prompt
Following [[http://blog.liangzan.net/blog/2012/12/12/customizing-your-emacs-eshell-prompt/][these instructions]], we build a better prompt with the Git branch in it (Of course, it matches my Bash prompt). First, we need a function that returns a string with the Git branch in it, e.g. ":master"
#+begin_src emacs-lisp :tangle no

View file

@ -244,16 +244,13 @@ Simply calling =vterm= fails to load my full environment, so this allows me to s
(defun ha-shell (&optional directory)
"Creates and tidies up a =vterm= terminal shell in side window."
(interactive (list (read-directory-name "Starting Directory: " (projectile-project-root))))
(let* ((win-name "Terminal")
(let* ((win-name (ha--terminal-name-from-dir directory))
(buf-name (format "*%s*" win-name))
(default-directory (or directory default-directory)))
(setq ha-latest-ssh-window-name buf-name)
(if (not (fboundp 'vterm))
(make-term win-name ha-ssh-shell)
(vterm buf-name)
;; (ha-ssh-send "source ~/.bash_profile" buf-name)
;; (ha-ssh-send "clear" buf-name)
)))
(vterm buf-name))))
#+end_src
Before we leave this section, I realize that I would like a way to /add/ to my list of hosts:
@ -264,6 +261,34 @@ Before we leave this section, I realize that I would like a way to /add/ to my l
(add-to-list 'ha-ssh-favorite-hostnames (cons hostname ip-address)))
#+end_src
** Programmatic Interface
Lets send stuff to it:
#+begin_src emacs-lisp
(defun ha-shell-send (command &optional directory)
"Send COMMAND to existing shell based on DIRECTORY.
If the shell doesn't already exist, start on up by calling
the `ha-shell' function."
(let* ((win-name (ha--terminal-name-from-dir directory))
(win-rx (rx "*" (literal win-name) "*"))
(bufs (seq-filter (lambda (b) (when (string-match win-rx (buffer-name b)) b))
(buffer-list)))
(buf (first bufs)))
(unless buf
(setq buf (ha-shell directory)))
(ha-ssh-send command buf)))
(defun ha--terminal-name-from-dir (&optional directory)
"Return an appropriate title for a terminal based on DIRECTORY.
If DIRECTORY is nil, use the `projectile-project-name'."
(unless directory
(setq directory (projectile-project-name)))
(format "Terminal: %s" (file-name-base (directory-file-name directory))))
(ert-deftest ha--terminal-name-from-dir-test ()
(should
(string= (ha--terminal-name-from-dir "~/other/hamacs/") "Terminal: hamacs"))
(should
(string= (ha--terminal-name-from-dir) "Terminal: hamacs")))
#+end_src
The previous functions (as well as my own end of sprint demonstrations) often need to issue some commands to a running terminal session, which is a simple wrapper around a /send text/ and /send return/ sequence:
@ -274,7 +299,7 @@ If you want to refer to another session, specify the correct WINDOW-NAME.
This is really useful for scripts and demonstrations."
(unless window-name
(setq window-name ha-latest-ssh-window-name))
(save-window-excursion
(pop-to-buffer window-name)
(if (fboundp 'vterm)
@ -283,7 +308,7 @@ This is really useful for scripts and demonstrations."
(vterm-send-return))
(progn
(term-send-raw-string phrase)
(term-send-input))))
(term-send-input)))))
#+end_src
On the rare occasion that I write a shell script, or at least, need to execute some one-line shell commands from some document, I have a function that combines a /read line from buffer/ and then send it to the currently running terminal: