Literate configuration for my Doom Emacs. This config extends Doom.
No sync
is required after modifying this file. Just a doom reload with SPC h r r
will do
Some functionality uses this to identify you, e.g. GPG configuration, email clients, file templates and snippets. It is optional.
(setq user-full-name "Shivek Khurana"
user-mail-address "[email protected]")
Not like a rogue rm
(setq delete-by-moving-to-trash t)
Set the undo limit to 80 mb
(setq undo-limit 80000000)
By default while in insert all changes are one big blob. Be more granular
(setq evil-want-fine-undo t)
(setq auto-save-default t)
(global-subword-mode 1)
Doom exposes five (optional) variables for controlling fonts in Doom:
doom-font
– the primary font to usedoom-variable-pitch-font
– a non-monospace font (where applicable)doom-big-font
– used for `doom-big-font-mode’; use this for presentations or streaming.doom-unicode-font
– for unicode glyphsdoom-serif-font
– for the `fixed-pitch-serif’ face
See C-h v doom-font
for documentation and more examples of what they
accept. For example:
(setq doom-font (font-spec :family "JetBrains Mono" :size 14 :weight 'normal)
doom-variable-pitch-font (font-spec :family "JetBrains Mono" :size 14)
doom-unicode-font (font-spec :family "Apple Color Emoji" :size 14))
If you or Emacs can’t find your font, use M-x describe-font
to look them
up, M-x eval-region
to execute elisp code, and M-x doom/reload-font
to
refresh your font settings. If Emacs still can’t find your font, it likely
wasn’t installed correctly. Font issues are rarely Doom issues!
There are two ways to load a theme. Both assume the theme is installed and
available. You can either set doom-theme
or manually load a theme with the
load-theme
function. This is the default:
(setq doom-theme 'doom-dracula)
This determines the style of line numbers in effect. If set to nil
, line
numbers are disabled. For relative line numbers, set this to relative
.
(setq display-line-numbers-type 'relative)
Setup a knot as a splash screen. A constant reminder of complexity and code.
;; Get all files in splash folder as alternatives
(let ((alternatives (directory-files (expand-file-name "~/.doom.d/splash/") nil "^\\([^.]\\|\\.[^.]\\|\\.\\..\\)")))
(setq fancy-splash-image
(concat doom-user-dir "splash/"
(nth (random (length alternatives)) alternatives))))
Org mode is a text based system to clarify thoughts. It also includes a nifty task management system. Unlike other todo softwares, that are centered around todos, Org is centered around text or ideas.
Tasks organically evolve from these ideas, and can be managed using an Agenda.
My organisation strategy is based on GTD. The core idea is to:
- Reduce friction while recording ideas, all tasks goto queue, add tags if you can
- Put everything on a queue, don’t process anything immediately
- Process the queue on a routine using processing strategy
- Make files sparingly, like courses or books to have notes or have just one file for notes ? A place that consists of everything I know I know
There should always be a space for the thing I’m doing, the thing to do next, and the things on hold.
Meditations should be logged religiously. So everyday, I can check my state and growth.
If you use org
and don’t want your org files in the default location below,
change org-directory
. It must be set before org loads!
(setq org-directory "~/Wip/time-machine/org")
(setq org-log-done 'time ; set a time when a task was complete
org-log-into-drawer "LOGBOOK" ; save state changes in ~:LOGBOOK:~ drawer
org-pretty-entities t)
Org’s agenda is a sophesticated view on top of all TODOs in the system
Start agenda in log mode and show clocked items, closed items and state changes on agenda
(setq org-agenda-start-with-log-mode t
org-agenda-log-mode-items '(closed clock state))
Show tags from all agenda files in autocomplete.
(setq org-complete-tags-always-offer-all-agenda-tags t)
Because all my ideas are supposed to goto a queue
(setq +org-capture-todo-file "queue.org")
Check organisation strategy to see reasons why these templates exist
(setq daily-tasks-list '("workout"
"meditation on pride"
"meditation on daily events"
"sleep on time"
"dinner before 6pm"
"practice portuguese"
))
(defun generate-checkbox-list (list)
(mapconcat (lambda (item) (format "- [ ] %s" item)) list "\n"))
(setq org-capture-templates
'(("t" "Enter TODO item in queue 🗳️" entry
(file+headline +org-capture-todo-file "Inbox")
"* TODO %U %?\n%i\n%a")
("s" "Start my day ☀️" entry
(file+datetree +org-capture-journal-file)
"* %U ☀️ [/]\n%(generate-checkbox-list daily-tasks-list)"
:immediate-finish t)
("j" "Journal ☁️" entry
(file+olp+datetree +org-capture-journal-file)
"* %U %?\n%i\n%a" :prepend t)))
- If a task can be done under 5 minutes, do it
- If it takes more time, it needs to be planned
- For a task that just needs time to be done, tag it with the respective project and mark it as TODO
- If its a time sensitive task, add a deadline or a schedule
routine.org
holds tasks that need to be done on repeat
I use Astro js for my site https://krimlabs.com. This setup makes emacs play nice with Astro.
Astro allows for markdown like front matter in .astro
files.
(setq web-mode-enable-front-matter-block t)
(define-derived-mode astro-mode web-mode "astro")
(setq auto-mode-alist
(append '((".*\\.astro\\'" . astro-mode))
auto-mode-alist))
(with-eval-after-load 'lsp-mode
(add-to-list 'lsp-language-id-configuration
'(astro-mode . "astro"))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection '("astro-ls" "--stdio"))
:activation-fn (lsp-activate-on "astro")
:server-id 'astro-ls)))
Treemacs is a file browsers with single key shortcuts.
Key | Function |
---|---|
d | Delete file under cursor |
c f | Create file in dir |
c d | Create directory in dir |
o v | Open in horizontal split |
o s | Open in vertical split |
? | View all shortcuts |
Set this variable to nil
. If set to true, I’m not able to jump to Treemacs with SPC w h
:
(setq treemacs-is-never-other-window nil)
Always show hidden files
(setq treemacs-show-hidden-files t)
Emacs LSP booster wraps the LSP server, making it faster. It does so by pre-parsing JSON returned from LSP server to an Elisp data structure. Reading an Elisp data structure is 4 times faster than reading JSON.
In order for this to run, download the emacs-lsp-booster
binary from the repo. Then move it to /usr/local/bin
. From the terminal, try to run emacs-lsp-booster
. The terminal will throw a security warning. Goto Privacy and security and allow it to run.
In the terminal, run emacs-lsp-booster
again. It should ask your permission to open it. Click open
. You will see an help output. This means that the binary is installed.
(setq lsp-use-plists t)
(defun lsp-booster--advice-json-parse (old-fn &rest args)
"Try to parse bytecode instead of json."
(or
(when (equal (following-char) ?#)
(let ((bytecode (read (current-buffer))))
(when (byte-code-function-p bytecode)
(funcall bytecode))))
(apply old-fn args)))
(advice-add (if (progn (require 'json)
(fboundp 'json-parse-buffer))
'json-parse-buffer
'json-read)
:around
#'lsp-booster--advice-json-parse)
(defun lsp-booster--advice-final-command (old-fn cmd &optional test?)
"Prepend emacs-lsp-booster command to lsp CMD."
(let ((orig-result (funcall old-fn cmd test?)))
(if (and (not test?) ;; for check lsp-server-present?
(not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper
lsp-use-plists
(not (functionp 'json-rpc-connection)) ;; native json-rpc
(executable-find "emacs-lsp-booster"))
(progn
(message "Using emacs-lsp-booster for %s!" orig-result)
(cons "emacs-lsp-booster" orig-result))
orig-result)))
(advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command)
Whenever you reconfigure a package, make sure to wrap your config in an
after!
block, otherwise Doom’s defaults may override your settings. E.g.
;; (after! PACKAGE
;; (setq x y))
The exceptions to this rule:
- Setting file/directory variables (like
org-directory
) - Setting variables which explicitly tell you to set them before their
package is loaded (see
C-h v VARIABLE
to look up their documentation). - Setting doom variables (which start with
doom-
or+
).
Here are some additional functions/macros that will help you configure Doom.
load!
for loading external *.el files relative to this oneuse-package!
for configuring packagesafter!
for running code after a package has loadedadd-load-path!
for adding directories to theload-path
, relative to this file. Emacs searches theload-path
when you load packages withrequire
oruse-package
.map!
for binding new keys
To get information about any of these functions/macros, move the cursor over
the highlighted symbol at press K
(non-evil users must press C-c c k
).
This will open documentation for it, including demos of how they are used.
Alternatively, use C-h o
to look up a symbol (functions, variables, faces,
etc).
You can also try gd
(or C-c c d
) to jump to their definition and see how
they are implemented.