I showed you my source code, pls respond
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

754 lines
20 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. #+TITLE: Dotfiles
  2. #+AUTHOR: Christopher James Hayward
  3. #+EMAIL: chris@chrishayward.xyz
  4. Immutable GNU Emacs dotfiles, inspired by Doom, built for Liberty.
  5. + 100% Literate
  6. + 100% Immutable
  7. + 100% Reproducible
  8. * Configuration
  9. :PROPERTIES:
  10. :header-args: :tangle init.el :results silent
  11. :END:
  12. Define a function to build literate programming projects.
  13. #+begin_src emacs-lisp
  14. (defun dotfiles/tangle (dir)
  15. "Recursively tangle the Org files within a directory."
  16. (let ((org-files (directory-files-recursively dir "org")))
  17. (dolist (f org-files)
  18. (org-babel-tangle-file f))))
  19. #+end_src
  20. Configure the system font with a single ~font-family~ and define the size, of which variations to the font size are relative to this value.
  21. #+begin_src emacs-lisp
  22. (defvar dotfiles/font "Fira Code")
  23. (defvar dotfiles/font-size 96)
  24. #+end_src
  25. Functionality like =completion= and =hints= can be delayed to avoid popups for common manuevers. Adjust this value to your personal taste.
  26. #+begin_src emacs-lisp
  27. (defvar dotfiles/idle 0.0)
  28. #+end_src
  29. Avoid the infamous *Emacs pinky* by binding =SPC= as a leader key, utilizing the thumb instead of the weaker pinky finger. You may change this value if you want to use something else.
  30. #+begin_src emacs-lisp
  31. (defvar dotfiles/leader-key "SPC")
  32. #+end_src
  33. Stored source projects are in ~~/.local/source/~.
  34. #+begin_src emacs-lisp
  35. (defvar dotfiles/src "~/.local/source/")
  36. (defvar dotfiles/pass (concat dotfiles/src "passwords/"))
  37. (defvar dotfiles/brain (concat dotfiles/src "brain/"))
  38. #+end_src
  39. Emacs creates a lot of files relative to ~user-emacs-directory~, these files are not part of this immutable configuration and do not belong in the emacs directory. To solve this issue, and to retain hermetic evaluation of the Emacs directory, we it to ~~/.cache/emacs~ shortly after initialization, before most packages are loaded.
  40. #+begin_src emacs-lisp
  41. (defvar dotfiles/home user-emacs-directory)
  42. (defvar dotfiles/cache "~/.cache/emacs")
  43. (setq create-lockfiles nil
  44. make-backup-files nil
  45. user-emacs-directory dotfiles/cache)
  46. #+end_src
  47. ** Packages
  48. https://github.com/raxod502/straight.el
  49. + Use the development branch
  50. + Integrate with ~use-package~
  51. Apply the configurations prior to bootstrapping the package manager, by setting (writing) to the variables that =straight= will ultimately read from.
  52. #+begin_src emacs-lisp
  53. (setq straight-repository-branch "develop"
  54. straight-use-package-by-default t)
  55. #+end_src
  56. Bootstrap the package manager, downloading, installing, or configuring depending on the state of the configuration. All packages are downloaded and built from source, and can be pinned to specific git commit hashes.
  57. #+begin_src emacs-lisp
  58. (defvar bootstrap-version)
  59. (let ((bootstrap-file
  60. (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
  61. (bootstrap-version 5))
  62. (unless (file-exists-p bootstrap-file)
  63. (with-current-buffer
  64. (url-retrieve-synchronously
  65. "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
  66. 'silent 'inhibit-cookies)
  67. (goto-char (point-max))
  68. (eval-print-last-sexp)))
  69. (load bootstrap-file nil 'nomessage))
  70. #+end_src
  71. Complete the integration with ~use-package~ by installing it with =straight=.
  72. #+begin_src emacs-lisp
  73. (straight-use-package 'use-package)
  74. #+end_src
  75. *Organize your plain life in plain text*
  76. =Org-mode= is one of the hallmark features of Emacs, and provides the basis for my Literate Programming platform. It's essentially a markdown language with rich features for project management, scheduling, development, and writing. It's hard to convey everything within its capabilities.
  77. + https://orgmode.org
  78. + https://orgmode.org/worg/org-contrib/babel/languages/index.html
  79. + https://orgmode.org/manual/Structure-Templates.html
  80. #+begin_src emacs-lisp
  81. (use-package org
  82. :hook
  83. (org-mode . (lambda ()
  84. (org-indent-mode)
  85. (visual-line-mode 1)
  86. (variable-pitch-mode 1)))
  87. :config
  88. (setq org-ellipsis " ▾"
  89. org-log-done 'time
  90. org-log-into-drawer t
  91. org-src-preserve-indentation t)
  92. (org-babel-do-load-languages
  93. 'org-babel-load-languages
  94. '((shell . t)
  95. (python . t)
  96. (emacs-lisp . t)))
  97. (require 'org-tempo)
  98. (add-to-list 'org-structure-template-alist '("s" . "src"))
  99. (add-to-list 'org-structure-template-alist '("q" . "quote"))
  100. (add-to-list 'org-structure-template-alist '("e" . "example"))
  101. (add-to-list 'org-structure-template-alist '("sh" . "src shell"))
  102. (add-to-list 'org-structure-template-alist '("py" . "src python"))
  103. (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")))
  104. #+end_src
  105. ** Cleanup
  106. Despite having our *stateful* and *immutable* configurations seperate, it's good practice to make efforts to reduce the trash created by Emacs.
  107. https://github.com/emacscollective/no-littering
  108. + Reduce the files created by Emacs
  109. #+begin_src emacs-lisp
  110. (use-package no-littering)
  111. #+end_src
  112. Emacs' default user interface is horrendous, but with less than 10 lines of code we can change that.
  113. #+begin_src emacs-lisp
  114. (setq inhibit-startup-message t)
  115. (global-prettify-symbols-mode)
  116. (scroll-bar-mode -1)
  117. (menu-bar-mode -1)
  118. (tool-bar-mode -1)
  119. (tooltip-mode -1)
  120. #+end_src
  121. Write out to all *3* of Emacs' default font faces.
  122. #+begin_src emacs-lisp
  123. (set-face-attribute 'default nil :font dotfiles/font :height dotfiles/font-size)
  124. (set-face-attribute 'fixed-pitch nil :font dotfiles/font :height dotfiles/font-size)
  125. (set-face-attribute 'variable-pitch nil :font dotfiles/font :height dotfiles/font-size)
  126. #+end_src
  127. ** Keybindings
  128. Make the =ESC= key quit prompts, instead of the default =C-g=.
  129. #+begin_src emacs-lisp
  130. (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
  131. #+end_src
  132. https://github.com/justbur/emacs-which-key
  133. + Display the currently incomplete keybinding in a mini-buffer.
  134. #+begin_src emacs-lisp
  135. (use-package which-key
  136. :diminish which-key-mode
  137. :init (which-key-mode)
  138. :config (setq which-key-idle-delay dotfiles/idle))
  139. #+end_src
  140. https://github.com/noctuid/general.el
  141. + Easily configure prefixed keybindings
  142. + Cleaner than default binding methods
  143. #+begin_src emacs-lisp
  144. (use-package general
  145. :config
  146. (general-create-definer dotfiles/leader
  147. :states '(normal motion)
  148. :keymaps 'override
  149. :prefix dotfiles/leader-key))
  150. #+end_src
  151. https://github.com/abo-abo/hydra
  152. + Transient keybindings sharing a common prefix
  153. #+begin_src emacs-lisp
  154. (use-package hydra)
  155. #+end_src
  156. *** Evil
  157. After a few hour with =vim= I knew it was game over, I cannot even think of another way I would feel comfortable editing text. Luckily, there exist packages to emulate this within Emacs.
  158. https://evil.readthedocs.io/en/latest/index.html
  159. + Extendable VI layer for Emacs
  160. + Disable default keybindings
  161. #+begin_src emacs-lisp
  162. (use-package evil
  163. :init (setq evil-want-integration t
  164. evil-want-keybinding nil)
  165. :config (evil-mode 1))
  166. #+end_src
  167. https://github.com/emacs-evil/evil-collection
  168. + Community keybindings for =evil-mode=
  169. #+begin_src emacs-lisp
  170. (use-package evil-collection
  171. :after evil
  172. :config (evil-collection-init))
  173. #+end_src
  174. https://github.com/redguardtoo/evil-nerd-commenter
  175. + Toggle comments with =M-;=
  176. #+begin_src emacs-lisp
  177. (use-package evil-nerd-commenter
  178. :bind ("M-;" . evilnc-comment-or-uncomment-lines))
  179. #+end_src
  180. *** Font
  181. Increase the font size in buffers with =SPC f=.
  182. + Increase =j=
  183. + Decrease =k=
  184. + Finish =f=
  185. #+begin_src emacs-lisp
  186. (defhydra hydra-text-scale (:timeout 4)
  187. "Scale"
  188. ("j" text-scale-increase "Increase")
  189. ("k" text-scale-decrease "Decrease")
  190. ("f" nil "Finished" :exit t))
  191. #+end_src
  192. #+begin_src emacs-lisp
  193. (dotfiles/leader
  194. "f" '(hydra-text-scale/body :which-key "Font"))
  195. #+end_src
  196. *** Shortcuts
  197. Again cherry picked from =Doom=, I want to continue utilizing the muscle memory I have developed from a year of mainlining the framework.
  198. + Find files =SPC . (period)=
  199. + Switch buffers with =SPC , (comma)=
  200. #+begin_src emacs-lisp
  201. (dotfiles/leader
  202. "," '(switch-to-buffer :which-key "Buffer")
  203. "." '(find-file :which-key "File"))
  204. #+end_src
  205. Quit emacs with =SPC q=.
  206. + Saving =q=
  207. + Without =w=
  208. + Frame (daemon) =f=
  209. #+begin_src emacs-lisp
  210. (dotfiles/leader
  211. "q" '(:ignore t :which-key "Quit")
  212. "qq" '(save-buffers-kill-emacs :which-key "Save")
  213. "qw" '(kill-emacs :which-key "Now")
  214. "qf" '(delete-frame :which-key "Frame"))
  215. #+end_src
  216. Window management with =SPC w=.
  217. + Swap with =w=
  218. + Close with =c=
  219. + Delete with =d=
  220. + Motions with =h,j,k,l=
  221. + Split with =s + <MOTION>=
  222. #+begin_src emacs-lisp
  223. (dotfiles/leader
  224. "w" '(:ignore t :which-key "Window")
  225. "ww" '(window-swap-states :which-key "Swap")
  226. "wd" '(kill-buffer-and-window :which-key "Delete")
  227. "wc" '(delete-window :which-key "Close")
  228. "wh" '(windmove-left :which-key "Left")
  229. "wj" '(windmove-down :which-key "Down")
  230. "wk" '(windmove-up :which-key "Up")
  231. "wl" '(windmove-right :which-key "Right")
  232. "ws" '(:ignore t :which-key "Split")
  233. "wsj" '(split-window-below :which-key "Down")
  234. "wsl" '(split-window-right :which-key "Right"))
  235. #+end_src
  236. ** Editor
  237. Relative line numbers are important when using =VI= emulation keys. You can prefix most commands with a *number*, allowing you to jump up / down by a line count.
  238. #+begin_example
  239. 5:
  240. 4:
  241. 3:
  242. 2:
  243. 1:
  244. 156: << CURRENT LINE >>
  245. 1:
  246. 2:
  247. 3:
  248. 4:
  249. 5:
  250. #+end_example
  251. https://github.com/emacsmirror/linum-relative
  252. + Integrate with ~display-line-numbers-mode~ for performance
  253. #+begin_src emacs-lisp
  254. (use-package linum-relative
  255. :init (setq linum-relative-backend
  256. 'display-line-numbers-mode)
  257. :config (linum-relative-global-mode))
  258. #+end_src
  259. https://github.com/Fanael/rainbow-delimiters
  260. + Colourize nested parenthesis
  261. #+begin_src emacs-lisp
  262. (use-package rainbow-delimiters
  263. :hook (prog-mode . rainbow-delimiters-mode))
  264. #+end_src
  265. ** VCS
  266. Another flagship feature of Emacs is =magit=, a complete git porcelain within Emacs.
  267. https://github.com/magit/magit
  268. #+begin_src emacs-lisp
  269. (use-package magit
  270. :custom (magit-display-buffer-function
  271. #'magit-display-buffer-same-window-except-diff-v1))
  272. #+end_src
  273. https://github.com/magit/forge
  274. + Requires ~$GITHUB_TOKEN~
  275. #+begin_src emacs-lisp
  276. (use-package forge)
  277. #+end_src
  278. Open the *status* page for the current repository with =SPC g=.
  279. #+begin_src emacs-lisp
  280. (dotfiles/leader
  281. "g" '(magit-status :which-key "Magit"))
  282. #+end_src
  283. ** Files
  284. Emacs' can feel more modern when icon-fonts are installed and prioritized. I feel that this makes navigation of folders much faster, given that file types may be quickly identified by their corresponding icons.
  285. https://github.com/domtronn/all-the-icons.el
  286. + Collects various icon fonts
  287. #+begin_src emacs-lisp
  288. (use-package all-the-icons)
  289. #+end_src
  290. https://github.com/jtbm37/all-the-icons-dired
  291. + Integration with dired
  292. #+begin_src emacs-lisp
  293. (use-package all-the-icons-dired
  294. :hook (dired-mode . all-the-icons-dired-mode))
  295. #+end_src
  296. When opening =dired=, I don't want to have to press =RET= twice to navigate to the current directory. This can be avoided with ~dired-jump~, included in the =dired-x= package shipped with =dired=.
  297. #+begin_src emacs-lisp
  298. (require 'dired-x)
  299. #+end_src
  300. Open a dired buffer with =SPC d=.
  301. #+begin_src emacs-lisp
  302. (dotfiles/leader
  303. "d" '(dired-jump :which-key "Dired"))
  304. #+end_src
  305. ** Shell
  306. While not a traditional terminal emulator, =eshell= provides me with all of the functionality I expect and require from one. Some users may be left wanting more, I would recommend they look into =vterm=.
  307. https://github.com/zwild/eshell-prompt-extras
  308. + Enable lambda shell prompt
  309. #+begin_src emacs-lisp
  310. (use-package eshell-prompt-extras
  311. :config (setq eshell-highlight-prompt nil
  312. eshell-prompt-function 'epe-theme-lambda))
  313. #+end_src
  314. Open an =eshell= buffer with =SPC e=.
  315. #+begin_src emacs-lisp
  316. (dotfiles/leader
  317. "e" '(eshell :which-key "Shell"))
  318. #+end_src
  319. ** Themes
  320. Bring Emacs' out of the eighties by cherry picking a few modules from =Doom=.
  321. https://github.com/hlissner/emacs-doom-themes
  322. + Modern colour themes
  323. #+begin_src emacs-lisp
  324. (use-package doom-themes
  325. :init (load-theme 'doom-moonlight t))
  326. #+end_src
  327. Load a theme with =SPC t=.
  328. #+begin_src emacs-lisp
  329. (dotfiles/leader
  330. "t" '(load-theme t nil :which-key "Theme"))
  331. #+end_src
  332. https://github.com/seagle0128/doom-modeline
  333. + Elegant status bar / modeline
  334. #+begin_src emacs-lisp
  335. (use-package doom-modeline
  336. :init (doom-modeline-mode 1)
  337. :custom ((doom-modeline-height 16)))
  338. #+end_src
  339. ** Passwords
  340. Pass makes managing passwords extremely easy, encrypring them in a file structure and providing easy commands for generating, modify, and copying passwords. =password-store.el= provides a wrapper for the functionality within Emacs.
  341. #+begin_src emacs-lisp
  342. (use-package password-store
  343. :custom (password-store-dir dotfiles/pass))
  344. #+end_src
  345. * Development
  346. :PROPERTIES:
  347. :header-args: :tangle init.el :results silent
  348. :END:
  349. An IDE like experience (or better) can be achieved in Emacs using two *Microsoft* open source initiatives.
  350. + https://microsoft.github.io/language-server-protocol/
  351. + https://microsoft.github.io/debug-adapter-protocol/
  352. https://emacs-lsp.github.io/lsp-mode/
  353. + Language servers for Emacs
  354. #+begin_src emacs-lisp
  355. (use-package lsp-mode
  356. :custom (gc-cons-threshold 1000000000)
  357. (lsp-idle-delay 0.500))
  358. #+end_src
  359. https://emacs-lsp.github.io/lsp-ui/
  360. + UI improvements for =lsp-mode=
  361. #+begin_src emacs-lisp
  362. (use-package lsp-ui
  363. :custom (lsp-ui-doc-position 'at-point)
  364. (lsp-ui-doc-delay 0.500))
  365. #+end_src
  366. https://emacs-lsp.github.io/dap-mode/
  367. + Debug adapters for Emacs
  368. #+begin_src emacs-lisp
  369. (use-package dap-mode)
  370. #+end_src
  371. Text completion framework via =company= aka *Complete Anything*.
  372. http://company-mode.github.io/
  373. + Integrate with =lsp-mode=
  374. #+begin_src emacs-lisp
  375. (use-package company)
  376. (use-package company-lsp)
  377. #+end_src
  378. ** C/C++
  379. Full *IDE* experience for Python within Emacs.
  380. + Completion, jumps via =lsp-mode=
  381. + Debugging via =dap-mode=
  382. Install the =ccls= language server.
  383. + https://github.com/MaskRay/ccls
  384. #+begin_src emacs-lisp
  385. (use-package ccls
  386. :hook ((c-mode c++-mode objc-mode cuda-mode) .
  387. (lambda () (require 'ccls) (lsp))))
  388. #+end_src
  389. ** Python
  390. Full *IDE* experience for Python within Emacs.
  391. + Completion, jumps via =lsp-mode=
  392. + Debugging via =dap-mode=
  393. Install the =pyls= language server.
  394. #+begin_src shell :tangle no
  395. pip install --user "python-language-server[all]"
  396. #+end_src
  397. https://www.emacswiki.org/emacs/PythonProgrammingInEmacs
  398. + Built in mode
  399. #+begin_src emacs-lisp
  400. (use-package python-mode
  401. :hook (python-mode . lsp)
  402. :config (require 'dap-python)
  403. :custom (python-shell-interpreter "python3") ;; Required if "python" is not python 3.
  404. (dap-python-executable "python3") ;; Same as above.
  405. (dap-python-debugger 'debugpy))
  406. #+end_src
  407. ** Rust
  408. Full *IDE* experience for Rust within Emacs.
  409. + Completion via =lsp-mode=
  410. + Debugging via =dap-mode=
  411. https://github.com/brotzeit/rustic
  412. + Install via ~lsp-install-server~
  413. #+begin_src shell :tangle no
  414. rustup default nightly
  415. #+end_src
  416. #+begin_src emacs-lisp
  417. (use-package rustic)
  418. #+end_src
  419. ** Go
  420. Full *IDE* experience for Rust within Emacs.
  421. + Completion via =lsp-mode=
  422. + Debugging via =dap-mode=
  423. Install the =gopls= language server.
  424. #+begin_src sh :tangle no
  425. GO111MODULE=on go get golang.org/x/tools/gopls@latest
  426. #+end_src
  427. #+begin_src emacs-lisp
  428. (use-package go-mode
  429. :hook (go-mode . lsp))
  430. #+end_src
  431. * Writing
  432. :PROPERTIES:
  433. :header-args: :tangle init.el :results silent
  434. :END:
  435. https://github.com/integral-dw/org-superstar-mode
  436. + Make the headline stars more *super*
  437. #+begin_src emacs-lisp
  438. (use-package org-superstar
  439. :hook (org-mode . org-superstar-mode))
  440. #+end_src
  441. https://github.com/org-roam/org-roam
  442. + Rudimentary roam replica with =org-mode=
  443. #+begin_src emacs-lisp
  444. (use-package org-roam
  445. :hook (after-init . org-roam-mode)
  446. :custom (org-roam-directory dotfiles/brain))
  447. #+end_src
  448. https://github.com/org-roam/org-roam
  449. + Visualizes the =org-roam= database
  450. + Available on http://localhost:8080
  451. #+begin_src emacs-lisp
  452. (use-package org-roam-server
  453. :hook (org-roam-mode . org-roam-server-mode))
  454. #+end_src
  455. Configure keybindings behind =SPC r=.
  456. + Find with =f=
  457. + Buffer with =b=
  458. + Capture with =c=
  459. + Dailies with =d=
  460. #+begin_src emacs-lisp
  461. (dotfiles/leader
  462. "r" '(:ignore t :which-key "Roam")
  463. "rf" '(org-roam-find-file :which-key "Find")
  464. "rb" '(org-roam-buffer-toggle-display :which-key "Buffer")
  465. "rc" '(org-roam-capture :which-key "Capture")
  466. "rd" '(:ignore t :which-key "Dailies")
  467. "rdd" '(org-roam-dailies-find-date :which-key "Date")
  468. "rdt" '(org-roam-dailies-find-today :which-key "Today")
  469. "rdm" '(org-roam-dailies-find-tomorrow :which-key "Tomorrow")
  470. "rdy" '(org-roam-dailies-find-yesterday :which-key "Yesterday"))
  471. #+end_src
  472. Configure the default capture template for new topics.
  473. #+begin_src emacs-lisp
  474. (setq org-roam-capture-templates
  475. '(("d" "Default" plain (function org-roam-capture--get-point)
  476. "%?"
  477. :file-name "${slug}"
  478. :head "#+TITLE: ${title}\n"
  479. :unnarrowed t)))
  480. #+end_src
  481. Configure the default capture template for daily entries.
  482. #+begin_src emacs-lisp
  483. (setq org-roam-dailies-capture-templates
  484. '(("d" "Default" entry (function org-roam-capture--get-point)
  485. "* %?"
  486. :file-name "daily/%<%Y-%m-%d>"
  487. :head "#+TITLE: %<%Y-%m-%d>\n")))
  488. #+end_src
  489. ** Mail
  490. #+begin_src emacs-lisp
  491. (add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e")
  492. #+end_src
  493. #+begin_src emacs-lisp
  494. (use-package mu4e
  495. :config
  496. (setq mu4e-change-filenames-when-moving t
  497. mu4e-update-interval (* 5 60) ;; Every 5 minutes.
  498. mu4e-get-mail-command "mbsync -a"
  499. mu4e-maildir "~/.cache/mail"
  500. mu4e-compose-signature
  501. (concat "Chris Hayward\n"
  502. "https://chrishayward.xyz\n"))
  503. ;; Ensure plain text scales for all devices.
  504. (setq mu4e-compose-format-flowed t)
  505. ;; GPG signing key for outbound mail.
  506. (setq mml-secure-openpgp-signers '("37AB1CB72B741E478CA026D43025DCBD46F81C0F"))
  507. (add-hook 'message-send-hook 'mml-secure-message-sign-pgpmime)
  508. (setq message-send-mail-function 'smtpmail-send-it)
  509. ;; Configure mail account(s).
  510. (setq mu4e-contexts
  511. (list
  512. ;; Main
  513. ;; chris@chrishayward.xyz
  514. (make-mu4e-context
  515. :name "Main"
  516. :match-func
  517. (lambda (msg)
  518. (when msg
  519. (string-prefix-p "/Main" (mu4e-message-field msg :maildir))))
  520. :vars
  521. '((user-full-name . "Christopher James Hayward")
  522. (user-mail-address . "chris@chrishayward.xyz")
  523. (smtpmail-smtp-server . "mail.chrishayward.xyz")
  524. (smtpmail-smtp-service . 587)
  525. (smtpmail-stream-type . starttls))))))
  526. #+end_src
  527. #+begin_src emacs-lisp
  528. (dotfiles/leader
  529. "m" '(mu4e :which-key "Mail"))
  530. #+end_src
  531. ** Agenda
  532. Configure agenda sources.
  533. + Dailies ~~/.local/source/brain/daily/~
  534. + Secrets ~~/.local/source/secrets/org/~
  535. #+begin_src emacs-lisp
  536. (setq org-agenda-files '("~/.local/source/brain/daily/"
  537. "~/.local/source/secrets/org/"))
  538. #+end_src
  539. Open an agenda buffer with =SPC a=.
  540. #+begin_src emacs-lisp
  541. (dotfiles/leader
  542. "a" '(org-agenda :which-key "Agenda"))
  543. #+end_src
  544. ** Blogging
  545. https://github.com/kaushalmodi/ox-hugo
  546. + Configure for =one-post-per-file=
  547. #+begin_src emacs-lisp
  548. (use-package ox-hugo
  549. :after ox)
  550. #+end_src
  551. Creaate a capture template for blog posts in the =posts= sub directory.
  552. #+begin_src emacs-lisp
  553. (add-to-list 'org-roam-capture-templates
  554. '("b" "Blogging" plain (function org-roam-capture--get-point)
  555. "%?"
  556. :file-name "posts/${slug}"
  557. :head "#+TITLE: ${title}\n#+HUGO_BASE_DIR: ../\n#+HUGO_SECTION: ./\n"))
  558. #+end_src
  559. ** Presentations
  560. Produce high quality presentations that work anywhere with =HTML/JS= via the =reveal.js= package.
  561. https://github.com/hexmode/ox-reveal
  562. + Configure to use =cdn=
  563. #+begin_src emacs-lisp
  564. (use-package ox-reveal
  565. :after ox
  566. :custom (org-reveal-root "https://cdn.jsdelivr.net/reveal.js/3.9.2/"))
  567. #+end_src
  568. Create a capture template for presentations stored in the =slides= sub directory.
  569. #+begin_src emacs-lisp
  570. (add-to-list 'org-roam-capture-templates
  571. '("p" "Presentation" plain (function org-roam-capture--get-point)
  572. "%?"
  573. :file-name "slides/${slug}"
  574. :head "#+TITLE: ${title}\n"))
  575. #+end_src