752 lines
22 KiB
Org Mode
752 lines
22 KiB
Org Mode
#+PROPERTY: header-args:emacs-lisp :tangle yes
|
|
#+TITLE: Emacs Configuration
|
|
* Literate emacs configuration
|
|
|
|
I can never rembember what various configs do. Jumping on this literate emacs
|
|
config to see if it helps!
|
|
|
|
** Start the emacs server
|
|
|
|
Starting as a server lets me connect externally to do things like change
|
|
themes, save buffers via cron and other such dumbary!
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'bind-key)
|
|
(load "server")
|
|
(unless (server-running-p) (server-start))
|
|
#+end_src
|
|
|
|
** Interface and Behavior
|
|
*** Interface
|
|
|
|
Global font
|
|
#+begin_src emacs-lisp
|
|
(set-frame-font "Go Mono 11")
|
|
#+end_src
|
|
|
|
Use 80 columns, this helps keep things readable when windows are split
|
|
#+begin_src emacs-lisp
|
|
(setq whitespace-style '(trailing lines space-before-tab)
|
|
whitespace-line-column 80)
|
|
(setq-default fill-column 80)
|
|
#+end_src
|
|
|
|
I know I am in emacs, don't need to see the startup screen.
|
|
#+begin_src emacs-lisp
|
|
(setq inhibit-startup-screen t)
|
|
#+end_src
|
|
|
|
**** Use UTF8 where ever possible
|
|
#+begin_src emacs-lisp
|
|
(prefer-coding-system 'utf-8)
|
|
(set-default-coding-systems 'utf-8)
|
|
(set-terminal-coding-system 'utf-8)
|
|
(set-keyboard-coding-system 'utf-8)
|
|
#+end_src
|
|
|
|
**** Change various UI bits
|
|
#+begin_src emacs-lisp
|
|
(tool-bar-mode -1)
|
|
(menu-bar-mode -1)
|
|
(scroll-bar-mode -1)
|
|
(column-number-mode +1)
|
|
(global-font-lock-mode 1)
|
|
#+end_src
|
|
|
|
**** direnv
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package direnv
|
|
:config
|
|
(direnv-mode))
|
|
#+end_src
|
|
|
|
**** project.el
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq project-list-file (expand-file-name "~/.emacs.d/projects"))
|
|
#+end_src
|
|
|
|
**** transient
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq transient-history-file (expand-file-name "~/.emacs.d/transient"))
|
|
#+end_src
|
|
|
|
*** Behavior
|
|
|
|
Switch various defaults to be more comfortable for myself.
|
|
|
|
#+begin_src emacs-lisp
|
|
(fset 'yes-or-no-p 'y-or-n-p)
|
|
(show-paren-mode t)
|
|
|
|
(setq desktop-dirname "~/.emacs.d/"
|
|
desktop-base-file-name "emacs.desktop"
|
|
desktop-base-lock-name "lock"
|
|
desktop-path (list desktop-dirname)
|
|
desktop-save t
|
|
desktop-files-not-to-save "^$" ;reload tramp paths
|
|
desktop-load-locked-desktop nil
|
|
desktop-auto-save-timeout 30)
|
|
(desktop-save-mode 1)
|
|
|
|
(setq backup-directory-alist '(("." . "~/.emacs-saves")))
|
|
(setq auto-mode-alist
|
|
(append
|
|
(list
|
|
'("\\.gpg$" . sensitive-minor-mode)
|
|
)
|
|
auto-mode-alist))
|
|
(setq auth-sources
|
|
'("/run/secrets/netrc"))
|
|
#+end_src
|
|
|
|
Use spelling and auto-fill when we are in text mode.
|
|
|
|
#+begin_src emacs-lisp
|
|
(add-hook 'text-mode-hook (lambda ()
|
|
(auto-fill-mode 1)
|
|
(turn-on-flyspell)))
|
|
#+end_src
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq eshell-history-file-name (expand-file-name "~/.emacs.d/eshell/history"))
|
|
#+end_src
|
|
** Unset custom-file
|
|
|
|
The customization file mostly just causes churn in the SCM so we disable it
|
|
here.
|
|
#+begin_src emacs-lisp
|
|
(setq custom-file (make-temp-file ""))
|
|
#+end_src
|
|
|
|
* Packages
|
|
|
|
** rust-mode
|
|
#+begin_src emacs-lisp
|
|
(use-package rust-mode)
|
|
#+end_src
|
|
|
|
** uxntal
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package uxntal-mode)
|
|
#+end_src
|
|
|
|
** breadcrumb
|
|
|
|
Handy breadcrumbs for seeing where things are in the LSP.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package breadcrumb)
|
|
#+end_src
|
|
|
|
** ollama
|
|
|
|
Simple wrapper for ~ollama~ that lets me pipe regions and what not into various buffers.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package ollama
|
|
:init
|
|
(setopt
|
|
ollama:endpoint "https://ollama.otter-alligator.ts.net/api/generate"
|
|
ollama:language "English"
|
|
ollama:model "llama3.1"))
|
|
#+end_src
|
|
|
|
** web-mode
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package web-mode
|
|
:config
|
|
(setq web-mode-markup-indent-offset 2)
|
|
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.php?\\'" . web-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.ts?\\'" . web-mode))
|
|
(add-to-list 'auto-mode-alist '("\\.js?\\'" . web-mode)))
|
|
#+end_src
|
|
|
|
** scpaste
|
|
|
|
Post pastes to https://paste.suah.dev
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package scpaste
|
|
:config (setq scpaste-scp-destination "suah.dev:/var/www/paste"
|
|
scpaste-http-destination "https://paste.suah.dev"))
|
|
#+end_src
|
|
|
|
** htmlize
|
|
|
|
This is needed for publishing org stuff
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package htmlize)
|
|
#+end_src
|
|
|
|
** parchment-theme
|
|
This is a nice theme that resembles acme in plan9. Minimal.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package parchment-theme
|
|
:config (load-theme 'parchment t))
|
|
#+end_src
|
|
|
|
** keychain-environment
|
|
|
|
I make heavy use of ~ssh-agent~ this lets emacs pickup / use the existing
|
|
agents I have running.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package keychain-environment
|
|
;;:pin "melpa"
|
|
:init
|
|
(keychain-refresh-environment))
|
|
#+end_src
|
|
|
|
** ivy
|
|
|
|
~ivy~ is fantastic. It gives me nice visual search for buffers,
|
|
code.. etc. Combined with ~smex~ for sorting (shows last used things first) and
|
|
~counsel~ (extends ivy into various areas like the help stuff).
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package counsel)
|
|
(setq smex-save-file (expand-file-name "~/.emacs.d/smex.save"))
|
|
(use-package smex)
|
|
(use-package ivy
|
|
:hook (after-init . ivy-mode)
|
|
:bind
|
|
("C-s" . swiper)
|
|
("M-x" . counsel-M-x)
|
|
("C-x C-f" . counsel-find-file)
|
|
("C-x b" . ivy-switch-buffer))
|
|
#+end_src
|
|
|
|
** magit
|
|
|
|
Magit is a awesome. Not sure what else to say about it. :P
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package magit
|
|
:bind ("C-c m" . magit-status)
|
|
:init
|
|
(setq magit-completing-read-function 'ivy-completing-read))
|
|
#+end_src
|
|
|
|
** lsp
|
|
|
|
Use ~eglot~ for lsp stuff. It's built in and shows a bit more information for
|
|
auto-completion stuff.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package eglot
|
|
:config
|
|
(add-hook 'elm-mode-hook 'eglot-ensure)
|
|
(add-hook 'go-mode-hook 'eglot-ensure)
|
|
(add-hook 'haskell-mode-hook 'eglot-ensure)
|
|
(add-hook 'nix-mode-hook 'eglot-ensure)
|
|
(add-hook 'perl-mode-hook 'eglot-ensure)
|
|
(add-hook 'ruby-mode-hook 'eglot-ensure)
|
|
(add-hook 'rust-mode-hook 'eglot-ensure)
|
|
(add-hook 'typescript-mode-hook 'eglot-ensure)
|
|
|
|
(add-to-list 'eglot-server-programs '(c-mode . ("clangd")))
|
|
(add-to-list 'eglot-server-programs '(c++-mode . ("clangd")))
|
|
(add-to-list 'eglot-server-programs '(rust-mode . ("rust-analyzer")))
|
|
|
|
(define-key eglot-mode-map (kbd "C-c r") 'eglot-rename)
|
|
(define-key eglot-mode-map (kbd "C-c f") 'eglot-format)
|
|
|
|
:hook
|
|
(eglot-managed-mode . (lambda() (add-hook 'before-save-hook 'eglot-format-buffer nil 'local))))
|
|
#+end_src
|
|
|
|
** company and friends
|
|
|
|
~company~ allows for auto-completion of various things. It can interface with ~lsp-mode~ to complete
|
|
things like Go.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package company
|
|
:config
|
|
(setq company-tooltip-limit 20
|
|
company-minimum-prefix-length 1
|
|
company-idle-delay .3
|
|
company-echo-delay 0)
|
|
:hook (prog-mode . company-mode))
|
|
#+end_src
|
|
|
|
** gitgutter
|
|
This gives me a nice in-ui way to see modifications and what not.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package git-gutter
|
|
:hook
|
|
(after-init . global-git-gutter-mode)
|
|
:config
|
|
(global-set-key (kbd "C-x g r") 'git-gutter:revert-hunk)
|
|
(global-set-key (kbd "C-x g p") 'git-gutter:previous-hunk)
|
|
(global-set-key (kbd "C-x g n") 'git-gutter:next-hunk))
|
|
#+end_src
|
|
|
|
** shell
|
|
|
|
I don't often use the shell from emacs, but when I do these bits make it
|
|
easier for me to treat it like a regular shell.
|
|
|
|
#+begin_src emacs-lisp
|
|
;; Kill terminal buffers on exit so I din't have to kill the buffer after I exit.
|
|
(defadvice term-handle-exit
|
|
(after term-kill-buffer-on-exit activate)
|
|
(kill-buffer))
|
|
#+end_src
|
|
|
|
* Language Configurations
|
|
|
|
** Shell
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package shfmt)
|
|
(add-hook 'sh-mode-hook 'shfmt-on-save-mode)
|
|
#+end_src
|
|
|
|
** Typescript
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package typescript-mode)
|
|
#+end_src
|
|
|
|
** Nix
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package nix-mode
|
|
:mode "\\.nix\\'")
|
|
#+end_src
|
|
|
|
** Elm
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package elm-mode)
|
|
#+end_src
|
|
|
|
** Haskell
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package haskell-mode)
|
|
#+end_src
|
|
|
|
** Go
|
|
|
|
*** go-add-tags
|
|
|
|
This lets one select a ~struct~ or similar and auto add the ~`json:"NAME"`~ bits.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package go-add-tags)
|
|
#+end_src
|
|
|
|
*** go-mode
|
|
|
|
This allows for things like ~gofmt~ and auto adding / removing of imports.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package go-mode
|
|
:bind
|
|
("C-c t" . go-add-tags))
|
|
(defun xin-eglot-organize-imports () (interactive)
|
|
(eglot-code-actions nil nil "source.organizeImports" t))
|
|
(defun lsp-go-install-save-hooks ()
|
|
(add-hook 'before-save-hook 'xin-eglot-organize-imports nil t))
|
|
(add-hook 'go-mode-hook #'lsp-go-install-save-hooks)
|
|
#+end_src
|
|
|
|
*** go-eldoc
|
|
|
|
This extends eldoc to be able to speak Go - quite handy for quickly looking
|
|
up what things do.
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package go-eldoc
|
|
:hook
|
|
(go-mode . go-eldoc-setup))
|
|
#+end_src
|
|
|
|
* org-mode
|
|
|
|
Oh ~org-mode~. It's the reason I started using emacs.. and it's the reason I
|
|
can't quit!
|
|
|
|
** Config
|
|
#+begin_src emacs-lisp
|
|
(org-babel-do-load-languages
|
|
'org-babel-load-languages
|
|
'((plantuml . t)
|
|
(dot . t)
|
|
(latex . t)))
|
|
#+end_src
|
|
** Publish bits
|
|
|
|
I publish some of my notes [[https://suah.dev/p][on suah.dev/p]]. Also some recipes.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq my-org-publish-alist
|
|
'(("bolddaemon" :components ("bolddaemon-web" "bolddaemon-static"))
|
|
("notes" :components ("org-notes" "notes-static" "notes-rss"))
|
|
("deftly" :components ("deftly-blog" "deftly-static"))
|
|
("ohmyksh" :components ("ohmy-web" "ohmy-static"))
|
|
("org-notes"
|
|
:auto-preamble t
|
|
:auto-sitemap t
|
|
:headline-levels 4
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://suah.dev/p/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://suah.dev/p/"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:sitemap-filename "index.org"
|
|
:sitemap-title "Notes"
|
|
:with-title t
|
|
:author-info nil
|
|
:creator-info nil
|
|
:base-directory "~/org/notes")
|
|
("deftly-blog"
|
|
:auto-preamble t
|
|
:auto-sitemap t
|
|
:headline-levels 1
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/new/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://deftly.net/new/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://deftly.net/new"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:sitemap-title "Deftly.net"
|
|
:with-title t
|
|
:author-info t
|
|
:creator-info nil
|
|
:base-directory "~/org/deftly")
|
|
("ohmy-web"
|
|
:auto-preamble t
|
|
:auto-sitemap nil
|
|
:headline-levels 2
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/ohmyksh/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://deftly.net/ohmyksh/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://deftly.net/ohmyksh"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:with-title t
|
|
:author-info t
|
|
:creator-info nil
|
|
:base-directory "~/src/ohmyksh")
|
|
("notes-static"
|
|
:base-directory "~/org/notes"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
|
|
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg\\|svg"
|
|
:recursive t
|
|
:publishing-function org-publish-attachment)
|
|
("deftly-static"
|
|
:base-directory "~/org/deftly"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/new/"
|
|
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
|
|
:recursive t
|
|
:publishing-function org-publish-attachment)
|
|
("ohmy-static"
|
|
:base-directory "~/src/ohmyksh"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/deftly.net/ohmyksh/"
|
|
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
|
|
:recursive t
|
|
:publishing-function org-publish-attachment)
|
|
("notes-rss"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/p/"
|
|
:publishing-function org-rss-publish-to-rss
|
|
:recursive t
|
|
:rss-extension "xml"
|
|
:section-numbers nil
|
|
:exclude ".*"
|
|
:include ("index.org")
|
|
:table-of-contents nil
|
|
:base-directory "~/org/notes")
|
|
("recipes"
|
|
:auto-preamble t
|
|
:auto-sitemap t
|
|
:headline-levels 4
|
|
:publishing-directory "/ssh:suah.dev:/var/www/suah.dev/recipes/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-head "<link rel=\"stylesheet\" href=\"https://suah.dev/p/css/stylesheet.css\" type=\"text/css\" />"
|
|
:html-link-home "http://suah.dev/recipes/"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:sitemap-filename "index.org"
|
|
:sitemap-title "Recipes"
|
|
:with-title t
|
|
:author-info nil
|
|
:creator-info nil
|
|
:base-directory "~/org/recipes")
|
|
("bolddaemon-web"
|
|
:auto-preamble t
|
|
:auto-sitemap t
|
|
:headline-levels 4
|
|
:publishing-directory "/ssh:suah.dev:/var/www/bolddaemon.com/"
|
|
:publishing-function org-html-publish-to-html
|
|
:recursive t
|
|
:section-numbers nil
|
|
:html-link-home "http://bolddaemon.com"
|
|
:html-link-up "../"
|
|
:style-include-default nil
|
|
:with-title t
|
|
:author-info nil
|
|
:creator-info nil
|
|
:base-directory "~/org/bold.daemon")
|
|
("bolddaemon-static"
|
|
:base-directory "~/org/bold.daemon"
|
|
:publishing-directory "/ssh:suah.dev:/var/www/bolddaemon.com/"
|
|
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|mp3\\|ogg"
|
|
:recursive t
|
|
:publishing-function org-publish-attachment)
|
|
))
|
|
#+end_src
|
|
|
|
** Capture templates
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq my-org-capture-templates
|
|
`(("t" "TODO"
|
|
entry (file+headline "~/org/todo.org" "TODOs")
|
|
,(concat
|
|
"* TODO %?\n"
|
|
":PROPERTIES:\n"
|
|
":LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!)\n"
|
|
":END:\n") :prepend t)
|
|
("f" "TODO with File"
|
|
entry (file+headline "~/org/todo.org" "TODOs")
|
|
,(concat
|
|
"* TODO %?\n"
|
|
":PROPERTIES:\n"
|
|
":LOGGING: TODO(!) WAIT(!) DONE(!) CANCELED(!)\n"
|
|
":END:\n"
|
|
"%i\n %a") :prepend t)
|
|
("b" "Bug"
|
|
entry (file+olp+datetree "~/org/bugs.org" "Bugs")
|
|
"* BUG %?\nEntered on %U\n :PROPERTIES:\n :FILE: %a\n :END:\n" :prepend t)
|
|
("p" "Protocol"
|
|
entry (file+headline "~/org/links.org" "Links")
|
|
"* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?")
|
|
("L" "Protocol Link" entry (file+headline "~/org/links.org" "Links")
|
|
"* %? %:link\n%:description\n")
|
|
("j" "Journal"
|
|
entry (file+olp+datetree "~/org/journal.org")
|
|
"* %?\nEntered on %U\n %i\n")))
|
|
#+end_src
|
|
|
|
** org
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package org
|
|
:hook
|
|
(org-mode . (lambda ()
|
|
(turn-on-flyspell)
|
|
(auto-revert-mode)
|
|
(auto-fill-mode 1)))
|
|
:bind
|
|
("C-c c" . org-capture)
|
|
("C-c p" . org-publish)
|
|
("C-c l" . org-store-link)
|
|
("C-c a" . org-agenda)
|
|
("C-c b" . org-iswitchb)
|
|
:config
|
|
(load-library "find-lisp")
|
|
(setq org-directory "~/org"
|
|
org-agenda-files (find-lisp-find-files "~/org" "\.org$")
|
|
org-startup-indented t
|
|
org-log-done 'time
|
|
org-export-with-sub-superscripts nil
|
|
org-html-inline-images t
|
|
org-log-into-drawer t
|
|
org-src-tab-acts-natively t
|
|
org-agenda-skip-scheduled-if-deadline-is-shown t
|
|
org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)")
|
|
(sequence "REPORT(r)" "BUG(b)" "KNOWNCAUSE(k)" "|" "FIXED(f)")
|
|
(sequence "|" "CANCELED(c)")))
|
|
(setq org-publish-project-alist my-org-publish-alist)
|
|
(setq org-capture-templates my-org-capture-templates))
|
|
(use-package org-contrib)
|
|
|
|
#+end_src
|
|
|
|
** Extra bits
|
|
#+begin_src emacs-lisp
|
|
(use-package org-journal
|
|
:defer t
|
|
:config
|
|
(setq org-journal-dir "~/org/journal/"
|
|
org-journal-file-format "%Y/%m-%d"
|
|
org-journal-date-format "%A, %d %B %Y"))
|
|
#+end_src
|
|
|
|
Add in some org-mode helpers:
|
|
|
|
- ~org-habit~ lets me keep track of TODOs and other things.
|
|
- ~org-checklist~ lets me reset checklists for reoccurring tasks.
|
|
- This requires one to ~pkg_add a2ps~.
|
|
- ~RESET_CHECK_BOXES~ property to be set to ~t~ on a task
|
|
headline. (properties can be set via ~C-c C-x d~
|
|
#+begin_src emacs-lisp
|
|
(require 'org-habit)
|
|
(require 'org-checklist)
|
|
#+end_src
|
|
|
|
Custom agenda commands for various things.
|
|
|
|
- ~Daily habits~ shows how well I am keeping track of daily things.
|
|
#+begin_src emacs-lisp
|
|
(setq org-agenda-custom-commands
|
|
'(("h" "Daily habits"
|
|
((agenda ""))
|
|
((org-agenda-show-log t)
|
|
(org-agenda-ndays 7)
|
|
(org-agenda-log-mode-items '(state))))))
|
|
#+end_src
|
|
|
|
#+begin_src emacs-lisp
|
|
(use-package org-roam
|
|
:custom
|
|
(org-roam-directory (file-truename "~/org-roam/"))
|
|
:bind (("C-c n l" . org-roam-buffer-toggle)
|
|
("C-c n f" . org-roam-node-find)
|
|
("C-c n g" . org-roam-graph)
|
|
("C-c n i" . org-roam-node-insert)
|
|
("C-c n c" . org-roam-capture)
|
|
;; Dailies
|
|
("C-c n j" . org-roam-dailies-capture-today))
|
|
:config
|
|
(setq org-roam-node-display-template (concat "${title:*} " (propertize "${tags:10}" 'face 'org-tag)))
|
|
|
|
;; If using org-roam-protocol
|
|
(require 'org-roam-protocol))
|
|
#+end_src
|
|
|
|
* gnus
|
|
|
|
[2024-08-22 Thu] Might need to switch go gnus. mu4e has been not showing new
|
|
mail for some things and having to sync state between two sources is a pita.
|
|
|
|
#+begin_src emacs-lisp
|
|
(setq gnus-fetch-old-headers t
|
|
gnus-select-method '(nnimap "imap.fastmail.com")
|
|
gnus-secondary-select-methods '((nntp "news.gwene.org"))
|
|
gnus-sum-thread-tree-false-root ""
|
|
gnus-sum-thread-tree-indent " "
|
|
gnus-sum-thread-tree-leaf-with-other "├► "
|
|
gnus-sum-thread-tree-root ""
|
|
gnus-sum-thread-tree-single-leaf "╰► "
|
|
gnus-sum-thread-tree-vertical "│"
|
|
gnus-summary-line-format "%U%R%z %(%&user-date>; %-15,15f %B%s%)\n"
|
|
gnus-summary-thread-gathering-function 'gnus-gather-threads-by-references
|
|
gnus-thread-sort-functions '(gnus-thread-sort-by-date)
|
|
gnus-user-date-format-alist '((t . "%Y-%m-%d %H:%M")))
|
|
|
|
(with-eval-after-load 'gnus
|
|
(setq gnus-select-method '(nnimap "imap.fastmail.com")
|
|
gnus-secondary-select-methods '((nntp "news.gwene.org"))))
|
|
|
|
#+end_src
|
|
|
|
* mu4e
|
|
~mu~ has been the best mail client for me on emacs.
|
|
|
|
** Initializing mu
|
|
|
|
The defaults ~mu~ uses make no sense. ~~/.cache~ is for .. caching data, not
|
|
persistent databases.. So we init things with sane defaults:
|
|
|
|
#+begin_src shell
|
|
mu init --muhome=/home/qbit/.mu -m /home/qbit/Maildir/fastmail/ --my-address="aaron@bolddaemon.com"
|
|
#+end_src
|
|
|
|
** General mail configuration
|
|
|
|
#+begin_src emacs-lisp
|
|
(require 'smtpmail)
|
|
(setq user-mail-address "aaron@bolddaemon.com"
|
|
user-full-name "Aaron Bieber"
|
|
message-send-mail-function 'smtpmail-send-it
|
|
message-kill-buffer-on-exit t
|
|
smtpmail-smtp-user "qbit@fastmail.com"
|
|
smtpmail-smtp-server "smtp.fastmail.com"
|
|
smtpmail-smtp-service 465
|
|
smtpmail-default-smtp-server "smtp.fastmail.com"
|
|
smtpmail-stream-type 'ssl)
|
|
#+end_src
|
|
|
|
** mu4e specific configs
|
|
#+begin_src emacs-lisp
|
|
(use-package mu4e
|
|
:init
|
|
(setq mail-user-agent 'mu4e-user-agent
|
|
read-mail-command 'mu4e
|
|
mu4e-get-mail-command "mbsync fastmail"
|
|
mu4e-update-interval 420
|
|
mu4e-compose-context-policy nil
|
|
mu4e-context-policy 'pick-first
|
|
mu4e-drafts-folder "/Drafts"
|
|
mu4e-sent-folder "/Sent Items"
|
|
mu4e-trash-folder "/Trash"
|
|
mu4e-maildir-shortcuts
|
|
'( ("/INBOX" . ?i)
|
|
("/Archive" . ?a)
|
|
("/Sent Items" . ?s))
|
|
org-mu4e-link-query-in-headers-mode nil
|
|
mu4e-attachment-dir
|
|
(lambda (fname mtype)
|
|
(cond
|
|
((and fname (string-match "\\.diff$" fname)) "~/patches")
|
|
((and fname (string-match "\\.patch$" fname)) "~/patches")
|
|
((and fname (string-match "\\.diff.gz$" fname)) "~/patches")
|
|
(t "~/Downloads")))
|
|
mu4e-bookmarks
|
|
`(( :name "Inbox"
|
|
:query "maildir:/Inbox AND NOT flag:trashed"
|
|
:key ?i)
|
|
( :name "TODO"
|
|
:query "maildir:/TODO AND NOT flag:trashed"
|
|
:key ?T)
|
|
( :name "Unread messages"
|
|
:query "flag:unread AND NOT flag:trashed AND NOT list:ports-changes.openbsd.org AND NOT list:source-changes.openbsd.org"
|
|
:key ?u)
|
|
( :name "Today's messages"
|
|
:query "date:today..now"
|
|
:key ?d)
|
|
( :name "Hackers"
|
|
:query "list:hackers.openbsd.org AND NOT flag:trashed"
|
|
:key ?h)
|
|
( :name "Bugs"
|
|
:query "list:bugs.openbsd.org AND NOT flag:trashed"
|
|
:key ?b)
|
|
( :name "Tech"
|
|
:query "list:tech.openbsd.org AND NOT flag:trashed"
|
|
:key ?t)
|
|
( :name "Ports"
|
|
:query "list:ports.openbsd.org AND NOT flag:trashed"
|
|
:key ?p)
|
|
( :name "Misc"
|
|
:query "list:misc.openbsd.org AND NOT flag:trashed"
|
|
:key ?m)
|
|
( :name "9front"
|
|
:query "list:9front.9front.org AND NOT flag:trashed"
|
|
:key ?9)
|
|
( :name "GOT"
|
|
:query "list:gameoftrees.openbsd.org AND NOT flag:trashed"
|
|
:key ?g))))
|
|
#+end_src
|