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.

666 lines
18 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
  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. ** Cleanup
  76. Despite having our *stateful* and *immutable* configurations seperate, it's good practice to make efforts to reduce the trash created by Emacs.
  77. https://github.com/emacscollective/no-littering
  78. + Reduce the files created by Emacs
  79. #+begin_src emacs-lisp
  80. (use-package no-littering)
  81. #+end_src
  82. Emacs' default user interface is horrendous, but with less than 10 lines of code we can change that.
  83. #+begin_src emacs-lisp
  84. (setq inhibit-startup-message t)
  85. (global-prettify-symbols-mode)
  86. (scroll-bar-mode -1)
  87. (menu-bar-mode -1)
  88. (tool-bar-mode -1)
  89. (tooltip-mode -1)
  90. #+end_src
  91. Write out to all *3* of Emacs' default font faces.
  92. #+begin_src emacs-lisp
  93. (set-face-attribute 'default nil :font dotfiles/font :height dotfiles/font-size)
  94. (set-face-attribute 'fixed-pitch nil :font dotfiles/font :height dotfiles/font-size)
  95. (set-face-attribute 'variable-pitch nil :font dotfiles/font :height dotfiles/font-size)
  96. #+end_src
  97. ** Keybindings
  98. Make the =ESC= key quit prompts, instead of the default =C-g=.
  99. #+begin_src emacs-lisp
  100. (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
  101. #+end_src
  102. https://github.com/justbur/emacs-which-key
  103. + Display the currently incomplete keybinding in a mini-buffer.
  104. #+begin_src emacs-lisp
  105. (use-package which-key
  106. :diminish which-key-mode
  107. :init (which-key-mode)
  108. :config (setq which-key-idle-delay dotfiles/idle))
  109. #+end_src
  110. https://github.com/noctuid/general.el
  111. + Easily configure prefixed keybindings
  112. + Cleaner than default binding methods
  113. #+begin_src emacs-lisp
  114. (use-package general
  115. :config
  116. (general-create-definer dotfiles/leader
  117. :states '(normal motion)
  118. :keymaps 'override
  119. :prefix dotfiles/leader-key))
  120. #+end_src
  121. https://github.com/abo-abo/hydra
  122. + Transient keybindings sharing a common prefix
  123. #+begin_src emacs-lisp
  124. (use-package hydra)
  125. #+end_src
  126. *** Evil
  127. 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.
  128. https://evil.readthedocs.io/en/latest/index.html
  129. + Extendable VI layer for Emacs
  130. + Disable default keybindings
  131. #+begin_src emacs-lisp
  132. (use-package evil
  133. :init (setq evil-want-integration t
  134. evil-want-keybinding nil)
  135. :config (evil-mode 1))
  136. #+end_src
  137. https://github.com/emacs-evil/evil-collection
  138. + Community keybindings for =evil-mode=
  139. #+begin_src emacs-lisp
  140. (use-package evil-collection
  141. :after evil
  142. :config (evil-collection-init))
  143. #+end_src
  144. https://github.com/redguardtoo/evil-nerd-commenter
  145. + Toggle comments with =M-;=
  146. #+begin_src emacs-lisp
  147. (use-package evil-nerd-commenter
  148. :bind ("M-;" . evilnc-comment-or-uncomment-lines))
  149. #+end_src
  150. *** Font
  151. Increase the font size in buffers with =SPC f=.
  152. + Increase =j=
  153. + Decrease =k=
  154. + Finish =f=
  155. #+begin_src emacs-lisp
  156. (defhydra hydra-text-scale (:timeout 4)
  157. "Scale"
  158. ("j" text-scale-increase "Increase")
  159. ("k" text-scale-decrease "Decrease")
  160. ("f" nil "Finished" :exit t))
  161. #+end_src
  162. #+begin_src emacs-lisp
  163. (dotfiles/leader
  164. "f" '(hydra-text-scale/body :which-key "Font"))
  165. #+end_src
  166. *** Shortcuts
  167. Again cherry picked from =Doom=, I want to continue utilizing the muscle memory I have developed from a year of mainlining the framework.
  168. + Find files =SPC . (period)=
  169. + Switch buffers with =SPC , (comma)=
  170. #+begin_src emacs-lisp
  171. (dotfiles/leader
  172. "," '(switch-to-buffer :which-key "Buffer")
  173. "." '(find-file :which-key "File"))
  174. #+end_src
  175. Quit emacs with =SPC q=.
  176. + Saving =q=
  177. + Without =w=
  178. + Frame (daemon) =f=
  179. #+begin_src emacs-lisp
  180. (dotfiles/leader
  181. "q" '(:ignore t :which-key "Quit")
  182. "qq" '(save-buffers-kill-emacs :which-key "Save")
  183. "qw" '(kill-emacs :which-key "Now")
  184. "qf" '(delete-frame :which-key "Frame"))
  185. #+end_src
  186. Window management with =SPC w=.
  187. + Swap with =w=
  188. + Close with =c=
  189. + Delete with =d=
  190. + Motions with =h,j,k,l=
  191. + Split with =s + <MOTION>=
  192. #+begin_src emacs-lisp
  193. (dotfiles/leader
  194. "w" '(:ignore t :which-key "Window")
  195. "ww" '(window-swap-states :which-key "Swap")
  196. "wd" '(kill-buffer-and-window :which-key "Delete")
  197. "wc" '(delete-window :which-key "Close")
  198. "wh" '(windmove-left :which-key "Left")
  199. "wj" '(windmove-down :which-key "Down")
  200. "wk" '(windmove-up :which-key "Up")
  201. "wl" '(windmove-right :which-key "Right")
  202. "ws" '(:ignore t :which-key "Split")
  203. "wsj" '(split-window-below :which-key "Down")
  204. "wsl" '(split-window-right :which-key "Right"))
  205. #+end_src
  206. ** Editor
  207. 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.
  208. #+begin_example
  209. 5:
  210. 4:
  211. 3:
  212. 2:
  213. 1:
  214. 156: << CURRENT LINE >>
  215. 1:
  216. 2:
  217. 3:
  218. 4:
  219. 5:
  220. #+end_example
  221. https://github.com/emacsmirror/linum-relative
  222. + Integrate with ~display-line-numbers-mode~ for performance
  223. #+begin_src emacs-lisp
  224. (use-package linum-relative
  225. :init (setq linum-relative-backend
  226. 'display-line-numbers-mode)
  227. :config (linum-relative-global-mode))
  228. #+end_src
  229. https://github.com/Fanael/rainbow-delimiters
  230. + Colourize nested parenthesis
  231. #+begin_src emacs-lisp
  232. (use-package rainbow-delimiters
  233. :hook (prog-mode . rainbow-delimiters-mode))
  234. #+end_src
  235. ** VCS
  236. Another flagship feature of Emacs is =magit=, a complete git porcelain within Emacs.
  237. https://github.com/magit/magit
  238. #+begin_src emacs-lisp
  239. (use-package magit
  240. :custom (magit-display-buffer-function
  241. #'magit-display-buffer-same-window-except-diff-v1))
  242. #+end_src
  243. https://github.com/magit/forge
  244. + Requires ~$GITHUB_TOKEN~
  245. #+begin_src emacs-lisp
  246. (use-package forge)
  247. #+end_src
  248. Open the *status* page for the current repository with =SPC g=.
  249. #+begin_src emacs-lisp
  250. (dotfiles/leader
  251. "g" '(magit-status :which-key "Magit"))
  252. #+end_src
  253. ** Files
  254. 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.
  255. https://github.com/domtronn/all-the-icons.el
  256. + Collects various icon fonts
  257. #+begin_src emacs-lisp
  258. (use-package all-the-icons)
  259. #+end_src
  260. https://github.com/jtbm37/all-the-icons-dired
  261. + Integration with dired
  262. #+begin_src emacs-lisp
  263. (use-package all-the-icons-dired
  264. :hook (dired-mode . all-the-icons-dired-mode))
  265. #+end_src
  266. 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=.
  267. #+begin_src emacs-lisp
  268. (require 'dired-x)
  269. #+end_src
  270. Open a dired buffer with =SPC d=.
  271. #+begin_src emacs-lisp
  272. (dotfiles/leader
  273. "d" '(dired-jump :which-key "Dired"))
  274. #+end_src
  275. ** Shell
  276. 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=.
  277. https://github.com/zwild/eshell-prompt-extras
  278. + Enable lambda shell prompt
  279. #+begin_src emacs-lisp
  280. (use-package eshell-prompt-extras
  281. :config (setq eshell-highlight-prompt nil
  282. eshell-prompt-function 'epe-theme-lambda))
  283. #+end_src
  284. Open an =eshell= buffer with =SPC e=.
  285. #+begin_src emacs-lisp
  286. (dotfiles/leader
  287. "e" '(eshell :which-key "Shell"))
  288. #+end_src
  289. ** Themes
  290. Bring Emacs' out of the eighties by cherry picking a few modules from =Doom=.
  291. https://github.com/hlissner/emacs-doom-themes
  292. + Modern colour themes
  293. #+begin_src emacs-lisp
  294. (use-package doom-themes
  295. :init (load-theme 'doom-moonlight t))
  296. #+end_src
  297. Load a theme with =SPC t=.
  298. #+begin_src emacs-lisp
  299. (dotfiles/leader
  300. "t" '(load-theme t nil :which-key "Theme"))
  301. #+end_src
  302. https://github.com/seagle0128/doom-modeline
  303. + Elegant status bar / modeline
  304. #+begin_src emacs-lisp
  305. (use-package doom-modeline
  306. :init (doom-modeline-mode 1)
  307. :custom ((doom-modeline-height 16)))
  308. #+end_src
  309. ** Passwords
  310. 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.
  311. #+begin_src emacs-lisp
  312. (use-package password-store
  313. :custom (password-store-dir dotfiles/pass))
  314. #+end_src
  315. * Development
  316. :PROPERTIES:
  317. :header-args: :tangle init.el :results silent
  318. :END:
  319. An IDE like experience (or better) can be achieved in Emacs using two *Microsoft* open source initiatives.
  320. + https://microsoft.github.io/language-server-protocol/
  321. + https://microsoft.github.io/debug-adapter-protocol/
  322. https://emacs-lsp.github.io/lsp-mode/
  323. + Language servers for Emacs
  324. #+begin_src emacs-lisp
  325. (use-package lsp-mode
  326. :custom (gc-cons-threshold 1000000000)
  327. (lsp-idle-delay 0.500))
  328. #+end_src
  329. https://emacs-lsp.github.io/lsp-ui/
  330. + UI improvements for =lsp-mode=
  331. #+begin_src emacs-lisp
  332. (use-package lsp-ui
  333. :custom (lsp-ui-doc-position 'at-point)
  334. (lsp-ui-doc-delay 0.500))
  335. #+end_src
  336. https://emacs-lsp.github.io/dap-mode/
  337. + Debug adapters for Emacs
  338. #+begin_src emacs-lisp
  339. (use-package dap-mode)
  340. #+end_src
  341. Text completion framework via =company= aka *Complete Anything*.
  342. http://company-mode.github.io/
  343. + Integrate with =lsp-mode=
  344. #+begin_src emacs-lisp
  345. (use-package company)
  346. (use-package company-lsp)
  347. #+end_src
  348. ** Python
  349. Full *IDE* experience for Python within Emacs.
  350. + Completion, jumps via =lsp-mode=
  351. + Debugging via =dap-mode=
  352. Install the =pyls= language server.
  353. #+begin_src shell :tangle no
  354. pip install --user "python-language-server[all]"
  355. #+end_src
  356. https://www.emacswiki.org/emacs/PythonProgrammingInEmacs
  357. + Built in mode
  358. #+begin_src emacs-lisp
  359. (use-package python-mode
  360. :hook (python-mode . lsp)
  361. :config (require 'dap-python)
  362. :custom (python-shell-interpreter "python3") ;; Required if "python" is not python 3.
  363. (dap-python-executable "python3") ;; Same as above.
  364. (dap-python-debugger 'debugpy))
  365. #+end_src
  366. ** Rust
  367. Full *IDE* experience for Rust within Emacs.
  368. + Completion via =lsp-mode=
  369. + Debugging via =dap-mode=
  370. https://github.com/brotzeit/rustic
  371. + Install via ~lsp-install-server~
  372. #+begin_src emacs-lisp
  373. (use-package rustic)
  374. #+end_src
  375. * Writing
  376. :PROPERTIES:
  377. :header-args: :tangle init.el :results silent
  378. :END:
  379. *Organize your plain life in plain text*
  380. =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.
  381. + https://orgmode.org
  382. + https://orgmode.org/worg/org-contrib/babel/languages/index.html
  383. + https://orgmode.org/manual/Structure-Templates.html
  384. #+begin_src emacs-lisp
  385. (use-package org
  386. :hook
  387. (org-mode . (lambda ()
  388. (org-indent-mode)
  389. (visual-line-mode 1)
  390. (variable-pitch-mode 1)))
  391. :config
  392. (setq org-ellipsis " ▾"
  393. org-log-done 'time
  394. org-log-into-drawer t
  395. org-src-preserve-indentation t)
  396. (org-babel-do-load-languages
  397. 'org-babel-load-languages
  398. '((shell . t)
  399. (python . t)
  400. (emacs-lisp . t)))
  401. (require 'org-tempo)
  402. (add-to-list 'org-structure-template-alist '("s" . "src"))
  403. (add-to-list 'org-structure-template-alist '("q" . "quote"))
  404. (add-to-list 'org-structure-template-alist '("e" . "example"))
  405. (add-to-list 'org-structure-template-alist '("sh" . "src shell"))
  406. (add-to-list 'org-structure-template-alist '("py" . "src python"))
  407. (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")))
  408. #+end_src
  409. https://github.com/integral-dw/org-superstar-mode
  410. + Make the headline stars more *super*
  411. #+begin_src emacs-lisp
  412. (use-package org-superstar
  413. :hook (org-mode . org-superstar-mode))
  414. #+end_src
  415. https://github.com/org-roam/org-roam
  416. + Rudimentary roam replica with =org-mode=
  417. #+begin_src emacs-lisp
  418. (use-package org-roam
  419. :hook (after-init . org-roam-mode)
  420. :custom (org-roam-directory dotfiles/brain))
  421. #+end_src
  422. https://github.com/org-roam/org-roam
  423. + Visualizes the =org-roam= database
  424. + Available on http://localhost:8080
  425. #+begin_src emacs-lisp
  426. (use-package org-roam-server
  427. :hook (org-roam-mode . org-roam-server-mode))
  428. #+end_src
  429. Configure keybindings behind =SPC r=.
  430. + Find with =f=
  431. + Buffer with =b=
  432. + Capture with =c=
  433. + Dailies with =d=
  434. #+begin_src emacs-lisp
  435. (dotfiles/leader
  436. "r" '(:ignore t :which-key "Roam")
  437. "rf" '(org-roam-find-file :which-key "Find")
  438. "rb" '(org-roam-buffer-toggle-display :which-key "Buffer")
  439. "rc" '(org-roam-capture :which-key "Capture")
  440. "rd" '(:ignore t :which-key "Dailies")
  441. "rdd" '(org-roam-dailies-find-date :which-key "Date")
  442. "rdt" '(org-roam-dailies-find-today :which-key "Today")
  443. "rdm" '(org-roam-dailies-find-tomorrow :which-key "Tomorrow")
  444. "rdy" '(org-roam-dailies-find-yesterday :which-key "Yesterday"))
  445. #+end_src
  446. Configure the default capture template for new topics.
  447. #+begin_src emacs-lisp
  448. (setq org-roam-capture-templates
  449. '(("d" "Default" plain (function org-roam-capture--get-point)
  450. "%?"
  451. :file-name "${slug}"
  452. :head "#+TITLE: ${title}\n"
  453. :unnarrowed t)))
  454. #+end_src
  455. Configure the default capture template for daily entries.
  456. #+begin_src emacs-lisp
  457. (setq org-roam-dailies-capture-templates
  458. '(("d" "Default" entry (function org-roam-capture--get-point)
  459. "* %?"
  460. :file-name "daily/%<%Y-%m-%d>"
  461. :head "#+TITLE: %<%Y-%m-%d>\n")))
  462. #+end_src
  463. ** Agenda
  464. Configure agenda sources.
  465. + Dailies ~~/.local/source/brain/daily/~
  466. + Secrets ~~/.local/source/secrets/org/~
  467. #+begin_src emacs-lisp
  468. (setq org-agenda-files '("~/.local/source/brain/daily/"
  469. "~/.local/source/secrets/org/"))
  470. #+end_src
  471. Open an agenda buffer with =SPC a=.
  472. #+begin_src emacs-lisp
  473. (dotfiles/leader
  474. "a" '(org-agenda :which-key "Agenda"))
  475. #+end_src
  476. ** Blogging
  477. https://github.com/kaushalmodi/ox-hugo
  478. + Configure for =one-post-per-file=
  479. #+begin_src emacs-lisp
  480. (use-package ox-hugo
  481. :after ox)
  482. #+end_src
  483. Creaate a capture template for blog posts in the =posts= sub directory.
  484. #+begin_src emacs-lisp
  485. (add-to-list 'org-roam-capture-templates
  486. '("b" "Blogging" plain (function org-roam-capture--get-point)
  487. "%?"
  488. :file-name "posts/${slug}"
  489. :head "#+TITLE: ${title}\n#+HUGO_BASE_DIR: ../\n#+HUGO_SECTION: ./\n"))
  490. #+end_src
  491. ** Presentations
  492. Produce high quality presentations that work anywhere with =HTML/JS= via the =reveal.js= package.
  493. https://github.com/hexmode/ox-reveal
  494. + Configure to use =cdn=
  495. #+begin_src emacs-lisp
  496. (use-package ox-reveal
  497. :after ox
  498. :custom (org-reveal-root "https://cdn.jsdelivr.net/reveal.js/3.9.2/"))
  499. #+end_src
  500. Create a capture template for presentations stored in the =slides= sub directory.
  501. #+begin_src emacs-lisp
  502. (add-to-list 'org-roam-capture-templates
  503. '("p" "Presentation" plain (function org-roam-capture--get-point)
  504. "%?"
  505. :file-name "slides/${slug}"
  506. :head "#+TITLE: ${title}\n"))
  507. #+end_src