Emacs
emacs notes
toggle-debug-on-quit
for stacktraces of hung commands- pgtk enabled
broadwayd
port 8080 with apps env varGDK_BACKEND=broadway
(deprecated in GTK 5) - 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 useWEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1
- maybe set
GST_PLUGIN_PATH
- maybe set
- 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
- android port of fdroid is old and branch is unmerged; newer builds are on sourceforge
- signal-cli integration init
signal-cli link --name device_name | head -1 | qrencode --type=UTF8
- guile scheme port of emacs lisp https://codeberg.org/ramin_hal9001/gypsum/
- guile-emacs project https://git.hcoop.net/bpt/emacs.git
(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)))))))))
;;;###autoload (defun jam/guix-env() "Guix variables for local guix daemon/client" (interactive) (require 'xdg) (setenv "GUIX_DAEMON_SOCKET" (concat (file-name-as-directory (xdg-data-home)) (file-name-as-directory "guix") (file-name-as-directory "var") (file-name-as-directory "guix") (file-name-as-directory "daemon-socket") "socket")) (setenv "GUIX_DATABASE_DIRECTORY" (concat (file-name-as-directory (xdg-data-home)) (file-name-as-directory "guix") (file-name-as-directory "var") (file-name-as-directory "guix") "db")) (setenv "GUIX_LOG_DIRECTORY" (concat (file-name-as-directory (xdg-data-home)) (file-name-as-directory "guix") (file-name-as-directory "var") (file-name-as-directory "log") "guix")) (setenv "GUIX_STATE_DIRECTORY" (concat (file-name-as-directory (xdg-data-home)) (file-name-as-directory "guix") (file-name-as-directory "var") "guix")) (setenv "GUIX_CONFIGURATION_DIRECTORY" (concat (file-name-as-directory (xdg-config-home))(file-name-as-directory "guix") "etc")) (setenv "GUIX_LOCPATH" (concat (file-name-as-directory (xdg-data-home)) (file-name-as-directory "guix") (file-name-as-directory "var") (file-name-as-directory "guix") (file-name-as-directory "profiles") (file-name-as-directory "per-user") (file-name-as-directory "root") (file-name-as-directory "guix-profile") (file-name-as-directory "lib") "locale")) (setenv "NIX_STORE" (concat (file-name-as-directory (xdg-data-home)) (file-name-as-directory "guix") (file-name-as-directory "gnu") "store")) ; NIX_STORE_DIR (setenv "PATH" (concat (getenv "PATH") path-separator (concat (file-name-as-directory (xdg-data-home)) (file-name-as-directory "guix") "bin"))))
(use-package newsticker :ensure nil ; built-in :commands (newsticker-start newsticker-treeview newsticker-plainview newsticker-stop) :bind (:map jam/open ("n" . newsticker-treeview) :map jam/toggle ("n" . newsticker-stop) :map newsticker-treeview-item-mode-map ("d" . (lambda () (interactive); Download the current newsticker enclosure to tmpdir/newsticker/feed/title (let* ((item (newsticker--treeview-get-selected-item)) (feedname "newsticker") (title (newsticker--title item)) (enclosure (newsticker--enclosure item)) (download-dir (file-name-as-directory (expand-file-name (newsticker--title (newsticker--treeview-get-selected-item)) (expand-file-name feedname (expand-file-name "newsticker" temporary-file-directory)))))) (newsticker-download-enclosures feedname item) (message download-dir))))) :init (setq newsticker-frontend 'newsticker-treeview newsticker-dir (concat user-emacs-directory (file-name-as-directory ".local") (file-name-as-directory "cache") "newsticker") newsticker-automatically-mark-items-as-old nil newsticker-automatically-mark-visited-items-as-old t newsticker-url-list-defaults nil newsticker-url-list '(("styx" "https://odysee.com/$/rss/@Styxhexenhammer666:2"))))
- 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 notes
- early-init will use guix-home packages if emacs package directory exists inside it otherwise uses use-package to download
- Pure elisp instead of makefiles and shell scripts
- sesquicolon 'shebang'
- build system
- runs any untangled elisp scripts
- sets timestamps
- exports custom elements for html/org-roam and expands INCLUDE directives
- build site
- git worktree
- sitemap self untangles an org document
- site search uses sqlite fts index and stores the db in opfs for reuse
- copy js, css, png, sqlite db, etc by timestamp
- migrated css from custom hand rolled to bulma then to pico for better defaults and less configuration
- navbar contains index/sitemap links
- INCLUDE in each page for css/navbar
- wraps couple common commands
- org roam dialies are a date tree journal
- tangled files set own timestamps in scripts
- defaults copied from doom/spacemacs when dropped
- all keys bounds under C-c c
- prefer defaults when possible
- prefer eshell for tramp traversal
- gnus over newsticker as more backends and own the frame
- prefix named interactive commands over inline functions for M-x and binds
- added mouse clicking to command buffer
- special case handling of Files:
- android support with termux build
- save files locally under .local/cache and .local/etc
- do not hardcode paths and use xdg
- tricks to speed up init
- defer package loading with use-package
- skip packages at startup
- add memory for skipping gc
- unbinding file-handler matching
- native code
- package-quickstart
- autoload functions
- dump saves a little time
- after-init hooks
- setq inhibits-*
- disable frame features without loading
- gc with idle timer
- cua for copy/paste
- xterm/broadwayd/daemon support
- transparent background
- extra mouse support
- sound alert
- packages in README for extras
- functions under
M-x jam/
prefix- sudo-edit
- auth-display
- vendored totp implementation for authinfo password storage
- draw
- eshell
- save-all (buffers)
- mpv-play
- screenshot
- image-crop is a bind
- ffmpeg for resize
ffmpeg -i cropped.png -vf "scale=1280:720" scaled.png
- replace unicode
- ZERO WIDTH NO-BREAK SPACE(BOM), ZERO WIDTH SPACE, RIGHT-TO-LEFT MARK, RIGHT-TO-LEFT OVERRIDE, LEFT-TO-RIGHT MARK, OBJECT REPLACEMENT CHARACTER
- compile-init-bytecode
- functions under
emacs-config README
This configuration is for emacs >= 30
Third party packages:
guix: package/environment management. alternative is cli and setting exec-path-from-shell/environment
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 org-node or self devised naming/search scheme with a datetree journal
undo-tree: undo edit persist restarts. alternative is built-in undo with session persistence redone
minions-mode: keeps the modeline visually brief with retained information. alternative is diminish/delight packages and config for each mode
osm: Map tile viewer. alternative is web browser viewing
gptel: interface with llms. alternative is llm package or cli
dape/geiser-guile/pyvenv/(rust,yaml,python)-tree-sitter: language specific modes with more than regex.
combobulate?: structural editing. alternative is regex
eglot-x?: rust-analyzer extensions for memory layout and structural-search-replace. alternative is to copy the functions
atomic-chrome?: counterpart to https://github.com/KarimAziev/chrome-emacs for using emacs to edit browser buffers. alternative is copy-paste
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