emacs setup
Table of Contents
- 1. Introduction
- 2. .emacs
- 2.1. misc
- 2.2. package bootstrapping
- 2.3. quality-of-life details
- 2.4. package: try
- 2.5. package: which-key
- 2.6. backup file location
- 2.7. prefer ibuffer
- 2.8. package: surround
- 2.9. package: highlight
- 2.10. track current directory reliably in
*shell*
buffers - 2.11. dynamic abbreviations
- 2.12. package: flycheck
- 2.13. package: ripgrep
- 2.14. completion assist
- 2.15. C++
- 2.16. Development
- 2.17. org-mode
- 2.18. email
- 2.19. eye candy: theme selection
- 2.20. emacsclient
1. Introduction
Roland Conybeare's curated emacs setup.
As of 6oct2023 using emacs version 29.0.91
, installed via the nix package manager.
~/.emacs
symlinks to ~/proj/env/dotfiles/emacs
from git repo https://github.com/Rconybea/env.git;
using this to streamline account setup on new hosts.
2. .emacs
2.1. misc
Compatibility with some Common Lisp idioms
(require 'cl-loaddefs)
2.2. package bootstrapping
(require 'package) ;;(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/")) (let ((repos '(("melpa" . "https://melpa.org/packages/") ;;("marmalade" . "http://marmalade-repo.org/packages/") ;;("elpa" . "http://elpa.gnu.org/packages/") ;;("elpa" . "http://tromey.com/elpa/") ;;("melpa" . "http://melpa.milkbox.net/packages/") ))) (while repos (add-to-list 'package-archives (car repos) t) (setq repos (cdr repos)))) (package-initialize) (when (not package-archive-contents) (package-refresh-contents)) (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package))
And some packages to autofetch
;; ---------------------------------------------------------------- ;; list of emacs packages to auto-install ;; (superseded by (use-package)...? I may be confused about this) ;; ---------------------------------------------------------------- ;; (defvar roland/packages '(surround treemacs highlight rg treemacs-projectile treemacs-magit lsp-mode lsp-treemacs lsp-ivy magit company flycheck exec-path-from-shell projectile yasnippet)) ;; install missing packages if they are whitelisted in roland/packages ;; (dolist (p roland/packages) (when (not (package-installed-p p)) (package-install p)))
2.3. quality-of-life details
2.3.1. qol: display
;; grab a little bit of extra screen real estate ;; disable scrollbars (if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1)) ;; disable toolbars (if (fboundp 'tool-bar-mode) (tool-bar-mode -1)) ;; disable menu bar (if (fboundp 'menu-bar-mode) (menu-bar-mode -1)) ;; prevent initial emacs splash screen (setq inhibit-splash-screen t)
2.3.2. qol: yes-or-no
;; don't like having to type 'yes' or 'no'; 'y' or 'n' will do (defalias 'yes-or-no-p 'y-or-n-p)
2.3.3. qol: nuke ctrl-Z
;; C-z bound to suspend frame is annoying, because ;; it gets typed by accident too often. ;; C-x C-z remains available as an alternative binding (global-unset-key (kbd "C-z")) (global-unset-key (kbd "<return>"))
2.3.4. qol: shortcut to bury current buffer
(global-set-key (kbd "C-x b") 'bury-buffer)
2.3.5. qol: navigation
(global-set-key (kbd "C-x t") 'beginning-of-buffer) (global-set-key (kbd "C-x e") 'end-of-buffer) ;; keeping window hopping to current frame allows for satellite frames that are ;; mostly display-only (e.g. magit status) ;; (global-set-key (kbd "C-x o") 'other-window) (global-set-key (kbd "C-x p") (lambda () (interactive) (other-window -1))) ;;(global-set-key "\C-xo" 'next-multiframe-window) ;;(global-set-key "\C-xp" 'previous-multiframe-window) (global-set-key (kbd "S-<left>") 'windmove-left) (global-set-key (kbd "S-<right>") 'windmove-right) (global-set-key (kbd "S-<up>") 'windmove-up) (global-set-key (kbd "S-<down>") 'windmove-down)
2.3.6. qol: kill
;; instead of kill-region, ;; prefer consistency with emacs-like keybindings e.g. gnu readline (global-set-key (kbd "C-w") 'backward-kill-word) ;; instead of C-w.. (global-set-key (kbd "C-x C-k") 'kill-region) (global-set-key (kbd "C-c C-k") 'kill-region)
This tweak allows using zap on necessary punctuation characters, without swallowing them.
;; use zap-up-to-char instead of zap-to-char (autoload 'zap-up-to-char "misc" "kill up to, but not including ARG'th occurence of CHAR. \(fn arg char)" 'interactive) (global-set-key "\M-z" 'zap-up-to-char)
2.3.7. qol: query replace
;; M-x qr --> M-x query-replace ;; M-x qrr --> M-x query-replace-regexp (defalias 'qr 'query-replace) (defalias 'qrr 'query-replace-regexp)
2.3.8. qol: mouse-3 on macos
;; mouse-3 annoying on macbook 11.3 (if (eq system-type 'darwin) (global-unset-key [mouse-3]))
2.3.9. qol: mouse avoidance
Don't let mouse icon obscure cursor
(mouse-avoidance-mode 'animate)
Make cursor and mouse easier to see
(set-mouse-color "red") (set-cursor-color "red")
2.4. package: try
;; the 'try' package lets us try a package without permanently installing it. ;; use ;; M-x try ${nameofpackage} ;; (use-package try :ensure t)
2.5. package: which-key
;; the 'which-key' package displays popup with key bindings following ;; currently entered incomplete command ;; (use-package which-key :ensure t :config (which-key-mode))
2.6. backup file location
;; backup location ;; (don't clutter filesystem with emacs backup files) (let ((backup-dir "~/tmp/emacs/backups") (auto-saves-dir "~/tmp/emacs/autosaves")) ;; create dirs if needed (dolist (dir (list backup-dir auto-saves-dir)) (when (not (file-directory-p dir)) (make-directory dir t))) (setq backup-directory-alist `(("." . ,backup-dir)) auto-save-file-name-transforms `((".*" ,auto-saves-dir t)) auto-save-list-file-prefix (concat auto-saves-dir ".saves-") ;; tramp-backup-directory-alist `((".*" . ,backup-dir)) ;; tramp-auto-save-directory auto-saves-dir ) (setq backup-by-copying t delete-old-versions t version-control t kept-new-versions 5 kept-old-versions 2) )
2.7. prefer ibuffer
;; ---------------------------------------------------------------- ;; replace list-buffers (^x^b) with ibuffer ;; ibuffer is much better (global-set-key "\C-x\C-b" 'ibuffer)
2.8. package: surround
Region selection based on matching parens
;; ---------------------------------------------------------------- ;; M-' i ( mark text up to but excluding surrounding (). ;; M-' ( will do the same ;; M-' o ( mark surrounding () can use either ( or ) to identify paren type ;; M-' ) will do the same ;; M-' s { surround word-around-point with {} ;; M-' d ( delete innermost surrounding pair of ()'s ;; M-' k ( kill surrounding text up to but not including innermost surrounding () pair ;; M-' K ( kill surrounding text including innermost surrounding () pair ;; (use-package surround :ensure t :bind-keymap ("M-'" . surround-keymap))
2.9. package: highlight
Manual highlighting
;; ---------------------------------------------------------------- ;; highlight.el ;; ;; C-x X u r unhighlight region ;; (use-package highlight :ensure t)
2.10. track current directory reliably in *shell*
buffers
;; ---------------------------------------------------------------- ;; Minor mode to track directory via /proc. ;; Will not work on macos! ;; (defun shell-procfs-dirtrack (str) ;;; shell-procfs-dirtrack --- use /proc/PID/cwd to track current working directory ;;; for emacs shell buffers. From emacswiki "Shell Dirtrack by Procfs" ;;; (prog1 str (when (string-match comint-prompt-regexp str) (let ((directory (file-symlink-p (format "/proc/%s/cwd" (process-id (get-buffer-process (current-buffer))))))) (when (file-directory-p directory) (cd directory)))))) ;; have to enable this ;; (define-minor-mode shell-procfs-dirtrack-mode "Track shell directory by inspecting procfs." nil nil nil (cond (shell-procfs-dirtrack-mode (when (bound-and-true-p shell-dirtrack-mode) (shell-dirtrack-mode 0)) (when (bound-and-true-p dirtrack-mode) (dirtrack-mode 0)) (add-hook 'comint-preoutput-filter-functions 'shell-procfs-dirtrack nil t)) (t (remove-hook 'comint-preoutput-filter-functions 'shell-procfs-dirtrack t)))) ;; ---------------------------------------------------------------- ;; command shell. ;; ;; invoking emacs from ;; nix develop -i ;; interferes with its ability to figure out suitable shell ;; tell emacs to use bash here ;; (setq-default shell-file-name "bash")
2.11. dynamic abbreviations
For consciously correcting typos
;; ---------------------------------------------------------------- ;; (global-set-key (kbd "C-<tab>") #'dabbrev-expand) (define-key minibuffer-local-map (kbd "C-<tab>") #'dabbrev-expand)
2.12. package: flycheck
Flycheck runs in the background. It automatically (and subtly) highlights syntax errors as you type. Preferred over built-in flyspell.
;; enable flycheck ;; see: ;; https://www.flycheck.org/en/latest/user/quickstart.html#flycheck-quickstart ;; ;; keybindings: ;; C-c ! v show version + configuration info for this buffer ;; C-c ! n / C-c ! p inspect errors on this line ;; C-c ! l show errors for this buffer (global-flycheck-mode) (if (eq system-type 'darwin) ;; need this for flycheck on macos only.. (exec-path-from-shell-initialize))
2.13. package: ripgrep
Projectile uses this automagically if available
;; ---------------------------------------------------------------- ;; ripgrep for search ;; see [[rg.el.readthedocs.io/en/latest/configuration.html]] ;; ;; rg-executable-per-connection ;; rg-custom-type-aliases ;; rg-prioritized -type-aliases ;; rg-default-alias-fallback ;; rg-command-line-flags ;; rg-group-result ;; rg-show-columns ;; rg-ignore-case ;; rg-hide-command t ;; rg-keymap-prefix "C-c s" ;; rg-use-transient-menu t ;; rg-show-header t ;; rg-buffer-name "rg" ;; rg-ignore-ripgreprc t ;; ...and more... ;; ;; See also rg-isearch to use ripgrep with isearch ;; (use-package rg :ensure t :init (progn (rg-enable-default-bindings) ;; want see rg command to debug it :) (setq rg-hide-command nil) ;; need filename to report line number for navigation with C-x ` to work (setq rg-command-line-flags nil) ;;(setq rg-use-transient-menu t) etc ;; trying to make it easy to visit match results in context (setq rg-group-result nil) ) )
2.14. completion assist
2.14.1. completion: ivy
;; ---------------------------------------------------------------- ;; ivy (completion assist) ;; ;; keybindings: ;; M-x ivy-mode disable/enable toggle ;; C-x b ivy-switch-buffer ;; C-c v ivy-push-view ;; C-c V ivy-pop-view ;; ivy-resume resume last ivy completion ;; ;; in minibuffer: ;; C-n ivy-next-line next line ;; C-p ivy-prev-line previous line ;; M-< ivy-beginning-of-buffer first candidate ;; M-> ivy-end-of-buffer last candidate ;; C-v ivy-scroll-up-command scroll up ivy-height lines ;; M-v ivy-scroll-down-command scroll down ivy-height lines ;; ;; actions (on selected choice): ;; c-M or RET ivy-done default action + exit minibuffer ;; M-o ivy-dispatching-done present menu of choices ;; C-j ivy-alt-done for file name, cd into selected dir candidate ;; TAB ivy-partial-or-done completion on current input ;; C-M-j ivy-immediate-done exit with current candidate (exact spelling) ;; C-' ivy-avy use avy to select from current candidate page ;; ;; C-M-m ivy-call non-exiting version of ivy-done ;; C-M-o ivy-dispatching-call non-exiting version of ivy-dispatching-done ;; ;; C-o hydra-ivy/body invoke hydra menu with short key bindings (use-package ivy :ensure t :init (progn (setq ivy-use-virtual-buffers t) (setq ivy-count-format "(%d/%d) ") (ivy-mode 1) (global-set-key (kbd "C-x b") 'ivy-switch-buffer) ;; or (bind-key "C-x b" 'ivy-switch-buffer) ) )
2.15. C++
2.15.1. c++: indenting + tabs
;; in general want to expand tabs, + use 4 characters (setq-default indent-tabs-mode nil) (setq-default tab-width 4) ;; used in style-specific modes, e.g. c++-mode ;; other styles: gnu | k&r | bsd | whitesmith | stroustrup | ellemtel | user ;; ;; C-c . <style> choose predefined style ;;(defvar 'c-default-style) ;;(defvar 'c-basic-offset) (setq-default c-default-style "linux") (setq-default c-basic-offset 4) (defun disable-tabs () "Function to disable tab insertion; intended to be attached via c++-mode-hook." (if (boundp 'indent-tabs-mode) (setq indent-tabs-mode nil) (error "Expected variable [indent-tabs-mode] to be defined") )) ;; in general disable tabs (expand to spaces) (add-hook 'c++-mode-hook 'disable-tabs)
2.15.2. c++: whitespace
;; will be using customized whitespace mode, that just highlights trailing spaces ;; (add-hook 'c++-mode-hook 'whitespace-mode) ;; tabs: visible tab characters ;; trailing: visible trailing whitespace ;; (setq-default whitespace-style '(face tabs tab-mark trailing)) ;; 124 is | character (setq-default whitespace-display-mappings '((tab-mark 9 [124 9] [92 9]))) (defun untabify-except-makefiles () "Replace tabs with spaces except in makefiles." (unless (derived-mode-p 'makefile-mode) (prog1 nil (untabify (point-min) (point-max)) (delete-trailing-whitespace) ))) (add-hook 'c++-mode-hook #'(lambda () (add-hook 'before-save-hook #'untabify-except-makefiles))) (add-hook 'nix-mode-hook #'(lambda () (add-hook 'before-save-hook #'untabify-except-makefiles)))
2.15.3. cmake editing
;; cmake mode ;; (use-package cmake-mode :ensure t :init (progn (setq cmake-tab-width 4) ) )
2.15.4. c++ completion
(use-package company :config (progn (setq company-minimum-prefix-length 1) ;; LOOKS LIKE MUST HAVE THIS for company to activate (setq company-idle-delay 0.1) ;; default 0.2 )) (add-hook 'c++-mode-hook 'company-mode)
2.15.5. compilation buffer
For example, to respond to cmake
colored output
;; ---------------------------------------------------------------- ;; xterm-color ;; ;; more modern package relative to ansi-color ;; see [[https://stackoverflow.com/questions/3072648/cucumbers-ansi-colors-messing-up-emacs-compilation-buffer]] ;; (defun my/advice-compilation-filter (f proc string) "colorize buffer output" (funcall f proc (xterm-color-filter string))) (defvar compilation-environment) (use-package xterm-color :ensure t :init (progn (setq compilation-environment '("TERM=xterm-256color")) (advice-add 'compilation-filter :around #'my/advice-compilation-filter)) )
2.16. Development
2.16.1. dev: snippets
;; snippets! ;; (see http://capitaomorte.github.io/yasnippet, ;; http://githib.com/capitaomorte/yasnippet) ;; snippets in ~/.emacs.d/elpa/yasnippet-20200604.246/snippets ;; ;; summary: ;; M-x yas-expand -- try to expand snippet before point. Usually TAB ;; M-x yas-load-directory -- load a directory of snippets ;; M-x yas-activate-extramode -- add snippets for a particular mode, in the current buffer ;; M-x yas-insert-snippet -- insert snippet at point ;; M-x yas-visit-snippet-file -- prompt for snippet expansion, but go to definition ;; M-x yas-new-snippet -- create a new snippet in ~/.emacs.d/snippets, function of major mode ;; M-x yas-load-snippet-buffer -- load the snippet you are editing C-c C-c in snippet-mode ;; M-x yas-tryout-snippet -- insert current snippet in a new empty buffer C-c C-t in snippet-mode ;; M-x yas-describe-tables -- list known snippets ;; (use-package yasnippet :ensure t :config (yas-global-mode 1)) (add-hook 'c++-mode-hook 'yas-minor-mode) (add-hook 'cmake-mode-hook 'yas-minor-mode) (add-hook 'emacs-lisp-mode-hook 'yas-minor-mode) (global-set-key (kbd "C-<return>") 'yas-expand) (global-set-key (kbd "C-c & C-n") 'yas-new-snippet) (global-set-key (kbd "C-c & C-v") 'yas-visit-snippet-file) ;;(yas-global-mode t) ;;;; yas-snippet-dirs ;;;; yas-installed-snippets-dir ;;;; (yas-reload-all)
2.16.2. dev: treemacs
;; ---------------------------------------------------------------- ;; treemacs (use-package treemacs :config (progn (setq treemacs-follow-after-init t treemacs-is-never-other-window t treemacs-width 40) (treemacs-follow-mode t) (treemacs-filewatch-mode t) (treemacs-git-mode 'simple) (treemacs-fringe-indicator-mode t) (treemacs-resize-icons 11) ;; default is 22 ) :hook (after-init . treemacs) :bind (:map global-map ("C-M-t" . treemacs)))
2.16.3. dev: projectile
;; projectile (defconst modi/rg-arguments `("--line-number" ; print line numbers "--smart-case" "--follow" ; follow symlinks "--mmap" ; use memory-map optimization where available ) "default rg args used in the `projectile` package.") (defun modi/advice-projectile-use-rg (mode) "always use `rg' to establish project file list" (mapconcat 'identity (append '("\\rg") ; unalised version of rg modi/rg-arguments '("--null" ; null-separated results "--files" ; locate + print file names (don't search them) )) " ")) (use-package projectile :ensure t :init (progn (projectile-mode +1) ;;(setq projectile-indexing-method 'native) -- want to use rg below (setq projectile-project-compilation-dir "") (setq projectile-enable-caching t) ;; using rg to identify project source files: ;; - honors .gitignore ;; - fast, too! (when (executable-find "rg") (progn (advice-add 'projectile-get-ext-command :override #'modi/advice-projectile-use-rg)))) :bind (:map projectile-mode-map ("s-p" . projectile-command-map) ("C-c p" . projectile-command-map)))
2.16.4. dev: treemacs+projectile integration
;; ---------------------------------------------------------------- ;; treemacs-projectile ;; use ;; M-x treemacs-add-project-to-workspace make project (directory tree) showup in treemacs ;; (use-package treemacs-projectile :ensure t )
2.16.5. dev: language server protocol (LSP)
;; ---------------------------------------------------------------- ;; language-server-protocol ;; +format-with-lsp: provided by lsp-mode (defvar +format-with-lsp) (defvar lsp-clients-clangd-args) ;; see: ;; https://emacs-lsp.github.io/lsp-mode (defun disable-lsp-format () "Disable clang-driven formatting via lsp to prefer emacs-native formatting." (setq +format-with-lsp nil)) (use-package lsp-mode :hook (lsp-mode . (lambda () ;; from [[https://github.com/emacs-lsp/lsp-mode/issues/1532]] (mar 2020) (let ((lsp-keymap-prefix "C-c l")) ; default s-l collides with windows key (lsp-enable-which-key-integration)))) :config (progn ;; reminder: :config runs *after* package is loaded (define-key lsp-mode-map (kbd "C-c l") lsp-command-map) (setq lsp-enable-indentation nil) ; disable clang indentation -- doesn't preserve newlines! (setq lsp-enable-on-type-formatting nil) (setq lsp-headerline-breadcrumb-enable t) ;; enable path-to-this-file headerline (setq lsp-modeline-diagnostics-enable t) (setq lsp-completion-provider :capf) (setq lsp-completion-show-detail t) ;; rhs of completion popup (setq lsp-completion-show-kind t) ;; semgrep crashing incessantly, looks like can't resolve host semgrep.dev? ;; *semgrep-ls::stderr* contains ;; TLS to non-TCP currenlty unsupported: host=semgrep.dev endp=(Unknown "name resolution failed") (setq lsp-disabled-clients '(semgrep-ls)) ;;(setq lsp-signature-render-documentation t) ;; include documentation with signatures (add-hook 'c++-mode-hook #'lsp-deferred) (add-hook 'c++-mode-hook #'disable-lsp-format) ;; additional clangd args: ;; --compile-commands-dir=path/to/compile_comamnds.json ;; (ed: prefer better discoverable with build-specific symlink in git root for each project) ;; --fallback-style ;; (ed: could use this instead of writing .clang-format) ;; --header-insertions=iwyu|never ;; --enable-config ;; (ed: docs at ;; --pch-storage=disk|memory (setq lsp-clients-clangd-args '("-j=4" "-background-index" "-log=error"))) ;;(add-hook 'python-mode-hook #'lsp) ) ;; ---------------------------------------------------------------- ;; lsp-ui-sideline: show info associated with symbols toward rhs of current line ;; lsp-ui-sideline-show-diagnostics ;; lsp-ui-sideline-show-hover ;; lsp-ui-sideline-show-code-actions ;; lsp-ui-sideline-update-mode ;; lsp-ui-sideline-delay ;; ;; lsp-ui-peek ;; examples ;; (define lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions) ;; (define lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references) ;; (lsp-ui-peek-jump-backward) ;; (lsp-ui-peek-jump-forward) ;; (lsp-ui-peek-find-workspace-symbol "pattern 0") ;; (lsp-ui-peek-find-custom 'base "$cquery/base") ;; ;; lsp-ui-peek-enable ;; lsp-ui-peek-show-directory ;; ;; lsp-ui-doc ;; lsp-ui-doc-enable ;; lsp-ui-doc-position ;; lsp-ui-doc-delay ;; lsp-ui-doc-show-with-cursor ;; lsp-ui-doc-show-with-mouse ;; ;; lsp-ui-imenu ;; lsp-ui-imenu-kind-position ;; lsp-ui-imenu-buffer-position ;; lsp-ui-imenu-window-width ;; lsp-ui-imenu-window-fix-width ;; lsp-ui-imenu--custome-mode-line-format ;; lsp-ui-imenu-auto-refresh ;; (use-package lsp-ui :ensure t :config (setq lsp-ui-sideline-show-diagnostics t) (setq lsp-ui-doc-enable t) ;; hover dialogs (setq lsp-ui-doc-show-with-cursor t) )
2.16.6. dev: lsp+ivy integration
;; ---------------------------------------------------------------- ;; LSP ivy integration ;; M-x lsp-ivy-worskpace-symbol ;; M-x lsp-ivy-global-workspace-symbol (use-package lsp-ivy :ensure t :bind (:map global-map ("M-g s" . lsp-ivy-workspace-symbol) ("M-g S" . lsp-ivy-global-workspace-symbol)) )
2.16.7. dev: git integration
;; ---------------------------------------------------------------- ;; git integration ;; C-x M-g j magit status buffer for current repo ;; ;; in status buffer: ;; d change diff parameters ;; -w suppress whitespace-only diffs ;; C-x extended menu ;; C-s save settings for future sessions ;; (use-package magit :ensure t :init (progn (bind-key "C-x M-g j" 'magit-status)))
2.16.8. dev: nix mode
Syntax highlighting in nix files
;; ---------------------------------------------------------------- ;; nix mode (syntax highlighting etc for .nix files) ;; (use-package nix-mode :ensure t)
2.16.9. dev: yaml mode
Syntax highlighting in yaml files
;; yaml mode (syntax highlighting etc for .yml, .yaml files) ;; (use-package yaml-mode :ensure t :init (progn (add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-mode))))
2.17. org-mode
2.17.1. org: publishing
;; org-mode publishing ;; (require 'ox-publish) ;; syntax highlighting in html exporter ;; (use-package htmlize :ensure t) ;; publishing setup -- this is a kitchen sink -- it's intended to cover ;; everything we want org-mode to publish ;; (setq org-publish-project-alist '( ("org-howto" :components ("org-howto-notes" "org-howto-static")) ("org-howto-notes" :base-directory "~/proj/org-howto" :base-extension "org" :publishing-directory "~/proj/public_html/org-howto" :recursive t :publishing-function org-html-publish-to-html :headling-levels 4 :auto-preamble t ) ("org-howto-static" :base-directory "~/proj/org-howto" :base-extension "md\\|css\\|html\\|js\\|svg\\|ico\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf" :publishing-directory "~/proj/public_html/org-howto" :recursive t :publishing-function org-publish-attachment ) ;; ----- non-public org stuff ----- ("org-private" :components ("org-private-notes" "org-private-static")) ("org-private-notes" :base-directory "~/proj/org-private" :base-extension "org" :publishing-directory "~/proj/private_html/org-private" :recursive t :publishing-function org-html-publish-to-html :headling-levels 4 :auto-preamble t ) ("org-private-static" :base-directory "~/proj/org-private" :base-extension "md\\|css\\|html\\|js\\|svg\\|ico\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|swf" :publishing-directory "~/proj/private_html/org-private" :recursive t :publishing-function org-publish-attachment ) ))
2.17.2. babel setup
For literate programming – execute code blocks, written in various languages, embedded in .org
files
;; ---------------------------------------------------------------- ;; org-mode babel setup ;; (execute dot/ditaa/bash/c++ etc. from .org code blocks) ;; ;; see ;; [[https://orgmode.org/worg/org-contrib/babel/intro.html]] ;; [[https://orgmode.org/worg/org-contrib/babel/languages/index.html]] ;; ;; code block: ;; #+begin_src ${language} ${switches} ${headerarguments} ;; ${body} ;; #+end_src ;; ;; use header argument ;; :results output ;; to insert code-block output (i.e. contents of stdout) into .org file below code block ;; ;; use ;; :results value ;; to just take value of last statement ;; ;; use ;; :session ;; to share language sub-process across code-blocks. ;; ;; can use ;; #+name: foo ;; to name an org-mode table; then: ;; #+begin_src ... :var myfreevar=foo ;; ... ;; #+end_src ;; with body mentioning myfreevar; .org will substitute foo ;; ;; can do inline coode block with ;; src_<${lang}>{${code}} or src_<${lang}[${args}]{${code}} ;; e.g. ;; src_python[:session]{10*x} ;; ;; notes: ;; [C-c C-v] org-babel prefix ;; [C-c C-v b] -- evaluate code blocks in buffer ;; [C-c C-v s] -- evaluate code blocks in subtree ;; [C-c C-v e] -- evaluate code block at point ;; [C-c '] M-x org-edit-src-code -- puts code block in new buffer with appropriate mode activated ;; [C-c M-b p] M-x org-babel-expand-src-block -- show expanded code block prior to evaluation ;; (org-babel-lob-ingest "path/to/file.org") to share code blogs as 'library' (org-babel-do-load-languages 'org-babel-load-languages '( (C . t) ; C,C++,D [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-C.html]] (ditaa .t) ; "diagrams through ascii art" (dot . t) ; graphviz [[https://orgmode.org/worg/org-contrib/babel/languages/ob-doc-dot.html]] see also graphviz-dot-mode ))
For ditaa
, need some paths. Nix makes these obscure, need to dig out the parts we want
;; extracted from command like ;; cat $(which ditaa) | sed -n -e '/^exec/s: -jar .*$::p' | sed -e 's:^exec ::' ;; expecting result like ;; /nix/store/6g5q62wafkpg0p3w854vc9yxy9bsnwi5-openjdk-19.0.2+7/bin/java ;; ;; the /usr/bin paths + /nix/store/.*ditaa.jar exprs for shmecurity ;; (setq org-babel-ditaa-java-cmd (shell-command-to-string "/usr/bin/cat $(which ditaa) | /usr/bin/sed -n -e '/^exec/s: -jar .*\$::p' | /usr/bin/sed -e 's:^exec ::' | /usr/bin/tr -d '\n'")) ;; extracted from command like ;; cat $(which ditaa) | grep ' -jar ' | sed -e 's:^exec.* -jar "::' -e 's:" "\$@"::' ;; expecting result like ;; /nix/store/in2hf1xcxr1i4rijw0g423kawr3624pv-ditaa-0.11.0/lib/ditaa.jar ;; ;; the /usr/bin paths + /nix/store/.*ditaa.jar exprs for shmecurity ;; (setq org-ditaa-jar-path (shell-command-to-string "/usr/bin/cat $(which ditaa) | /usr/bin/grep ' -jar ' | /usr/bin/sed -e 's:^exec.* -jar \"::' -e 's:\" \"\\$@\"::' | /usr/bin/grep '^/nix/store/.*ditaa.jar' | /usr/bin/tr -d '\n'")) ;; (setq org-ditaa-eps-jar-path "path/to/related/jar") ;; not using, but if so would need it
2.18. email
2.18.1. incoming mail
Using notmuch
for incoming mail (notmuch
configured using notmuch setup
)
;; ---------------------------------------------------------------- ;; local email storage ;; ;; 1. sync email (e.g. fetch remote emails) with ;; $ mbsync -a ;; ;; 2. apply rules locally (move emails to folders etc.) with ;; $ cleanmbox ;; ;; 3. sync email again (e.g. propagate changes back to remote mailboxes) ;; $ mbsync -a ;; ;; 4. to read email from local copy, use ;; M-x notmuch ;; ;; show ;; to see everything ;; ;; use [M-x customize-group RET notmuch RET] to customize ;; use [M-x notmuch] to invoke ;; in a [*notmuch-hello*] buffer, use ;; folder:gmail/.health ;; to see messages in ;; ${MAILDIR}/gmail/.health (require 'notmuch)
2.18.2. outgoing mail
(require 'smtpmail) (setq user-mail-address "alice@gmail.com" user-full-name "Alice Exampleton") (setq message-send-mail-function 'smtpmail-send-it) (setq smtpmail-stream-type 'starttls smtpmail-smtp-server "smtp.gmail.com" smtpmail-smtp-service 587 ) ;; prevent send buffers accumulating (setq message-kill-buffer-on-exit t)
Note: smtpmail
also requires credentials in ~/.authinfo
:
machine smtp.gmail.com login rconybeare@gmail.com port 587 password somegoogleapppassword
2.19. eye candy: theme selection
;; ---------------------------------------------------------------- ;; theme selection (load-theme 'misterioso t)
2.19.1. eye candy: default font
;; ---------------------------------------------------------------- ;; default font ;; note: ;; C-x C-+ increase buffer text size ;; C-x C-= something buffer text size ;; C-x C-- decrease buffer text size ;; C-x C-0 restore default buffer text size ;; M-x describe-font display font canonical name + stats in a new buffer ;; ;; to install inconsolata on ubuntu: ;; $ sudo apt-get -y install fonts-inconsolata ;; for nix, can use package ;; nixpkgs.inconsolata-lgc (add-to-list 'default-frame-alist '(font . "-PfEd-Inconsolata-medium-normal-normal-*-14-*-*-*-m-0-iso10646-1"))
2.19.2. eye candy: initial window height
(defvar target-frame-width (+ 1 (* 2 135))) (defun set-frame-size-from-screen-resolution () "Infer suitable default frame size. Reminder: no such thing as .Xresources under WSL." (interactive) (if (display-graphic-p) (progn (let* ((horizontal-room (/ (x-display-pixel-width) (frame-char-width))) (using-width (min target-frame-width horizontal-room))) (set-frame-width (selected-frame) using-width) ;;(add-to-list 'default-frame-alist (cons 'width using-width)) ) ;; subtracting 200 pixels of vertical space (let* ((vertical-padding 100) (vertical-room (/ (- (x-display-pixel-height) vertical-padding) (frame-char-height)))) (set-frame-height (selected-frame) vertical-room) ;;(add-to-list 'default-frame-alist (cons 'height vertical-room)) )))) (set-frame-size-from-screen-resolution)
2.20. emacsclient
EDITOR=emacsclient
to adopt running emacs session when unix wants something edited.
For example when running git commit
from shell.
;; + set EDITOR=emacsclient in shell (server-start)