diff options
-rw-r--r-- | init.el | 159 | ||||
-rw-r--r-- | lisp/+cus-edit.el | 12 | ||||
-rw-r--r-- | lisp/+org-capture.el | 82 |
3 files changed, 173 insertions, 80 deletions
diff --git a/init.el b/init.el index a1efcaf..0866f17 100644 --- a/init.el +++ b/init.el | |||
@@ -343,10 +343,93 @@ | |||
343 | ;; context-menu-dictionary)) | 343 | ;; context-menu-dictionary)) |
344 | (context-menu-mode +1))) | 344 | (context-menu-mode +1))) |
345 | 345 | ||
346 | (setup org | ||
347 | ;; Plain org with the `setup' form for sorting, but I install with straight. | ||
348 | (:straight (org | ||
349 | :type git :host nil | ||
350 | :repo "https://git.savannah.gnu.org/git/emacs/org-mode.git" | ||
351 | :local-repo "org" | ||
352 | :depth full | ||
353 | :pre-build (straight-recipes-org-elpa--build) | ||
354 | :build (:not autoloads) | ||
355 | :files (:defaults | ||
356 | "lisp/*.el" | ||
357 | ("etc/styles/" "etc/styles/*"))) | ||
358 | (org-contrib | ||
359 | :type git :host nil | ||
360 | :repo "https://git.sr.ht/~bzg/org-contrib")) | ||
361 | ;; DO NOT load system-installed org !!! | ||
362 | (setq load-path (cl-remove-if (lambda (path) | ||
363 | (string-match-p "lisp/org\\'" path)) | ||
364 | load-path)) | ||
365 | (:also-load +org | ||
366 | ox-md) | ||
367 | (:option org-adapt-indentation nil | ||
368 | org-archive-mark-done t | ||
369 | org-catch-invisible-edits 'show-and-error | ||
370 | org-clock-clocked-in-display 'mode-line | ||
371 | org-clock-frame-title-format (cons | ||
372 | '(t org-mode-line-string) | ||
373 | (cons " --- " frame-title-format)) | ||
374 | org-clock-string-limit 7 ; just the clock bit | ||
375 | ;; org-clock-string-limit 25 ; gives enough information | ||
376 | org-clock-persist t | ||
377 | org-confirm-babel-evaluate nil | ||
378 | org-cycle-separator-lines 0 | ||
379 | org-directory "~/org" | ||
380 | org-ellipsis "…" | ||
381 | org-export-coding-system 'utf-8-unix | ||
382 | org-export-headline-levels 8 | ||
383 | org-export-with-section-numbers nil | ||
384 | org-export-with-smart-quotes t | ||
385 | org-export-with-sub-superscripts t | ||
386 | org-export-with-toc nil | ||
387 | org-fontify-done-headline t | ||
388 | org-fontify-quote-and-verse-blocks t | ||
389 | org-fontify-whole-heading-line t | ||
390 | org-hide-emphasis-markers t | ||
391 | org-html-coding-system 'utf-8-unix | ||
392 | org-image-actual-width (list (* (window-font-width) | ||
393 | (- fill-column 8))) | ||
394 | org-imenu-depth 3 | ||
395 | org-list-demote-modify-bullet '(("-" . "+") | ||
396 | ("+" . "*") | ||
397 | ("*" . "-")) | ||
398 | org-log-done 'time | ||
399 | org-log-into-drawer t | ||
400 | org-outline-path-complete-in-steps nil | ||
401 | org-pretty-entities t | ||
402 | org-pretty-entities-include-sub-superscripts nil | ||
403 | org-refile-use-outline-path 'file | ||
404 | org-special-ctrl-a/e t | ||
405 | org-special-ctrl-k t | ||
406 | org-src-fontify-natively t | ||
407 | org-src-tab-acts-natively t | ||
408 | org-src-window-setup 'current-window | ||
409 | org-startup-truncated nil | ||
410 | org-startup-with-inline-images t | ||
411 | org-tags-column (- (- fill-column (length org-ellipsis)))) | ||
412 | (:bind "RET" #'+org-return-dwim | ||
413 | "<S-return>" #'+org-table-copy-down | ||
414 | "C-c C-l" #'+org-insert-link-dwim | ||
415 | "C-c C-n" #'+org-next-heading-widen | ||
416 | "C-c C-p" #'+org-previous-heading-widen) | ||
417 | (:local-hook before-save-hook #'+org-before-save@prettify-buffer) | ||
418 | (advice-add #'org-delete-backward-char :override #'+org-delete-backward-char) | ||
419 | (with-eval-after-load 'org | ||
420 | (org-clock-persistence-insinuate) | ||
421 | (org-link-set-parameters "tel" :follow #'+org-tel-open))) | ||
422 | |||
346 | (setup org-agenda | 423 | (setup org-agenda |
347 | (:option org-agenda-skip-deadline-if-done t) | 424 | (:option org-agenda-skip-deadline-if-done t) |
425 | (add-to-list '+custom-variable-allowlist 'org-agenda-file-regexp) | ||
426 | (add-to-list '+custom-variable-allowlist 'org-agenda-templates) | ||
348 | (:+leader "a" #'org-agenda "C-a" #'org-agenda)) | 427 | (:+leader "a" #'org-agenda "C-a" #'org-agenda)) |
349 | 428 | ||
429 | (setup org-capture | ||
430 | (:require +org-capture) | ||
431 | (:+leader "c" #'org-capture "C-c" #'org-capture)) | ||
432 | |||
350 | (setup prog | 433 | (setup prog |
351 | (:local-set comment-auto-fill-only-comments t) | 434 | (:local-set comment-auto-fill-only-comments t) |
352 | (:hook #'prettify-symbols-mode | 435 | (:hook #'prettify-symbols-mode |
@@ -848,82 +931,6 @@ See also `crux-reopen-as-root-mode'." | |||
848 | (setup (:straight orderless) | 931 | (setup (:straight orderless) |
849 | (:option completion-styles '(orderless))) | 932 | (:option completion-styles '(orderless))) |
850 | 933 | ||
851 | (setup (:straight (org | ||
852 | :type git :host nil | ||
853 | :repo "https://git.savannah.gnu.org/git/emacs/org-mode.git" | ||
854 | :local-repo "org" | ||
855 | :depth full | ||
856 | :pre-build (straight-recipes-org-elpa--build) | ||
857 | :build (:not autoloads) | ||
858 | :files (:defaults | ||
859 | "lisp/*.el" | ||
860 | ("etc/styles/" "etc/styles/*"))) | ||
861 | (org-contrib | ||
862 | :type git :host nil | ||
863 | :repo "https://git.sr.ht/~bzg/org-contrib")) | ||
864 | ;; DO NOT load system-installed org !!! | ||
865 | (setq load-path (cl-remove-if (lambda (path) | ||
866 | (string-match-p "lisp/org\\'" path)) | ||
867 | load-path)) | ||
868 | (:also-load +org | ||
869 | ox-md) | ||
870 | (:option org-adapt-indentation nil | ||
871 | org-archive-mark-done t | ||
872 | org-catch-invisible-edits 'show-and-error | ||
873 | org-clock-clocked-in-display 'mode-line | ||
874 | org-clock-frame-title-format (cons | ||
875 | '(t org-mode-line-string) | ||
876 | (cons " --- " frame-title-format)) | ||
877 | org-clock-string-limit 7 ; just the clock bit | ||
878 | ;; org-clock-string-limit 25 ; gives enough information | ||
879 | org-clock-persist t | ||
880 | org-confirm-babel-evaluate nil | ||
881 | org-cycle-separator-lines 0 | ||
882 | org-directory "~/org" | ||
883 | org-ellipsis "…" | ||
884 | org-export-coding-system 'utf-8-unix | ||
885 | org-export-headline-levels 8 | ||
886 | org-export-with-section-numbers nil | ||
887 | org-export-with-smart-quotes t | ||
888 | org-export-with-sub-superscripts t | ||
889 | org-export-with-toc nil | ||
890 | org-fontify-done-headline t | ||
891 | org-fontify-quote-and-verse-blocks t | ||
892 | org-fontify-whole-heading-line t | ||
893 | org-hide-emphasis-markers t | ||
894 | org-html-coding-system 'utf-8-unix | ||
895 | org-image-actual-width (list (* (window-font-width) | ||
896 | (- fill-column 8))) | ||
897 | org-imenu-depth 3 | ||
898 | org-list-demote-modify-bullet '(("-" . "+") | ||
899 | ("+" . "*") | ||
900 | ("*" . "-")) | ||
901 | org-log-done 'time | ||
902 | org-log-into-drawer t | ||
903 | org-outline-path-complete-in-steps nil | ||
904 | org-pretty-entities t | ||
905 | org-pretty-entities-include-sub-superscripts nil | ||
906 | org-refile-use-outline-path 'file | ||
907 | org-special-ctrl-a/e t | ||
908 | org-special-ctrl-k t | ||
909 | org-src-fontify-natively t | ||
910 | org-src-tab-acts-natively t | ||
911 | org-src-window-setup 'current-window | ||
912 | org-startup-truncated nil | ||
913 | org-startup-with-inline-images t | ||
914 | org-tags-column (- (- fill-column (length org-ellipsis)))) | ||
915 | (:bind "RET" #'+org-return-dwim | ||
916 | "<S-return>" #'+org-table-copy-down | ||
917 | "C-c C-l" #'+org-insert-link-dwim | ||
918 | "C-c C-n" #'+org-next-heading-widen | ||
919 | "C-c C-p" #'+org-previous-heading-widen) | ||
920 | (:+leader "c" #'org-capture "C-c" #'org-capture) | ||
921 | (:local-hook before-save-hook #'+org-before-save@prettify-buffer) | ||
922 | (advice-add #'org-delete-backward-char :override #'+org-delete-backward-char) | ||
923 | (with-eval-after-load 'org | ||
924 | (org-clock-persistence-insinuate) | ||
925 | (org-link-set-parameters "tel" :follow #'+org-tel-open))) | ||
926 | |||
927 | (setup (:straight org-appear) | 934 | (setup (:straight org-appear) |
928 | (:option org-appear-autoemphasis t | 935 | (:option org-appear-autoemphasis t |
929 | org-appear-autoentities t | 936 | org-appear-autoentities t |
diff --git a/lisp/+cus-edit.el b/lisp/+cus-edit.el index 6ab8527..7fa46d4 100644 --- a/lisp/+cus-edit.el +++ b/lisp/+cus-edit.el | |||
@@ -34,15 +34,19 @@ | |||
34 | "Variables to allow changing while loading the Custom file.") | 34 | "Variables to allow changing while loading the Custom file.") |
35 | 35 | ||
36 | (defun +custom-load-ignoring-most-customizations (&optional | 36 | (defun +custom-load-ignoring-most-customizations (&optional |
37 | noerror | 37 | error |
38 | nomessage | 38 | nomessage |
39 | nosuffix | 39 | nosuffix |
40 | must-suffix) | 40 | must-suffix) |
41 | "Load `custom-file', ignoring most customizations. | 41 | "Load `custom-file', ignoring most customizations. |
42 | Ignore all faces, and only load variables in | 42 | Ignore all faces, and only load variables in |
43 | `+customize-variable-allowlist'. All the optional | 43 | `+customize-variable-allowlist'. All the optional |
44 | variables---NOERROR, NOMESSAGE, NOSUFFIX, MUST-SUFFIX---are | 44 | variables---ERROR, NOMESSAGE, NOSUFFIX, MUST-SUFFIX---are |
45 | passed on to `load'." | 45 | passed on to `load'. |
46 | |||
47 | NOTE: ERROR is the opposite of its value in `load' -- meaning | ||
48 | that this function by default does /not/ error, but will if you | ||
49 | pass t to it." | ||
46 | (cl-letf (((symbol-function 'custom-set-faces) 'ignore) | 50 | (cl-letf (((symbol-function 'custom-set-faces) 'ignore) |
47 | ((symbol-function 'custom-set-variables) | 51 | ((symbol-function 'custom-set-variables) |
48 | (lambda (&rest args) | 52 | (lambda (&rest args) |
@@ -51,7 +55,7 @@ passed on to `load'." | |||
51 | (memq (car el) | 55 | (memq (car el) |
52 | +custom-variable-allowlist)) | 56 | +custom-variable-allowlist)) |
53 | args))))) | 57 | args))))) |
54 | (load custom-file noerror nomessage nosuffix must-suffix))) | 58 | (load custom-file (not error) nomessage nosuffix must-suffix))) |
55 | 59 | ||
56 | (defun +cus-edit-expand-widgets (&rest _) | 60 | (defun +cus-edit-expand-widgets (&rest _) |
57 | "Expand descriptions in `Custom-mode' buffers." | 61 | "Expand descriptions in `Custom-mode' buffers." |
diff --git a/lisp/+org-capture.el b/lisp/+org-capture.el new file mode 100644 index 0000000..1631bdd --- /dev/null +++ b/lisp/+org-capture.el | |||
@@ -0,0 +1,82 @@ | |||
1 | ;;; +org-capture.el -*- lexical-binding: t; -*- | ||
2 | |||
3 | ;;; Code: | ||
4 | |||
5 | (require 'cl-lib) | ||
6 | ;; We don't require `org-capture' here because I'll have to require this library | ||
7 | ;; to init.el /before/ org-capture is fully needed. | ||
8 | |||
9 | (defun +org-capture--get (key &optional list) | ||
10 | "Find KEY in LIST, or return nil. | ||
11 | LIST defaults to `org-capture-templates'." | ||
12 | (alist-get key (or list org-capture-templates) nil nil #'equal)) | ||
13 | |||
14 | ;; Set it up as a generic value. Based on the one for `alist-get'. | ||
15 | (gv-define-expander +org-capture--get | ||
16 | (lambda (do key &optional alist) | ||
17 | (setq alist (or alist org-capture-templates)) | ||
18 | (macroexp-let2 macroexp-copyable-p k key | ||
19 | (gv-letplace (getter setter) alist | ||
20 | (macroexp-let2 nil p `(assoc ,k ,getter 'equal) | ||
21 | (funcall do `(cdr ,p) | ||
22 | (lambda (v) | ||
23 | (macroexp-let2 nil v v | ||
24 | (let ((set-exp | ||
25 | `(if ,p (setcdr ,p ,v) | ||
26 | ,(funcall setter | ||
27 | `(cons (setq ,p (cons ,k ,v)) | ||
28 | ,getter))))) | ||
29 | `(progn | ||
30 | ,set-exp | ||
31 | ,v)))))))))) | ||
32 | |||
33 | (defun +org-capture-sort (&optional list) | ||
34 | "Sort LIST by string keys. | ||
35 | LIST is a symbol and defaults to `org-capture-templates'." | ||
36 | (setq list (or list 'org-capture-templates)) | ||
37 | (set list (sort (symbol-value list) (lambda (a b) | ||
38 | (string< (car a) (car b)))))) | ||
39 | |||
40 | ;;;###autoload | ||
41 | (defun +org-capture-templates-setf (key value &optional list sort-after) | ||
42 | "Add KEY to LIST, using `setf'. | ||
43 | LIST is a symbol and defaults to `org-capture-templates' -- so | ||
44 | this function sets values on a list that's structured as such. | ||
45 | |||
46 | Thus, KEY is a string key. If it's longer than one character, | ||
47 | this function will search LIST for each successive run of | ||
48 | characters before the final, ensuring sub-lists exist of the | ||
49 | form (CHARS DESCRIPTION). | ||
50 | |||
51 | For example, if KEY is \"abc\", first a LIST item of the form (a | ||
52 | DESCRIPTION), if non-existant, will be added to the list (with a | ||
53 | default description), then an item of the | ||
54 | form (\"ab\" DESCRIPTION), before adding (KEY VALUE) to the LIST. | ||
55 | |||
56 | VALUE is the template or group header required for | ||
57 | `org-capture-templates', which see. | ||
58 | |||
59 | SORT-AFTER, when set to t, will call | ||
60 | `+org-capture-templates-sort' after setting, to ensure org can | ||
61 | properly process the variable." | ||
62 | ;; LIST defaults to `org-capture-templates' | ||
63 | (declare (indent 2)) | ||
64 | (unless list (setq list 'org-capture-templates)) | ||
65 | ;; Ensure VALUE is a list to cons properly | ||
66 | (unless (listp value) (setq value (list value))) | ||
67 | (when (> (length key) 1) | ||
68 | ;; Check for existence of groups. | ||
69 | (let ((expected (cl-loop for i from 1 to (1- (length key)) | ||
70 | collect (substring key 0 i) into keys | ||
71 | finally return keys))) | ||
72 | (cl-loop for ek in expected | ||
73 | if (not (+org-capture--get ek (symbol-value list))) do | ||
74 | (setf (+org-capture--get ek (symbol-value list)) | ||
75 | (list (format "(Group %s)" ek)))))) | ||
76 | (prog1 ;; Set KEY to VALUE | ||
77 | (setf (+org-capture--get key (symbol-value list)) value) | ||
78 | ;; Sort after, maybe | ||
79 | (when sort-after (+org-capture-sort list)))) | ||
80 | |||
81 | (provide '+org-capture) | ||
82 | ;;; +org-capture.el ends here | ||