.gitignore | ||
config.org | ||
init.el | ||
packages.el | ||
README.org |
- Table of Contents
- Misc
- Theme
- Programming
- Org mode
- Magit
Table of Contents TOC_3
Misc
Lexical bindings
Enable lexical binding, of course…
;;; -*- lexical-binding: t; -*-
Dir local variables
Disable these because I don't use them and don't want to get prompted by them in some projects.
(setq enable-dir-local-variables nil)
Taking SVG screenshots
Since Emacs 27, we can take SVG screenshots! Emacs needs to be built with
cairo
to support this.
(defun screenshot-svg ()
"Save a screenshot of the current frame as an SVG image.
Saves to a temp file and puts the filename in the kill ring."
(interactive)
(let* ((filename (make-temp-file "Emacs" nil ".svg"))
(data (x-export-frames nil 'svg)))
(with-temp-file filename
(insert data))
(kill-new filename)
(message filename)))
Theme
Main theme
A list of all doom themes can be found here:
https://github.com/hlissner/emacs-doom-themes
(setq doom-theme 'doom-solarized-light)
Dark theme toggle
I've come to prefer using a light theme during the day, and a dark theme at night. Using a dark theme with daylight leads to cranking up the screen brightness, which hurts my eyes more than using the light theme.
Set my light and dark themes:
(setq my/light-theme doom-theme
my/dark-theme 'doom-one)
Function to toggle between the two easily:
(defun my/toggle-dark-theme ()
(interactive)
(if (eq my/dark-theme doom-theme)
(load-theme my/light-theme t)
(load-theme my/dark-theme t)))
Bind this to SPC t d
:
(map! :leader
(:prefix-map ("t" . "toggle")
:desc "Dark theme" "d" #'my/toggle-dark-theme))
Font
Doom exposes five (optional) variables for controlling fonts in Doom. Here are the three important ones:
doom-font
doom-variable-pitch-font
doom-big-font
– used fordoom-big-font-mode
; use this for presentations or streaming.
They all accept either a font-spec, font string (Input Mono-12
), or xlfd font
string. You generally only need these two:
(setq doom-font
(font-spec :family "Input Mono Narrow" :size 12 :style 'regular))
Line numbers
Possible values of display-line-numbers-type
are nil
, t
, and 'relative
.
(setq display-line-numbers-type 'relative)
Battery indicator
I'm on a laptop, so let's display my battery in the modeline:
(display-battery-mode 1)
Programming
Smart parens
Disable smart parens because half of the time it doesn't do what I want:
(remove-hook 'doom-first-buffer-hook #'smartparens-global-mode)
Rust
Column width
rustfmt
limits lines to 100 characters, let's display it correctly.
(add-hook! rustic-mode
(set-fill-column 100))
Run clippy in rust-analyzer
The default is "check"
, but I want clippy lints as well.
(setq lsp-rust-analyzer-cargo-watch-command "clippy")
C/C++
Default style
Setup the default format for C/C++ editing.
(add-hook! (c-mode c++-mode)
(setq c-default-style "gnu")
(setq c-basic-offset 2))
Org mode
Directory
Set a default directory for all my org-mode files.
(setq org-directory "~/org/")
Appearance
Disable fancy stars
(remove-hook 'org-mode-hook #'org-superstar-mode)
Don't hide leading stars
Currently doesn't work due to hlissner/doom-emacs#3076
(after! org
(setq org-hide-leading-stars nil
org-startup-indented nil
org-adapt-indentation nil))
Fancier ellipsis indicator
(setq org-ellipsis " ▼ ")
Agenda setup
Default task keywords
Here are the keywords I'm using to track task progress. I'm also making use of some automatic state changes.
keyword | meaning |
---|---|
TODO |
Self explanatory |
DONE |
This task is finished, no longer displayed in the agenda |
CANCELLED |
This task isn't finished but is no longer relevant |
(after! org
(setq org-todo-keywords
'((sequence
"TODO(t)"
"|"
"DONE(d!)"
"CANCELLED(c@/!)")
(sequence
"[ ](T)"
"|"
"[X](D)"))))
Org capture setup
Of course I also need to setup capture templates:
The first one just prompts me for a new task to add to my inbox, I can then refile them where I want later.
The second one exists because I like to keep a separate list of articles / papers / books to read.
(after! org
(setq org-capture-templates
'(("t" "New entry" entry (file "inbox.org")
"* TODO %?")
("T" "Task" entry (file+headline "tasks.org" "Misc")
"* TODO %?")
("r" "Reading" entry (file "reading.org")
"* TODO %x"
:immediate-finish t)
("w" "Watching" entry (file "watching.org")
"* TODO %x"
:immediate-finish t))))
I also change the default Doom binding for #'org-capture
to be SPC x
instead
of SPC X
. Also need to rebind what was previously bound to SPC x
, to SPC
X
.
(map! :leader
:desc "Org Capture" "x" #'org-capture
:desc "Pop up scratch buffer" "X" #'doom/open-scratch-buffer)
Main agenda view
All these tasks, once captured, are then centralized in my agenda view.
I'm using multiple categories to organize tasks, depending on their triage / status (inspired by https://blog.jethro.dev/posts/org_mode_workflow_preview/).
(after! org-agenda
(setq org-agenda-custom-commands
'((" " "Agenda"
((agenda ""
((org-agenda-span 'day)
(org-agenda-start-day nil)
(org-deadline-warning-days 365)))
(todo "TODO"
((org-agenda-overriding-header "Triage")
(org-agenda-files '("~/org/inbox.org"))))
(todo "TODO"
((org-agenda-overriding-header "School")
(org-agenda-files '(
"~/org/image.org"
"~/org/rdi.org"
))
(org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline
'scheduled))))
(todo "TODO"
((org-agenda-overriding-header "Assistant")
(org-agenda-files '("~/org/assistant.org"))
(org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline
'scheduled))))
(todo "TODO"
((org-agenda-overriding-header "Job")
(org-agenda-files '("~/org/job.org"))
(org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline
'scheduled))))
(todo "TODO"
((org-agenda-overriding-header "Tasks")
(org-agenda-files '("~/org/tasks.org"))
(org-agenda-skip-function '(org-agenda-skip-entry-if 'deadline
'scheduled))))
(todo "TODO"
((org-agenda-files '("~/org/watching.org"))
(org-agenda-overriding-header "To Watch")))
(todo "TODO"
((org-agenda-files '("~/org/reading.org"))
(org-agenda-overriding-header "To Read")))
(todo "TODO"
((org-agenda-files '("~/org/notes.org"))
(org-agenda-overriding-header "Note Taking")))
(todo "TODO"
((org-agenda-files '("~/org/project.org"))
(org-agenda-overriding-header "Personal projects")))
)))))
I want the default agenda view to be a weekly view, with a log of what I've done during the day.
(after! org-agenda
(setq org-agenda-span 'week)
(setq org-agenda-start-on-weekday 1)
(setq org-agenda-start-with-log-mode '(clock)))
I also remove the block separators in the agenda view:
(after! org-agenda
(setq org-agenda-block-separator ""))
Habits
Let's enable the org-habit
module:
(add-to-list 'org-modules 'org-habit)
Save all org buffers shortcut
By default bound to C-x C-s
, rebind it to SPC m s
in org-agenda-mode
:
(map! :after org-agenda
:map org-agenda-mode-map
:localleader
"s" #'org-save-all-org-buffers)
Org IDs
Org can link to entries using UUIDs, but we need the module to be loaded for links to work:
(add-to-list 'org-modules 'org-id)
Roam
Setup for org-roam.
Roam Directory
First, set a directory where org-roam
will index things.
(setq org-roam-directory (expand-file-name "notes/" org-directory))
Graph browser
Instruct org-roam
to use firefox-developer-edition
to open the graph:
(setq org-roam-graph-viewer (executable-find "firefox-developer-edition"))
Roam link font face
Change link color for org-roam
links, to distinguish them from standard Org
links:
(after! org-roam
(set-face-attribute 'org-roam-link nil :foreground "#FF8860"))
Roam capture template
Customize the capture templates:
- the first one is the default one, I just removed the timestamp from the file title.
- the second one I use to create new entries about website links, blog posts,
articles… The
%x
in the template is replaced by the content of my X clipboard, so I just have to copy the website URL before capturing it.
(after! org-roam
(setq org-roam-capture-templates
'(("d" "default" plain (function org-roam-capture--get-point)
"%?"
:file-name "${slug}"
:head "#+TITLE: ${title}\n"
:unnarrowed t)
("i" "instant" plain (function org-roam-capture--get-point)
"%?"
:file-name "${slug}"
:head "#+TITLE: ${title}\n"
:unnarrowed t
:immediate-finish t)
("w" "website" plain (function org-roam-capture--get-point)
""
:file-name "websites/${slug}"
:head "#+TITLE: ${title}\n#+ROAM_KEY: %x\n"
:unnarrowed t)
("p" "paper" plain (function org-roam-capture--get-point)
"%?"
:file-name "papers/${slug}"
:head "#+TITLE: ${title}\n"
:unnarrowed t))))
Roam daily capture templates
Also setup daily captures templates, mainly used to store them in a journal/
directory instead of at the root.
(after! org-roam
(setq org-roam-dailies-capture-templates
'(("d" "daily" plain (function org-roam-capture--get-point)
""
:immediate-finish t
:file-name "journal/%<%Y-%m-%d>"
:head "#+TITLE: %<%Y-%m-%d>"))))
Org Roam Server
org-roam-server
provides a fancy JS interface to visualize the graph. Just
needs to be loaded, along with its dependency simple-httpd
.
(use-package! simple-httpd)
(use-package! org-roam-server)
Export backends
Sometimes I need to export an Org subtree to a file, which is quite easy with
the org
export backend. It doesn't seem to be enabled by default, so let's add
it to the list:
(after! org
(add-to-list 'org-export-backends 'org))
Doom specific
Doom replaces the default tab behavior on headings, this restores the default one. Taken from here.
(after! evil-org
(remove-hook 'org-tab-first-hook #'+org-cycle-only-current-subtree-h))
Magit
(after! magit
(transient-append-suffix 'magit-push "-n"
'(4 "-s" "Skip GitLab CI" "--push-option=ci.skip")))