.gitignore | ||
.lohr | ||
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 "Iosevka Fixed" :size 10.0 :weight 'medium))
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")
Enable proc macro support
By default lsp-mode disable these, I want them.
(setq lsp-rust-analyzer-experimental-proc-attr-macros t)
(setq lsp-rust-analyzer-proc-macro-enable t)
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 "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/project.org"))
(org-agenda-overriding-header "Personal projects")))
(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-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")))
)))))
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"))
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>"))))
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
Gitlab CI skip flag
This option tells GitLab to skip the CI run for this push, in case I know it's not ready yet.
(after! magit
(transient-append-suffix 'magit-push "-n"
'(4 "-s" "Skip GitLab CI" "--push-option=ci.skip")))
GitLab push options are documented here.
magit-delta
(use-package! magit-delta
:hook (magit-mode . magit-delta-mode))
Account configuration
This setting instructs mu4e
to prompt for login credentials if none are found
when trying to connect to one of the servers that match the regex (see variable
documentation).
(setq smtpmail-servers-requiring-authorization "smtp.migadu.com\\|smtp.lrde.epita.fr")
Setup my main email account.
(set-email-account! "alarsyo.net"
'((mu4e-sent-folder . "/alarsyo.net/Sent")
(mu4e-drafts-folder . "/alarsyo.net/Drafts")
(mu4e-refile-folder . "/alarsyo.net/Archive")
(mu4e-trash-folder . "/alarsyo.net/Trash")
(smtpmail-smtp-server . "smtp.migadu.com")
(smtpmail-smtp-service . 465)
(smtpmail-stream-type . ssl)
(user-mail-address . "antoine@alarsyo.net")
(user-full-name . "Antoine Martin")
(mu4e-compose-signature . "Antoine Martin"))
t)
(set-email-account! "lrde"
'((mu4e-sent-folder . "/lrde/Sent")
(mu4e-drafts-folder . "/lrde/Drafts")
(mu4e-trash-folder . "/lrde/Trash")
(smtpmail-smtp-server . "smtp.lrde.epita.fr")
(smtpmail-smtp-service . 587)
(smtpmail-stream-type . starttls)
(user-mail-address . "amartin@lrde.epita.fr")
(user-full-name . "Antoine Martin")
(mu4e-compose-signature . "Antoine Martin"))
nil)
Disable org-msg
by default
Doom adds a hook, making it impossible to disable. This allows us to toggle it manually.
(remove-hook! mu4e-compose-pre #'org-msg-mode)
Message quoting style
Has to be duplicated because mu4e
doesn't use message-cite-style
's values.
(defconst message-cite-style-custom
'((message-cite-function 'message-cite-original-without-signature)
(message-citation-line-function 'message-insert-formatted-citation-line)
(message-cite-reply-position 'traditional)
(message-yank-prefix "> ")
(message-yank-cited-prefix "> ")
(message-yank-empty-prefix ">")
(message-citation-line-format "%f writes:"))
"Message citation style used for email. Use with `message-cite-style'.")
(after! message
(setq message-cite-style message-cite-style-custom
message-cite-function 'message-cite-original-without-signature
message-citation-line-function 'message-insert-formatted-citation-line
message-cite-reply-position 'traditional
message-yank-prefix "> "
message-yank-cited-prefix "> "
message-yank-empty-prefix ">"
message-citation-line-format "%f writes:"))
Use Gnus view for mu4e
(after! mu4e
(setq mu4e-view-use-gnus t))
Disable format=flowed
(after! mu4e
(setq mu4e-compose-format-flowed nil))
Add git-apply-path to mu4e actions
(after! mu4e
(add-to-list 'mu4e-view-actions
'("GitApply" . mu4e-action-git-apply-patch) t)
(add-to-list 'mu4e-view-actions
'("MboxGitApply" . mu4e-action-git-apply-mbox) t))