###########################'`################################ ########################### V##'############################ #########################V' `V ############################ ########################V' ,############################ #########`#############V ,A###########################V ########' `###########V ,###########################V',# ######V' ###########l ,####################V~~~~'',### #####V' ###########l ##P' ###########V~~' ,A####### #####l d#########l V' ,#######V~' A######### #####l ##########l ,####V'' ,########### #####l `V######l ,###V' .....;A############## #####A, `######A, ,##V' ,A####################### #######A, `######A, #V' A########'''''##########'' ##########,,, `####A, `#'' ''' ,,, #############A, ,,, ,###### ######################oooo, ;####, ,######### ##################P' A, ;#####V########## #####P' '''' ,### `#, `V############ ##P' ,d###; ##, `V######### ##########A,, #########A )##, ##A,..,ooA### #############A, Y#########A, )####, ,############# ###############A ############A, ,###### ############## ############################### ,#######V############## ############################### ,####################### ##############################P ,d######################## ##############################' d######################### ############################## ########################## ############################## ########################## #############################P ########################## #############################' ########################## ############################P ########################## ###########################P' ;########################## ###########################' ,########################### ########################## ############################ ######################### ,############################ ######################## d###########P' `Y######### ####################### ,############ ######### ###################### ,############# ######### ##################### ,##############b. ,d######### #################### ,################################ ################### ################################# ################## #######################P' `V##P' #######P' `V# ###################P' #####P' ,#################P' ###P' d##############P'' ##P' V##############' #P' `V###########' #' `V##P'
I primarily use org-babel because it helps with organizing. You’re at
least forced to acknowledge headings. Otherwise I’d just get a messy
init.el file. Which, well, maybe I’ll go back to.
Lexical binding for certain packages & personal functions.
;; -*- lexical-binding: t -*-;; needed for gccemacs
(setenv "LIBRARY_PATH" "/opt/homebrew/lib/gcc/11:/opt/homebrew/lib/gcc/11/gcc/aarch64-apple-darwin20/11")
(setq gc-cons-threshold (* 50 1000 1000))
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
(straight-use-package 'use-package)
(setq straight-use-package-by-default t)
(use-package no-littering)
(setq custom-file "~/.emacs.d/custom.el")
(if (file-exists-p custom-file)
(message (concat "File " (concat custom-file " already exists")))
(with-temp-buffer (write-file custom-file)))
(load custom-file)Need to get the environment set correctly, otherwise terminals won’t work or certain packages. This is for GUI emacs.
(use-package exec-path-from-shell
:init
(exec-path-from-shell-initialize))
(let ((default-directory "/opt/homebrew/share/emacs/site-lisp"))
(normal-top-level-add-subdirs-to-load-path))
(autoload 'gerbil-mode "gerbil-mode" "Gerbil editing mode." t)To Diminish a mode is to no longer have it show up in the modeline. Useful to remove clutter from the modeline display.
(use-package diminish)Now that we’re loading in emacs, it’s nice to keep it clean, but not
too clean.
Many people seem to discount the satisfaction of using the
menu-bar-mode - it’s a great way to explore and remind yourself. I
find myself using my mouse more than I thought I would - to scroll a
buffer, click a command, resize stuff, etc.
Relative line column numbers (counting which line you’re on) helps with command chording. But of course they’re useless for some buffers, so we’ll disable them.
(menu-bar-mode t)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(toggle-frame-maximized)
(set-fringe-mode 10)
(setq-default tab-width 2)
(setq-default indent-tabs-mode nil)
(setq inhibit-startup-message t)
(if (equal window-system nil)
(menu-bar-mode -1))
(setq ring-bell-function 'ignore)
(column-number-mode t)
(setq display-line-numbers-type 'relative)
(add-hook 'prog-mode-hook (lambda()
(display-line-numbers-mode)
))I enjoy Iosevka. The cramped nature of it can be off-putting, but after some use you can’t use anything else.
Comes with ligatures. Real easy with ligature.el - they gave me the Iosevka example below.
(set-face-attribute 'default nil :family "Iosevka Nerd Font" :height 170)
(set-face-attribute 'fixed-pitch nil :family "Iosevka Nerd Font" :height 170)
(set-face-attribute 'variable-pitch nil :family "Iosevka Nerd Font" :height 170)
(global-prettify-symbols-mode +1)
(use-package ligature
:straight (ligature :type git :host github :repo "mickeynp/ligature.el" :files ("*.el" "*"))
:config
(ligature-set-ligatures '(prog-mode text-mode) '("<---" "<--" "<<-" "<-" "->" "-->" "--->" "<->" "<-->" "<--->" "<---->" "<!--"
"<==" "<===" "<=" "=>" "=>>" "==>" "===>" ">=" "<=>" "<==>" "<===>" "<====>" "<!---"
"<~~" "<~" "~>" "~~>" "::" ":::" "==" "!=" "===" "!=="
":=" ":-" ":+" "<*" "<*>" "*>" "<|" "<|>" "|>" "+:" "-:" "=:" "<******>" "++" "+++"))
(global-ligature-mode t))Rainbow Parentheses/Curlies. Super nice to have in any prog file.
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode)
:diminish rainbow-delimiters-mode)Using moody. Stealing some theme management :~)
(use-package moody
:config
(setq x-underline-at-descent-line t)
(setq moody-mode-line-height 24)
(moody-replace-mode-line-buffer-identification)
(moody-replace-vc-mode)
(moody-replace-eldoc-minibuffer-message-function))Trying out a new theme. Was using solarized regular.
(use-package kaolin-themes)
(defun phl-theme-mods ()
"Fix look after loading a theme"
;; preserve syntax highlighting
;; (set-face-background 'region (face-attribute 'highlight :background))
(set-face-foreground 'region nil)
(setq moody-line (face-attribute 'mode-line :underline))
(set-face-attribute 'mode-line nil :overline moody-line)
(set-face-attribute 'mode-line-inactive nil :overline moody-line)
(set-face-attribute 'mode-line-inactive nil :underline moody-line)
(setq show-paren-priority -50)
(set-face-attribute 'mode-line nil :box nil)
(set-face-attribute 'mode-line-inactive nil :box nil))
(defun phl-apply-theme (appearance)
"Load theme, taking current system APPEARANCE into consideration."
(mapc #'disable-theme custom-enabled-themes)
(pcase appearance
('light (load-theme 'kaolin-breeze t))
('dark (load-theme 'kaolin-mono-dark t)))
(phl-theme-mods)
(phl-fix-bookmark))
(if (equal window-system nil)
(load-theme 'kaolin-temple))
(defun phl-fix-bookmark ()
"Set bookmark appearance after load"
(set-face-foreground 'bookmark-face (face-attribute 'default :foreground))
(set-face-background 'bookmark-face (face-attribute 'default :background)))
(add-hook 'bookmark-load-hook #'phl-fix-bookmark)
(add-hook 'ns-system-appearance-change-functions #'phl-apply-theme)which key is a little popup that comes after you start a key chord. Super useful, use it all the time, excessively.
(use-package which-key
:init (which-key-mode)
:diminish which-key-mode
:config (setq which-key-idle-delay 0.3))It’s magit! Getting used to it, a lot nicer than grabbing a terminal, that’s for sure.
(use-package magit)
(setq magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1)Easy way to select what you want, mostly use it for removing chars within quotes. Maybe I don’t need it. But it seems like the embark cycle isn’t a good use case for this
(use-package expand-region
:bind(
("C-=" . er/expand-region)))Need a place to drop some custom keys
(global-set-key (kbd "C-x M-k") #'kill-this-buffer)
(global-set-key (kbd "C-c s") #'ispell)Quicker confirmations
(fset 'yes-or-no-p 'y-or-n-p)hydra allows repeatable commands. Only use it for text size, but maybe more ideas will come or I’ll stop using this.
(use-package hydra)
(defhydra hydra-text-scale (global-map "<f2>")
"scale text"
("C-p" text-scale-increase "in")
("C-n" text-scale-decrease "out"))Improved help info. Getting comfortable at looking variables/functions is the way to go.
(use-package helpful
:bind
([remap describe-function] . helpful-function)
([remap describe-command] . helpful-command)
([remap describe-variable] . helpful-variable)
([remap describe-key] . helpful-key))Autocompletion is smart for any sort of typing, isn’t it? So I enable company.
(use-package company
:after lsp-mode
:hook (lsp-mode . company-mode)
:bind (:map company-active-map
("<tab>" . company-complete-selection))
(:map lsp-mode-map
("<tab>" . company-indent-or-complete-common))
:custom
(company-minimum-prefix-length 3)
(company-idle-delay 0.0))
yasnippet for code templates. Templating is sure convenient to have, wondering when I’ll make more use of it.
(use-package yasnippet
:init (yas-global-mode 1))
(use-package doom-snippets
:after yasnippet
:straight (doom-snippets :type git :host github :repo "hlissner/doom-snippets" :files ("*.el" "*")))
(use-package common-lisp-snippets
:after yasnippet
:straight (common-lisp-snippets :type git :host github :repo "mrkkrp/common-lisp-snippets" :files ("*.el" "*")))
whole-line-or-region is a quick swap-out to make more use of M-w instead of doing C-a C-k C-k
(use-package whole-line-or-region
:straight (whole-line-or-region :type git :host github :repo "purcell/whole-line-or-region" :files ("*.el" "*")))
(whole-line-or-region-global-mode t)Originally used projectile, going to give project.el a try. Don’t have much to say about it at this point.
(use-package project
:after magit
:init
(setq project-switch-commands
'((project-find-file "Find file" nil)
(project-find-regexp "Find regexp" nil)
(project-find-dir "Find directory" nil)
(project-vc-dir "VC-Dir" nil)
(project-eshell "Eshell" nil)
(magit-status "Magit" ?m))))
;; scan on startup for new projects
(mapc
#'project-remember-projects-under
'("~/common-lisp"
"~/repos"))
Going to try out using tabs as ‘workspaces’ and just switch to eshell buffer when its needed so far so good
(setq tab-bar-show nil)
(setq tab-bar-select-tab-modifiers '(super))
(tab-bar-mode t)To help move around buffers. Just going to replace C-x o.
(use-package ace-window)
(defvar global-keys-minor-mode-map (make-sparse-keymap)
"global-keys-minor-mode keymap.")
(defun phl-split-window-right ()
(interactive)
(split-window-right)
(other-window 1))
(defun phl-split-window-below ()
(interactive)
(split-window-below)
(other-window 1))
(define-key global-keys-minor-mode-map "\C-c\C-r" 'revert-buffer)
(define-key global-keys-minor-mode-map (kbd "C-x o") 'ace-window)
(define-key global-keys-minor-mode-map (kbd "C-x 2") 'phl-split-window-below)
(define-key global-keys-minor-mode-map (kbd "C-x 3") 'phl-split-window-right)
;; (define-key global-keys-minor-mode-map (kbd "M-`") 'popper-toggle-latest)
(define-key global-keys-minor-mode-map (kbd "C-'") 'avy-goto-char-2)
(define-minor-mode global-keys-minor-mode
"A minor mode so that global key settings override annoying major modes."
t "global-keys" 'global-keys-minor-mode-map)
(global-keys-minor-mode 1)
;; A keymap that's supposed to be consulted before the first
;; minor-mode-map-alist.
(defconst global-minor-mode-alist (list (cons 'global-keys-minor-mode
global-keys-minor-mode-map)))
(setf emulation-mode-map-alists '(global-minor-mode-alist))
(defun my-minibuffer-setup-hook ()
(global-keys-minor-mode 0))
(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)
(diminish 'global-keys-minor-mode)Originally tried out ivy, going to try out all of these other packages and see how it goes. For now I’ll use vertico after some debilitating thought. So far consult buffer preview is pretty nice.
Vertico is Vertical completion in command searching
(use-package vertico
:init
(vertico-mode)
(defun phl-minibuffer-backward-kill (arg)
"When minibuffer is completing a file name delete up to parent
folder, otherwise delete a word."
(interactive "p")
(if minibuffer-completing-file-name
(if (string-match-p "/." (minibuffer-contents))
(zap-up-to-char (- arg) ?/)
(delete-minibuffer-contents))
(delete-word (- arg))))
:bind (:map vertico-map
("C-f" . vertico-exit)
:map minibuffer-local-map
("M-DEL" . phl-minibuffer-backward-kill))
:custom
(vertico-cycle t)
(custom-set-faces '(vertico-current ((t (:background "#3a3f5a"))))))Orderless; any order searching
(use-package orderless
:init
(setq completion-styles '(orderless)
completion-category-defaults nil
completion-category-overrides '((file (styles . (partial-completion))))))Consult; improved interfacing with emacs
;; Example configuration for Consult
(use-package consult
;; Replace bindings. Lazily loaded due by `use-package'.
:bind (;; C-c bindings (mode-specific-map)
("C-c h" . consult-history)
("C-c m" . consult-mode-command)
("C-c b" . consult-bookmark)
("C-c k" . consult-kmacro)
;; C-x bindings (ctl-x-map)
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
("<help> a" . consult-apropos) ;; orig. apropos-command
;; M-g bindings (goto-map)
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line) ;; orig. goto-line
("M-g M-g" . consult-goto-line) ;; orig. goto-line
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
;; M-s bindings (search-map)
("M-s f" . consult-find)
("M-s F" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s m" . consult-multi-occur)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi)) ;; needed by consult-line to detect isearch
:init
(setq register-preview-delay 0
register-preview-function #'consult-register-format)
(advice-add #'register-preview :override #'consult-register-window)
(advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:config
(consult-customize
consult-theme
:preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-file consult--source-project-file consult--source-bookmark
:preview-key (kbd "M-."))
(setq consult-narrow-key "<") ;; (kbd "C-+")
(setq consult-project-root-function
(lambda ()
(when-let (project (project-current))
(car (project-roots project)))))
)
(require 'consult)
(use-package consult-yasnippet
:bind ("C-x C-y" . consult-yasnippet))Marginalia; Command info as well as keybinding for minibuffer
;; Enable richer annotations using the Marginalia package
(use-package marginalia
:init
(marginalia-mode))Embark; emacs action flow & Avy; char tree movement Just adding this in since it is often paired with the others. Trying out some embark+avy combinations too.
(use-package embark
:bind (("M-o" . embark-act)
("M-C-o" . embark-export))
:config
(setq embark-cycle-key (kbd "O"))
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none))))
(define-key embark-command-map "f" #'helpful-function)
)
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key.
The which-key help message will show the type and value of the
current target followed by an ellipsis if there are further
targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (plist-get (car targets) :type) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "…" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t (lambda (binding)
(not (string-suffix-p "-argument" (cdr binding))))))))
(setq embark-indicators
'(embark-which-key-indicator
embark-highlight-indicator
embark-isearch-highlight-indicator))
(defun embark-hide-which-key-indicator (fn &rest args)
"Hide the which-key indicator immediately when using the completing-read prompter."
(which-key--hide-popup-ignore-command)
(let ((embark-indicators
(remq #'embark-which-key-indicator embark-indicators)))
(apply fn args)))
(advice-add #'embark-completing-read-prompter
:around #'embark-hide-which-key-indicator)
;; Consult users will also want the embark-consult package.
(use-package embark-consult
:after (embark consult)
:demand t ; only necessary if you have the hook below
;; if you want to have consult previews as you move around an
;; auto-updating embark collect buffer
:hook
(embark-collect-mode . consult-preview-at-point-mode))
(use-package avy
:demand
:bind (("C-;" . avy-goto-char-timer)
("C-:" . avy-isearch)
("C-'" . avy-goto-char-2)))
(defun avy-action-embark (pt)
(unwind-protect
(save-excursion
(goto-char pt)
(embark-act))
(select-window
(cdr (ring-ref avy-ring 0))))
t)
(defun avy-action-helpful (pt)
(save-excursion
(goto-char pt)
(helpful-at-point))
(select-window
(cdr (ring-ref avy-ring 0)))
t)
(defun avy-action-mark-to-char (pt)
(activate-mark)
(goto-char pt))
(defun avy-action-copy-whole-line (pt)
(save-excursion
(goto-char pt)
(cl-destructuring-bind (start . end)
(bounds-of-thing-at-point 'line)
(copy-region-as-kill start end)))
(select-window
(cdr
(ring-ref avy-ring 0)))
t)
(defun avy-action-yank-whole-line (pt)
(avy-action-copy-whole-line pt)
(save-excursion (yank))
t)
(defun avy-action-kill-whole-line (pt)
(save-excursion
(goto-char pt)
(kill-whole-line))
(select-window
(cdr
(ring-ref avy-ring 0)))
t)
(defun avy-action-teleport-whole-line (pt)
(avy-action-kill-whole-line pt)
(save-excursion (yank)) t)
(setf (alist-get ?t avy-dispatch-alist) 'avy-action-teleport
(alist-get ?T avy-dispatch-alist) 'avy-action-teleport-whole-line)
(setf (alist-get ?k avy-dispatch-alist) 'avy-action-kill-stay
(alist-get ?K avy-dispatch-alist) 'avy-action-kill-whole-line)
(setf (alist-get ?y avy-dispatch-alist) 'avy-action-yank
(alist-get ?w avy-dispatch-alist) 'avy-action-copy
(alist-get ?W avy-dispatch-alist) 'avy-action-copy-whole-line
(alist-get ?Y avy-dispatch-alist) 'avy-action-yank-whole-line)
(setf (alist-get ? avy-dispatch-alist) 'avy-action-mark-to-char)
(setf (alist-get ?H avy-dispatch-alist) 'avy-action-helpful)
(setf (alist-get ?o avy-dispatch-alist) 'avy-action-embark)The more I use it the more I wonder why I haven’t used it before.
(defun phl-org-mode-setup ()
(org-indent-mode)
(auto-fill-mode 1)
(visual-line-mode 1))(use-package org
:hook (org-mode . phl-org-mode-setup)
:config
(setq org-agenda-start-with-log-mode t)
(setq org-agenda-window-setup 'current-window)
(setq org-agenda-tags-column org-tags-column)
(setq org-agenda-sticky t)
(setq org-agenda-inhibit-startup nil)
(setq org-agenda-dim-blocked-tasks nil)
(setq org-agenda-compact-blocks nil)
(setq org-agenda-time-grid
(quote
((daily today remove-match)
(800 1200 1600 2000)
"......"
"----------------")))
(setq org-log-done 'time)
(setq org-log-into-drawer t)
(setq org-ellipsis " ⤵"
org-hide-emphasis-markers t)
(setq org-todo-keywords
'((sequence "BACKLOG(b)" "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
(sequence "HABIT(h)" "|" "CHECKED(c)")))
(setq org-refile-targets
'(("Archive.org" :maxlevel . 1)
("Tasks.org" :maxlevel . 1)))
(require 'org-habit)
(add-to-list 'org-modules 'org-habit)
(setq org-habit-graph-column 60)
;; Save Org buffers after refiling!
(advice-add 'org-refile :after 'org-save-all-org-buffers)
:bind ("C-c a" . org-agenda))
(use-package org-download)
(add-hook 'dired-mode-hook 'org-download-enable)(use-package org-superstar
:after org
:hook (org-mode . org-superstar-mode)
:config
(setq org-superstar-headline-bullets-list '("∗")))
(defun phl-org-mode-visual-fill ()
(setq visual-fill-column-width 100
visual-fill-column-center-text t)
(visual-fill-column-mode 1))
(use-package visual-fill-column
:hook (org-mode . phl-org-mode-visual-fill))Makes writing easy compared to everything else I’ve tried.
(use-package org-roam
:after consult
:straight t
:demand
:init
(setq org-roam-v2-ack t)
:custom
(org-roam-directory "~/Documents/notes")
(org-roam-completion-everywhere t)
(org-roam-dailies-capture-templates
'(("d" "default" entry "* %<%I:%M %p>: %?"
:if-new (file+head "%<%Y-%m-%d>.org" "#+title: %<%Y-%m-%d>\n"))))
(org-roam-capture-templates
`(("d" "default" plain
"%?"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)
("b" "book notes" plain (file ,(concat org-roam-directory "/Templates/BookTemplate.org"))
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)
("a" "design notes" plain
(file ,(concat org-roam-directory "/Templates/DesignAnalysisTemplate.org"))
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${title}\n")
:unnarrowed t)
)
)
:bind (("C-c n l" . org-roam-buffer-toggle)
("C-c n f" . org-roam-node-find)
("C-c n i" . org-roam-node-insert)
("C-c n r" . phl-org-roam-rg)
:map org-mode-map
("C-M-i" . completion-at-point)
:map org-roam-dailies-map
("Y" . org-roam-dailies-capture-yesterday)
("T" . org-roam-dailies-capture-tomorrow))
:bind-keymap
("C-c n d" . org-roam-dailies-map)
:config
(defun phl-org-roam-rg ()
"Search across the content of the root org dir."
(interactive)
(consult-ripgrep org-roam-directory))
(require 'org-roam-dailies) ;; Ensure the keymap is available
(org-roam-db-autosync-mode)
(org-roam-setup))(use-package org-make-toc)(defun org-roam-node-insert-immediate (arg &rest args)
(interactive "P")
(let ((args (cons arg args))
(org-roam-capture-templates (list (append (car org-roam-capture-templates)
'(:immediate-finish t)))))
(apply #'org-roam-node-insert args)))
(global-set-key (kbd "C-c n I") #'org-roam-node-insert-immediate)This is how one generates the configuration. And also edit this configuration. We can just autogenerate it with this snippet.
(org-babel-do-load-languages
'org-babel-load-languagesp
'((emacs-lisp . t)
(python . t)
(lisp . t)))
(setq org-babel-lisp-eval-fn "sly-eval")
(setq org-src-tab-acts-natively nil)
(setq org-src-window-setup 'current-window)
(push '("conf-unix" . conf-unix) org-src-lang-modes)
(require 'org-tempo)
(add-to-list 'org-structure-template-alist '("sh" . "src shell"))
(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
(add-to-list 'org-structure-template-alist '("py" . "src python"))
(add-to-list 'org-structure-template-alist '("cl" . "src lisp"))
;; Automatically tangle our .org config file when we save it
(defun phl-org-babel-tangle-config ()
(when (string-equal (buffer-file-name)
(expand-file-name "~/.emacs.d/README.org"))
;; Dynamic scoping to the rescue
(let ((org-confirm-babel-evaluate nil))
(org-babel-tangle))))
(add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'phl-org-babel-tangle-config)))To make it easier to write up notes around certain domains, as well as having a project note to show up in agenda.
(defun phl-org-roam-filter-by-tag (tag-name)
(lambda (node)
(member tag-name (org-roam-node-tags node))))
(defun phl-org-roam-list-notes-by-tag (tag-name)
(mapcar #'org-roam-node-file
(seq-filter
(phl-org-roam-filter-by-tag tag-name)
(org-roam-node-list))))
(defun phl-org-roam-refresh-agenda-list ()
(interactive)
(setq org-agenda-files
(append
(phl-org-roam-list-notes-by-tag "Project")
'("~/Documents/notes/agenda/Tasks.org"
"~/Documents/notes/agenda/Habits.org"))))
;; Build the agenda list the first time for the session
(phl-org-roam-refresh-agenda-list)
(defun phl-org-roam-project-finalize-hook ()
"Adds the captured project file to `org-agenda-files' if the
capture was not aborted."
;; Remove the hook since it was added temporarily
(remove-hook 'org-capture-after-finalize-hook #'phl-org-roam-project-finalize-hook)
;; Add project file to the agenda list if the capture was confirmed
(unless org-note-abort
(with-current-buffer (org-capture-get :buffer)
(add-to-list 'org-agenda-files (buffer-file-name)))))
(defun phl-org-roam-find-project ()
(interactive)
;; Add the project file to the agenda after capture is finished
(add-hook 'org-capture-after-finalize-hook #'phl-org-roam-project-finalize-hook)
;; Select a project file to open, creating it if necessary
(org-roam-node-find nil nil
(phl-org-roam-filter-by-tag "Project")
:templates
'(("p" "project" plain
"* Goals\n\n%?\n\n* Tasks\n\n** TODO Add initial tasks\n\n* Dates\n\n"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n#+category: ${title}\n#+filetags: Project")
:unnarrowed t))))
(defun phl-org-roam-capture-inbox ()
(interactive)
(org-roam-capture- :node (org-roam-node-create)
:templates '(("i" "inbox" plain "* %?"
:if-new (file+head "Inbox.org" "#+title: Inbox\n")))))
(defun phl-org-roam-capture-project-task ()
(interactive)
;; Add the project file to the agenda after capture is finished
(add-hook 'org-capture-after-finalize-hook #'phl-org-roam-project-finalize-hook)
;; Capture the new task, creating the project file if necessary
(org-roam-capture- :node (org-roam-node-read nil (phl-org-roam-filter-by-tag "Project"))
:templates '(("p" "project" plain "** TODO %?"
:if-new (file+head+olp "%<%Y%m%d%H%M%S>-${slug}.org"
"#+title: ${title}\n#+category: ${title}\n#+filetags: Project"
("Tasks"))))))
(defun phl-org-roam-copy-todo-to-today ()
(interactive)
(let ((org-refile-keep t)
(org-roam-dailies-capture-templates
'(("t" "tasks" entry "%?"
:if-new (file+head+olp "%<%Y-%m-%d>.org"
"#+title: %<%Y-%m-%d>\n"
("Tasks")))))
(org-after-refile-insert-hook #'save-buffer) today-file pos)
(save-window-excursion
(org-roam-dailies--capture
(current-time) t)
(setq today-file (buffer-file-name))
(setq pos (point)))
(unless (equal (file-truename today-file)
(file-truename
(buffer-file-name)))
(org-refile nil nil (list "Tasks" today-file nil pos)))))
(add-to-list 'org-after-todo-state-change-hook
(lambda ()
(when (equal org-state "DONE")
(phl-org-roam-copy-todo-to-today))))
(global-set-key (kbd "C-c n t") #'phl-org-roam-capture-project-task)
(global-set-key (kbd "C-c n n") #'phl-org-roam-capture-inbox)
(global-set-key (kbd "C-c n p") #'phl-org-roam-find-project)It just works.
(defun phl-start-new-eshell ()
"Spawn a new eshell always."
(interactive)
(eshell)
(rename-uniquely))
(global-set-key (kbd "C-c e") #'phl-start-new-eshell)
(defun phl-configure-eshell ()
;; Save command history when commands are entered
(add-hook 'eshell-pre-command-hook 'eshell-save-some-history)
;; Truncate buffer for performance
(add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer)
(setq eshell-history-size 10000
eshell-buffer-maximum-lines 10000
eshell-hist-ignoredups t
eshell-scroll-to-bottom-on-input t))
(use-package eshell
:hook (eshell-first-time-mode . phl-configure-eshell))It just works more
(require 'term)
(defun phl-start-new-term ()
"Spawn a new term always."
(interactive)
(pop-to-buffer-same-window
(set-buffer (make-term "terminal" "/bin/zsh")))
(term-line-mode)
(rename-uniquely))
(defun phl-term-toggle-mode ()
"Toggles term between line mode and char mode"
(interactive)
(if (term-in-line-mode)
(term-char-mode)
(term-line-mode)))
(define-key term-mode-map (kbd "C-c C-j") #'phl-term-toggle-mode)
(define-key term-mode-map (kbd "C-c C-k") #'phl-term-toggle-mode)
(define-key term-raw-map (kbd "C-c C-j") #'phl-term-toggle-mode)
(define-key term-raw-map (kbd "C-c C-k") #'phl-term-toggle-mode)
(global-set-key (kbd "C-c t") #'phl-start-new-term)Using lsp-mode because it just works
(use-package lsp-mode
:commands (lsp lsp-deffered)
:init
(setq lsp-keymap-prefix "C-c l")
:config
(lsp-enable-which-key-integration t))
(use-package lsp-ui
:hook (lsp-mode . lsp-ui-mode)
:custom
(lsp-ui-doc-position 'bottom))Surprised how well this is integrated. You just need more packages
(use-package flutter
:after dart-mode
:bind (:map dart-mode-map
("C-M-x" . #'flutter-run-or-hot-reload))
:custom
(setq flutter-sdk-path "/Users/100phlecs/packages/flutter/"))(use-package dart-mode
:hook (dart-mode . lsp))
;; UI and such, sine they're dependences of lsp-dart
(use-package flycheck)
(use-package treemacs)
(use-package lsp-treemacs)
(use-package lsp-dart
:init
(setq lsp-dart-sdk-dir "/Users/100phlecs/packages/flutter/bin/cache/dart-sdk")
(setq lsp-dart-flutter-sdk-dir "/Users/100phlecs/packages/flutter")
(setq lsp-dart-enable-sdk-formatter t))alien technology
(use-package sly)
(setq inferior-lisp-program "/opt/homebrew/bin/sbcl")
(use-package rainbow-blocks)
(use-package lispy)
(add-hook
'emacs-lisp-mode-hook
(lambda () (lispy-mode 1)
(company-mode)
(rainbow-blocks-mode)))
(add-hook
'lisp-mode-hook
(lambda () (lispy-mode 1)
(company-mode)
(rainbow-blocks-mode)))
(add-hook 'sly-mode-hook (lambda ()
(electric-pair-mode)
(company-mode)
(rainbow-blocks-mode)))
(use-package rustic
:bind (:map rustic-mode-map
("M-j" . lsp-ui-imenu)
("M-?" . lsp-find-references)
("C-c C-c l" . flycheck-list-errors)
("C-c C-c a" . lsp-execute-code-action)
("C-c C-c r" . lsp-rename)
("C-c C-c q" . lsp-workspace-restart)
("C-c C-c Q" . lsp-workspace-shutdown)
("C-c C-c s" . lsp-rust-analyzer-status)
("C-c r" . rustic-compile))
:config
(progn
;; (setq rustic-lsp-setup-p nil)
(setq rustic-lsp-server 'rust-analyzer)
(setq rustic-format-on-save nil)
(setq rustic-indent-offset 2)
(electric-pair-mode 1)))
(use-package web-mode
:config
(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.svelte\\'" . web-mode))
(setq web-mode-engines-alist
'(("svelte" "\\.svelte\\'"))))
(add-hook 'web-mode-hook (lambda ()
(setq web-mode-code-indent-offset 2)
(setq web-mode-markup-indent-offset 2)
(setq web-mode-css-indent-offset 2)))I rarely use this. might remove
(use-package multiple-cursors)(use-package command-log-mode
:straight (command-log-mode :type git :host github :repo "pierre-rouleau/command-log-mode" :files ("*.el" "*")))Doc view works just fine! but I just prefer to have the pdf in a separate window.
(use-package doc-view
:config
(setq doc-view-resolution 400))