Compare commits
22 commits
e2ae7b0736
...
17bd8557db
Author | SHA1 | Date | |
---|---|---|---|
Kiana Sheibani | 17bd8557db | ||
Kiana Sheibani | e8e6d0e8f8 | ||
Kiana Sheibani | a18b74230d | ||
Kiana Sheibani | 60725904d6 | ||
Kiana Sheibani | d7b69bdf5a | ||
Kiana Sheibani | 4af08961a6 | ||
Kiana Sheibani | e3fcc7e7ca | ||
Kiana Sheibani | d56254d4eb | ||
Kiana Sheibani | a0c0c8994c | ||
Kiana Sheibani | 4fb75bf17b | ||
Kiana Sheibani | 962ffbe623 | ||
Kiana Sheibani | f03848adf3 | ||
Kiana Sheibani | 9a9c140a70 | ||
Kiana Sheibani | e03555ee38 | ||
Kiana Sheibani | 6eee16462e | ||
Kiana Sheibani | 3e6172d1fe | ||
Kiana Sheibani | 9b73e3037f | ||
Kiana Sheibani | 9d45fde62b | ||
Kiana Sheibani | b61c83f282 | ||
Kiana Sheibani | 608d469102 | ||
Kiana Sheibani | 221b4fa145 | ||
Kiana Sheibani | 5861e16b92 |
225
config.org
225
config.org
|
@ -67,22 +67,22 @@ The second block above was automatically generated by =org-mode=.
|
||||||
|
|
||||||
**** Tangle, Weave, Export, Publish
|
**** Tangle, Weave, Export, Publish
|
||||||
|
|
||||||
Since Org's ability to execute code and process its output is so robust, it's only natural that one might consider using Org to annotate a codebase, storing the code inside source blocks in the document. This could be done by maintaining both the Org file and the actual source files separately, but that would require manually duplicating edits in both files, which is not ideal.
|
Since Org's ability to execute code and process its output is so robust, it's only natural that one might consider using Org to annotate a codebase, storing the code inside source blocks in the document. This would provide the space for much more thorough commentary than regular comments, but also prevent the file from being interpreted as a program, which is the important part! You could maintain both the Org file and the actual source files separately, but that would require manually duplicating edits in both files, which is not ideal.
|
||||||
|
|
||||||
The solution is [[https://en.wikipedia.org/wiki/Literate_programming][literate programming]], the practice of embedding usable code into a markup document. Literate programming can be done in a few different ways; a handful of languages support directly processing these markup documents, such as Haskell and Julia. However, the way Org implements it is closer to the traditional method, which involves two processing systems:
|
The solution is [[https://en.wikipedia.org/wiki/Literate_programming][literate programming]], the practice of embedding usable code into a markup document. Literate programming can be handled in a few different ways. A handful of languages support directly processing these markup documents, such as Haskell and Julia; however, the way Org implements it is closer to the traditional method, which involves two parallel processes:
|
||||||
|
|
||||||
1. /Tangling/, converting the file into raw source code. Tangling must be performed before the code is used; in Org, code is tangled into a new file, and this can be done to generate many source files at once.
|
1. /Tangling/, converting the file into raw source code. Tangling must be performed before the code is used; in Org, code is tangled into a new file, and this can be done to generate many source files from a single Org file.
|
||||||
2. /Weaving/, formatting the file into a human-readable document. Org conceptually divides this further into "exporting" and "publishing," where the latter is intended specifically for converting into web-ready HTML.
|
2. /Weaving/, formatting the file into a human-readable document. Org conceptually divides this further into "exporting" and "publishing," where the latter is intended specifically for converting into web-ready HTML.
|
||||||
|
|
||||||
You are currently reading the published version of this literate program[fn:1]. If you were to download this repository and use it as your config, Emacs would be running the tangled version. These versions are generated in separate processes, but both are ultimately derived from the content and metadata inside of the Org file.
|
You are currently reading the published version of this literate program[fn:1]. If you were to download this repository and use it as your config, Emacs would be running the tangled version. These versions are generated in separate processes, but both are ultimately derived from the content and metadata inside of the Org file.
|
||||||
|
|
||||||
[fn:1] Unless you're reading the raw file on Github, in which case you are probably already decently familiar with =org-mode= to be able to read its markup.
|
[fn:1] Unless you're reading the raw file on Github, in which case you are probably already decently familiar with =org-mode= to be able to read its markup.
|
||||||
|
|
||||||
**** From Code into Comprehension
|
**** Code and Comprehension
|
||||||
|
|
||||||
The simultaneous handling of documentation and code inherent to literate programming is reminiscent of documentation generation (doc comments) in traditional programming. Both systems involve superimposing code and documentation into one file, but the literate style takes the concept one step further; the document isn't embedded in the code, the code is embedded in the document.
|
The simultaneous handling of documentation and code inherent to literate programming is reminiscent of documentation generation (doc comments) in traditional programming. Both systems involve superimposing code and documentation into one file, but the literate style takes the concept one step further; the document isn't embedded in the code, the code is embedded in the document.
|
||||||
|
|
||||||
Instead of documentation having to be bent around the restrictions of source code, the source code can be written and organized with all the freedoms of prose. If written well, the literate program can be structured in a manner closer to how the human mind understands code, rather than how a computer processes it. This is assisted by features such as literate macros and tangling configuration, features intended to break one's code out of the restrictions of standard programming.
|
Instead of documentation having to be bent around the restrictions of source code, the source code can be written and organized with all the freedoms of prose. If written well, the literate program can be structured in a manner closer to how the human mind understands code, rather than how a computer processes it. This is assisted by features such as literate macros, features intended to break one's code out of the restrictions of standard programming.
|
||||||
|
|
||||||
It's not the right tool for every codebase, but proper use of literate programming can make a program much, much easier to comprehend and maintain. This is especially true for configuration languages like Emacs Lisp, where much of the code is conceptually disconnected and can easily be split into categories.
|
It's not the right tool for every codebase, but proper use of literate programming can make a program much, much easier to comprehend and maintain. This is especially true for configuration languages like Emacs Lisp, where much of the code is conceptually disconnected and can easily be split into categories.
|
||||||
|
|
||||||
|
@ -119,9 +119,10 @@ Luckily, I don't need to be able to understand code in order to do what I do bes
|
||||||
|
|
||||||
If you're reading the raw org file instead of the published version, the code for =confpkg= is below. It is mostly unchanged, aside from these tweaks:
|
If you're reading the raw org file instead of the published version, the code for =confpkg= is below. It is mostly unchanged, aside from these tweaks:
|
||||||
|
|
||||||
|
- Prevent =confpkg='s code from being exported
|
||||||
- Change the package template to contain my information
|
- Change the package template to contain my information
|
||||||
- Reorganize to get rid of superfluous noweb references
|
- Reorganize to get rid of superfluous noweb references
|
||||||
- Prevent the code from being exported
|
- Hook into only babel calls that contain =confpkg= as a substring
|
||||||
- Allow package statements anywhere in subconfig files, rather than only at the beginning
|
- Allow package statements anywhere in subconfig files, rather than only at the beginning
|
||||||
|
|
||||||
** confpkg :noexport:
|
** confpkg :noexport:
|
||||||
|
@ -135,8 +136,10 @@ If you're reading the raw org file instead of the published version, the code fo
|
||||||
(message "Intitialising confpkg")
|
(message "Intitialising confpkg")
|
||||||
(org-fold-core-ignore-fragility-checks
|
(org-fold-core-ignore-fragility-checks
|
||||||
(org-babel-map-executables nil
|
(org-babel-map-executables nil
|
||||||
(when (eq (org-element-type (org-element-context)) 'babel-call)
|
(let ((context (org-element-context)))
|
||||||
(org-babel-lob-execute-maybe)))))
|
(and (eq (org-element-type context) 'babel-call)
|
||||||
|
(string-match-p "confpkg" (org-element-property :call context))
|
||||||
|
(org-babel-lob-execute-maybe))))))
|
||||||
(quit (revert-buffer t t t)))
|
(quit (revert-buffer t t t)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -999,7 +1002,7 @@ idris
|
||||||
;;lua
|
;;lua
|
||||||
markdown
|
markdown
|
||||||
;;nim
|
;;nim
|
||||||
(nix +tree-sitter)
|
(nix +lsp +tree-sitter)
|
||||||
;;ocaml
|
;;ocaml
|
||||||
(org +roam2 +present
|
(org +roam2 +present
|
||||||
+gnuplot +jupyter
|
+gnuplot +jupyter
|
||||||
|
@ -1187,6 +1190,8 @@ If PARENTS is non-nil, the parents of the specified directory will also be creat
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(map! :leader
|
(map! :leader
|
||||||
|
:desc "Undo Tree"
|
||||||
|
"o u" #'undo-tree-visualize
|
||||||
:desc "Open URL"
|
:desc "Open URL"
|
||||||
"s u" #'goto-address-at-point)
|
"s u" #'goto-address-at-point)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
@ -1317,7 +1322,7 @@ I have rather specific tastes when it comes to line wrapping. I like soft line w
|
||||||
(setq +word-wrap-fill-style 'soft ; Soft line wrapping
|
(setq +word-wrap-fill-style 'soft ; Soft line wrapping
|
||||||
evil-respect-visual-line-mode t ; Respect visual line mode
|
evil-respect-visual-line-mode t ; Respect visual line mode
|
||||||
)
|
)
|
||||||
(setq-default fill-column 90) ; More space before wrap
|
(setq-default fill-column 100) ; More space before wrap
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Hacks
|
*** Hacks
|
||||||
|
@ -1450,7 +1455,25 @@ Everything else goes in ~config.el~, which is managed by [[*=confpkg=][confpkg]]
|
||||||
;; I don't really use TAB very often, so prefer other actions
|
;; I don't really use TAB very often, so prefer other actions
|
||||||
(setq +corfu-want-tab-prefer-navigating-snippets t
|
(setq +corfu-want-tab-prefer-navigating-snippets t
|
||||||
+corfu-want-tab-prefer-expand-snippets t
|
+corfu-want-tab-prefer-expand-snippets t
|
||||||
+corfu-want-tab-prefer-navigating-org-tables t))
|
+corfu-want-tab-prefer-navigating-org-tables t
|
||||||
|
|
||||||
|
+corfu-want-minibuffer-completion nil
|
||||||
|
|
||||||
|
corfu-min-width 25))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Before switching to Corfu, I got really used to Doom's omnicomplete bindings for various company backends. Doom unfortunately doesn't do this for CAPFs, so we'll have to do the work ourselves.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(map! :prefix "C-x"
|
||||||
|
:i "C-e" #'cape-elisp-symbol
|
||||||
|
:i "C-f" #'cape-file
|
||||||
|
:i "C-l" #'cape-line
|
||||||
|
:i "C-]" #'complete-tag
|
||||||
|
:i "s" #'cape-dict
|
||||||
|
:i "C-s" #'yasnippet-capf
|
||||||
|
:i "C-d" #'cape-dabbrev
|
||||||
|
:i "\\" #'cape-tex)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
** Eldoc
|
** Eldoc
|
||||||
|
@ -1967,9 +1990,12 @@ Having an IDE-style tooltip pop up is nice, but ~flymake-popon~ is a bit ugly by
|
||||||
|
|
||||||
I use GPG signing for commits, which means that committing often takes longer than the single second timeout. Eight seconds seems like a reasonable amount of time to type in a password.
|
I use GPG signing for commits, which means that committing often takes longer than the single second timeout. Eight seconds seems like a reasonable amount of time to type in a password.
|
||||||
|
|
||||||
|
Let's also increase the maximum length of commit summaries past the default of 50 characters, because that's a very restrictive limit.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(after! git-commit
|
(after! git-commit
|
||||||
(setq git-commit-post-finish-hook-timeout 8))
|
(setq git-commit-post-finish-hook-timeout 8
|
||||||
|
git-commit-summary-max-length 60))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Magit Syntax Highlighting
|
*** Magit Syntax Highlighting
|
||||||
|
@ -2142,6 +2168,35 @@ Doom's command to create a new snippet, ~+snippets/new~, defines a template insi
|
||||||
(find-file snippet-file-name))))
|
(find-file snippet-file-name))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
*** File Templates
|
||||||
|
|
||||||
|
Doom's =file-templates= module extends =yasnippet= to provide a nice file template system. The idea is simple: the variable ~+file-templates-alist~ maps file predicates to snippets. If a file that matches a predicate is created, the corresponding snippet is automatically expanded inside of it.
|
||||||
|
|
||||||
|
This system works well for the most part, but there's a serious issue with its UI: the function that registers file templates, ~set-file-templates!~, takes a plist to configure the template. If this list is empty, an existing template is removed instead. This is not only unintuitive, but it prevents you from having an empty property list, which is often necessary! We'll advise the function to remove this issue with a =:remove= key, as well as to have templates appended to the alist instead of prepended to make the order of templates more clear.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(defadvice! ~/file-templates-set (pred plist)
|
||||||
|
:override #'+file-templates--set
|
||||||
|
(if (plist-member plist :remove)
|
||||||
|
(setq +file-templates-alist
|
||||||
|
(assoc-delete-all pred +file-templates-alist))
|
||||||
|
(setq +file-templates-alist
|
||||||
|
(nconc +file-templates-alist `((,pred ,@plist))))))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Now that we have our new-and-improved template registry system, we can add new file templates as we please.
|
||||||
|
|
||||||
|
**** Nix
|
||||||
|
|
||||||
|
The default Nix file template is for a NixOS module. This is nice when you're writing a module, but most Nix files aren't modules. We'll restrict the default template to only trigger for files inside ~/etc/nixos~, and for there to be no template in other cases. We'll also add a template for flakes.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(set-file-templates!
|
||||||
|
'(nix-mode :remove t)
|
||||||
|
'("/etc/nixos/.*\\.nix$" :mode nix-mode)
|
||||||
|
'("/flake\\.nix$" :trigger "__flake.nix" :mode nix-mode))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
** Spell Checking
|
** Spell Checking
|
||||||
|
|
||||||
#+call: confpkg("Pkg: ispell")
|
#+call: confpkg("Pkg: ispell")
|
||||||
|
@ -2154,6 +2209,7 @@ Doom Emacs sets up spell-checking with ~ispell~ (Emacs-internal tool) and =aspel
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
We also need to generate a plain-text dictionary for some ~ispell~ functionality, which is annoying, but I haven't figured out a way around it. I could use my automated nix-build system for this, but I want to have access to my =aspell= config file, so it's easier to just put it in the usual location.
|
We also need to generate a plain-text dictionary for some ~ispell~ functionality, which is annoying, but I haven't figured out a way around it. I could use my automated nix-build system for this, but I want to have access to my =aspell= config file, so it's easier to just put it in the usual location.
|
||||||
|
Now that we have our new-and-improved template registry system, we can add new file templates as we please.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defvar ~/plaintext-dict (expand-file-name "ispell/dict.plain" doom-data-dir)
|
(defvar ~/plaintext-dict (expand-file-name "ispell/dict.plain" doom-data-dir)
|
||||||
|
@ -2228,6 +2284,16 @@ Treemacs is a really useful package, but it also has a lot of defaults I don't l
|
||||||
)
|
)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
*** Bindings
|
||||||
|
|
||||||
|
A natural thing to do when browsing through the project tree is create a new file. The best way to do this is with the usual ~find-file~ command, bound to =SPC .=, but it would be nice to have a binding to save that leader key press.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(map! :after treemacs
|
||||||
|
:mode treemacs-mode
|
||||||
|
"." #'find-file)
|
||||||
|
#+end_src
|
||||||
|
|
||||||
*** Project Integration
|
*** Project Integration
|
||||||
|
|
||||||
I often accidentally open the project tree before I've even selected a project, which I don't want because it messes up =treemacs-projectile=. Let's fix that problem:
|
I often accidentally open the project tree before I've even selected a project, which I don't want because it messes up =treemacs-projectile=. Let's fix that problem:
|
||||||
|
@ -2482,7 +2548,7 @@ I use the standard Unix-style password management system, [[https://www.password
|
||||||
:desc "Password Store"
|
:desc "Password Store"
|
||||||
"o s" #'pass)
|
"o s" #'pass)
|
||||||
|
|
||||||
(after! password-store
|
(after! pass
|
||||||
(setq pass-show-keybindings nil ; Keybindings take up too much space
|
(setq pass-show-keybindings nil ; Keybindings take up too much space
|
||||||
pass-suppress-confirmations t ; Quit shouldn't need a confirm step
|
pass-suppress-confirmations t ; Quit shouldn't need a confirm step
|
||||||
)
|
)
|
||||||
|
@ -2505,9 +2571,7 @@ Unfortunately, with that power comes a *lot* of configuration work up-front. It
|
||||||
(setq org-directory "~/org/")
|
(setq org-directory "~/org/")
|
||||||
|
|
||||||
(after! org
|
(after! org
|
||||||
(setq org-archive-location ; Global archive file
|
(setq org-cycle-emulate-tab nil ; We don't need this with evil
|
||||||
(concat org-directory ".org_archive::")
|
|
||||||
org-cycle-emulate-tab nil ; We don't need this with evil
|
|
||||||
org-attach-dir-relative t
|
org-attach-dir-relative t
|
||||||
org-log-into-drawer t ; Write logs into :LOGBOOK:
|
org-log-into-drawer t ; Write logs into :LOGBOOK:
|
||||||
org-footnote-auto-label 'confirm ; Allow editing of footnote names
|
org-footnote-auto-label 'confirm ; Allow editing of footnote names
|
||||||
|
@ -2633,7 +2697,7 @@ While this is a complex problem, the solution is actually rather simple: just re
|
||||||
"<tab>" nil)
|
"<tab>" nil)
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
This also means we don't need ~org-cycle~ to emulate indentation, which is nice. Unfortunately, this breaks something else: ~org-cycle~ not only handles visibility cycling, but also navigating inside tables. This means that we need a little extra binding configuration so that we can make this properly work:
|
This also means we don't need ~org-cycle~ to emulate indentation, which is nice. Unfortunately, this breaks something else: ~org-cycle~ not only handles visibility cycling, but also navigating inside tables. If ~org-cycle~ isn't being called when in insert mode, then we can't use =TAB= to move fields. This means that we need a little extra binding configuration:
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(let ((item
|
(let ((item
|
||||||
|
@ -2690,8 +2754,6 @@ Doom Emacs's =+pretty= flag by default uses the package =org-superstar= to prett
|
||||||
org-modern-list '((?- . "•")
|
org-modern-list '((?- . "•")
|
||||||
(?+ . "•")
|
(?+ . "•")
|
||||||
(?* . "•"))
|
(?* . "•"))
|
||||||
org-modern-footnote
|
|
||||||
(cons nil (cadr org-script-display))
|
|
||||||
org-modern-todo nil
|
org-modern-todo nil
|
||||||
org-modern-todo-faces
|
org-modern-todo-faces
|
||||||
'(("TODO" :inverse-video t :inherit org-todo)
|
'(("TODO" :inverse-video t :inherit org-todo)
|
||||||
|
@ -2702,11 +2764,11 @@ Doom Emacs's =+pretty= flag by default uses the package =org-superstar= to prett
|
||||||
("KILL" :inverse-video t :inherit +org-todo-cancel))
|
("KILL" :inverse-video t :inherit +org-todo-cancel))
|
||||||
org-modern-block-fringe nil
|
org-modern-block-fringe nil
|
||||||
org-modern-block-name
|
org-modern-block-name
|
||||||
'((t . t)
|
'(("src" "»" "«")
|
||||||
("src" "»" "«")
|
|
||||||
("example" "»–" "–«")
|
("example" "»–" "–«")
|
||||||
("quote" "❝" "❞")
|
("quote" "❝" "❞")
|
||||||
("export" "⏩" "⏪"))
|
("export" "⏩" "⏪")
|
||||||
|
(t . t))
|
||||||
org-modern-priority nil
|
org-modern-priority nil
|
||||||
org-modern-horizontal-rule (make-string 36 ?─)
|
org-modern-horizontal-rule (make-string 36 ?─)
|
||||||
org-modern-keyword
|
org-modern-keyword
|
||||||
|
@ -2788,7 +2850,7 @@ The default colors for various elements of =org-modern= don't match with our the
|
||||||
:background ,(doom-color 'bg-alt)
|
:background ,(doom-color 'bg-alt)
|
||||||
:foreground ,(doom-color 'fg-alt))
|
:foreground ,(doom-color 'fg-alt))
|
||||||
`(org-modern-progress-complete
|
`(org-modern-progress-complete
|
||||||
:background ,(doom-color 'yellow)
|
:background ,(doom-color 'base5)
|
||||||
:foreground ,(doom-color 'bg-alt))))
|
:foreground ,(doom-color 'bg-alt))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
@ -2828,7 +2890,9 @@ Org uses many popup windows for various things, and we can use Doom to make them
|
||||||
|
|
||||||
While Org-mode provides a very comprehensive set of tools and systems, there are a few small things that are missing or that would make the overall UX smoother. Luckily, Org-mode being implemented as an Emacs package gives us more than enough control over its function to crowbar in a few new features!
|
While Org-mode provides a very comprehensive set of tools and systems, there are a few small things that are missing or that would make the overall UX smoother. Luckily, Org-mode being implemented as an Emacs package gives us more than enough control over its function to crowbar in a few new features!
|
||||||
|
|
||||||
*** Archive Restore
|
*** Archiving
|
||||||
|
|
||||||
|
**** Archive Restore
|
||||||
|
|
||||||
Org offers a wonderfully useful trash system called archiving, which lets you move subtrees into a file where they can be saved without permanently deleting them. However, there's no system for automatically restoring these subtrees once they're archived!
|
Org offers a wonderfully useful trash system called archiving, which lets you move subtrees into a file where they can be saved without permanently deleting them. However, there's no system for automatically restoring these subtrees once they're archived!
|
||||||
|
|
||||||
|
@ -2847,7 +2911,7 @@ the attachment cannot be restored!"
|
||||||
(interactive)
|
(interactive)
|
||||||
(let* ((archived-p
|
(let* ((archived-p
|
||||||
(lambda (element)
|
(lambda (element)
|
||||||
(and (org-element-type-p element 'headline)
|
(and (eq (org-element-type element) 'headline)
|
||||||
(org-element-property :ARCHIVE_FILE element))))
|
(org-element-property :ARCHIVE_FILE element))))
|
||||||
(lineage (org-element-lineage (org-element-at-point) nil t))
|
(lineage (org-element-lineage (org-element-at-point) nil t))
|
||||||
(heading (or (-first archived-p lineage)
|
(heading (or (-first archived-p lineage)
|
||||||
|
@ -2882,6 +2946,32 @@ the attachment cannot be restored!"
|
||||||
(message "Restored \"%s\" to file %s" title file)))
|
(message "Restored \"%s\" to file %s" title file)))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
**** File Archive
|
||||||
|
|
||||||
|
Currently, there only exists capabilities to archive a subtree, not an entire file. This matters for me because I often want to remove Org Roam files so that they don't clutter up the database and bog down my agenda. As a quick hacky way to implement this, we can just rename the file to make it look like an archive file.
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(defun org-archive-file (file)
|
||||||
|
"Archive the entire Org file FILE by renaming it to an org_archive file.
|
||||||
|
|
||||||
|
Interactively, this operates on the current buffer. With a prefix arg,
|
||||||
|
prompt for a file instead."
|
||||||
|
(interactive (list (if current-prefix-arg
|
||||||
|
(read-file-name "Archive file: " nil nil t)
|
||||||
|
(buffer-file-name (buffer-base-buffer)))))
|
||||||
|
(find-file file)
|
||||||
|
(widen)
|
||||||
|
(let ((archive (car (org-archive--compute-location org-archive-location))))
|
||||||
|
(if (file-exists-p archive)
|
||||||
|
(progn
|
||||||
|
(goto-char (point-min))
|
||||||
|
(insert "\n# Final contents:\n\n")
|
||||||
|
(append-to-file (point-min) (point-max) archive))
|
||||||
|
(add-file-local-variable-prop-line 'mode 'org)
|
||||||
|
(write-file archive))
|
||||||
|
(doom/delete-this-file nil t)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
*** Todo Date Overriding
|
*** Todo Date Overriding
|
||||||
|
|
||||||
My attention span being what it is, I often forget to update TODO entries in my Org files until long after the task has been completed. I rely heavily on tracking TODOs through timestamps, so it would be nice to have a command to specify the time to log the task as being completed at. To do this, we can create a new variable ~org-todo-time~ that will override the time when set.
|
My attention span being what it is, I often forget to update TODO entries in my Org files until long after the task has been completed. I rely heavily on tracking TODOs through timestamps, so it would be nice to have a command to specify the time to log the task as being completed at. To do this, we can create a new variable ~org-todo-time~ that will override the time when set.
|
||||||
|
@ -3007,7 +3097,7 @@ The simple package =org-checklist= from =org-contrib= makes it so that checkboxe
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(when (modulep! :lang org)
|
(when (modulep! :lang org)
|
||||||
(use-package org-checklist
|
(use-package! org-checklist
|
||||||
:commands (org-reset-checkbox-state-maybe
|
:commands (org-reset-checkbox-state-maybe
|
||||||
org-make-checklist-export
|
org-make-checklist-export
|
||||||
org-checklist)
|
org-checklist)
|
||||||
|
@ -3021,11 +3111,7 @@ The simple package =org-checklist= from =org-contrib= makes it so that checkboxe
|
||||||
The ~org-checklist~ function will reset the checkboxes on any task, but I only want them reset when the task repeats.
|
The ~org-checklist~ function will reset the checkboxes on any task, but I only want them reset when the task repeats.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(defadvice! ~/org-checklist-only-on-repeating (old-fn)
|
(advice-add #'org-checklist :before-while #'org-get-repeat)
|
||||||
"Only reset checkboxes when marking repeater tasks as DONE."
|
|
||||||
:around #'org-checklist
|
|
||||||
(when (org-get-repeat)
|
|
||||||
(funcall old-fn)))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
I don't want to have to specify the =RESET_CHECK_BOXES= property for every TODO I write, though. I would much prefer if it was on by default, and the system allowed me to turn it off if I wanted to. Luckily, the fine control Org gives you over property inheritance nicely fixes this problem.
|
I don't want to have to specify the =RESET_CHECK_BOXES= property for every TODO I write, though. I would much prefer if it was on by default, and the system allowed me to turn it off if I wanted to. Luckily, the fine control Org gives you over property inheritance nicely fixes this problem.
|
||||||
|
@ -3043,47 +3129,6 @@ I don't want to have to specify the =RESET_CHECK_BOXES= property for every TODO
|
||||||
|
|
||||||
** Bug Fixes and Tweaks
|
** Bug Fixes and Tweaks
|
||||||
|
|
||||||
*** Improved Tag Selection
|
|
||||||
|
|
||||||
The facilities for selecting and adding tags do not play very nicely with complex tag hierarchies, especially fast tag selection. The main problems are:
|
|
||||||
|
|
||||||
- Fast tag selection interprets regex tags as actual tags
|
|
||||||
- Fast tag selection can assign multiple keys to the same tag
|
|
||||||
- Regular tag selection interprets special tag entries such as ~:startgroup~ as actual tags
|
|
||||||
|
|
||||||
To fix this, we'll need some liberal use of override advising.
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(defadvice! ~/org-assign-fast-keys (alist)
|
|
||||||
:override #'org-assign-fast-keys
|
|
||||||
(let (new e (alt ?0))
|
|
||||||
(while (setq e (pop alist))
|
|
||||||
(if (or (memq (car e) '(:newline :grouptags :endgroup :startgroup :startgrouptag :endgrouptag))
|
|
||||||
(and (string-prefix-p "{" (car e)) (string-suffix-p "}" (car e)))
|
|
||||||
(cdr e)) ;; Key already assigned.
|
|
||||||
(push e new)
|
|
||||||
(let ((clist (string-to-list (downcase (car e))))
|
|
||||||
(used (append new alist)))
|
|
||||||
(when (= (car clist) ?@)
|
|
||||||
(pop clist))
|
|
||||||
(while (and clist (rassoc (car clist) used))
|
|
||||||
(pop clist))
|
|
||||||
(unless clist
|
|
||||||
(while (rassoc alt used)
|
|
||||||
(cl-incf alt)))
|
|
||||||
(push (cons (car e) (or (car clist) alt)) new))))
|
|
||||||
(nreverse new)))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
The last problem is that Org automatically assigns keys alphabetically if not specified, which means keys can often be difficult to reach. To fix this, we can simply configure some variables.
|
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
|
||||||
(after! org
|
|
||||||
(setq org--fast-tag-selection-keys
|
|
||||||
(string-to-list "asdfghjklrueitywovnASDFGHJKLRUEITYWOVN")
|
|
||||||
org-fast-tag-selection-maximum-tags 40))
|
|
||||||
#+end_src
|
|
||||||
|
|
||||||
*** Export Directory
|
*** Export Directory
|
||||||
|
|
||||||
Org mode by default exports to the same directory the org-mode file is in. This is inconvenient for me, as I use a lot of subdirectories. To fix this, we can advise the function ~org-export-output-file-name~.
|
Org mode by default exports to the same directory the org-mode file is in. This is inconvenient for me, as I use a lot of subdirectories. To fix this, we can advise the function ~org-export-output-file-name~.
|
||||||
|
@ -3536,7 +3581,7 @@ A full week-long agenda is usually too cluttered for me to read, so I'll narrow
|
||||||
org-agenda-start-on-weekday 1 ; 1 = Monday
|
org-agenda-start-on-weekday 1 ; 1 = Monday
|
||||||
|
|
||||||
org-agenda-sorting-strategy
|
org-agenda-sorting-strategy
|
||||||
'((agenda time-up habit-down prority-down category-up)
|
'((agenda time-up habit-down priority-down category-up)
|
||||||
(todo habit-down priority-down time-up category-up)
|
(todo habit-down priority-down time-up category-up)
|
||||||
(tags habit-down priority-down time-up category-up)
|
(tags habit-down priority-down time-up category-up)
|
||||||
(search category-up))
|
(search category-up))
|
||||||
|
@ -3547,10 +3592,10 @@ A full week-long agenda is usually too cluttered for me to read, so I'll narrow
|
||||||
|
|
||||||
;; Agenda prefix
|
;; Agenda prefix
|
||||||
org-agenda-prefix-format
|
org-agenda-prefix-format
|
||||||
'((agenda . " %i %-18:c%?-12t% s")
|
'((agenda . " %i %-36:c%?-12t% s")
|
||||||
(todo . " %i %-18:c")
|
(todo . " %i %-36:c")
|
||||||
(tags . " %i %-18:c")
|
(tags . " %i %-36:c")
|
||||||
(search . " %i %-18:c"))))
|
(search . " %i %-36:c"))))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
*** Agenda View
|
*** Agenda View
|
||||||
|
@ -3574,7 +3619,6 @@ The Org agenda is a very nice feature, but by default it doesn't really provide
|
||||||
(setq org-super-agenda-header-map nil))
|
(setq org-super-agenda-header-map nil))
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
The ~org-agenda~ dispatcher is occasionally useful, but most of the time when I want to open my agenda, it's to see my "preferred" view.
|
|
||||||
By customizing ~org-super-agenda-groups~ via a let-binding in my custom agenda view, I can set up a sophisticated multi-category agenda system.
|
By customizing ~org-super-agenda-groups~ via a let-binding in my custom agenda view, I can set up a sophisticated multi-category agenda system.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
|
@ -3597,23 +3641,30 @@ By customizing ~org-super-agenda-groups~ via a let-binding in my custom agenda v
|
||||||
((org-super-agenda-groups
|
((org-super-agenda-groups
|
||||||
'((:name "Next/In Progress"
|
'((:name "Next/In Progress"
|
||||||
:todo ("NEXT" "STRT" "WAIT" "HOLD"))
|
:todo ("NEXT" "STRT" "WAIT" "HOLD"))
|
||||||
|
(:discard
|
||||||
|
(:date t
|
||||||
|
:deadline t
|
||||||
|
:scheduled t))
|
||||||
(:name "Important"
|
(:name "Important"
|
||||||
:priority "A"
|
:priority "A"
|
||||||
:order 1)
|
:order 1)
|
||||||
|
(:name "Goals"
|
||||||
|
:tag "goal"
|
||||||
|
:order 9)
|
||||||
(:name "Notes to Intake"
|
(:name "Notes to Intake"
|
||||||
:tag "notes"
|
:tag "notes"
|
||||||
:order 10)
|
:order 10)
|
||||||
(:name "Assignments"
|
(:name "Assignments"
|
||||||
:tag "assign"
|
:tag "assign"
|
||||||
:order 2)
|
:order 2)
|
||||||
|
(:order-multi
|
||||||
|
(3
|
||||||
(:auto-map (lambda (item)
|
(:auto-map (lambda (item)
|
||||||
(~/org-agenda-section-by-link
|
(~/org-agenda-section-by-link
|
||||||
"Goal: " "goal" item))
|
"Goal: " "goal" item)))
|
||||||
:order 3)
|
|
||||||
(:auto-map (lambda (item)
|
(:auto-map (lambda (item)
|
||||||
(~/org-agenda-section-by-link
|
(~/org-agenda-section-by-link
|
||||||
"Area: " "area" item))
|
"Area: " "area" item))))))))))))))
|
||||||
:order 4))))))))))
|
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
This "overview" agenda command is very nice. It's so nice, in fact, that it's almost always the only agenda view I want to use! Having to go through the dispatcher every time I want to access it is annoying and unnecessary.
|
This "overview" agenda command is very nice. It's so nice, in fact, that it's almost always the only agenda view I want to use! Having to go through the dispatcher every time I want to access it is annoying and unnecessary.
|
||||||
|
@ -3671,7 +3722,7 @@ Let's start with some configuration. I use [[https://www.zotero.org/][Zotero]] t
|
||||||
|
|
||||||
*** Citation Settings
|
*** Citation Settings
|
||||||
|
|
||||||
I primarily use the CSL export processor to create MLA-style citation, so let's configure that to make its citations more standard.
|
I primarily use the CSL export processor to create MLA-style citations, so let's configure that to make its citations more standard.
|
||||||
|
|
||||||
#+begin_src emacs-lisp
|
#+begin_src emacs-lisp
|
||||||
(after! org
|
(after! org
|
||||||
|
@ -3829,7 +3880,7 @@ The Doom module is very outdated, so I'll be overriding it.
|
||||||
idris-repl-show-repl-on-startup nil ; Don't show repl on startup
|
idris-repl-show-repl-on-startup nil ; Don't show repl on startup
|
||||||
)
|
)
|
||||||
|
|
||||||
(add-hook! idris-mode :append #'lsp!)
|
;; (add-hook! idris-mode :append #'lsp!)
|
||||||
|
|
||||||
(set-repl-handler! 'idris-mode (cmd! (idris-repl-buffer)))
|
(set-repl-handler! 'idris-mode (cmd! (idris-repl-buffer)))
|
||||||
(set-lookup-handlers! 'idris-mode
|
(set-lookup-handlers! 'idris-mode
|
||||||
|
@ -3895,9 +3946,9 @@ Since I've started using [[https://github.com/elkowar/eww/tree/master?tab=readme
|
||||||
This section is for code with little or no associated documentation. This could be because the code is:
|
This section is for code with little or no associated documentation. This could be because the code is:
|
||||||
|
|
||||||
1. Temporary
|
1. Temporary
|
||||||
2. Unimportant
|
2. Self-explanatory
|
||||||
3. Self-explanatory
|
3. Hard to categorize
|
||||||
4. Just not really worth the time it takes to write these explanations
|
4. Just not really worth the time it takes to write commentary
|
||||||
|
|
||||||
** Org
|
** Org
|
||||||
|
|
||||||
|
|
17
snippets/nix-mode/__flake.nix
Normal file
17
snippets/nix-mode/__flake.nix
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# -*- mode: snippet -*-
|
||||||
|
# contributor: Kiana Sheibani <kiana.a.sheibani@gmail.com>
|
||||||
|
# key: __flake.nix
|
||||||
|
# name: nix flake template
|
||||||
|
# --
|
||||||
|
{
|
||||||
|
description = "${1:Flake description}";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
${2:nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
|
}${3:flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
}$4
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self$5, ... }:
|
||||||
|
$0
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
# -*- mode: snippet -*-
|
# -*- mode: snippet -*-
|
||||||
# contributor: Kiana Sheibani
|
# contributor: Kiana Sheibani <kiana.a.sheibani@gmail.com>
|
||||||
# key: __
|
# key: __
|
||||||
# name: Snippet template
|
# name: Snippet template
|
||||||
# --
|
# --
|
||||||
|
|
Loading…
Reference in a new issue