Move stuff around

Needed to move the Terminal stuff over to remoting, as I don't include
the aux-apps in my Work-specific Emacs system. While I was at it, I
noticed some key conflicts with org, so fixed that too.
This commit is contained in:
Howard Abrams 2022-01-06 15:36:39 -08:00
parent a85aae30b9
commit 87e2d4e292
6 changed files with 174 additions and 147 deletions

View file

@ -124,16 +124,20 @@ And I need to install the [[https://gpgtools.org/][GPG Suite]]. While very nice,
** Basic Libraries
The following packages come with Emacs, but seems like they still need loading:
#+BEGIN_SRC emacs-lisp
(require 'subr-x)
#+END_SRC
Ugh. Why am I getting a missing =first= function error? Let's just define it:
#+BEGIN_SRC emacs-lisp
(defun first (elt) (car elt))
(use-package cl-lib
:straight (:type built-in)
:init (defun first (elt) (car elt))
:commands (first))
(require 'subr-x)
#+END_SRC
Ugh. Why am I getting a missing =first= function error? I define a simple implementation, that the CL library will overwrite ... at some point.
While most libraries will take care of their dependencies, I want to install /my dependent libraries/. Especially, [[https://github.com/magnars/.emacs.d/][Magnar Sveen]]'s Clojure-inspired [[https://github.com/magnars/dash.el][dash.el]] project:
#+BEGIN_SRC emacs-lisp
(use-package dash)
#+END_SRC
Sure this package is essentially syntactic sugar, and to help /share/ my configuration, I attempt to use =thread-last= instead of =->>=, but, I still like it.
The [[https://github.com/magnars/s.el][s.el]] project is a simpler string manipulation library that I (and other projects) use:
#+BEGIN_SRC emacs-lisp
@ -189,13 +193,13 @@ The following loads the rest of my org-mode literate files. I add them as they a
"ha-org-clipboard.org"
"ha-capturing-notes.org"
"ha-agendas.org"
"ha-irc.org"
"ha-passwords.org"
"ha-remoting.org"
"ha-programming.org"
"ha-programming-python.org"
,(unless (ha-emacs-for-work?)
'("ha-org-journaling.org"
"ha-irc.org"
"ha-org-publishing.org"
"ha-email.org"
"ha-aux-apps.org"

View file

@ -24,113 +24,6 @@ A literate programming file for helper apps in Emacs.
#+END_SRC
* Introduction
The following applications are not really needed. I alternate between trying to /stay in Emacs/ taking advantage of the consistent interface, and simply using a stand-alone app on my Workday computer.
* Terminal
The following section configures my Terminal experience, both inside and outside Emacs.
** Eshell
I used to use [[http://www.howardism.org/Technical/Emacs/eshell.html][Eshell all the time]], but now I've migrated most of /work/ directly into Emacs (rewriting all those shell scripts a Emacs Lisp code). However, a shell is pretty good for my brain at organizing files (old habits, maybe).
#+BEGIN_SRC emacs-lisp
(use-package eshell
:config (ha-leader "a e" '("eshell" . eshell-here)))
#+END_SRC
I usually want a new window running Eshell, that is smaller than the current buffer:
#+BEGIN_SRC emacs-lisp
(defun eshell-here ()
"Opens up a new shell in the directory associated with the
current buffer's file. Rename the eshell buffer name to match
that directory to make multiple eshell windows easier."
(interactive)
(let* ((parent (if (buffer-file-name)
(file-name-directory (buffer-file-name))
default-directory))
(height (/ (window-total-height) 3))
(name (car (last (split-string parent "/" t)))))
(split-window-vertically (- height))
(eshell "new")
(rename-buffer (concat "*eshell: " name "*"))
(insert (concat "ls"))
(eshell-send-input)))
#+END_SRC
And since Emacs supplies Eshell, we can just define these helper functions:
#+BEGIN_SRC emacs-lisp
(defun eshell/e (file)
(find-file file))
(defun eshell/ee (file)
(find-file-other-window file))
(defun eshell/x ()
(insert "exit")
(eshell-send-input)
(delete-window))
#+END_SRC
Add my org-specific predicates, see this [[http://www.howardism.org/Technical/Emacs/eshell-fun.html][this essay]] for the details:
#+BEGIN_SRC emacs-lisp
(defun eshell-org-file-tags ()
"Helps the eshell parse the text the point is currently on,
looking for parameters surrounded in single quotes. Returns a
function that takes a FILE and returns nil if the file given to
it doesn't contain the org-mode #+FILETAGS: entry specified."
;; Step 1. Parse the eshell buffer for our tag between quotes
;; Make sure to move point to the end of the match:
(if (looking-at "'\\([^)']+\\)'")
(let* ((tag (match-string 1))
(reg (rx bol "#+FILETAGS: "
(zero-or-more any)
word-start
(literal tag)
word-end
(zero-or-more any)
eol)))
(goto-char (match-end 0))
;; Step 2. Return the predicate function:
;; Careful when accessing the `reg' variable.
`(lambda (file)
(with-temp-buffer
(insert-file-contents file)
(re-search-forward ,reg nil t 1))))
(error "The `T' predicate takes an org-mode tag value in single quotes.")))
(defvar eshell-predicate-alist nil
"A list of predicates than can be applied to a globbing pattern.")
(add-to-list 'eshell-predicate-alist '(?T . (eshell-org-file-tags)))
#+END_SRC
** VTerm
I'm not giving up on Eshell, but I am playing around with [[https://github.com/akermu/emacs-libvterm][vterm]], and it is pretty good, but I use it primarily as a more reliable approach to [[file:ha-remoting.org][a remote shell]].
VTerm has an issue (at least for me) with ~M-Backspace~ not deleting the previous word, and yeah, I want to make sure that both keystrokes do the same thing.
#+BEGIN_SRC emacs-lisp :tangle no
(use-package vterm
:init
(setq vterm-shell "/usr/local/bin/fish")
;; Granted, I seldom pop out to the shell except during code demonstrations,
;; but I like how C-p/C-n jumps up to each prompt entry using this setting
;; that works with my prompt:
(setq vterm-use-vterm-prompt-detection-method nil
term-prompt-regexp "^.* $ ")
:config
(dolist (k '("<C-backspace>" "<M-backspace>"))
(define-key vterm-mode-map (kbd k)
(lambda () (interactive) (vterm-send-key (kbd "C-w")))))
(advice-add 'vterm-copy-mode :after 'evil-normal-state))
#+END_SRC
The advantage of running terminals in Emacs is the ability to copy text without a mouse. For that, hit ~C-c C-t~ to enter a special copy-mode. If I go into this mode, I might as well also go into normal mode to move the cursor.
*Note:* To exit the copy-mode (and copy the selected text to the clipboard), hit ~Return~.
Hrm. Seems that I might want a function to copy the output of the last command to a register, or even an org-capture...
* Twitter
The venerable [[https://github.com/hayamiz/twittering-mode/tree/master][twittering-mode]] allows me to follow all the twits.
#+BEGIN_SRC emacs-lisp
@ -152,18 +45,7 @@ I'm thinking the [[https://zevlg.github.io/telega.el/][Telega package]] would be
For some reason, you need [[https://github.com/Fanael/rainbow-identifiers][rainbow-identifiers]] to work, oh, I guess the docs state this.
*Note:* Turning this off as it needs version 1.7.7 of =tdlib=, and that isn't easily available on my Mac. Maybe I may enable this on my Linux system.
* Demo It
Making demonstrations /within/ Emacs with [[https://github.com/howardabrams/demo-it][demo-it]].
#+BEGIN_SRC emacs-lisp
(use-package demo-it
:straight (:type git :protocol ssh :host github :repo "howardabrams/demo-it")
:commands (demo-it-create demo-it-start))
#+END_SRC
Perhaps I should change the reference to this for more local development:
#+begin_example
:straight (:local-repo "~/other/demo-it")
#+end_example
** RPG DM
* RPG DM
Been working on a project for getting Emacs helping as a /Dungeon Master's Assistant/, and I must say, it is coming along nicely. In case you are reading this, let me know, and I'll start to share it.
#+BEGIN_SRC emacs-lisp

View file

@ -650,6 +650,9 @@ Ways to search for information goes under the ~s~ key. This primarily depends on
#+BEGIN_SRC emacs-lisp
(use-package rg
:init ; I sometimes call `grep`:
; (grep-apply-setting 'grep-command "rg -n -H --no-heading -e ")
:config
(ha-leader
"s" '(:ignore t :which-key "search")
@ -1215,6 +1218,17 @@ I primarily use [[https://github.com/jaypei/emacs-neotree][Neotree]] when I am s
(evil-define-key 'normal neotree-mode-map (kbd "g") 'neotree-refresh)
(evil-define-key 'normal neotree-mode-map (kbd "H") 'neotree-hidden-file-toggle))
#+END_SRC
** Demo It
Making demonstrations /within/ Emacs with [[https://github.com/howardabrams/demo-it][demo-it]].
#+BEGIN_SRC emacs-lisp
(use-package demo-it
:straight (:type git :protocol ssh :host github :repo "howardabrams/demo-it")
:commands (demo-it-create demo-it-start))
#+END_SRC
Perhaps I should change the reference to this for more local development:
#+begin_example
:straight (:local-repo "~/other/demo-it")
#+end_example
* Technical Artifacts :noexport:
Let's provide a name so that the file can be required:

View file

@ -68,7 +68,7 @@ According to Ben Maughan and [[http://pragmaticemacs.com/emacs/to-eww-or-not-to-
#+END_SRC
Finally, we can add it to the =apps= menu:
#+BEGIN_SRC emacs-lisp
(ha-leader "a e" 'elfeed)
(ha-leader "a f" 'elfeed)
#+END_SRC
* The Feeds :elfeed:
** Personal :personal:

View file

@ -319,10 +319,10 @@ To make the snippets more context aware, this predicate
Keybindings available to all file buffers:
#+NAME: global-keybindings
#+BEGIN_SRC emacs-lisp :tangle no
(ha-leader
"o l" '("store link" . org-store-link)
"o x" '("org capture" . org-capture)
"o c" '("clock out" . org-clock-out))
(ha-leader
"o l" '("store link" . org-store-link)
"o x" '("org capture" . org-capture)
"o c" '("clock out" . org-clock-out))
#+END_SRC
Bindings specific to org files:
@ -332,9 +332,9 @@ Bindings specific to org files:
"e" '("exports" . org-export-dispatch)
"I" '("insert id" . org-id-get-create)
"l" '("insert link" . org-insert-link)
"n" '("store link" . org-store-link)
"N" '("store link" . org-store-link)
"o" '("goto link" . ace-link-org)
"p" '("set property" . org-set-property)
"P" '("set property" . org-set-property)
"q" '("set tags" . org-set-tags-command)
"t" '("todo" . org-todo)
"T" '("list todos" . org-todo-list)

View file

@ -22,7 +22,103 @@ A literate configuration for accessing remote systems.
;;
;;; Code:
#+END_SRC
* Introduction
* Local Terminals
The following section configures my Terminal experience, both inside and outside Emacs.
** Eshell
I used to use [[http://www.howardism.org/Technical/Emacs/eshell.html][Eshell all the time]], but now I've migrated most of /work/ directly into Emacs (rewriting all those shell scripts a Emacs Lisp code). However, a shell is pretty good for my brain at organizing files (old habits, maybe).
First, my /aliases/ follow me around, and the following creates the alias file, =~/.emacs.d/eshell/alias=:
#+BEGIN_SRC shell :tangle (identity eshell-aliases-file) :mkdirp yes
alias ll ls -l $*
alias clear recenter 0
alias emacs 'find-file $1'
alias e 'find-file $1'
alias ee 'find-file-other-window $1'
alias grep 'rg -n -H --no-heading -e "$*"'
alias find 'echo Please use fd instead.' # :-)
#+END_SRC
Since that file already exists (probably), the following command may not be necessary:
#+BEGIN_SRC emacs-lisp
(use-package eshell
:custom
(eshell-kill-on-exit t)
(eshell-destroy-buffer-when-process-dies t)
:hook
(eshell-exit . (lambda () (delete-window))))
#+END_SRC
I usually want a new window running Eshell, that is smaller than the current buffer:
#+BEGIN_SRC emacs-lisp
(defun eshell-there (parent)
"Open an eshell session in a PARENT directory
in a smaller window named after this directory."
(let ((name (thread-first parent
(split-string "/" t)
(last)
(car)))
(height (/ (window-total-height) 3)))
(split-window-vertically (- height))
(eshell "new")
(rename-buffer (concat "*eshell: " name "*"))
(insert (concat "ls"))
(eshell-send-input)))
#+END_SRC
We either want to start the shell in the same parent as the current buffer, or at the root of the project:
#+BEGIN_SRC emacs-lisp
(defun eshell-here ()
"Opens up a new shell in the directory associated with the
current buffer's file. Rename the eshell buffer name to match
that directory to make multiple eshell windows easier."
(interactive)
(eshell-there (if (buffer-file-name)
(file-name-directory (buffer-file-name))
default-directory)))
(defun eshell-project ()
"Open a new shell in the project root directory, in a smaller window."
(interactive)
(eshell-there (projectile-project-root)))
#+END_SRC
Add my org-specific predicates, see this [[http://www.howardism.org/Technical/Emacs/eshell-fun.html][this essay]] for the details:
#+BEGIN_SRC emacs-lisp
(defun eshell-org-file-tags ()
"Helps the eshell parse the text the point is currently on,
looking for parameters surrounded in single quotes. Returns a
function that takes a FILE and returns nil if the file given to
it doesn't contain the org-mode #+FILETAGS: entry specified."
;; Step 1. Parse the eshell buffer for our tag between quotes
;; Make sure to move point to the end of the match:
(if (looking-at "'\\([^)']+\\)'")
(let* ((tag (match-string 1))
(reg (rx bol "#+FILETAGS: "
(zero-or-more any)
word-start
(literal tag)
word-end
(zero-or-more any)
eol)))
(goto-char (match-end 0))
;; Step 2. Return the predicate function:
;; Careful when accessing the `reg' variable.
`(lambda (file)
(with-temp-buffer
(insert-file-contents file)
(re-search-forward ,reg nil t 1))))
(error "The `T' predicate takes an org-mode tag value in single quotes.")))
(defvar eshell-predicate-alist nil
"A list of predicates than can be applied to a globbing pattern.")
(add-to-list 'eshell-predicate-alist '(?T . (eshell-org-file-tags)))
#+END_SRC
* Remote Terminals
Sure =iTerm= is nice for connecting and running commands on remote systems, however, it lacks a command line option that allows you to select and manipulate the displayed text without a mouse. This is where Emacs can shine.
*Feature One:*
@ -58,8 +154,36 @@ Working with remote shell connections programmatically, for instance:
Actually the =win-name= in this case is optional, as it will use a good default.
* Variables
** VTerm
I'm not giving up on Eshell, but I am playing around with [[https://github.com/akermu/emacs-libvterm][vterm]], and it is pretty good, but I use it primarily as a more reliable approach for remote terminal sessions.
VTerm has an issue (at least for me) with ~M-Backspace~ not deleting the previous word, and yeah, I want to make sure that both keystrokes do the same thing.
#+BEGIN_SRC emacs-lisp :tangle no
(use-package vterm
:init
(setq vterm-shell "/usr/local/bin/fish")
;; Granted, I seldom pop out to the shell except during code demonstrations,
;; but I like how C-p/C-n jumps up to each prompt entry using this setting
;; that works with my prompt:
(setq vterm-use-vterm-prompt-detection-method nil
term-prompt-regexp "^.* $ ")
:config
(dolist (k '("<C-backspace>" "<M-backspace>"))
(define-key vterm-mode-map (kbd k)
(lambda () (interactive) (vterm-send-key (kbd "C-w")))))
(advice-add 'vterm-copy-mode :after 'evil-normal-state))
#+END_SRC
The advantage of running terminals in Emacs is the ability to copy text without a mouse. For that, hit ~C-c C-t~ to enter a special copy-mode. If I go into this mode, I might as well also go into normal mode to move the cursor.
*Note:* To exit the copy-mode (and copy the selected text to the clipboard), hit ~Return~.
Hrm. Seems that I might want a function to copy the output of the last command to a register, or even an org-capture...
** Variables
Let's begin by defining some variables used for communication between the functions.
#+BEGIN_SRC emacs-lisp
@ -79,7 +203,7 @@ Also, let's make it easy for me to change my default shell:
"The executable to the shell I want to use locally.")
#+END_SRC
* Interactive Interface to Remote Systems
** Interactive Interface to Remote Systems
The function, =ha-ssh= pops up a list of /favorite hosts/ and then uses the =vterm= functions to automatically SSH into the chosen host:
@ -149,7 +273,7 @@ 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
** Programmatic Interface
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:
@ -207,7 +331,7 @@ Let's have a quick way to bugger out of the terminal:
(delete-window))
#+END_SRC
* Editing Remote Files
** Editing Remote Files
TRAMP, when it works, is amazing that we can give it a reference to a remote directory, and have =find-file= magically autocomplete.
@ -238,7 +362,7 @@ We can even edit it as root:
(ha-ssh--find-file tramp-ssh-ref other-window)))
#+END_SRC
* OpenStack Interface
** OpenStack Interface
Instead of making sure I have a list of remote systems already in the favorite hosts cache, I can pre-populate it with a call to OpenStack (my current VM system I'm using). These calls to the =openstack= CLI assume that the environment is already filled with the credentials. Hey, it is my local laptop ...
@ -324,15 +448,18 @@ Emacs), hit =C-c C-k=."
This file, so far, as been good-enough for a Vanilla Emacs installation, but to hook into Doom's leader for some sequence binding, this code isn't:
#+BEGIN_SRC emacs-lisp
(ha-leader
"a s" '(:ignore t :which-key "ssh")
"a s v" '("vterm" . vterm)
"a s o" '("overcloud" . ha-ssh-overcloud)
"a s l" '("local shell" . ha-shell)
"a s s" '("remote shell" . ha-ssh)
"a s q" '("quit shell" . ha-ssh-exit)
"a s f" '("find-file" . ha-ssh-find-file)
"a s r" '("find-root" . ha-ssh-find-root))
(ha-leader
"a e" '("eshell" . eshell-here)
"a E" '("top eshell" . eshell-project)
"a s" '(:ignore t :which-key "ssh")
"a s v" '("vterm" . vterm)
"a s o" '("overcloud" . ha-ssh-overcloud)
"a s l" '("local shell" . ha-shell)
"a s s" '("remote shell" . ha-ssh)
"a s q" '("quit shell" . ha-ssh-exit)
"a s f" '("find-file" . ha-ssh-find-file)
"a s r" '("find-root" . ha-ssh-find-root))
#+END_SRC
* Technical Artifacts :noexport: