Emacs

emacs notes

  • toggle-debug-on-quit for stacktraces of hung commands
  • pgtk enabled broadwayd port 8080 with apps env var GDK_BACKEND=broadway
  • magit-generate-changelog for commit msg
  • gnus needs app password from google for 2fa or oauth token from gcloud
  • webkit environment variable(s) for built-in browser
    • WEBKIT_FORCE_SANDBOX="0" is obe use WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1
      • maybe set GST_PLUGIN_PATH
  • android port manual entry specifies enabling 'special app permissions' for all files to access /sdcard
    • android port of fdroid is old and branch is unmerged; newer builds are on sourceforge
      • custom build of termux for supporting utils
  • signal-cli integration init signal-cli link --name device_name | head -1 | qrencode --type=UTF8
(use-package! signal-msg ; https://github.com/AsamK/signal-cli
  :commands (signal-msg-new-message) ; jam/signal-msg-rec
  :config (setq signal-msg-username (alist-get 'secret (auth-source-pass-parse-entry "signal/account"))
                signal-msg-number (alist-get 'secret (auth-source-pass-parse-entry "signal/phone")))
  (advice-add 'signal-msg-send :override #'jam/signal-msg-send))

;;;###autoload
(defun jam/signal-msg-send ()
  "Override to use -a account notation and stdin for sending buffer to signal-cli"
  (interactive)
  (let ((exit-code (call-process-region
                    (point-min)
                    (point-max)
                    "signal-cli"
                    nil                                  ; delete
                    nil                                  ; buffer
                    nil                                  ; display
                    "-a" signal-msg-number "send" "--message-from-stdin" signal-msg-dest-number)))
    (if (= exit-code 0)
        (kill-buffer)
      (warn (format "Something went wrong. signal-cli returned %d" exit-code)))))

;;;###autoload
(defun jam/signal-msg-rec ()
  "Reads all json encoded messages from signal-cli into *Signal* buffer"
  (interactive)
  (with-temp-buffer (progn (call-process "signal-cli" nil (current-buffer) nil "--output=json" "receive"); (call-process "cat" nil (current-buffer) nil "signals.json")
                           ;(message "current buffer is %s " (buffer-string))
                           (goto-char (point-min))
                           (unwind-protect
                               (while (not (eobp))
                                 (let* (;(message-json (json-read-file "signals.json"))
                                        (message-json (json-read))
                                        (message-content (alist-get 'envelope message-json ))
                                        (message-from (alist-get 'sourceName message-content))
                                        (message-data (alist-get 'dataMessage message-content))
                                        (message-text (alist-get 'message message-data)))
                                   ;(message "\nFrom: %s\nMessage: %s\n" message-from message-text)
                                   (with-current-buffer (get-buffer-create "*Signal*") (insert (format "\nFrom: %s\nMessage: %s\n" message-from message-text)))))))))
  • German air control ATC ran on emacs in the 90's
  • calc can plot with gnuplot
    • set yrange [0:50], set xrange [0:2200], plot 4 * sqrt(x + 10) / log10(x + 10) - 4 * sqrt(10)

org-mode notes

  • noweb can link code verbatium with or evaluate it with ()
  • #+INCLUDE "file.org::selector" :only-contents t to select heading contents to include from other files
  • disable tangling with :tangle no on src blocks
(ignore-errors
  (let* ((base-dir (file-name-directory (or load-file-name buffer-file-name)))
         (readme (concat base-dir (file-name-as-directory "..") (file-name-as-directory "..") "README.org"))
         (readme-time (file-attribute-modification-time (file-attributes readme)))
         (emacs-org (concat base-dir "emacs.org"))
         (emacs-org-time (file-attribute-modification-time (file-attributes emacs-org))))
    (if (time-less-p emacs-org-time readme-time); set timestamp of emacs.html when readme.org has newer edits
      (set-file-times (concat base-dir "emacs.html") (time-add readme-time (seconds-to-time 1))))))

emacs-config README

This configuration is for emacs >= 29

Third party packages:

guix: package/environment management. alternative is cli and setting exec-path-from-shell/environment

pass/pass-otp: frontend to password-store. alternative is cli

eat: graphical terminal emulation. alternative is built-in multi-term w/o visual commands

magit/forge/code-review: git/forge manipulation. alternative is built-in vc that lacks complex workflows like interactive rebase, forge pull requests or code review comments

debbugs: track emacs/guix bugs. alternative is bookmarking websites/mailing lists

transmission: manage torrent client. alternative is cli

org-roam: tag system for note database. alternative is self devised naming/search scheme with org-captured datetree journal

undo-tree: undo edit persist restarts. alternative is built-in undo with session persistence redone

company: automatic typing suggestions. alternative is corfu with cape

minions-mode: keeps the modeline visually brief with retained information. alternative is diminish/delight packages and config for each mode

which-key: show keymap keybinds. alternative is describe-* functions for bind discovery

osm: Map tile viewer. alternative is web browser viewing

dape/geiser-guile/pyvenv/(rust,yaml,python)-tree-sitter/combobulate?/eglot-x?: language specific modes with more than regex

Clone

Branch names diverging and "." complicate fetching the correct heads.

git clone --single-branch --recurse-submodules --shallow-submodules --depth=1 git@github.com:jamartin9/emacs-config.git
# get branch heads
git submodule foreach 'git checkout master'

Tangle Install

Emacs untangles the script from the org file (using noweb to copy/eval code) while expanding INCLUDE directives. Tangling is rerun when the org file is newer than the script (if present) and the html file. Cleanup is done via the clean arguments to the make-el wrapper. The wrapper is needed for org-roam, org-ids and html export tags.

pwsh make-el.ps1 install

Link

Installable org files tangle to a script of the same name for installation. The script needs itself and emacs on the PATH or CWD.

(ignore-errors
      (make-symbolic-link (file-name-directory (or load-file-name buffer-file-name)) (concat (file-name-as-directory (if (getenv "XDG_CONFIG_HOME") (getenv "XDG_CONFIG_HOME") (concat (file-name-as-directory (getenv "HOME")) ".config"))) "emacs")))

Run

The one line org-mode sesquicolon 'shebang' is a multipart shell/powershell wrapper. Passed arguments to the elisp script are available by argv (ignoring “–” and “$@”). To run with powershell use the same wrapper format with a .ps1 extension.

":"; emacs -Q --script README.sh -- $@ $args ; exit $? # -*- mode: emacs-lisp; lexical-binding: t; -*-

Cherry Picking

Copy files by url with emacs

(url-copy-file "https://raw.githubusercontent.com/jamartin9/emacs-config/master/init.el" "init.el")
(url-copy-file "https://raw.githubusercontent.com/jamartin9/emacs-config/master/early-init.el" "early-init.el")
(call-process "git" nil t nil "clone" "https://github.com/jamartin9/emacs-config")

Site

Clone the site

git worktree add --track -b gh-pages ./gh-pages origin/gh-pages

Build the updated site

pwsh make-el.ps1 site