Commit dicipline fail
This commit is contained in:
@@ -639,6 +639,8 @@ Beloved Faye's Wishsys is an incredibly impressive 3-kloc NixOS config with seve
|
|||||||
- [cite:@ayats2024dropping]
|
- [cite:@ayats2024dropping]
|
||||||
- [cite:@zaynetdinov2024you]
|
- [cite:@zaynetdinov2024you]
|
||||||
- [cite:@schafer2017advanced]
|
- [cite:@schafer2017advanced]
|
||||||
|
- [cite:@bosio2023beautifying]
|
||||||
|
- [cite:@zamboni2018beautifying]
|
||||||
- [[https://prelude.emacsredux.com/en/stable/][Emacs Prelude]]
|
- [[https://prelude.emacsredux.com/en/stable/][Emacs Prelude]]
|
||||||
- [[https://github.com/doomemacs/doomemacs][Doom Emacs]]
|
- [[https://github.com/doomemacs/doomemacs][Doom Emacs]]
|
||||||
- [[https://cce.whatthefuck.computer/cce][Ryan Rix's Complete Computing Environment]]
|
- [[https://cce.whatthefuck.computer/cce][Ryan Rix's Complete Computing Environment]]
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ in {
|
|||||||
"Pictures"
|
"Pictures"
|
||||||
"Documents"
|
"Documents"
|
||||||
"Videos"
|
"Videos"
|
||||||
|
"src"
|
||||||
".ssh"
|
".ssh"
|
||||||
{
|
{
|
||||||
directory = ".local/share/Steam";
|
directory = ".local/share/Steam";
|
||||||
|
|||||||
@@ -5,4 +5,106 @@
|
|||||||
|
|
||||||
(require 'general)
|
(require 'general)
|
||||||
|
|
||||||
|
(defvar syd-leader-key "SPC"
|
||||||
|
"A prefix key akin to Vim's <Leader>.")
|
||||||
|
|
||||||
|
(defvar syd-localleader-key "SPC m"
|
||||||
|
"A prefix key akin to Vim's <LocalLeader>.")
|
||||||
|
|
||||||
|
(defvar syd-alt-leader-key "M-SPC"
|
||||||
|
"`syd-leader', but for the states specified in `syd-alt-leader-key-states'.
|
||||||
|
|
||||||
|
Often, your \"usual\" leader key will be something unavailable in the Insert
|
||||||
|
state. This key exists as a fallback for when you need your Leader, but must
|
||||||
|
remain in the Insert state. Substitute \"Insert state\" for your states of
|
||||||
|
choice with `syd-alt-leader-key-states'.")
|
||||||
|
|
||||||
|
(defvar syd-alt-localleader-key "M-SPC m"
|
||||||
|
"`syd-localleader', but for the states specified in `syd-alt-leader-key-states'.
|
||||||
|
|
||||||
|
See `syd-alt-leader-key' for rationale.")
|
||||||
|
|
||||||
|
(defvar syd-leader-key-states '(normal visual motion)
|
||||||
|
"States for which the Leader keys (`syd-leader-key', `syd-localleader-key')
|
||||||
|
are active.")
|
||||||
|
|
||||||
|
(defvar syd-alt-leader-key-states '(emacs insert)
|
||||||
|
"States for which the alternative Leader keys are active. See
|
||||||
|
`syd-alt-leader-key' and `syd-alt-localleader-key'.")
|
||||||
|
|
||||||
|
(defvar-keymap syd-leader-map
|
||||||
|
:doc "Leader-prefixed commands")
|
||||||
|
|
||||||
|
(defun syd-initialise-leader ()
|
||||||
|
"Set up the (empty) keymap associated with `syd-leader-key',
|
||||||
|
`syd-localleader-key', `syd-alt-leader-key', and `syd-alt-localleader-key'."
|
||||||
|
(require 'evil)
|
||||||
|
;; Define `syd/leader' as a command corresponding to the prefix map
|
||||||
|
;; `syd-leader-map'.
|
||||||
|
(define-prefix-command 'syd/leader 'syd-leader-map)
|
||||||
|
;; This should help make the Leader key close to universally available.
|
||||||
|
;; Ideally, *nothing* takes precedence over Leader — it's an incredibly
|
||||||
|
;; important key!
|
||||||
|
;; https://github.com/noctuid/evil-guide?tab=readme-ov-file#undoprevent-overridingintercept-maps
|
||||||
|
;; See `evil-make-overriding-map'.
|
||||||
|
(define-key syd-leader-map [override-state] 'all)
|
||||||
|
;; Finally, we shall bind the damned keys. }:)
|
||||||
|
(let ((map general-override-mode-map))
|
||||||
|
(evil-define-key* syd-leader-key-states map (kbd syd-leader-key) 'syd/leader)
|
||||||
|
(evil-define-key* syd-alt-leader-key-states map (kbd syd-alt-leader-key) 'syd/leader))
|
||||||
|
(general-override-mode 1))
|
||||||
|
|
||||||
|
(defvar syd-escape-hook nil
|
||||||
|
"A hook run when C-g is pressed (or ESC in Evil's normal state).
|
||||||
|
|
||||||
|
More specifically, when `syd/escape' is pressed. If any hook returns non-nil,
|
||||||
|
all hooks after it are ignored.")
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Universal, non-nuclear escape
|
||||||
|
|
||||||
|
;; `keyboard-quit' is too much of a nuclear option. I want ESC/C-g to
|
||||||
|
;; do-what-I-mean. It serves four purposes (in order):
|
||||||
|
;;
|
||||||
|
;; 1. Quit active states; e.g. highlights, searches, snippets, iedit,
|
||||||
|
;; multiple-cursors, recording macros, etc.
|
||||||
|
;; 2. Close popup windows remotely (if it is allowed to)
|
||||||
|
;; 3. Refresh buffer indicators, like diff-hl and flycheck
|
||||||
|
;; 4. Or fall back to `keyboard-quit'
|
||||||
|
;;
|
||||||
|
;; And it should do these things incrementally, rather than all at once. And it
|
||||||
|
;; shouldn't interfere with recording macros or the minibuffer. This may
|
||||||
|
;; require you press ESC/C-g two or three times on some occasions to reach
|
||||||
|
;; `keyboard-quit', but this is much more intuitive.
|
||||||
|
|
||||||
|
(defun syd/escape (&optional interactive)
|
||||||
|
"Run `syd-escape-hook'."
|
||||||
|
(interactive (list 'interactive))
|
||||||
|
(let ((inhibit-quit t))
|
||||||
|
(cond ((minibuffer-window-active-p (minibuffer-window))
|
||||||
|
;; quit the minibuffer if open.
|
||||||
|
(when interactive
|
||||||
|
(setq this-command 'abort-recursive-edit))
|
||||||
|
(abort-recursive-edit))
|
||||||
|
;; Run all escape hooks. If any returns non-nil, then stop there.
|
||||||
|
((run-hook-with-args-until-success 'syd-escape-hook))
|
||||||
|
;; don't abort macros
|
||||||
|
((or defining-kbd-macro executing-kbd-macro) nil)
|
||||||
|
;; Back to the default
|
||||||
|
((unwind-protect (keyboard-quit)
|
||||||
|
(when interactive
|
||||||
|
(setq this-command 'keyboard-quit)))))))
|
||||||
|
|
||||||
|
(with-eval-after-load 'eldoc
|
||||||
|
(eldoc-add-command 'syd/escape))
|
||||||
|
|
||||||
|
;; In normal state, pressing escape should run `syd-escape-hook'.
|
||||||
|
(with-eval-after-load 'evil
|
||||||
|
(defun evil-syd/escape-a (&rest _)
|
||||||
|
"Call `syd/escape' if `evil-force-normal-state' is called interactively."
|
||||||
|
(when (called-interactively-p 'any)
|
||||||
|
(call-interactively #'syd/escape)))
|
||||||
|
(advice-add #'evil-force-normal-state
|
||||||
|
:after #'evil-syd/escape-a))
|
||||||
|
|
||||||
(provide 'syd-general)
|
(provide 'syd-general)
|
||||||
|
|||||||
@@ -124,6 +124,21 @@ comment, if there is one. Returns nil or a pair (BEG . END)."
|
|||||||
"When `syd-evil-a-defun' is used in combination with one of these operators,
|
"When `syd-evil-a-defun' is used in combination with one of these operators,
|
||||||
some cleanup will be performed.")
|
some cleanup will be performed.")
|
||||||
|
|
||||||
|
;; FIXME(#12): Comments should only attach to the *immediately* following sexp.
|
||||||
|
;; Consider the following snippet:
|
||||||
|
;;
|
||||||
|
;; ;; Call the continuation if non-nil. Wraps the return value in a singleton
|
||||||
|
;; ;; list for "affine" use with unquote-splicing.
|
||||||
|
;; (let ((call-cont (lambda (cont arg)
|
||||||
|
;; (if cont
|
||||||
|
;; (list (funcall cont arg))
|
||||||
|
;; nil)))
|
||||||
|
;; names)
|
||||||
|
;; ...)
|
||||||
|
;;
|
||||||
|
;; The curreny behaviour of `syd-sexp--backward-attached-comment' considers the
|
||||||
|
;; comment to be attached to both the (let ...) form, as well as the ((call-cont
|
||||||
|
;; ...)) form and the (call-cont ...) form. Not good!
|
||||||
(defun syd-sexp--backward-attached-comment ()
|
(defun syd-sexp--backward-attached-comment ()
|
||||||
"Assuming point is on the opening delimiter of a sexp, move point backward to
|
"Assuming point is on the opening delimiter of a sexp, move point backward to
|
||||||
the beginning of the \"attached\" comment."
|
the beginning of the \"attached\" comment."
|
||||||
@@ -155,7 +170,7 @@ to clean up whitespace following certain operators."
|
|||||||
(list beg-0 :end)))))
|
(list beg-0 :end)))))
|
||||||
|
|
||||||
;; IDEA: How about the inner-defun text object selects the defun /without/ the
|
;; IDEA: How about the inner-defun text object selects the defun /without/ the
|
||||||
;; comment? Is that more useful, or less? I can't think of the last time I've
|
;; comment? Is that more useful, or less? I can't think of the last time Ive
|
||||||
;; needed the top-level sexp without the brackets.
|
;; needed the top-level sexp without the brackets.
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
@@ -189,6 +204,7 @@ delimiters."
|
|||||||
(sexp (syd-get-enclosing-sexp)))
|
(sexp (syd-get-enclosing-sexp)))
|
||||||
(if cleanup-p
|
(if cleanup-p
|
||||||
(save-excursion
|
(save-excursion
|
||||||
|
(goto-char (sp-get sexp :beg))
|
||||||
(if (syd-sexp--looking-at-last-p)
|
(if (syd-sexp--looking-at-last-p)
|
||||||
(progn (syd-sexp--backward-leading-whitespace sexp)
|
(progn (syd-sexp--backward-leading-whitespace sexp)
|
||||||
(list (point) (sp-get sexp :end)))
|
(list (point) (sp-get sexp :end)))
|
||||||
@@ -208,9 +224,9 @@ sexp-wise analogue to Evil's line-wise `evil-open-below'."
|
|||||||
:suppress-operator t
|
:suppress-operator t
|
||||||
(evil-with-single-undo
|
(evil-with-single-undo
|
||||||
;; We want to add an additional blank line when operating at the top level.
|
;; We want to add an additional blank line when operating at the top level.
|
||||||
;; Instead of parsing upward until we can no longer find an enclosing sexp, we
|
;; Instead of parsing upward until we can no longer find an enclosing sexp,
|
||||||
;; simply check if the opening bracket is on the first column. This is not
|
;; we simply check if the opening bracket is on the first column. This is
|
||||||
;; very correct, but it's way less work (for myself and the CPU). If we
|
;; not very correct, but it's way less work (for myself and the CPU). If we
|
||||||
;; switch to a tree-sitter–based parser, I'd love to switch to the correct
|
;; switch to a tree-sitter–based parser, I'd love to switch to the correct
|
||||||
;; algorithm.
|
;; algorithm.
|
||||||
(-let* (((beg . end) (sp-get (syd-get-enclosing-sexp) (cons :beg :end)))
|
(-let* (((beg . end) (sp-get (syd-get-enclosing-sexp) (cons :beg :end)))
|
||||||
|
|||||||
@@ -12,40 +12,70 @@
|
|||||||
,todo
|
,todo
|
||||||
(error ,todo))))
|
(error ,todo))))
|
||||||
|
|
||||||
(cl-defun syd--lift-lambdas (forms &key with-each with-all)
|
;; FIXME: When `arg-list' contains nils, things break.
|
||||||
|
(cl-defun syd-parse-rest-and-keys (arg-list)
|
||||||
|
"The default behaviour of `cl-defun' makes combining &rest with &keys pretty
|
||||||
|
useless. This function will partition ARG-LIST by returning a pair (REST
|
||||||
|
. KEYS), where REST is the list of ARGS that belong to no key-value pair, and
|
||||||
|
KEYS is an alist of the parsed keywords."
|
||||||
|
;; Ugh.
|
||||||
|
(let (parsed-rest parsed-keys)
|
||||||
|
(cl-loop for (lead lag) on arg-list by (lambda (x) (-drop 2 x))
|
||||||
|
do (if (keywordp lead)
|
||||||
|
(push (cons lead lag) parsed-keys)
|
||||||
|
;; Push in reverse order; we reverse the whole list as a
|
||||||
|
;; post-processing step.
|
||||||
|
(push lead parsed-rest)
|
||||||
|
(when lag
|
||||||
|
(push lag parsed-rest))))
|
||||||
|
(cons (reverse parsed-rest) parsed-keys)))
|
||||||
|
|
||||||
|
(cl-defun syd-lift-lambdas (&rest args)
|
||||||
;; Call the continuation if non-nil. Wraps the return value in a singleton
|
;; Call the continuation if non-nil. Wraps the return value in a singleton
|
||||||
;; list for "affine" use with unquote-splicing.
|
;; list for "affine" use with unquote-splicing.
|
||||||
(let ((call-cont (lambda (cont)
|
(-let (((forms . (&alist :with-each with-each
|
||||||
|
:with-all with-all))
|
||||||
|
(syd-parse-rest-and-keys args))
|
||||||
|
(call-cont (lambda (cont arg)
|
||||||
(if cont
|
(if cont
|
||||||
(lambda (name) (list (funcall with-each name)))
|
(list (funcall cont arg))
|
||||||
(lambda (_) nil))))
|
nil)))
|
||||||
names)
|
names)
|
||||||
`(progn ,@(mapconcat (lambda (form)
|
`(progn
|
||||||
(cond ((and (symbolp form) (functionp form))
|
,@(cl-loop
|
||||||
|
for form in forms
|
||||||
|
appending (cond ((and (symbolp form) (functionp form))
|
||||||
(push form names)
|
(push form names)
|
||||||
(call-cont with-each form))
|
(funcall call-cont with-each form))
|
||||||
((eq (car-safe form) 'defun)
|
((syd-hform-defun form)
|
||||||
(let ((name (nth 1 form)))
|
(let ((name (nth 1 form)))
|
||||||
(push name names)
|
(push name names)
|
||||||
`(,form
|
`(,form
|
||||||
,@(call-cont with-each))))
|
,@(funcall call-cont with-each name))))
|
||||||
((eq (car-safe form) 'lambda)
|
((syd-hform-lambda form)
|
||||||
(let ((name (gensym "lifted-lambda")))
|
(let ((name (gensym "lifted-lambda")))
|
||||||
(push name names)
|
(push name names)
|
||||||
`((defun ,name (&rest args)
|
`((defun ,name (&rest args)
|
||||||
(,form args))
|
(,form args))
|
||||||
,@(call-cont with-each))))))
|
,@(funcall call-cont with-each name))))
|
||||||
(ensure-list forms))
|
(t (error "IDK!"))))
|
||||||
,@(call-cont with-all names))))
|
,@(funcall call-cont with-all names))))
|
||||||
|
|
||||||
;; (defun syd-hform-defun (hform)
|
(defun syd-hform-defun (hform)
|
||||||
;; "If HFORM is a defun form, return the defun's name. Otherwise, return nil"
|
"If HFORM is a defun form, return the defun's name. Otherwise, return nil"
|
||||||
;; (and (listp hform)
|
(when-let* ((sym (car-safe hform)))
|
||||||
;; (<= 2 (length hform))
|
(and (symbolp sym)
|
||||||
;; (nth 1 hform)))
|
(eq sym 'defun)
|
||||||
|
(nth 1 hform))))
|
||||||
|
|
||||||
|
(defun syd-hform-lambda (hform)
|
||||||
|
"If HFORM is a lambda, return non-nil."
|
||||||
|
(when-let* ((sym (car-safe hform)))
|
||||||
|
(and (symbolp sym)
|
||||||
|
(eq sym 'lambda))))
|
||||||
|
|
||||||
(defmacro comment (&rest _)
|
(defmacro comment (&rest _)
|
||||||
"Completely every argument, and expand to nil."
|
"Ignore each argument, and expand to nil."
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defmacro with-transient-after (hook-or-function &rest forms)
|
(defmacro with-transient-after (hook-or-function &rest forms)
|
||||||
@@ -74,4 +104,30 @@ not mutated; a new plist is returned."
|
|||||||
(list prop* new-val)
|
(list prop* new-val)
|
||||||
(list prop* old-val))))
|
(list prop* old-val))))
|
||||||
|
|
||||||
|
;; TODO: Support (syd-add-hook 'hook (defun my-hook () ...))
|
||||||
|
(defun syd-add-hook (hooks &rest functions)
|
||||||
|
(declare (indent defun))
|
||||||
|
(dolist (hook (ensure-list hooks))
|
||||||
|
(dolist (fn functions)
|
||||||
|
(add-hook hook fn))))
|
||||||
|
|
||||||
|
(defmacro syd-silently (&rest body)
|
||||||
|
`(error "TODO: syd-silently"))
|
||||||
|
|
||||||
|
(defmacro syd-quietly (&rest body)
|
||||||
|
"Evaluate BODY without generating any output.
|
||||||
|
|
||||||
|
This silences calls to `message', `load', `write-region' and anything that
|
||||||
|
writes to `standard-output'. In interactive sessions this inhibits output to
|
||||||
|
the echo-area, but not to *Messages*. Return value is that of BODY's final
|
||||||
|
form."
|
||||||
|
`(if init-file-debug
|
||||||
|
(progn ,@body)
|
||||||
|
,(if noninteractive
|
||||||
|
`(syd-silently ,@body)
|
||||||
|
`(let ((inhibit-message t)
|
||||||
|
(save-silently t))
|
||||||
|
(prog1 (progn ,@body)
|
||||||
|
(message ""))))))
|
||||||
|
|
||||||
(provide 'syd-prelude)
|
(provide 'syd-prelude)
|
||||||
|
|||||||
27
users/crumb/programs/emacs/lib/syd-prose.el
Normal file
27
users/crumb/programs/emacs/lib/syd-prose.el
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
;;; syd-prose.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(use-package visual-fill-column
|
||||||
|
:defer t)
|
||||||
|
|
||||||
|
(defun syd-prose-disable-display-line-numbers-mode-h ()
|
||||||
|
"Disable `display-line-numbers-mode'."
|
||||||
|
(display-line-numbers-mode -1))
|
||||||
|
|
||||||
|
(defun syd-prose-set-visual-fill-column-center ()
|
||||||
|
"Sets the buffer-local value for `visual-fill-column-center-text'."
|
||||||
|
(setq-local visual-fill-column-center-text t))
|
||||||
|
|
||||||
|
(defvar syd-prose-mode-hook
|
||||||
|
(list #'syd-prose-set-visual-fill-column-center
|
||||||
|
#'visual-fill-column-mode
|
||||||
|
#'visual-line-mode
|
||||||
|
#'variable-pitch-mode
|
||||||
|
#'syd-prose-disable-display-line-numbers-mode-h)
|
||||||
|
"Hooks run for `syd-prose-mode'.")
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode syd-prose-mode
|
||||||
|
"A minor mode for writing prose."
|
||||||
|
:lighter nil)
|
||||||
|
|
||||||
|
(provide 'syd-prose)
|
||||||
@@ -91,4 +91,15 @@ to a pop up buffer."
|
|||||||
(use-package rainbow-delimiters
|
(use-package rainbow-delimiters
|
||||||
:hook (emacs-lisp-mode . rainbow-delimiters-mode))
|
:hook (emacs-lisp-mode . rainbow-delimiters-mode))
|
||||||
|
|
||||||
|
(use-package macrostep
|
||||||
|
:commands (macrostep-expand)
|
||||||
|
:init
|
||||||
|
(general-define-key
|
||||||
|
:keymaps 'emacs-lisp-mode-map
|
||||||
|
:states '(normal visual motion emacs insert)
|
||||||
|
:major-modes t
|
||||||
|
:prefix syd-localleader-key
|
||||||
|
:non-normal-prefix syd-alt-localleader-key
|
||||||
|
"m" #'macrostep-expand))
|
||||||
|
|
||||||
(provide 'syd-lang-emacs-lisp)
|
(provide 'syd-lang-emacs-lisp)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
:preface
|
:preface
|
||||||
(setq evil-want-minibuffer t
|
(setq evil-want-minibuffer t
|
||||||
evil-move-beyond-eol t
|
evil-move-beyond-eol t
|
||||||
|
evil-respect-visual-line-mode t
|
||||||
evil-vsplit-window-right t
|
evil-vsplit-window-right t
|
||||||
evil-ex-search-vim-style-regexp t
|
evil-ex-search-vim-style-regexp t
|
||||||
evil-want-Y-yank-to-eol t
|
evil-want-Y-yank-to-eol t
|
||||||
|
|||||||
@@ -1,110 +1,10 @@
|
|||||||
;;; syd-keybinds.el -*- lexical-binding: t; -*-
|
;;; syd-keybinds.el -*- lexical-binding: t; -*-
|
||||||
;;; Universal keybindings, not /too/ tied to any particular packages.
|
;;; Universal keybindings, not /too/ tied to any particular packages.
|
||||||
|
|
||||||
(defvar syd-leader-key "SPC"
|
(require 'syd-general)
|
||||||
"A prefix key akin to Vim's <Leader>.")
|
|
||||||
|
|
||||||
(defvar syd-localleader-key "SPC m"
|
|
||||||
"A prefix key akin to Vim's <LocalLeader>.")
|
|
||||||
|
|
||||||
(defvar syd-alt-leader-key "M-SPC"
|
|
||||||
"`syd-leader', but for the states specified in `syd-alt-leader-key-states'.
|
|
||||||
|
|
||||||
Often, your \"usual\" leader key will be something unavailable in the Insert
|
|
||||||
state. This key exists as a fallback for when you need your Leader, but must
|
|
||||||
remain in the Insert state. Substitute \"Insert state\" for your states of
|
|
||||||
choice with `syd-alt-leader-key-states'.")
|
|
||||||
|
|
||||||
(defvar syd-alt-localleader-key "M-SPC m"
|
|
||||||
"`syd-localleader', but for the states specified in `syd-alt-leader-key-states'.
|
|
||||||
|
|
||||||
See `syd-alt-leader-key' for rationale.")
|
|
||||||
|
|
||||||
(defvar syd-leader-key-states '(normal visual motion)
|
|
||||||
"States for which the Leader keys (`syd-leader-key', `syd-localleader-key')
|
|
||||||
are active.")
|
|
||||||
|
|
||||||
(defvar syd-alt-leader-key-states '(emacs insert)
|
|
||||||
"States for which the alternative Leader keys are active. See
|
|
||||||
`syd-alt-leader-key' and `syd-alt-localleader-key'.")
|
|
||||||
|
|
||||||
(defvar-keymap syd-leader-map
|
|
||||||
:doc "Leader-prefixed commands")
|
|
||||||
|
|
||||||
(defun syd--initialise-leader ()
|
|
||||||
"Set up the (empty) keymap associated with `syd-leader-key',
|
|
||||||
`syd-localleader-key', `syd-alt-leader-key', and `syd-alt-localleader-key'."
|
|
||||||
(require 'evil)
|
|
||||||
;; Define `syd/leader' as a command corresponding to the prefix map
|
|
||||||
;; `syd-leader-map'.
|
|
||||||
(define-prefix-command 'syd/leader 'syd-leader-map)
|
|
||||||
;; This should help make the Leader key close to universally available.
|
|
||||||
;; Ideally, *nothing* takes precedence over Leader — it's an incredibly
|
|
||||||
;; important key!
|
|
||||||
;; https://github.com/noctuid/evil-guide?tab=readme-ov-file#undoprevent-overridingintercept-maps
|
|
||||||
;; See `evil-make-overriding-map'.
|
|
||||||
(define-key syd-leader-map [override-state] 'all)
|
|
||||||
;; Finally, we shall bind the damned keys. }:)
|
|
||||||
(let ((map general-override-mode-map))
|
|
||||||
(evil-define-key* syd-leader-key-states map (kbd syd-leader-key) 'syd/leader)
|
|
||||||
(evil-define-key* syd-alt-leader-key-states map (kbd syd-alt-leader-key) 'syd/leader))
|
|
||||||
(general-override-mode 1))
|
|
||||||
|
|
||||||
(defvar syd-escape-hook nil
|
|
||||||
"A hook run when C-g is pressed (or ESC in Evil's normal state).
|
|
||||||
|
|
||||||
More specifically, when `syd/escape' is pressed. If any hook returns non-nil,
|
|
||||||
all hooks after it are ignored.")
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Universal, non-nuclear escape
|
|
||||||
|
|
||||||
;; `keyboard-quit' is too much of a nuclear option. I want ESC/C-g to
|
|
||||||
;; do-what-I-mean. It serves four purposes (in order):
|
|
||||||
;;
|
|
||||||
;; 1. Quit active states; e.g. highlights, searches, snippets, iedit,
|
|
||||||
;; multiple-cursors, recording macros, etc.
|
|
||||||
;; 2. Close popup windows remotely (if it is allowed to)
|
|
||||||
;; 3. Refresh buffer indicators, like diff-hl and flycheck
|
|
||||||
;; 4. Or fall back to `keyboard-quit'
|
|
||||||
;;
|
|
||||||
;; And it should do these things incrementally, rather than all at once. And it
|
|
||||||
;; shouldn't interfere with recording macros or the minibuffer. This may
|
|
||||||
;; require you press ESC/C-g two or three times on some occasions to reach
|
|
||||||
;; `keyboard-quit', but this is much more intuitive.
|
|
||||||
|
|
||||||
(defun syd/escape (&optional interactive)
|
|
||||||
"Run `syd-escape-hook'."
|
|
||||||
(interactive (list 'interactive))
|
|
||||||
(let ((inhibit-quit t))
|
|
||||||
(cond ((minibuffer-window-active-p (minibuffer-window))
|
|
||||||
;; quit the minibuffer if open.
|
|
||||||
(when interactive
|
|
||||||
(setq this-command 'abort-recursive-edit))
|
|
||||||
(abort-recursive-edit))
|
|
||||||
;; Run all escape hooks. If any returns non-nil, then stop there.
|
|
||||||
((run-hook-with-args-until-success 'syd-escape-hook))
|
|
||||||
;; don't abort macros
|
|
||||||
((or defining-kbd-macro executing-kbd-macro) nil)
|
|
||||||
;; Back to the default
|
|
||||||
((unwind-protect (keyboard-quit)
|
|
||||||
(when interactive
|
|
||||||
(setq this-command 'keyboard-quit)))))))
|
|
||||||
|
|
||||||
(with-eval-after-load 'eldoc
|
|
||||||
(eldoc-add-command 'syd/escape))
|
|
||||||
|
|
||||||
;; In normal state, pressing escape should run `syd-escape-hook'.
|
|
||||||
(with-eval-after-load 'evil
|
|
||||||
(defun evil-syd/escape-a (&rest _)
|
|
||||||
"Call `syd/escape' if `evil-force-normal-state' is called interactively."
|
|
||||||
(when (called-interactively-p 'any)
|
|
||||||
(call-interactively #'syd/escape)))
|
|
||||||
(advice-add #'evil-force-normal-state
|
|
||||||
:after #'evil-syd/escape-a))
|
|
||||||
|
|
||||||
(defun syd-keybinds-initialise ()
|
(defun syd-keybinds-initialise ()
|
||||||
(syd--initialise-leader)
|
(syd-initialise-leader)
|
||||||
|
|
||||||
(global-set-key [remap keyboard-quit] #'syd/escape)
|
(global-set-key [remap keyboard-quit] #'syd/escape)
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,127 @@
|
|||||||
;;; syd-org.el -*- lexical-binding: t; -*-
|
;;; syd-org.el -*- lexical-binding: t; -*-
|
||||||
|
|
||||||
|
(require 'syd-prose)
|
||||||
|
|
||||||
|
(defun syd-org--init-hacks-h ()
|
||||||
|
;; Open file links in current window, rather than new ones
|
||||||
|
(setf (alist-get 'file org-link-frame-setup) #'find-file)
|
||||||
|
;; Open directory links in dired
|
||||||
|
(add-to-list 'org-file-apps '(directory . emacs))
|
||||||
|
(add-to-list 'org-file-apps '(remote . emacs))
|
||||||
|
|
||||||
|
(defun syd-org--restart-mode-h ()
|
||||||
|
"Restart `org-mode', but only once."
|
||||||
|
(syd-quietly (org-mode-restart))
|
||||||
|
(setq org-agenda-new-buffers
|
||||||
|
(delq (current-buffer)
|
||||||
|
org-agenda-new-buffers))
|
||||||
|
(run-hooks 'find-file-hook))
|
||||||
|
|
||||||
|
(defun syd-org-exclude-agenda-buffers-from-workspace-h ()
|
||||||
|
"Don't associate temporary agenda buffers with current workspace."
|
||||||
|
(when (and org-agenda-new-buffers
|
||||||
|
(bound-and-true-p persp-mode)
|
||||||
|
(not org-agenda-sticky))
|
||||||
|
(let (persp-autokill-buffer-on-remove)
|
||||||
|
(persp-remove-buffer org-agenda-new-buffers
|
||||||
|
(get-current-persp)
|
||||||
|
nil))))
|
||||||
|
(add-hook 'org-agenda-finalize-hook
|
||||||
|
#'syd-org-exclude-agenda-buffers-from-workspace-h)
|
||||||
|
|
||||||
|
(defun syd-org--restart-mode-before-indirect-buffer-a (&optional buffer _)
|
||||||
|
"Restart `org-mode' in buffers in which the mode has been deferred (see
|
||||||
|
`syd-org-defer-mode-in-agenda-buffers-h') before they become the base buffer for an
|
||||||
|
indirect org-cpature buffer. This ensures that the buffer is fully functional
|
||||||
|
not only when the *user* visits it, but also when org-capture interacts with it
|
||||||
|
via an indirect buffer."
|
||||||
|
(with-current-buffer (or buffer (current-buffer))
|
||||||
|
(when (memq #'syd-org--restart-mode-h on-switch-buffer-hook)
|
||||||
|
(syd-org--restart-mode-h))))
|
||||||
|
(advice-add #'org-capture-get-indirect-buffer
|
||||||
|
:before #'syd-org--restart-mode-before-indirect-buffer-a)
|
||||||
|
|
||||||
|
(defvar recentf-exclude)
|
||||||
|
(defun syd-org--optimize-backgrounded-agenda-buffers-a (fn file)
|
||||||
|
"Disable `org-mode's startup processes for temporary agenda buffers.
|
||||||
|
|
||||||
|
Prevents recentf pollution as well. However, if the user tries to visit one of
|
||||||
|
these buffers they'll see a gimped, half-broken org buffer, so to avoid that,
|
||||||
|
install a hook to restart `org-mode' when they're switched to so they can grow
|
||||||
|
up to be fully-fledged org-mode buffers."
|
||||||
|
(if-let* ((buf (org-find-base-buffer-visiting file)))
|
||||||
|
buf
|
||||||
|
(let ((recentf-exclude '(always))
|
||||||
|
;; (doom-inhibit-large-file-detection t)
|
||||||
|
;; (doom-inhibit-local-var-hooks t)
|
||||||
|
(org-inhibit-startup t)
|
||||||
|
vc-handled-backends
|
||||||
|
enable-local-variables
|
||||||
|
find-file-hook)
|
||||||
|
(when-let ((buf (delay-mode-hooks (funcall fn file))))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(add-hook 'on-switch-buffer-hook #'syd-org--restart-mode-h
|
||||||
|
nil 'local))
|
||||||
|
buf))))
|
||||||
|
(advice-add #'org-get-agenda-file-buffer
|
||||||
|
:around #'syd-org--optimize-backgrounded-agenda-buffers-a)
|
||||||
|
|
||||||
|
(defun syd-org--fix-inconsistent-uuidgen-case-a (uuid)
|
||||||
|
"Ensure uuidgen is always lowercase (consistent) regardless of system.
|
||||||
|
See https://lists.gnu.org/archive/html/emacs-orgmode/2019-07/msg00081.html."
|
||||||
|
:filter-return #'org-id-new
|
||||||
|
(if (eq org-id-method 'uuid)
|
||||||
|
(downcase uuid)
|
||||||
|
uuid))
|
||||||
|
(advice-add #'org-id-new
|
||||||
|
:filter-return #'syd-org--fix-inconsistent-uuidgen-case-a))
|
||||||
|
|
||||||
|
(defun syd-org-init-faces ()
|
||||||
|
(let ((headline `(:weight bold)))
|
||||||
|
(custom-theme-set-faces
|
||||||
|
'user
|
||||||
|
;; It is important that the `org-indent' face uses a fixed-pitch font, lest
|
||||||
|
;; e.g. multi-line bullets appear misaligned.
|
||||||
|
'(org-indent ((t (:inherit (org-hide fixed-pitch)))))
|
||||||
|
;; Must be fixed-pitch; `[ ]` and `[X]' should be the same width.
|
||||||
|
'(org-checkbox ((t (:inherit fixed-pitch))))
|
||||||
|
'(org-drawer ((t (:inherit (font-lock-comment-face fixed-pitch)))))
|
||||||
|
'(org-property-value ((t (:inherit fixed-pitch)))))))
|
||||||
|
|
||||||
|
(defun syd-org-init-keybinds ()
|
||||||
|
(general-def
|
||||||
|
:keymaps 'org-mode-map
|
||||||
|
:states '(insert emacs)
|
||||||
|
[tab] #'org-cycle
|
||||||
|
[C-M-return] #'org-insert-subheading)
|
||||||
|
(general-def
|
||||||
|
:prefix-map 'syd-org-mode-links-map
|
||||||
|
"l" #'org-insert-link)
|
||||||
|
(general-define-key
|
||||||
|
:keymaps 'org-mode-map
|
||||||
|
:states '(normal visual motion emacs insert)
|
||||||
|
:major-modes t
|
||||||
|
:prefix syd-localleader-key
|
||||||
|
:non-normal-prefix syd-alt-localleader-key
|
||||||
|
"m" `("Org-roam" . ,org-roam-mode-map)
|
||||||
|
"." #'consult-org-heading
|
||||||
|
"/" #'consult-org-agenda
|
||||||
|
"@" #'org-cite-insert
|
||||||
|
"e" #'org-export-dispatch
|
||||||
|
"f" #'org-footnote-action
|
||||||
|
"h" #'org-toggle-heading
|
||||||
|
"i" #'org-toggle-item
|
||||||
|
"I" #'org-id-get-create
|
||||||
|
"k" #'org-babel-remove-result
|
||||||
|
"l" `("Links" . ,syd-org-mode-links-map)))
|
||||||
|
|
||||||
(use-package org
|
(use-package org
|
||||||
:defer-incrementally
|
:defer-incrementally
|
||||||
calendar find-func format-spec org-macs org-compat org-faces org-entities
|
calendar find-func format-spec org-macs org-compat org-faces org-entities
|
||||||
org-list org-pcomplete org-src org-footnote org-macro ob org org-agenda
|
org-list org-pcomplete org-src org-footnote org-macro ob org org-agenda
|
||||||
org-capture
|
org-capture
|
||||||
|
:custom ((org-startup-folded 'content)
|
||||||
|
(org-directory "~/org"))
|
||||||
:preface
|
:preface
|
||||||
(defvar org-modules
|
(defvar org-modules
|
||||||
'(;; ol-w3m
|
'(;; ol-w3m
|
||||||
@@ -17,7 +134,48 @@
|
|||||||
;; ol-mhe
|
;; ol-mhe
|
||||||
;; ol-rmail
|
;; ol-rmail
|
||||||
;; ol-eww
|
;; ol-eww
|
||||||
)))
|
))
|
||||||
|
:config
|
||||||
|
(syd-add-hook 'org-mode-hook
|
||||||
|
#'org-indent-mode
|
||||||
|
#'syd-prose-mode)
|
||||||
|
(syd-org-init-faces)
|
||||||
|
(syd-org-init-keybinds))
|
||||||
|
|
||||||
|
(defun syd-org--init-roam-keybinds ()
|
||||||
|
)
|
||||||
|
|
||||||
|
(use-package org-roam
|
||||||
|
:hook (org-load . syd-org-init-roam-h)
|
||||||
|
:commands (org-roam-buffer-toggle-display
|
||||||
|
org-roam-dailies-find-date
|
||||||
|
org-roam-dailies-find-today
|
||||||
|
org-roam-dailies-find-tomorrow
|
||||||
|
org-roam-dailies-find-yesterday)
|
||||||
|
:init (progn (syd-org--init-roam-keybinds)
|
||||||
|
(syd-load-packages-incrementally
|
||||||
|
'(ansi-color dash f rx seq magit-section emacsql)))
|
||||||
|
:custom ((org-roam-directory org-directory)
|
||||||
|
(org-roam-db-location (file-name-concat syd-data-dir
|
||||||
|
"org-roam.db"))
|
||||||
|
;; Make org-roam buffer sticky; i.e. don't replace it when opening a
|
||||||
|
;; file with an *-other-window command.
|
||||||
|
(org-roam-buffer-window-parameters '((no-delete-other-windows . t)))
|
||||||
|
(org-roam-completion-everywhere t))
|
||||||
|
:config
|
||||||
|
(defun syd-org-init-roam-h ()
|
||||||
|
"Setup `org-roam' but don't immediately initialize its database.
|
||||||
|
Instead, initialize it when it will be actually needed."
|
||||||
|
(cl-letf (((symbol-function #'org-roam-db-sync) #'ignore))
|
||||||
|
(org-roam-db-autosync-enable)))
|
||||||
|
(defun syd-org-roam-try-init-db-a (&rest _)
|
||||||
|
"Try to initialize org-roam database at the last possible safe moment.
|
||||||
|
In case of failure, fail gracefully."
|
||||||
|
(message "Initializing org-roam database...")
|
||||||
|
(advice-remove 'org-roam-db-query #'syd-org-roam-try-init-db-a)
|
||||||
|
(org-roam-db-sync))
|
||||||
|
(advice-add #'org-roam-db-query
|
||||||
|
:before #'syd-org-roam-try-init-db-a))
|
||||||
|
|
||||||
(provide 'syd-org)
|
(provide 'syd-org)
|
||||||
;;; syd-org.el ends here
|
;;; syd-org.el ends here
|
||||||
|
|||||||
2
users/crumb/programs/emacs/projects
Normal file
2
users/crumb/programs/emacs/projects
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
;;; -*- lisp-data -*-
|
||||||
|
(("/persist/dots/"))
|
||||||
Reference in New Issue
Block a user