1371 lines
54 KiB
Org Mode
1371 lines
54 KiB
Org Mode
#+Title: Phil's Doom Emacs Literate Config
|
||
#+author: Phil Bajsicki
|
||
#+STARTUP: indent show2levels
|
||
#+auto_tangle: t
|
||
|
||
* Intro
|
||
:PROPERTIES:
|
||
:ID: de888450-40a6-4255-81dc-e6e65a9cf07c
|
||
:END:
|
||
|
||
This is my personal [[https://github.com/doomemacs/doomemacs][Doom Emacs]] config. The important bit is that I have some additional keybinds. This file is a catch-all for all the files in $DOOMDIR - you can use ~org-babel-tangle~ to tangle them into their respective files.
|
||
|
||
Some of the comments are from the default config.el file that ships with Doom Emacs.
|
||
|
||
You can extract all the source/ config files from here by running Emacs and hitting ~C-c C-v t~.
|
||
|
||
A lot of these are swiped from [[https://gitlab.com/dwt1/configuring-emacs/][DT's Configuring Emacs config files]], as well as [[https://github.com/novoid/dot-emacs][Karl Voit's Emacs config.]]
|
||
* Header
|
||
:PROPERTIES:
|
||
:CREATED: <2024-09-23 Mon 01:07>
|
||
:END:
|
||
This will generate a header, clarifying that the resulting Doom Emacs ~config.el~ is not to be modified directly.
|
||
#+begin_src elisp :tangle config.el
|
||
;; -*- lexical-binding: t -*-
|
||
;; DO NOT EDIT THIS FILE
|
||
;; This file was generated from the .config/doom/README.org file
|
||
;; in the following repo: https://git.bajsicki.com/phil/dot/
|
||
|
||
#+end_src
|
||
* config.el
|
||
** Basic settings
|
||
*** Author/ personal info
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq user-full-name "Phil Bajsicki")
|
||
#+end_src
|
||
*** Global settings
|
||
- ~backup-inhibited~ is true because I use git for the vast majority of my work.
|
||
- ~global-auto-revert-mode~ is true because I sometimes use external tools on my
|
||
org-files, and don't want to have to manually ~revert-buffer~ when these changes
|
||
happen. Mild inconvenience but it's nice to have.
|
||
- ~indent-tabs-mode~ because that's what tabs are for.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq-default backup-inhibited t)
|
||
(setq global-auto-revert-mode t)
|
||
(setq-default indent-tabs-mode t)
|
||
#+end_src
|
||
Ensure visited files are called by their true names. Kinda insignificant but nice.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq find-file-visit-truename t)
|
||
#+end_src
|
||
|
||
**** Auth
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq auth-sources '("~/.authinfo"))
|
||
#+end_src
|
||
**** Locale
|
||
#+begin_src elisp :tangle config.el
|
||
(setq locale-coding-system 'utf-8)
|
||
(set-terminal-coding-system 'utf-8)
|
||
(set-keyboard-coding-system 'utf-8)
|
||
(set-clipboard-coding-system 'utf-8)
|
||
(prefer-coding-system 'utf-8)
|
||
#+end_src
|
||
*** Langtool
|
||
|
||
Note that for this functionality you do need some resources, namely:
|
||
- some kind of Java runtime (OpenJRE for instance)
|
||
- [[https://languagetool.org/][LanguageTool]]
|
||
|
||
This command only sets up the path to your java runtime binary.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq langtool-java-bin "/usr/bin/java")
|
||
#+end_src
|
||
|
||
*** Theming and prettifying
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(after! counsel
|
||
(setq counsel-outline-display-style 'title))
|
||
#+end_src
|
||
**** Doom Theme
|
||
¯\_(ツ)_/¯
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(load-theme 'doom-one t)
|
||
(doom-themes-neotree-config)
|
||
(doom-themes-org-config)
|
||
#+end_src
|
||
**** org-modern
|
||
Just some bits here that affect the entirety of Emacs; the parts relevant to
|
||
org-mode specifically are in [[*Appearance and style][org's appearance section.]]
|
||
|
||
This part removes all the unnecessary bits that take up screen space and add clutter.
|
||
#+begin_src elisp :tangle config.el
|
||
(menu-bar-mode -1)
|
||
(tool-bar-mode -1)
|
||
(scroll-bar-mode -1)
|
||
#+end_src
|
||
Then fixing up some borders and dividers. It's a very clean look, imo.
|
||
#+begin_src elisp :tangle config.el
|
||
(modify-all-frames-parameters
|
||
'((right-divider-width . 0)
|
||
(internal-border-width . 0)))
|
||
(dolist (face '(window-divider
|
||
window-divider-first-pixel
|
||
window-divider-last-pixel))
|
||
(face-spec-reset-face face)
|
||
(set-face-foreground face (face-attribute 'default :background)))
|
||
(set-face-background 'fringe (face-attribute 'default :background))
|
||
#+end_src
|
||
**** Transparency
|
||
¯\_(ツ)_/¯
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(set-frame-parameter nil 'alpha-background 85)
|
||
(add-to-list 'default-frame-alist '(alpha-background . 85))
|
||
#+end_src
|
||
**** Fonts
|
||
To be entirely fair, I pretty much exclusively use Iosevka. Such a good font.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq doom-themes-enable-bold t
|
||
doom-themes-enable-italic t
|
||
doom-font (font-spec :family "Iosevka" :size 14)
|
||
doom-big-font (font-spec :family "Iosevka" :size 16)
|
||
;; doom-variable-pitch-font (font-spec :family "Iosevka" :size 14)
|
||
doom-unicode-font (font-spec :family "Iosevka"))
|
||
;; doom-serif-font (font-spec :family "IBM Plex Mono" :size 10 :weight 'light))
|
||
|
||
;; (set-face-attribute 'default nil :family "Iosevka")
|
||
;; (set-face-attribute 'variable-pitch nil :family "Iosevka Aile")
|
||
;; (set-face-attribute 'org-modern-symbol nil :family "Iosevka")
|
||
#+end_src
|
||
|
||
***** Font Family List
|
||
This is a simple command that outputs the fonts you have available in Emacs.
|
||
Not really a config thing, but it's useful when trying to find out why that one
|
||
specific thing isn't showing correctly.
|
||
#+begin_src emacs-lisp :results value format: pp :tangle no
|
||
(print (font-family-list))
|
||
#+end_src
|
||
|
||
***** Ligature.el
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(ligature-set-ligatures 't '("www"))
|
||
;; Enable traditional ligature support in eww-mode, if the
|
||
;; `variable-pitch' face supports it
|
||
(ligature-set-ligatures 'eww-mode '("ff" "fi" "ffi"))
|
||
;; Enable all Cascadia Code ligatures in programming modes
|
||
(ligature-set-ligatures 'org-mode '("|||>" "<|||" "<==>" "<!--" "####" "~~>" "***" "||=" "||>"
|
||
":::" "::=" "=:=" "===" "==>" "=!=" "=>>" "=<<" "=/=" "!=="
|
||
"!!." ">=>" ">>=" ">>>" ">>-" ">->" "->>" "-->" "---" "-<<"
|
||
"<~~" "<~>" "<*>" "<||" "<|>" "<$>" "<==" "<=>" "<=<" "<->"
|
||
"<--" "<-<" "<<=" "<<-" "<<<" "<+>" "</>" "###" "#_(" "..<"
|
||
"..." "+++" "/==" "///" "_|_" "www" "&&" "^=" "~~" "~@" "~="
|
||
"~>" "~-" "**" "*>" "*/" "||" "|}" "|]" "|=" "|>" "|-" "{|"
|
||
"[|" "]#" "::" ":=" ":>" ":<" "$>" "==" "=>" "!=" "!!" ">:"
|
||
">=" ">>" ">-" "-~" "-|" "->" "--" "-<" "<~" "<*" "<|" "<:"
|
||
"<$" "<=" "<>" "<-" "<<" "<+" "</" "#{" "#[" "#:" "#=" "#!"
|
||
"##" "#(" "#?" "#_" "%%" ".=" ".-" ".." ".?" "+>" "++" "?:"
|
||
"?=" "?." "??" ";;" "/*" "/=" "/>" "//" "__" "~~" "(*" "*)"
|
||
"\\\\" "://"))
|
||
;; Enables ligature checks globally in all buffers. You can also do it
|
||
;; per mode with `ligature-mode'.
|
||
(global-ligature-mode t)
|
||
|
||
#+end_src
|
||
|
||
**** Helpers for text editing
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq display-line-numbers-type 'relative) ;; best honestly
|
||
(setq-default global-visual-line-mode t)
|
||
(setq column-number-mode t)
|
||
(setq next-screen-context-lines 4)
|
||
(setq x-stretch-cursor t)
|
||
#+end_src
|
||
** Global Keybinds
|
||
Setting this here because I experiment with these occasionally and want them reset properly eaach time.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(global-set-key "\C-g" 'keyboard-quit)
|
||
(global-set-key "\C-cu" 'browse-url-chrome)
|
||
#+end_src
|
||
|
||
** Package settings
|
||
*** Straight
|
||
Living on the edge. Honestly I probably should not... but then I do find joy in
|
||
fixing up my config...
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq straight-repository-branch "develop")
|
||
#+end_src
|
||
*** org-mode
|
||
I am including pretty much everything here, *mostly* sorted by package, but I'm
|
||
keeping org-mode and org-agenda together since they're virtually inseparable in
|
||
my mind.
|
||
**** Basic settings
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
;; must be set before `org` is loaded
|
||
|
||
(add-to-list 'auto-mode-alist
|
||
'("\\.org\\'" . org-mode))
|
||
|
||
(setq-default calendar-week-start-day 1)
|
||
#+end_src
|
||
****** Directories and structure
|
||
Basic directory set-up for org-mode
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-contacts-files '("~/enc/org/people.org"))
|
||
(setq org-directory "~/enc/org/")
|
||
#+end_src
|
||
Agenda files
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-agenda-files (directory-files-recursively "~/enc/org/" ".org$"))1
|
||
#+end_src
|
||
=org-refile= targets. I just want to see nearly everything. If something is more
|
||
than 9 levels deep then I should start questioning my sanity. I do want to go
|
||
step by step on these (~org-outline-path-complete-in-steps~ controls this), since
|
||
I have /a lot/ of information collected.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-refile-targets '((nil :maxlevel . 9)
|
||
(org-agenda-files :maxlevel . 9)))
|
||
(setq org-outline-path-complete-in-steps nil)
|
||
(setq org-refile-use-outline-path 'file)
|
||
#+end_src
|
||
****** Appearance and style
|
||
Keeps images contained on the screen.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-image-actual-width '(0.8))
|
||
#+end_src
|
||
|
||
Footnote positioning and style.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-footnote-auto-adjust t)
|
||
(setq org-footnote-define-inline t)
|
||
#+end_src
|
||
|
||
Pretty!
|
||
#+begin_src emacs-lisp config.el
|
||
(setq org-superstar-headline-bullets-list
|
||
'("⁖" "◉" "○" "✸" "✿")
|
||
org-hide-emphasis-markers t
|
||
org-pretty-entities t
|
||
org-fontify-todo-headline t
|
||
org-hide-leading-stars t)
|
||
#+end_src
|
||
Code highlighting in code blocks!
|
||
#+begin_src emacs-lisp
|
||
(setq org-src-fontify-natively t)
|
||
#+end_src
|
||
Naturally, I prefer to have a consistent look in my numbers.
|
||
#+begin_src emacs-lisp config.el
|
||
(setq org-table-duration-hour-zero-padding t)
|
||
#+end_src
|
||
Tags flush right to the 80th column, and realign them when the length/
|
||
indentation of the heading changes.
|
||
#+begin_src emacs-lisp config.el
|
||
(setq org-tags-column -80
|
||
org-auto-align-tags t)
|
||
#+end_src
|
||
And, enable org-modern-mode by default, since it's nice.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(global-org-modern-mode)
|
||
#+end_src
|
||
|
||
****** Editing and comfort
|
||
It's preferable to have org guess dates in the future when scheduling.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-read-date-prefer-future t)
|
||
#+end_src
|
||
This makes the notes I take read like a book. I can /imagine/ there's folks who
|
||
enjoy reversing their notes and having the most recent at the top but... no.
|
||
Just no.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-reverse-note-order nil)
|
||
#+end_src
|
||
This one really annoyed me for a long time, until I just gave up. There is no
|
||
better way to have more vertical space in my files than by just... not wasting
|
||
more space between headings and list items.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-blank-before-new-entry (quote ((heading . nil)
|
||
(plain-list-item . nil))))
|
||
#+end_src
|
||
This is something I struggled with, particularly when dealing with lots of
|
||
nested headings; ultimately I have settled on 'smart' as 'good enough'. May move
|
||
to 'nil' at some point?
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-catch-invisible-edits "smart")
|
||
#+end_src
|
||
Special functions for headings.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-special-ctrl-a/e t)
|
||
(setq org-special-ctrl-k t)
|
||
#+end_src
|
||
This fits the yanked subtree into the appropriate level in the structure it's
|
||
yanked into.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-yank-adjusted-subtrees t)
|
||
#+end_src
|
||
I like being able to split lines sometimes, especially when cleaning up large
|
||
pieces of text.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-M-RET-may-split-line '((headline . t)
|
||
(item . t)
|
||
(default . nil)))
|
||
#+end_src
|
||
This ensures that I can insert my headings anywhere without having to consider
|
||
structure; particularly useful when I'm breaking large pieces of text into
|
||
headings, and don't want to jiggle things around much.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-insert-heading-respect-content nil)
|
||
#+end_src
|
||
Keep the footnotes per heading, instead of per file; when =t=, it'll create a
|
||
footnote heading at the end of the file and that's a pain when dealing with
|
||
large files.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-footnote-section nil)
|
||
#+end_src
|
||
****** Logging and Properties
|
||
Logging into a drawer.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-log-done (quote time)
|
||
org-log-into-drawer t
|
||
org-clock-into-drawer t)
|
||
#+end_src
|
||
Do not log inserting the TODO heading for the first time; only when further
|
||
changes are made to the heading.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-treat-insert-todo-heading-as-state-change nil)
|
||
#+end_src
|
||
Property inheritance is... difficult. I don't believe it has a place in my
|
||
world, but I can see specific scenarios where it would. Haven't found one myself
|
||
yet, despite experimenting.
|
||
#+begin_src elisp :tangle config.el
|
||
(setq org-use-property-inheritance nil)
|
||
;;(setq org-use-property-inheritance '(category columns archive logging))
|
||
#+end_src
|
||
****** Tasking and Dependencies
|
||
Forcing myself to acknowledge and address dependencies has been of great help
|
||
for me, especially on more involved projects; I am occasionally prone to
|
||
being lazy and leaving tasks I set for myself unaddressed, but these little
|
||
settings have really helped me maintain my files over time.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq-default org-enforce-todo-dependencies t)
|
||
(setq org-enforce-todo-checkbox-dependencies t)
|
||
#+end_src
|
||
I want to know when my deadlines are approaching.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-deadline-warning-days 7)
|
||
#+end_src
|
||
I like my statistics.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-provide-todo-statistics t
|
||
org-hierarchical-todo-statistics t)
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-todo-repeat-to-state "LOOP")
|
||
#+end_src
|
||
****** Todo keywords
|
||
I got these from... I frankly don't even know where. They're not bad, imo.
|
||
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-todo-keywords
|
||
'((sequence
|
||
"INBOX(i!)"
|
||
"TASK(t!)" ; A task that needs doing & is ready to do
|
||
"PROJ(p!)" ; A project, which usually contains other tasks
|
||
"LOOP(r!)" ; A recurring task
|
||
"WAIT(w!)" ; Something external is holding up this task
|
||
"HOLD(h!)" ; This task is paused/on hold because of me
|
||
"|"
|
||
"DONE(d!@)" ; Task successfully completed
|
||
"KILL(k!@)") ; Task was cancelled, aborted or is no longer applicable
|
||
(sequence
|
||
"DECIDE()" ; for making decisions
|
||
"|"
|
||
"OKAY(o!)" ; okay as-is
|
||
"YES(y!)" ; take action
|
||
"NO(n!)")) ; don't take action
|
||
org-todo-keyword-faces
|
||
'(
|
||
("INBOX" :foreground "cyan" :weight bold)
|
||
("TASK" :foreground "purple" :weight bold)
|
||
("PROJ" :foreground "violet" :weight bold)
|
||
("LOOP" :foreground "magenta" :weight bold)
|
||
("WAIT" :foreground "yellow" :weight bold)
|
||
("HOLD" :foreground "orange" :weight bold)
|
||
("DONE" :foreground "green" :weight bold)
|
||
("KILL" :foreground "grey" :weight bold)))
|
||
#+end_src
|
||
Change font for DONE tasks
|
||
- https://lists.gnu.org/archive/html/emacs-orgmode/2007-03/msg00179.html
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(setq org-fontify-done-headline t)
|
||
(custom-set-faces
|
||
'(org-done ((t (:foreground "PaleGreen"
|
||
:weight normal
|
||
:strike-through t))))
|
||
'(org-headline-done
|
||
((((class color) (min-colors 16) (background dark))
|
||
(:foreground "LightSalmon" :strike-through t)))))
|
||
#+END_SRC
|
||
**** Capture templates
|
||
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-capture-templates '(("t" "inbox" entry (file+headline "~/enc/org/agenda.org" "Inbox") "* %i%?")
|
||
("i" "idea" entry (file+headline "~/enc/org/agenda.org" "Ideas") "* %?")
|
||
("d" "reminder" entry (file+headline "~/enc/org/agenda.org" "Reminders") "* %i%? \n %U")
|
||
("p" "person" entry (file+headline "~/enc/org/people.org" "Sort")
|
||
"* %(org-contacts-template-name)
|
||
:PROPERTIES:
|
||
:EMAIL: %(org-contacts-template-email)
|
||
:PHONE:
|
||
:ALIAS:
|
||
:NICKNAME:
|
||
:IGNORE:
|
||
:ICON:
|
||
:NOTE:
|
||
:ADDRESS:
|
||
:BIRTHDAY:
|
||
:END:")))
|
||
#+end_src
|
||
|
||
#+RESULTS:
|
||
| t | inbox | entry | (file+headline ~/enc/org/agenda.org Inbox) | * %i%? |
|
||
| i | idea | entry | (file+headline ~/enc/org/agenda.org Ideas) | * %? |
|
||
| d | reminder | entry | (file+headline ~/enc/org/agenda.org Reminders) | * %i%? |
|
||
|
||
**** Keybinds
|
||
Pretty self-explanatory.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(global-set-key "\C-cl" 'org-store-link)
|
||
(global-set-key "\C-cnn" 'org-capture)
|
||
#+end_src
|
||
***** Timestamp keybinds
|
||
Inserts timestamps in the proper format. ~'(16)~ stands for two universal arguments, keeping the command from prompting for the time. Two keybinds here, which insert an active or inactive timestamp.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(global-set-key "\C-cia" '(lambda ()(interactive)
|
||
(org-time-stamp '(16))))
|
||
(global-set-key "\C-cii" '(lambda () (interactive)
|
||
(org-time-stamp-inactive '(16))))
|
||
#+end_src
|
||
|
||
**** org-roam
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-roam-v2-ack t)
|
||
(setq org-roam-completion-everywhere t)
|
||
(setq org-roam-directory
|
||
(file-truename "~/enc/org/roam"))
|
||
(org-roam-db-autosync-mode)
|
||
(org-roam-db-autosync-enable)
|
||
#+end_src
|
||
***** Capture templates
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-roam-capture-templates
|
||
'(("n" "default" plain
|
||
"%?"
|
||
:if-new (file+head "${slug}.org" "#+title: ${title}\n#+category: ${title}\n#+filetags: \n")
|
||
:empty-lines 1
|
||
:unnarrowed t)
|
||
("t" "Therapy" plain
|
||
"#+title: ${title}\n"
|
||
:if-new (file+head "therapy/therapy-${slug}.org" "#+title: ${title}\n#+category: 📗 ${title}\n#+filetags: 📗\n")
|
||
:empty-lines 1
|
||
:unnarrowed)))
|
||
#+end_src
|
||
***** Keybinds
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(define-prefix-command 'org-roam-map)
|
||
(global-set-key "\C-r" 'org-roam-map)
|
||
(define-key org-roam-map "o" 'org-roam-buffer-toggle)
|
||
(define-key org-roam-map "f" 'org-roam-node-find)
|
||
(define-key org-roam-map "i" 'org-roam-node-insert)
|
||
(define-key org-roam-map "n" 'org-roam-capture)
|
||
#+end_src
|
||
**** Functions
|
||
***** my-id-get-or-generate
|
||
Straight from Karl Voit's config.
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(defun my-id-get-or-generate()
|
||
"Returns the ID property if set or generates and returns a new one if not set.
|
||
The generated ID is stripped off potential progress indicator cookies and
|
||
sanitized to get a slug. Furthermore, it is prepended with an ISO date-stamp
|
||
if none was found before."
|
||
(interactive)
|
||
(when (not (org-id-get))
|
||
(progn
|
||
(let* (
|
||
(my-heading-text (nth 4 (org-heading-components)));; retrieve heading string
|
||
(my-heading-text (replace-regexp-in-string "\\(\\[[0-9]+%\\]\\)" "" my-heading-text));; remove progress indicators like "[25%]"
|
||
(my-heading-text (replace-regexp-in-string "\\(\\[[0-9]+/[0-9]+\\]\\)" "" my-heading-text));; remove progress indicators like "[2/7]"
|
||
(my-heading-text (replace-regexp-in-string "\\(\\[#[ABC]\\]\\)" "" my-heading-text));; remove priority indicators like "[#A]"
|
||
(my-heading-text (replace-regexp-in-string "\\[\\[\\(.+?\\)\\]\\[" "" my-heading-text t));; removes links, keeps their description and ending brackets
|
||
;; (my-heading-text (replace-regexp-in-string "[<\\[][12][0-9]\\{3\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\( .*?\\)[>\\]]" "" my-heading-text t));; removes day of week and time from date- and time-stamps (doesn't work somehow)
|
||
(my-heading-text (replace-regexp-in-string "<[12][0-9]\\{3\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\( .*?\\)>" "" my-heading-text t));; removes day of week and time from active date- and time-stamps
|
||
(my-heading-text (replace-regexp-in-string "\\[[12][0-9]\\{3\\}-[0-9]\\{2\\}-[0-9]\\{2\\}\\( .*?\\)\\]" "" my-heading-text t));; removes day of week and time from inactive date- and time-stamps
|
||
(new-id (my-generate-sanitized-alnum-dash-string my-heading-text));; get slug from heading text
|
||
(my-created-property (assoc "CREATED" (org-entry-properties))) ;; nil or content of CREATED time-stamp
|
||
)
|
||
(when (not (string-match "[12][0-9][0-9][0-9]-[01][0-9]-[0123][0-9]-.+" new-id))
|
||
;; only if no ISO date-stamp is found at the beginning of the new id:
|
||
(if my-created-property (progn
|
||
;; prefer date-stamp of CREATED property (if found):
|
||
(setq my-created-datestamp (substring (org-entry-get nil "CREATED" nil) 1 11)) ;; returns "2021-12-16" or nil (if no CREATED property)
|
||
(setq new-id (concat my-created-datestamp "-" new-id))
|
||
)
|
||
;; use today's date-stamp if no CREATED property is found:
|
||
(setq new-id (concat (format-time-string "%Y-%m-%d-") new-id))))
|
||
(org-set-property "ID" new-id)
|
||
)
|
||
)
|
||
)
|
||
(kill-new (concat "id:" (org-id-get)));; put ID in kill-ring
|
||
(org-id-get);; retrieve the current ID in any case as return value
|
||
)
|
||
|
||
|
||
#+END_SRC
|
||
|
||
***** Directory to org
|
||
Frankly I don't know where I got this from, it's been a long time, and I don't
|
||
recall ever using it but... it's so nice that I don't dare remove this just in
|
||
case I need it at some point in the future.
|
||
#+begin_src elisp :tangle config.el
|
||
(defun my-dir-to-org (dir org-file)
|
||
"Create a file ORG-FILE which has all txt files in DIR as linked headlines
|
||
and the contents of the files below the headlines."
|
||
(interactive "DDirectory to convert: \nFFilename: ")
|
||
(let ((files (directory-files
|
||
dir t ".*\\.txt\\'")))
|
||
(with-temp-file org-file
|
||
(dolist (file files)
|
||
(insert (concat "* " (file-name-nondirectory file) "\n\n"))
|
||
(insert-file-contents file)
|
||
(goto-char (point-max))
|
||
(insert "\n")))))
|
||
|
||
(defun my-dir-to-org-with-links (dir org-file)
|
||
"Create a file ORG-FILE which has all txt files in DIR as linked headlines
|
||
and the contents of the files below the headlines."
|
||
(interactive "DDirectory to convert: \nFFilename: ")
|
||
(let ((files (directory-files
|
||
dir t ".*\\.txt\\'")))
|
||
(with-temp-file org-file
|
||
(dolist (file files)
|
||
(insert (concat "* " "[[" file "][" (file-name-nondirectory file) "]]\n\n"))
|
||
(insert-file-contents file)
|
||
(goto-char (point-max))
|
||
(insert "\n")))))
|
||
|
||
|
||
(defun my-mass-conversion (source-dir target-dir)
|
||
"Create one org file per directory of SOURCE-DIR inside TARGET-DIR."
|
||
(interactive "DDirectory to convert: \nDTarget Directory:")
|
||
(let ((dirs-full
|
||
(remove-if-not #'file-directory-p
|
||
(directory-files
|
||
source-dir t
|
||
directory-files-no-dot-files-regexp))))
|
||
|
||
(mapc (lambda (dir)
|
||
(my-dir-to-org dir
|
||
(concat target-dir
|
||
(file-name-base dir) ".org")))
|
||
dirs-full)))
|
||
|
||
|
||
#+end_src
|
||
|
||
***** my-org-tree-to-indirect-buffer
|
||
#+begin_quote
|
||
This beautiful piece of code was done by [[https://www.reddit.com/user/github-alphapapa][alphapapa]] and published on
|
||
[[https://www.reddit.com/r/orgmode/comments/dbsngi/finally_solving_the_lack_of_a_treeview_navigation/f26qpzr/][reddit]]. Its purpose is to provide more than one indirect buffer when
|
||
using =org-tree-to-indirect-buffer()= (via ~C-c C-x b~). Further more,
|
||
it has a different way of naming these buffers.
|
||
|
||
Using an advice, the original function gets overwritten.
|
||
#+end_quote
|
||
--Karl Voit
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(defun my-org-tree-to-indirect-buffer (&optional arg)
|
||
"Create indirect buffer and narrow it to current subtree.
|
||
The buffer is named after the subtree heading, with the filename
|
||
appended. If a buffer by that name already exists, it is
|
||
selected instead of creating a new buffer."
|
||
(interactive "P")
|
||
(let* ((new-buffer-p)
|
||
(pos (point))
|
||
w (buffer-name (let* ((heading (org-get-heading t t))
|
||
(level (org-outline-level))
|
||
(face (intern (concat "outline-" (number-to-string level))))
|
||
(heading-string (propertize (org-link-display-format heading)
|
||
'face face)))
|
||
(concat heading-string "::" (buffer-name))))
|
||
(new-buffer (or (get-buffer buffer-name)
|
||
(prog1 (condition-case nil
|
||
(make-indirect-buffer (current-buffer) buffer-name 'clone)
|
||
(error (make-indirect-buffer (current-buffer) buffer-name)))
|
||
(setq new-buffer-p t)))))
|
||
(switch-to-buffer new-buffer)
|
||
(when new-buffer-p
|
||
;; I don't understand why setting the point again is necessary, but it is.
|
||
(goto-char pos)
|
||
(rename-buffer buffer-name)
|
||
(org-narrow-to-subtree))))
|
||
|
||
(advice-add 'org-tree-to-indirect-buffer :override 'my-org-tree-to-indirect-buffer)
|
||
#+END_SRC
|
||
|
||
***** preserving all heading levels when archiving
|
||
#+begin_quote
|
||
Preserve the hierarchy when archiving: [[https://fuco1.github.io/2017-04-20-Archive-subtrees-under-the-same-hierarchy-as-original-in-the-archive-files.html][blog article]], [[https://gist.github.com/Fuco1/e86fb5e0a5bb71ceafccedb5ca22fcfb][source code (GitHub gist)]]
|
||
--Karl Voit
|
||
#+end_quote
|
||
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(setq org-archive-default-command #'org-archive-subtree-hierarchically)
|
||
|
||
(defun org-archive-subtree-hierarchically (&optional prefix)
|
||
(interactive "P")
|
||
(let* ((fix-archive-p (and (not prefix)
|
||
(not (use-region-p))))
|
||
(afile (car (org-archive--compute-location
|
||
(or (org-entry-get nil "ARCHIVE" 'inherit) org-archive-location))))
|
||
(buffer (or (find-buffer-visiting afile) (find-file-noselect afile))))
|
||
(org-archive-subtree prefix)
|
||
(when fix-archive-p
|
||
(with-current-buffer buffer
|
||
(goto-char (point-max))
|
||
(while (org-up-heading-safe))
|
||
(let* ((olpath (org-entry-get (point) "ARCHIVE_OLPATH"))
|
||
(path (and olpath (split-string olpath "/")))
|
||
(level 1)
|
||
tree-text)
|
||
(when olpath
|
||
(org-mark-subtree)
|
||
(setq tree-text (buffer-substring (region-beginning) (region-end)))
|
||
(let (this-command (inhibit-message t)) (org-cut-subtree)) ; we don’t want to see "Cut subtree" messages
|
||
(goto-char (point-min))
|
||
(save-restriction
|
||
(widen)
|
||
(-each path
|
||
(lambda (heading)
|
||
(if (re-search-forward
|
||
(rx-to-string
|
||
`(: bol (repeat ,level "*") (1+ " ") ,heading)) nil t)
|
||
(org-narrow-to-subtree)
|
||
(goto-char (point-max))
|
||
(unless (looking-at "^")
|
||
(insert "\n"))
|
||
(insert (make-string level ?*)
|
||
" "
|
||
heading
|
||
"\n"))
|
||
(cl-incf level)))
|
||
(widen)
|
||
(org-end-of-subtree t t)
|
||
(org-paste-subtree level tree-text))))))))
|
||
#+END_SRC
|
||
***** my-dired-insert-lfile-link-list-to-other-org-window()
|
||
|
||
#+begin_quote
|
||
| 2022-06-20 | I had this idea and implemented it |
|
||
|
||
Development task: id:2022-06-20-implement-add-lfile-links-to-buffer-with-marked-dired-files
|
||
|
||
[[https://emacs.stackexchange.com/questions/60359/is-there-a-quicker-way-to-create-links-to-attachments][This stackexchange snippet]] had the almost exactly perfect code which I adapted.
|
||
|
||
The idea of the process is:
|
||
|
||
1. I have an Org-mode buffer and a dired buffer side-by-side (which is my usual setup).
|
||
2. I place the cursor in the Org-mode buffer so that I may add a list.
|
||
3. I switch to the dired buffer and mark one or more files.
|
||
4. I invoke this function.
|
||
|
||
This results in a list that gets added to the Org-mode buffer similar to:
|
||
|
||
: - [[lfile:This is an example.odt][This is an example.odt]]
|
||
: - [[lfile:2022-06-20 an image.png][2022-06-20 an image.png]]
|
||
#+end_quote
|
||
|
||
|
||
#+begin_src emacs-lisp :results none :tangle no
|
||
(defun my-dired-insert-lfile-link-list-to-other-org-window (files)
|
||
;; adapted by Karl Voit from https://emacs.stackexchange.com/a/60369
|
||
(interactive
|
||
(list (dired-get-marked-files)))
|
||
(unless (eq major-mode 'dired-mode)
|
||
(user-error "This command must be triggered in a dired buffer"))
|
||
(let ((dired-win (selected-window))
|
||
(orgmode-win
|
||
(get-window-with-predicate
|
||
(lambda (window)
|
||
(with-current-buffer (window-buffer window)
|
||
(eq major-mode 'org-mode))))))
|
||
(unless orgmode-win
|
||
(user-error
|
||
"Can't attach to subtree. No window displaying an Org buffer"))
|
||
(select-window orgmode-win)
|
||
(dolist (file files)
|
||
(let* ((fname (file-name-nondirectory file))
|
||
(link (format "lfile:%s" fname))
|
||
(desc fname))
|
||
;;(push (list link desc) org-stored-links) ;; original idea was to insert to this buffer in order to paste via C-c C-l
|
||
(insert (format "%s" (concat "- [[" link "][" desc "]]\n")))
|
||
))
|
||
(select-window dired-win)))
|
||
#+end_src
|
||
|
||
**** org-agenda
|
||
These are settings specifically for org-agenda, that don't overlap with any
|
||
other settings.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-agenda-start-day nil)
|
||
(setq org-agenda-start-on-weekday nil)
|
||
(setq org-agenda-span 'day)
|
||
#+end_src
|
||
Dim blocked tasks to clearly see that their prerequisites are not met.
|
||
Make the agenda blocks more compact by skipping certain elements.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-agenda-dim-blocked-tasks t)
|
||
(setq org-agenda-compact-blocks t)
|
||
#+end_src
|
||
|
||
Non-nil means skip timestamp line if same entry shows because of deadline.
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(setq org-agenda-skip-timestamp-if-deadline-is-shown t)
|
||
#+END_SRC
|
||
|
||
Remove completed deadline and scheduled tasks from the agenda view
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(setq org-agenda-skip-deadline-if-done t)
|
||
(setq org-agenda-skip-scheduled-if-done t)
|
||
#+END_SRC
|
||
|
||
Remove completed items from search results
|
||
#+BEGIN_SRC emacs-lisp :tangle no
|
||
(setq org-agenda-skip-timestamp-if-done t)
|
||
#+END_SRC
|
||
|
||
Include agenda archive files when searching for things
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(setq org-agenda-text-search-extra-files (quote (agenda-archives)))
|
||
#+END_SRC
|
||
Do not search for time in heading when displaying a date-stamp
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(setq org-agenda-search-headline-for-time nil)
|
||
#+END_SRC
|
||
Show all agenda dates - even if they are empty
|
||
#+BEGIN_SRC emacs-lisp :tangle config.el
|
||
(setq org-agenda-show-all-dates t)
|
||
#+END_SRC
|
||
|
||
|
||
Show the following items in log mode.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-agenda-log-mode-items '(closed clock state))
|
||
#+end_src
|
||
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-agenda-sorting-strategy
|
||
(quote ((agenda time-up user-defined-up priority-down category-keep)
|
||
(todo priority-down category-keep)
|
||
(tags priority-down category-keep)
|
||
(search category-keep))))
|
||
#+end_src
|
||
|
||
Ensuring that tag inheritance is applied in the agenda view.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-agenda-use-tag-inheritance (quote (agenda)))
|
||
#+end_src
|
||
|
||
Agenda prefixes and org-modern agenda styling.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-agenda-prefix-format '((agenda . " %l %i %c %s %t")
|
||
(todo . " %i %-12:c")
|
||
(tags . " %i $-12:c")
|
||
(search . " %i %-12:c")))
|
||
|
||
(setq org-agenda-tags-column -80
|
||
org-agenda-block-separator ?─
|
||
org-agenda-current-time-string "◀── now ─────────────────────────────────────────────────")
|
||
#+end_src
|
||
Two to choose from, I'm not sure which one is better here. I don't know where I
|
||
got this one from.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq org-agenda-time-grid
|
||
'((daily today remove-match)
|
||
(800 1000 1200 1400 1600 1800 2000)
|
||
" ┄┄┄┄┄ "
|
||
"┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄"))
|
||
#+end_src
|
||
Add hook into the agenda mode for highlighting.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(add-hook 'org-agenda-mode-hook '(lambda () (hl-line-mode 1)))
|
||
#+end_src
|
||
|
||
**** org-habits
|
||
I try to run a reasonable routine, and it doesn't always work. This helps me
|
||
review if I'm sticking to it well (or, reasonably well) over time.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(add-to-list 'org-modules 'habit)
|
||
(setq org-habit-following-days 2
|
||
org-habit-preceding-days 7
|
||
org-habit-show-all-today nil
|
||
org-habit-show-habits-only-for-today t
|
||
org-habit-show-habits t)
|
||
#+end_src
|
||
Some keybinds and a hook.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(define-key org-mode-map (kbd "C-c h") 'org-habit-stats-view-habit-at-point)
|
||
(add-hook 'org-after-todo-state-change-hook 'org-habit-stats-update-properties)
|
||
#+end_src
|
||
**** multiple-cursors
|
||
I /rarely/ use these, since I don't edit much structured data, and when I do it's
|
||
less like this and more like massive articles or books or whatnot. Still, it
|
||
does come in handy occasionally.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
|
||
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
|
||
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
|
||
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
|
||
#+end_src
|
||
|
||
**** [disabled] copilot.el
|
||
#+begin_src emacs-lisp :tangle no
|
||
;; accept completion from copilot and fallback to company
|
||
(use-package! copilot
|
||
:hook (prog-mode . copilot-mode)
|
||
:bind (:map copilot-completion-map
|
||
("<tab>" . 'copilot-accept-completion)
|
||
("TAB" . 'copilot-accept-completion)
|
||
("C-TAB" . 'copilot-accept-completion-by-word)
|
||
("C-<tab>" . 'copilot-accept-completion-by-word)))
|
||
#+end_src
|
||
**** Hooks
|
||
***** org-auto-tangle
|
||
By adding ~#+auto_tangle: t~ to the frontmatter of an org-mode file, this enables
|
||
automatic tangling upon the file being saved.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(require 'org-auto-tangle)
|
||
(add-hook 'org-mode-hook 'org-auto-tangle-mode)
|
||
#+end_src
|
||
***** Automated timestamps in headings
|
||
I need this because hitting the [[*Timestamp keybinds][timestamp keybinds]] is tedious.
|
||
|
||
For the files whose paths match the strings in the function, it will advise the org-insert-heading function to insert an inactive timestamp into the new heading.
|
||
|
||
This turns making new entries from ~C-<return> C-i i~ into just ~C-<return>~. Much easier, and I don't have to think about this any more.
|
||
|
||
Additionally, outside of the structured files where I am tracking time linearly, I want ~org-expiry-insert-created~, which fits in neatly into this little hook, thus allowing me to inspect my workflows more carefully.
|
||
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(use-package! org-expiry)
|
||
(after! org
|
||
(add-hook! 'org-insert-heading-hook
|
||
(if (or
|
||
(string-match-p "journal.org" buffer-file-name)
|
||
(string-match-p "money.org" buffer-file-name)
|
||
(string-match-p "therapy.org" buffer-file-name))
|
||
(progn
|
||
(org-time-stamp-inactive '(16))
|
||
(newline))
|
||
(org-expiry-insert-created))))
|
||
#+end_src
|
||
|
||
*** org-mode expansions
|
||
**** org-babel
|
||
This is really important for me since I tend to use PlantUML to generate charts,
|
||
graphs and diagrams.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)
|
||
#+end_src
|
||
**** org-crypt
|
||
This is nice, since it lets me easily encrypt parts of my notes using my GPG
|
||
key, which I have set up with my NitroKey. It's some really really cool tech.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(require 'org-crypt)
|
||
(require 'epa-file)
|
||
(epa-file-enable)
|
||
(org-crypt-use-before-save-magic)
|
||
(setq org-tags-exclude-from-inheritance (quote ("crypt")))
|
||
(setq org-crypt-key "phil@bajsicki.com")
|
||
(setenv "GPG_AGENT_INFO" nil)
|
||
#+end_src
|
||
**** org-export
|
||
Just a catch-all category for this... I honestly should split things up better
|
||
instead of this, but it is what it is.
|
||
***** LaTeX
|
||
Adding the tufte-handout and the memoir classes.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(with-eval-after-load 'ox-latex
|
||
(add-to-list 'org-latex-classes
|
||
'("tufte-handout"
|
||
"\\documentclass[nobib]{tufte-handout}
|
||
\\usepackage{nicefrac}
|
||
\\usepackage{units}
|
||
[NO-DEFAULT-PACKAGES]
|
||
[EXTRA]"
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}")
|
||
("\\paragraph{%s}" . "\\paragraph*{%s}")
|
||
("\\subparagraph{%s}" . "\\subparagraph*{%s}"))
|
||
'("memoir"
|
||
"\\documentclass{memoir}"
|
||
("\\chapter{%s}" . "\\chapter*{%s}")
|
||
("\\section{%s}" . "\\section*{%s}")
|
||
("\\subsection{%s}" . "\\subsection*{%s}")
|
||
("\\subsubsection{%s}" . "\\subsubsection*{%s}"))))
|
||
|
||
#+end_src
|
||
Testing function, not tangled.
|
||
#+begin_src emacs-lisp :tangle no
|
||
(print org-latex-classes)
|
||
#+end_src
|
||
I have not settled on this. Meh.
|
||
#+begin_src elisp :tangle no
|
||
(setq org-latex-default-class "tufte-handout"
|
||
org-latex-pdf-process '("latexmk -pdf -bibtex-cond -f -outdir=%o %f"))
|
||
#+end_src
|
||
***** ox-hugo
|
||
:PROPERTIES:
|
||
:CREATED: <2024-09-24 Tue 15:08>
|
||
:END:
|
||
#+begin_src elisp :tangle config.el
|
||
(use-package! ox-hugo
|
||
:ensure t
|
||
:after ox)
|
||
#+end_src
|
||
**** org-transclusion
|
||
I don't use this enough, and hopefully I'll find happiness with this if I do end
|
||
up working on larger projects.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(use-package! org-transclusion
|
||
:after org
|
||
:init
|
||
(map!
|
||
:map global-map "<f12>" #'org-transclusion-add
|
||
:leader
|
||
:prefix "n"
|
||
:desc "Org Transclusion Mode" "t" #'org-transclusion-mode))
|
||
#+end_src
|
||
**** Org-wild-notifier
|
||
This lets me get desktop notifications for TODO items.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(org-wild-notifier-mode)
|
||
(setq alert-default-style 'libnotify
|
||
org-wild-notifier-alert-time '(0 5 15 60)
|
||
org-wild-notifier-keyword-whitelist nil
|
||
;; good for testing
|
||
org-wild-notifier--alert-severity 'high
|
||
alert-fade-time 50)
|
||
#+end_src
|
||
*** mu4e
|
||
Email in Emacs... what more can a man want?
|
||
#+begin_src elisp :tangle config.el
|
||
(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e/")
|
||
|
||
(setq mu4e-change-filenames-when-moving t)
|
||
(setq mu4e-update-interval (* 10 60))
|
||
(setq mu4e-get-mail-command "mbsync -a")
|
||
(setq mu4e-maildir "~/enc/.mail")
|
||
|
||
(setq mu4e-drafts-folder "/Drafts")
|
||
(setq mu4e-sent-folder "/Sent")
|
||
(setq mu4e-refile-folder "/Refile")
|
||
(setq mu4e-trash-folder "/Trash")
|
||
|
||
(mu4e t)
|
||
|
||
#+end_src
|
||
|
||
#+RESULTS:
|
||
*** circe
|
||
:PROPERTIES:
|
||
:CREATED: <2024-09-21 Sat 23:50>
|
||
:END:
|
||
Doesn't work very well. I guess it "works", but I still need to auth manually; not sure what the issue is - my best guess is that my passwords use unusual unicode characters and that screws with the ~(read)~ instruction.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq my-credentials-file "~/enc/keys/emacs/circe.el")
|
||
|
||
(defun my-nickserv-password (server)
|
||
(with-temp-buffer
|
||
(insert-file-contents-literally my-credentials-file)
|
||
(plist-get (read (buffer-string)) :nickserv-password)))
|
||
|
||
(setq circe-network-options
|
||
'(("Libera Chat"
|
||
:nick "phil_bb"
|
||
:channels ("#emacs" "#emacs-circe")
|
||
:nickserv-password my-nickserv-password)))
|
||
#+end_src
|
||
|
||
*** pdf-tools
|
||
Gotta read in Emacs, sometimes. Usually in the browser, but when I have to take
|
||
notes there's nothing more convenient.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(use-package! pdf-tools
|
||
:defer t
|
||
:commands (pdf-loader-install)
|
||
:mode "\\.pdf\\'"
|
||
:bind (:map pdf-view-mode-map
|
||
("n" . pdf-view-next-line-or-next-page)
|
||
("p" . pdf-view-previous-line-or-previous-page)
|
||
("C-=" . pdf-view-enlarge)
|
||
("C--" . pdf-view-shrink))
|
||
:init (pdf-loader-install)
|
||
:config (add-to-list 'revert-without-query ".pdf"))
|
||
|
||
(add-hook 'pdf-view-mode-hook #'(lambda () (interactive (display-line-numbers-mode))))
|
||
|
||
#+end_src
|
||
|
||
*** yasnippets
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq doom-snippets-enable-short-helpers t)
|
||
#+end_src
|
||
*** csv-mode
|
||
Just making sure it loads when I load up csv files.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(add-to-list 'auto-mode-alist '("\\.[Cc][Ss][Vv]\\'" . csv-mode))
|
||
(autoload 'csv-mode "csv-mode"
|
||
"Major mode for editing comma-separated value files." t)
|
||
#+end_src
|
||
*** sly
|
||
Basic settings for Common Lisp development.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
;; (load (expand-file-name "~/.roswell/helper.el"))
|
||
|
||
(setq inferior-lisp-program "sbcl --dynamic-space-size 8192 -Q -l ~/.sbclrc")
|
||
#+end_src
|
||
*** gptel
|
||
This is exclusively local, as I am not entirely comfortable letting third
|
||
parties into my journals and personal notes. I usually run LLMs as they come,
|
||
using them largely for brainstorming when I'm trying to plan out projects or
|
||
consider my habits.
|
||
|
||
With their context size only increasing as time goes by, this is turning into a
|
||
very easy way to get feedback on the ideas I have.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(use-package! gptel)
|
||
(gptel-make-openai "ooba" ;Any name
|
||
:key "thisisanapikey"
|
||
:stream t ;Stream responses
|
||
:protocol "http"
|
||
:host "localhost:6666" ;Llama.cpp server location
|
||
:models '("model")) ;Any names, doesn't matter for Llama
|
||
|
||
(gptel-make-openai "OpenRouter"
|
||
:host "openrouter.ai"
|
||
:endpoint "/api/v1/chat/completions"
|
||
:key (getenv "GPTEL_OPENROUTER_API")
|
||
:stream t ;Stream responses
|
||
:models '(qwen/qwen-2.5-coder-32b-instruct))
|
||
|
||
(setq gptel--debug t)
|
||
#+end_src
|
||
|
||
#+RESULTS:
|
||
*** elfeed
|
||
RSS is not dead. RSS is not dead. RSS is not dead.
|
||
#+begin_src emacs-lisp :tangle config.el
|
||
(setq-default elfeed-search-filter "@1-week-ago +unread ")
|
||
#+end_src
|
||
* custom.el
|
||
Custom variables. Note that this file is generally set up automatically by Emacs" so I'm not exporting this block. I'm keeping the default warning comments in just for completion here.
|
||
#+begin_src emacs-lisp :tangle no
|
||
(custom-set-variables)
|
||
;; custom-set-variables was added by Custom.
|
||
;; If you edit it by hand" you could mess it up" so be careful.
|
||
;; Your init file should contain only one such instance.
|
||
;; If there is more than one" they won't work right.
|
||
(custom-set-faces
|
||
;; custom-set-faces was added by Custom.
|
||
;; If you edit it by hand" you could mess it up" so be careful.
|
||
;; Your init file should contain only one such instance.
|
||
;; If there is more than one" they won't work right.
|
||
)
|
||
#+end_src
|
||
* init.el
|
||
#+begin_src emacs-lisp :tangle init.el
|
||
;;; init.el -*- lexical-binding: t; -*-
|
||
|
||
;; This file controls what Doom modules are enabled and what order they load
|
||
;; in. Remember to run 'doom sync' after modifying it!
|
||
|
||
;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
|
||
;; documentation. There you'll find a link to Doom's Module Index where all
|
||
;; of our modules are listed" including what flags they support.
|
||
|
||
;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
|
||
;; 'C-c c k' for non-vim users) to view its documentation. This works on
|
||
;; flags as well (those symbols that start with a plus).
|
||
;;
|
||
;; Alternatively" press 'gd' (or 'C-c c d') on a module to browse its
|
||
;; directory (for easy access to its source code).
|
||
|
||
(doom! :input
|
||
;;bidi ; (tfel ot) thgir etirw uoy gnipleh
|
||
;;chinese
|
||
;;japanese
|
||
;;layout ; auie" ctsrnm is the superior home row
|
||
|
||
:completion
|
||
(company +childframe) ; the ultimate code completion backend
|
||
;;helm ; the *other* search engine for love and life
|
||
;;ido ; the other *other* search engine...
|
||
;;ivy ; a search engine for love and life
|
||
vertico ; the search engine of the future
|
||
|
||
:ui
|
||
;;deft ; notational velocity for Emacs
|
||
doom ; what makes DOOM look the way it does
|
||
doom-dashboard ; a nifty splash screen for Emacs
|
||
doom-quit ; DOOM quit-message prompts when you quit Emacs
|
||
(emoji +unicode) ; 🙂
|
||
;;hl-todo ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
|
||
hydra
|
||
indent-guides ; highlighted indent columns
|
||
(ligatures +iosevka +extra) ; ligatures and symbols to make your code pretty again
|
||
minimap ; show a map of the code on the side
|
||
modeline ; snazzy" Atom-inspired modeline" plus API
|
||
nav-flash ; blink cursor line after big motions
|
||
;;neotree ; a project drawer" like NERDTree for vim
|
||
ophints ; highlight the region an operation acts on
|
||
(popup +defaults) ; tame sudden yet inevitable temporary windows
|
||
;;tabs ; a tab bar for Emacs
|
||
treemacs ; a project drawer" like neotree but cooler
|
||
unicode ; extended unicode support for various languages
|
||
(vc-gutter +pretty) ; vcs diff in the fringe
|
||
vi-tilde-fringe ; fringe tildes to mark beyond EOB
|
||
;;window-select ; visually switch windows
|
||
workspaces ; tab emulation" persistence & separate workspaces
|
||
;;zen ; distraction-free coding or writing
|
||
|
||
:editor
|
||
;;(evil +everywhere); come to the dark side" we have cookies
|
||
file-templates ; auto-snippets for empty files
|
||
fold ; (nigh) universal code folding
|
||
(format +onsave) ; automated prettiness
|
||
;;god ; run Emacs commands without modifier keys
|
||
;;lispy ; vim for lisp" for people who don't like vim
|
||
;;multiple-cursors ; editing in many places at once
|
||
;;objed ; text object editing for the innocent
|
||
;;parinfer ; turn lisp into python" sort of
|
||
;;rotate-text ; cycle region at point between text candidates
|
||
snippets ; my elves. They type so I don't have to
|
||
word-wrap ; soft wrapping with language-aware indent
|
||
|
||
:emacs
|
||
dired ; making dired pretty [functional]
|
||
electric ; smarter" keyword-based electric-indent
|
||
;;ibuffer ; interactive buffer management
|
||
(undo +tree) ; persistent" smarter undo for your inevitable mistakes
|
||
vc ; version-control and Emacs" sitting in a tree
|
||
|
||
:term
|
||
;;eshell ; the elisp shell that works everywhere
|
||
;;shell ; simple shell REPL for Emacs
|
||
;;term ; basic terminal emulator for Emacs
|
||
vterm ; the best terminal emulation in Emacs
|
||
|
||
:checkers
|
||
syntax ; tasing you for every semicolon you forget
|
||
(spell +flyspell) ; tasing you for misspelling mispelling
|
||
;;grammar ; tasing grammar mistake every you make
|
||
|
||
:tools
|
||
ansible
|
||
;;biblio ; Writes a PhD for you (citation needed)
|
||
debugger ; FIXME stepping through code" to help you add bugs
|
||
;;direnv
|
||
docker
|
||
editorconfig ; let someone else argue about tabs vs spaces
|
||
;;ein ; tame Jupyter notebooks with emacs
|
||
(eval +overlay) ; run code" run (also" repls)
|
||
;;gist ; interacting with github gists
|
||
lookup ; navigate your code and its documentation
|
||
lsp ; M-x vscode
|
||
magit ; a git porcelain for Emacs
|
||
;;make ; run make tasks from Emacs
|
||
;;pass ; password manager for nerds
|
||
pdf ; pdf enhancements
|
||
;;prodigy ; FIXME managing external services & code builders
|
||
rgb ; creating color strings
|
||
;;taskrunner ; taskrunner for all your projects
|
||
terraform ; infrastructure as code
|
||
;;tmux ; an API for interacting with tmux
|
||
;;upload ; map local to remote projects via ssh/ftp
|
||
|
||
:os
|
||
(:if IS-MAC macos) ; improve compatibility with macOS
|
||
;;tty ; improve the terminal Emacs experience
|
||
|
||
:lang
|
||
;;agda ; types of types of types of types...
|
||
;;beancount ; mind the GAAP
|
||
(cc +lsp) ; C > C++ == 1
|
||
;;(clojure +lsp) ; java with a lisp
|
||
common-lisp ; if you've seen one lisp" you've seen them all
|
||
;;coq ; proofs-as-programs
|
||
;;crystal ; ruby at the speed of c
|
||
;;csharp ; unity" .NET" and mono shenanigans
|
||
data ; config/data formats
|
||
;;(dart +flutter) ; paint ui and not much else
|
||
;;dhall
|
||
;;elixir ; erlang done right
|
||
;;elm ; care for a cup of TEA?
|
||
emacs-lisp ; drown in parentheses
|
||
;;erlang ; an elegant language for a more civilized age
|
||
;;ess ; emacs speaks statistics
|
||
;;factor
|
||
;;faust ; dsp" but you get to keep your soul
|
||
;;fortran ; in FORTRAN" GOD is REAL (unless declared INTEGER)
|
||
;;fsharp ; ML stands for Microsoft's Language
|
||
;;fstar ; (dependent) types and (monadic) effects and Z3
|
||
;;gdscript ; the language you waited for
|
||
(go +lsp) ; the hipster dialect
|
||
;;(graphql +lsp) ; Give queries a REST
|
||
(haskell +lsp) ; a language that's lazier than I am
|
||
;;hy ; readability of scheme w/ speed of python
|
||
;;idris ; a language you can depend on
|
||
json ; At least it ain't XML
|
||
;;(java +lsp) ; the poster child for carpal tunnel syndrome
|
||
(javascript +lsp) ; all(hope(abandon(ye(who(enter(here))))))
|
||
;;(julia +lsp) ; a better" faster MATLAB
|
||
;;kotlin ; a better" slicker Java(Script)
|
||
latex ; writing papers in Emacs has never been so fun
|
||
;;lean ; for folks with too much to prove
|
||
;;ledger ; be audit you can be
|
||
;;lua ; one-based indices? one-based indices
|
||
markdown ; writing docs for people to ignore
|
||
;;nim ; python + lisp at the speed of c
|
||
;;nix ; I hereby declare "nix geht mehr!"
|
||
;;ocaml ; an objective camel
|
||
(org +dragndrop +pandoc +pretty +gnuplot +roam2) ; organize your plain life in plain text
|
||
;;php ; perl's insecure younger brother
|
||
plantuml ; diagrams for confusing people more
|
||
;;purescript ; javascript" but functional
|
||
(python +lsp) ; beautiful is better than ugly
|
||
;;qt ; the 'cutest' gui framework ever
|
||
;;racket ; a DSL for DSLs
|
||
;;raku ; the artist formerly known as perl6
|
||
;;rest ; Emacs as a REST client
|
||
;;rst ; ReST in peace
|
||
;;(ruby +rails) ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
|
||
;;(rust +lsp) ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
|
||
;;scala ; java" but good
|
||
;;(scheme +guile) ; a fully conniving family of lisps
|
||
(sh +lsp) ; she sells {ba" z" fi}sh shells on the C xor
|
||
;;sml
|
||
;;solidity ; do you need a blockchain? No.
|
||
;;swift ; who asked for emoji variables?
|
||
;;terra ; Earth and Moon in alignment for performance.
|
||
(web +lsp) ; the tubes
|
||
yaml ; JSON" but readable
|
||
;;(zig +lsp) ; C" but simpler
|
||
|
||
:email
|
||
(mu4e +org +gmail)
|
||
;;notmuch
|
||
;;(wanderlust +gmail)
|
||
|
||
:app
|
||
calendar
|
||
emms
|
||
everywhere ; *leave* Emacs!? You must be joking
|
||
irc ; how neckbeards socialize
|
||
(rss +org) ; emacs as an RSS reader
|
||
;;twitter ; twitter client https://twitter.com/vnought
|
||
|
||
:config
|
||
;;literate
|
||
(default +bindings))
|
||
|
||
#+end_src
|
||
|
||
#+RESULTS:
|
||
|
||
* packages.el
|
||
*** Core
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
;; -*- no-byte-compile: t; -*-
|
||
;;; $DOOMDIR/packages.el
|
||
|
||
(unpin! straight)
|
||
(package! beacon)
|
||
(package! counsel)
|
||
(package! deft)
|
||
#+end_src
|
||
*** Themes
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
(package! all-the-icons)
|
||
(package! all-the-icons-dired)
|
||
(package! doom-themes)
|
||
#+end_src
|
||
*** Modes:
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
(package! battle-haxe)
|
||
(package! fish-mode)
|
||
(package! typescript-mode)
|
||
(package! terraform-mode)
|
||
(package! wc-mode)
|
||
(package! plantuml-mode)
|
||
(package! csv-mode)
|
||
#+end_src
|
||
*** dired
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
(package! dired-open)
|
||
#+end_src
|
||
*** pdf-tools
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
(package! pdf-tools)
|
||
#+end_src
|
||
|
||
*** Org
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
;; Fix for org-roam link issue
|
||
(package! org-auto-tangle)
|
||
(package! ox-slack)
|
||
(package! ox-tufte)
|
||
(package! ox-hugo)
|
||
(package! ox-gemini
|
||
:recipe (
|
||
:host sourcehut
|
||
:repo "abrahms/ox-gemini"))
|
||
(package! org-special-block-extras)
|
||
(package! org-transclusion)
|
||
(package! org-modern)
|
||
(package! org-ql)
|
||
(package! org-sidebar
|
||
:recipe (
|
||
:host github
|
||
:repo "alphapapa/org-sidebar"
|
||
))
|
||
(package! org-contacts)
|
||
(package! org-bullets)
|
||
(package! org-download)
|
||
(package! org-cliplink)
|
||
(package! org-roam)
|
||
;; (package! org-super-agenda)
|
||
(package! org-wild-notifier)
|
||
(package! org-habit-stats)
|
||
#+end_src
|
||
**** org-contrib
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
(package! org-contrib
|
||
:recipe (:host sourcehut :type git
|
||
:repo "~bzg/org-contrib"
|
||
:files ("lisp/*.el")))
|
||
|
||
#+end_src
|
||
*** LLM
|
||
Some packages for dealing with LLM integrations.
|
||
**** copilot.el
|
||
#+begin_src emacs-lisp :tangle no
|
||
(package! copilot
|
||
:recipe (:host github :repo "zerolfx/copilot.el" :files ("*.el" "dist")))
|
||
#+end_src
|
||
**** gptel
|
||
I mostly use this for my locally hosted LLM solutions. It's pretty neat since
|
||
large-context models are coming out at an increasing pace.
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
(package! gptel
|
||
:recipe (:host github
|
||
:repo "karthink/gptel"
|
||
:files ("*.el")))
|
||
#+end_src
|
||
*** Better Internet
|
||
**** elpher
|
||
Gopher and Gemini browser in Emacs!
|
||
#+begin_src emacs-lisp :tangle packages.el
|
||
(package! elpher)
|
||
#+end_src
|