refactor(emacs): Simpler architecture for msyds emacs

This commit is contained in:
2025-08-11 16:20:25 -06:00
parent aad37f62a3
commit ce288fdbd9
43 changed files with 1016 additions and 382 deletions

View File

@@ -11,8 +11,11 @@
wifi.enable = true;
stylix.enable = true;
niri.enable = true;
steam.enable = true;
bluetooth.enable = true;
users.users = [
"crumb"
"msyds"
];
impermanence = {
@@ -101,6 +104,7 @@
environment.systemPackages = [
pkgs.neovim
pkgs.git
pkgs.waypipe
sydnix-cli.packages.x86_64-linux.default
];

View File

@@ -18,18 +18,3 @@ in {
};
};
}
{ pkgs, ... }:
let
device = "/dev/disk/by-id/ata-APPLE_SSD_SM0512G_S29ANYAH526520";
subvol = name: {
type = "btrfs";
inherit device;
options = ["subvol=${name}"];
};
in {
fileSystems."/" = subvol "rootfs";
fileSystems."/nix" = subvol "nix";
fileSystems."/persist" = subvol "persist";
fileSystems."/persist/home" = subvol "persist/home";
}

View File

@@ -69,3 +69,4 @@
(require 'syd-tramp)
(require 'syd-trust)
(require 'syd-ui)
(put 'narrow-to-region 'disabled nil)

View File

@@ -468,8 +468,7 @@ See https://lists.gnu.org/archive/html/emacs-orgmode/2019-07/msg00081.html."
;; Increase size of previews.
(org-latex-preview-appearance-options
(plist-put org-latex-preview-appearance-options :zoom 1.4)))
;; :hook (org-mode . org-latex-preview-auto-mode)
)
:hook (org-mode . org-latex-preview-mode))
(use-package org-appear
:hook (org-mode . org-appear-mode)

View File

@@ -206,10 +206,15 @@ in {
{ # Start with low width.
matches = [
{ app-id = "com\\.mitchellh\\.ghostty"; }
{ app-id = "^emacs$"; }
];
default-column-width.proportion = 1.0 / 3.0;
}
{
matches = [
{ app-id = "^emacs$"; }
];
default-column-width.fixed = 640;
}
{
# Enable rounded corners for all windows.
geometry-corner-radius =

View File

@@ -3,14 +3,18 @@
(add-to-list 'load-path
(file-name-concat user-emacs-directory "lisp"))
(defun syd-load-directory (dir)
"Load each file matching DIR/*.el in lexicographical order."
(dolist (file
;; The returned list is sorted, which is what we want. The files are
;; named with a two-digit prefix defining its load order.
(directory-files dir 'full "\\.el$"))
(load file)))
(defconst syd-init-load-order-seed
(or (when-let ((x (getenv "SYD_INIT_LOAD_ORDER_SEED")))
(string-to-number x))
(random))
"Seed used to load top-level modules in pseudo-random order. Loading modules
in an unpredictable order by default is a tactic to prevent implicit
dependencies between modules. For debugging purposes, the load-order may be
made deterministic by starting Emacs with the environment variable
SYD_INIT_LOAD_ORDER_SEED set to a non-negative integer.")
;; Load each file matching lisp/syd/early-init/*.el.
(syd-load-directory
(file-name-concat user-emacs-directory "lisp/syd/early-init"))
;; Log as early as possible to make it difficult to miss.
(message "Top-level modules will be loaded in the order determined by seed %d"
syd-init-load-order-seed)
(require 'syd/disable-package)

View File

@@ -1,5 +1,49 @@
;;; init.el -*- lexical-binding: t -*-
;; Load each file matching lisp/syd/init/*.el.
(syd-load-directory
(file-name-concat user-emacs-directory "lisp/syd/init"))
(require 'cl-lib)
(defconst syd-features
'(syd/base
syd/constants
syd/dash
syd/disable-package
syd/straight
syd/general
syd/kanagawa-palette
syd/on
syd/prelude
syd/use-package
syd/line-numbers
syd/kanagawa
syd/comint
syd/evil
syd/scrolling
syd/fonts
syd/frame
syd/risky-variables
syd/completion
syd/emacs-lisp
syd/vc
syd/compilation
syd/grep
syd/top-level-keymaps
syd/escape
syd/leader
syd/which-key))
(defun syd-random-permutation (lst &optional seed)
"Return a random permutation of list LST using SEED as the random state. The
permutation is deterministic for a given SEED."
(let* ((random-state (cl-make-random-state (or seed (random))))
(len (length lst))
(vec (vconcat lst)))
;; Fisher-Yates shuffle.
(cl-loop for i from (1- len) downto 1 do
(cl-rotatef (aref vec i)
(aref vec (cl-random (1+ i) random-state))))
;; Convert vector to list.
(append vec nil)))
(dolist (feature (syd-random-permutation syd-features
syd-init-load-order-seed))
(require feature))

View File

@@ -0,0 +1,15 @@
;;; base.el -*- lexical-binding: t -*-
;;; The bare minimum configuration expected to be present by the majority of
;;; components. The package manager, utility libraries, shared definitions,
;;; etc.
(require 'syd/constants)
(require 'syd/straight)
(require 'syd/use-package)
(require 'syd/general)
(require 'syd/on)
(require 'syd/dash)
(require 'syd/prelude)
(provide 'syd/base)

View File

@@ -1,15 +1,18 @@
;;; -*- lexical-binding: t; -*-
(with-eval-after-load 'comint
(require 'syd/kanagawa)
(require 'syd/base)
(defun syd-comint--set-theme ()
(require 'syd/kanagawa-palette)
(custom-theme-set-faces
'user
;; Default prompt face is very ugly. Give it a more subtle look.
`(comint-highlight-prompt
((t :foreground ,(syd-kanagawa-get 'old-white)
:background unspecified
:weight bold))))
:weight bold)))))
(defun syd-comint--set-keybinds ()
(general-def
:keymaps 'comint-mode-map
:states '(normal insert)
@@ -21,4 +24,8 @@
:states 'insert
"C-d" #'comint-delchar-or-maybe-eof))
(provide 'syd/init/comint)
(with-eval-after-load 'comint
(syd-comint--set-theme)
(syd-comint--set-keybinds))
(provide 'syd/comint)

View File

@@ -0,0 +1,11 @@
;;; -*- lexical-binding: t -*-
(setq
;; Log native-compiler warnings, but don't display the buffer. Most of the
;; warnings are "«symbol» is not known to be defined" which are typically
;; nothing worth concerning.
native-comp-async-report-warnings-errors 'silent
;; Scroll compilation buffer to follow output.
compilation-scroll-output t)
(provide 'syd/compilation)

View File

@@ -0,0 +1,164 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/base)
;;; Hide commands in M-x which do not work in the current mode
(setq read-extended-command-predicate
#'command-completion-default-include-p)
;;; Consult
;;;###autoload
(defun syd-enable-recentf-mode-a ()
"Used as :before advice for `consult-recent-file' to ensure recentf mode is
enabled."
;; REVIEW: Shall we take any extra precautions to only enable `recentf-mode'
;; if it was going to be enabled anyway?
(recentf-mode 1))
;; Consult adds various search and navigation tools using Emacs' completing-read
;; function; i.e., in our case, Vertico.
(use-package consult
:defer t
:config
(advice-add #'consult-recent-file
:before #'syd-enable-recentf-mode-a))
(use-package embark-consult
:after (embark consult))
;;; Vertico
;;;###autoload
(defun syd-vertico-embark-preview ()
"Previews candidate in vertico buffer, unless it's a consult command"
(interactive)
(unless (bound-and-true-p consult--preview-function)
(if (fboundp 'embark-dwim)
(save-selected-window
(let (embark-quit-after-action)
(embark-dwim)))
(user-error "Embark not installed, aborting..."))))
;; Vertico is a simple completion engine that replaces Emacs' built-in
;; completion engine, achieving Just Works™ compatibility. This is in contrast
;; to e.g. Helm and Ivy, which spawn ecosystems orthogonal to Emacs, and
;; diametrically-opposed to each other.
(use-package vertico
:hook (on-first-input . vertico-mode)
:general
(:keymaps 'vertico-map
"DEL" #'vertico-directory-delete-char
"C-SPC" #'syd-vertico-embark-preview
"C-j" #'vertico-next
"C-k" #'vertico-previous
"C-M-j" #'vertico-next-group
"C-M-k" #'vertico-previous-group)
(:keymaps 'vertico-map
:states 'normal
"j" #'vertico-next
"k" #'vertico-previous
"RET" #'vertico-exit)
:custom ((vertico-resize nil)
(vertico-count 17)
(vertico-cycle t))
:config
(setq-default completion-in-region-function #'consult-completion-in-region)
;; Cleans up path when moving directories with shadowed paths syntax, e.g.
;; cleans ~/foo/bar/// to /, and ~/foo/bar/~/ to ~/.
(add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy))
(defun syd-vertico-orderless-dispatch (pattern _index _total)
"Like `orderless-affix-dispatch', but allows affixes to be escaped.
Shamelessly stolen from Doom. }:3"
(let ((len (length pattern))
(alist orderless-affix-dispatch-alist))
(when (> len 0)
(cond
;; Ignore single dispatcher character
((and (= len 1) (alist-get (aref pattern 0) alist)) #'ignore)
;; Prefix
((when-let ((style (alist-get (aref pattern 0) alist))
((not (char-equal (aref pattern (max (1- len) 1)) ?\\))))
(cons style (substring pattern 1))))
;; Suffix
((when-let ((style (alist-get (aref pattern (1- len)) alist))
((not (char-equal (aref pattern (max 0 (- len 2))) ?\\))))
(cons style (substring pattern 0 -1))))))))
;;; Orderless
;; Orderless provides a completion style that divides the pattern into
;; space-separated components, and matches candidates that match all of the
;; components in any order. Each component can match in any one of several
;; ways: literally, as a regexp, as an initialism, in the flex style, or as
;; multiple word prefixes. By default, regexp and literal matches are enabled.
(use-package orderless
:after vertico
:custom ((completion-styles '(orderless basic))
(completion-category-overrides
'((file
(styles ;basic-remote
orderless partial-completion))))
(orderless-style-dispatchers '(syd-vertico-orderless-dispatch))
;; TODO: See Doom's `+vertico-orderless-dispatch'.
(orderless-affix-dispatch-alist
'((?! . orderless-without-literal)
(?& . orderless-annotation)
;; %1 -> {1, ₁, ꘡, ⒈, ...}
(?% . char-fold-to-regexp)
;; ,wcb -> {with-current-buffer, widget-convert-button, ...}
(?, . orderless-initialism)
(?= . orderless-literal)
(?^ . orderless-literal-prefix)
(?~ . orderless-flex)))))
;;;###autoload
(defun embark-which-key-indicator ()
"An embark indicator that displays keymaps using which-key. The which-key
help message will show the type and value of the current target followed by an
ellipsis if there are further targets."
(lambda (&optional keymap targets prefix)
(if (null keymap)
(which-key--hide-popup-ignore-command)
(which-key--show-keymap
(if (eq (plist-get (car targets) :type) 'embark-become)
"Become"
(format "Act on %s '%s'%s"
(plist-get (car targets) :type)
(embark--truncate-target (plist-get (car targets) :target))
(if (cdr targets) "" "")))
(if prefix
(pcase (lookup-key keymap prefix 'accept-default)
((and (pred keymapp) km) km)
(_ (key-binding prefix 'accept-default)))
keymap)
nil nil t (lambda (binding)
(not (string-suffix-p "-argument" (cdr binding))))))))
;; TODO: Mark the Embark export buffer as a popup.
(use-package embark
:after vertico
:defer t
:custom ((which-key-use-C-h-commands nil)
(prefix-help-command #'embark-prefix-help-command)
;; Embark uses their own custom interface that is essentially
;; equivalent to which-key; just use which-key. }:)
(embark-indicators '(embark-which-key-indicator)))
:general
(:keymaps 'minibuffer-local-map
"C-;" `("Actions" . ,#'embark-act))
(:keymaps 'syd-leader-map
"a" `("Actions" . ,#'embark-act)))
(provide 'syd/completion)

View File

@@ -0,0 +1,15 @@
;;; -*- lexical-binding: t -*-
(require 'xdg)
(defvar syd-data-dir
(or (getenv "EMACS_DATA_DIR")
(file-name-concat (xdg-state-home)
"emacs")))
(defvar syd-cache-dir
(or (getenv "EMACS_CACHE_DIR")
(file-name-concat (xdg-cache-home)
"emacs")))
(provide 'syd/constants)

View File

@@ -0,0 +1,8 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/straight)
(require 'syd/use-package)
(use-package dash)
(provide 'syd/dash)

View File

@@ -2,4 +2,4 @@
(setq package-enable-at-startup nil)
(provide 'syd/early-init/disable-package)
(provide 'syd/disable-package)

View File

@@ -1,15 +0,0 @@
;;; -*- lexical-binding: t -*-
(defvar syd-data-dir
(or (getenv "EMACS_DATA_DIR")
(file-name-concat (or (getenv "XDG_DATA_HOME")
(expand-file-name "~/.local/share"))
"emacs")))
(defvar syd-cache-dir
(or (getenv "EMACS_CACHE_DIR")
(file-name-concat (or (getenv "XDG_CACHE_HOME")
(expand-file-name "~/.cache"))
"emacs")))
(provide 'syd/early-init/define-constants)

View File

@@ -1,5 +1,8 @@
;;; -*- lexical-binding: t -*-
(require 'syd/disable-package)
(require 'syd/constants)
;;; Installation
@@ -47,12 +50,12 @@
(elpaca `(,@elpaca-order))
;;; Use-package support
;;; Support for `use-package'
;; Install use-package support.
;; Install `use-package' support.
(elpaca elpaca-use-package
(elpaca-use-package-mode))
(provide 'syd/init/elpaca)
(provide 'syd/elpaca)

View File

@@ -1,5 +1,9 @@
;;; -*- lexical-binding: t -*-
(with-eval-after-load 'evil-surround
;; In Elisp, `' is a much more common pair than ``.
(add-hook 'emacs-lisp-mode-hook
(lambda ()
(push '(?` . ("`" . "'")) evil-surround-pairs-alist))))
(provide 'syd/emacs-lisp)

View File

@@ -0,0 +1,63 @@
;;; -*- lexical-binding: t; -*-
(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)))))))
;;; Hacks
(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/escape)

View File

@@ -1,11 +1,17 @@
;;; -*- lexical-binding: t; -*-
;;; syd-evil.el -*- lexical-binding: t; -*-
(require 'syd/base)
(require 'syd/leader)
(require 'syd/escape)
;; More sensible undo functionality. Emacs' default is very weird, not
;; maintaining a proper history.
;; (use-package undo-fu)
;; Vim emulation.
(use-package evil
:preface
@@ -32,11 +38,12 @@
;; Only do highlighting in selected window so that Emacs has less work
;; to do highlighting them all.
evil-ex-interactive-search-highlight 'selected-window
;; It's infuriating that innocuous "beginning of line" or "end of line"
;; errors will abort macros, so we suppress them:
;; It's is frustrating how innocuous "beginning of line" or "end of
;; line" errors will abort macros, so we suppress them:
evil-kbd-macro-suppress-motion-error t
evil-undo-system (cond ((featurep 'undo-tree) 'undo-tree)
((featurep 'undo-fu) 'undo-fu)))
((featurep 'undo-fu) 'undo-fu)
(t 'undo-redo)))
;; These two are required for evil-collection.
(setq evil-want-keybinding nil
evil-want-integration t)
@@ -80,6 +87,9 @@ Otherwise, nil."
(evil-mode 1))
;;; Evil-collection
;; A large, community-sourced collection of preconfigured Evil-mode
;; integrations.
(use-package evil-collection
@@ -215,6 +225,9 @@ modules."
mode
:disabled-modules syd-evil-collection-disabled-list))))))))
;;; Surround.vim
;; Tim Pope's famous `surround.vim' for Evil.
(use-package evil-surround
:commands (global-evil-surround-mode
@@ -223,6 +236,9 @@ modules."
evil-surround-region)
:hook (on-first-input . global-evil-surround-mode))
;;; Escape with 'jk'
;; TODO: I'd like JK to escape visual state. evil-escape only allows defining a
;; single key sequence. Perhaps key-chord is capable of this?
(use-package evil-escape
@@ -231,6 +247,9 @@ modules."
(evil-escape-excluded-states '(normal visual multiedit emacs motion))
(evil-escape-delay 0.15)))
;;; Commentary.vim
;; `evil-nerd-commenter' has a bunch of cool functions[1]. Here, only the Evil
;; operator is used. }:3
;; [1]: https://github.com/redguardtoo/evil-nerd-commenter?tab=readme-ov-file#commands-and-hotkeys
@@ -251,11 +270,17 @@ modules."
:config
(evil-embrace-enable-evil-surround-integration))
;;; Swap the contents of two given regions
;; Provides an Evil operator to swap two spans of text.
(use-package evil-exchange
:bind (:map evil-normal-state-map ("gX" . evil-exchange)
:map evil-visual-state-map ("gX" . evil-exchange)))
;;; Vim's 'C-a' / 'C-x' (increment/decrement number at point)
;; Evil doesn't ship with support for Vim's 'g-'/'g+'. `evil-numbers'
;; implements this.
(use-package evil-numbers
@@ -265,11 +290,15 @@ modules."
:map evil-normal-state-map ("g-" . 'evil-numbers/dec-at-pt))
:defer t)
;; Tree-sitter queries → Evil text objects.
(use-package evil-textobj-tree-sitter
:defer t)
;; Visually "flash" the region acted upon by Evil-mode operations.
;;; Visually "flash" the region acted upon by Evil-mode operations
(use-package evil-goggles
:hook (on-first-input . evil-goggles-mode)
;; The flash animation will delay actions, which can be very annoying for some
@@ -279,6 +308,9 @@ modules."
(evil-goggles-enable-change nil)
(evil-goggles-duration 0.1)))
;;; Fix cursor
;; Change cursor shape and color by evil state in terminal.
(use-package evil-terminal-cursor-changer
;; This package is only useful in the terminal.
@@ -286,11 +318,16 @@ modules."
:defer t
:hook (on-first-input . evil-terminal-cursor-changer-activate))
;; Automatic alignment in region, by regexp.
;;; Automatic alignment in region, by regexp.
(use-package evil-lion
:hook (on-first-input . evil-lion-mode))
;; 'g' text object selecting the entire buffer.
;;; "Entire buffer" text object
;; 'g' text object selecting the entire visible buffer.
(with-eval-after-load 'evil
(evil-define-text-object
evil-entire-buffer (count &optional beg end type)
@@ -299,18 +336,21 @@ modules."
(define-key evil-inner-text-objects-map "g" #'evil-entire-buffer)
(define-key evil-outer-text-objects-map "g" #'evil-entire-buffer))
;; 2-character search.
;;; Enhanced 'f'/'t'
(use-package evil-snipe
:commands (evil-snipe-local-mode evil-snipe-override-local-mode)
:hook ((on-first-input . evil-snipe-override-mode)
;; (on-first-input . evil-snipe-mode)
)
:hook ((on-first-input . evil-snipe-override-mode))
:custom ((evil-snipe-smart-case t)
(evil-snipe-scope 'visible)
(evil-snipe-repeat-scope 'visible)
(evil-snipe-char-fold t)))
;; Evil's default behaviour for '#'/'*' in visual state will remain in visual
;;; Fix visual-state '#' / '*' to use region
;; Evil's default behaviour for '#' / '*' in visual state will remain in visual
;; mode, and jump to the next occurence of the symbol under point. That is, the
;; movement is exactly the same as it is in normal state; if the region is over
;; the text `two words`, but the point is over `two`, Evil will search for
@@ -320,6 +360,50 @@ modules."
:bind (:map evil-visual-state-map
("*" . evil-visualstar/begin-search-forward)))
;;; Miscellaneous keybinds
;; Up/down with 'C-k'/'C-j'
(general-def
:keymaps 'evil-ex-completion-map
"C-k" #'previous-history-element
"C-j" #'next-history-element)
(defun syd-insert-newline-above (count)
"Insert a blank line below the current line."
(interactive "p")
(dotimes (_ count)
(let ((point-was-at-bol-p (= (current-column) 0)))
(save-excursion
(evil-insert-newline-above))
;; Special case: with `syd-insert-newline-above' is called with point at
;; BOL, the point unexpectedly fails to "stick" to its original position.
(when point-was-at-bol-p
(next-line)))))
;;;###autoload
(defun syd-insert-newline-below (count)
"Insert a blank line below the current line."
(interactive "p")
(dotimes (_ count)
(save-excursion (evil-insert-newline-below))))
(general-def
:states 'motion
"[ b" #'previous-buffer
"] b" #'next-buffer
"] SPC" #'syd-insert-newline-below
"[ SPC" #'syd-insert-newline-above)
(general-def
:keymaps 'global-map
:states 'motion
"M-:" #'eval-expression
"M-x" #'execute-extended-command)
;;; Save the last 'M-x eval-expression' input to an Evil register.
(defvar syd-evil-last-eval-expression-register ?e
"An Evil-mode register in which the last expression evaluated with an
interactive call to `eval-expression' is stored.")
@@ -335,6 +419,8 @@ interactive call to `eval-expression' is stored.")
(advice-add #'eval-expression
:after #'syd-set-eval-expression-register-a))
;; HACK: '=' unpredictably moves the cursor when it really doesn't need to.
(defun syd-evil-dont-move-point-a (fn &rest args)
"Used as :around advice on Evil operators to avoid moving the point."
@@ -345,6 +431,8 @@ interactive call to `eval-expression' is stored.")
(advice-add #'evil-indent
:around #'syd-evil-dont-move-point-a))
;(use-package evil-leap
; :hook (on-first-input . evil-leap-mode)
; :load-path "/home/crumb/src/evil-leap"
@@ -355,4 +443,6 @@ interactive call to `eval-expression' is stored.")
; :config
; (evil-leap-install-default-keybindings))
(provide 'syd/init/evil)
(provide 'syd/evil)

View File

@@ -22,14 +22,14 @@
:width 'normal :weight 'normal
:slant 'normal :font font))))
(let ((hook (if (daemonp)
(let ((hook-point (if (daemonp)
'server-after-make-frame-hook
'after-init-hook)))
(add-hook hook #'syd-init-fonts-h))
(add-hook hook-point #'syd-init-fonts-h -10))
;; Use JuliaMono as a fallback for some glyphs that VictorMono does not cover.
(dolist (char-range '((#x0250 . #x02af) ; IPA extensions
(#x2200 . #x22FF))) ; Mathematical operators
(set-fontset-font "fontset-default" char-range "JuliaMono"))
(provide 'syd/init/fonts)
(provide 'syd/fonts)

View File

@@ -0,0 +1,11 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/base)
;; Display form-feed characters (typically rendered as ^L) as full-line
;; horizontal rules.
(use-package form-feed-st
:hook ((prog-mode . form-feed-st-mode)
(text-mode . form-feed-st-mode)))
(provide 'syd/form-feeds)

View File

@@ -0,0 +1,28 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/base)
(require 'syd/fonts)
(let ((hook (if (daemonp)
'server-after-make-frame-hook
'after-init-hook)))
(syd-add-hook hook
(defun syd-configure-default-frame-h ()
"Customise the default frame."
(modify-all-frames-parameters
'(;; Disable the titlebar and borders (decorations).
(undecorated . t)
;; Set the frame size to a little over 80 columns (to account for the
;; margin on the left-hand side of the screen).
(width . (text-pixels . 1060))))
;; Disable the menu bar, tool bar, and blinking cursor.
(menu-bar-mode -1)
(tool-bar-mode -1)
(blink-cursor-mode -1)
;; Allow `fit-window-to-buffer' to make horizontal adjustments.
(setq fit-window-to-buffer-horizontally t))))
(provide 'syd/frame)
123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789

View File

@@ -0,0 +1,11 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/straight)
(use-package general
:custom (general-use-package-emit-autoloads t)
:demand t)
(require 'general)
(provide 'syd/general)

View File

@@ -0,0 +1,7 @@
;;; -*- lexical-binding: t -*-
;; I don't like that `grep' asks me to save unsaved files. It makes
;; me think it's about to kill my buffers.
(setq grep-save-buffers nil)
(provide 'syd/grep)

View File

@@ -1,111 +0,0 @@
;;; -*- lexical-binding: t; -*-
(use-package general
:custom (general-use-package-emit-autoloads t)
:ensure (:wait t))
(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/init/general)

View File

@@ -1,15 +0,0 @@
;;; -*- lexical-binding: t; -*-
(defun syd-configure-default-frame-h ()
"Customise the default frame, primarily by adding to `default-frame-alist'."
;; Maximise the frame.
;; (add-to-list 'default-frame-alist '(fullscreen . maximized))
;; Disable the titlebar and borders (decorations).
(add-to-list 'default-frame-alist '(undecorated . t)))
(let ((hook (if (daemonp)
'server-after-make-frame-hook
'after-init-hook)))
(add-hook hook #'syd-configure-default-frame-h))
(provide 'syd/init/default-frame)

View File

@@ -1,7 +0,0 @@
;;; syd-ui.el -*- lexical-binding: t; -*-
(use-package kanagawa-themes
:config
(load-theme 'kanagawa-wave t))
(provide 'syd/init/kanagawa)

View File

@@ -1,44 +0,0 @@
;;; -*- lexical-binding: t; -*-
(syd-add-hook 'prog-mode-hook
;; Display (relative) line numbers only in prog-mode derivatives.
(defun syd-prog-mode-line-numbers-h ()
(display-line-numbers-mode 1)))
(setq display-line-numbers-type 'relative
;; Always ask "y/n"; never "yes/no".
use-short-answers t
;; Scroll compilation buffer to follow output.
compilation-scroll-output t
;; Allow `fit-window-to-buffer' to make horizontal adjustments.
fit-window-to-buffer-horizontally t
;; I don't like that `grep' asks me to save unsaved files. It makes
;; me think it's about to kill my buffers.
grep-save-buffers nil
;; The default value is `ask', meaning that Emacs will ask for
;; confirmation any time you follow a symlink to a file under version
;; control. The documentation claims this is "dangerous, and
;; probably not what you want;" I personally don't see it, and it's
;; usually what I want.
vc-follow-symlinks t
;; Log native-compiler warnings, but don't display the
;; buffer. Most of the warnings are "`X' is not known to
;; be defined" which are typically nothing worth concerning.
native-comp-async-report-warnings-errors 'silent
;; Don't recenter the view unless >10 lines are scrolled off-screen
;; in a single movement.
scroll-conservatively 10
;; In modes making use of `recenter-top-bottom' (e.g. Comint,
;; Eshell), this will make the command behave more like a plain old
;; `clear` invocation.
recenter-positions '(top))
;; Disable the menu bar, scroll bar, and tool bar.
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1)
;; Remember allowed risky variabled.
(advice-add 'risky-local-variable-p :override #'ignore)
(provide 'syd/init/ui)

View File

@@ -0,0 +1,133 @@
;;; -*- lexical-binding: t; -*-
;;; Rationale: I need direct access to the Kanagawa palette, which kanagawa.el
;;; does not provide.
(defvar syd-kanagawa-palette (make-hash-table :test 'eq :size 130))
(defvar syd-kanagawa-palette-list
'((sumi-ink-0 "#16161D")
(sumi-ink-1 "#181820")
(sumi-ink-2 "#1a1a22")
(sumi-ink-3 "#1F1F28")
(sumi-ink-4 "#2A2A37")
(sumi-ink-5 "#363646")
(sumi-ink-6 "#54546D") ; fg
;; Popup and Floats
(wave-blue-1 "#223249")
(wave-blue-2 "#2D4F67")
;; Diff and Git
(winter-green "#2B3328")
(winter-yellow "#49443C")
(winter-red "#43242B")
(winter-blue "#252535")
(autumn-green "#76946A")
(autumn-red "#C34043")
(autumn-yellow "#DCA561")
;; Diag
(samurai-red "#E82424")
(ronin-yellow "#FF9E3B")
(wave-aqua-1 "#6A9589")
(dragon-blue "#658594")
;; Fg and Comments
(old-white "#C8C093")
(fuji-white "#DCD7BA")
(fuji-gray "#727169")
(oni-violet "#957FB8")
(oni-violet-2 "#b8b4d0")
(crystal-blue "#7E9CD8")
(spring-violet-1 "#938AA9")
(spring-violet-2 "#9CABCA")
(spring-blue "#7FB4CA")
(light-blue "#A3D4D5")
(wave-aqua-2 "#7AA89F") ;; improve lightness: desaturated greenish Aqua
(spring-green "#98BB6C")
(boat-yellow-1 "#938056")
(boat-yellow-2 "#C0A36E")
(carp-yellow "#E6C384")
(sakura-pink "#D27E99")
(wave-red "#E46876")
(peach-red "#FF5D62")
(surimi-orange "#FFA066")
(katana-gray "#717C7C")
(dragon-black-0 "#0d0c0c")
(dragon-black-1 "#12120f")
(dragon-black-2 "#1D1C19")
(dragon-black-3 "#181616")
(dragon-black-4 "#282727")
(dragon-black-5 "#393836")
(dragon-black-6 "#625e5a")
(dragon-white "#c5c9c5")
(dragon-green "#87a987")
(dragon-green-2 "#8a9a7b")
(dragon-pink "#a292a3")
(dragon-orange "#b6927b")
(dragon-orange-2 "#b98d7b")
(dragon-gray "#a6a69c")
(dragon-gray1 "#9e9b93")
(dragon-gray-3 "#7a8382")
(dragon-blue-2 "#8ba4b0")
(dragon-violet "#8992a7")
(dragon-red "#c4746e")
(dragon-aqua "#8ea4a2")
(dragon-ash "#737c73")
(dragon-teal "#949fb5")
(dragon-yellow "#c4b28a")
(lotus-ink-1 "#545464")
(lotus-ink-2 "#43436c")
(lotus-gray "#dcd7ba")
(lotus-gray-2 "#716e61")
(lotus-gray-3 "#8a8980")
(lotus-white-0 "#d5cea3")
(lotus-white-1 "#dcd5ac")
(lotus-white-2 "#e5ddb0")
(lotus-white-3 "#f2ecbc")
(lotus-white-4 "#e7dba0")
(lotus-white-5 "#e4d794")
(lotus-violet-1 "#a09cac")
(lotus-violet-2 "#766b90")
(lotus-violet-3 "#c9cbd1")
(lotus-violet-4 "#624c83")
(lotus-blue-1 "#c7d7e0")
(lotus-blue-2 "#b5cbd2")
(lotus-blue-3 "#9fb5c9")
(lotus-blue-4 "#4d699b")
(lotus-blue-5 "#5d57a3")
(lotus-green "#6f894e")
(lotus-green-2 "#6e915f")
(lotus-green-3 "#b7d0ae")
(lotus-pink "#b35b79")
(lotus-orange "#cc6d00")
(lotus-orange2 "#e98a00")
(lotus-yellow "#77713f")
(lotus-yellow-2 "#836f4a")
(lotus-yellow-3 "#de9800")
(lotus-yellow-4 "#f9d791")
(lotus-red "#c84053")
(lotus-red-2 "#d7474b")
(lotus-red-3 "#e82424")
(lotus-red-4 "#d9a594")
(lotus-aqua "#597b75")
(lotus-aqua-2 "#5e857a")
(lotus-teal-1 "#4e8ca2")
(lotus-teal-2 "#6693bf")
(lotus-teal-3 "#5a7785")
(lotus-cyan "#d7e3d8")))
(cl-loop for (k v) in syd-kanagawa-palette-list
do (puthash k v syd-kanagawa-palette))
(defun syd-kanagawa-get (k)
(gethash k syd-kanagawa-palette nil))
(provide 'syd/kanagawa-palette)

View File

@@ -1,133 +1,9 @@
;;; -*- lexical-binding: t; -*-
;;; Rationale: I need direct access to the Kanagawa palette, which kanagawa.el
;;; does not provide.
(require 'syd/base)
(defvar syd-kanagawa-palette (make-hash-table :test 'eq :size 130))
(defvar syd-kanagawa-palette-list
'((sumi-ink-0 "#16161D")
(sumi-ink-1 "#181820")
(sumi-ink-2 "#1a1a22")
(sumi-ink-3 "#1F1F28")
(sumi-ink-4 "#2A2A37")
(sumi-ink-5 "#363646")
(sumi-ink-6 "#54546D") ; fg
;; Popup and Floats
(wave-blue-1 "#223249")
(wave-blue-2 "#2D4F67")
;; Diff and Git
(winter-green "#2B3328")
(winter-yellow "#49443C")
(winter-red "#43242B")
(winter-blue "#252535")
(autumn-green "#76946A")
(autumn-red "#C34043")
(autumn-yellow "#DCA561")
;; Diag
(samurai-red "#E82424")
(ronin-yellow "#FF9E3B")
(wave-aqua-1 "#6A9589")
(dragon-blue "#658594")
;; Fg and Comments
(old-white "#C8C093")
(fuji-white "#DCD7BA")
(fuji-gray "#727169")
(oni-violet "#957FB8")
(oni-violet-2 "#b8b4d0")
(crystal-blue "#7E9CD8")
(spring-violet-1 "#938AA9")
(spring-violet-2 "#9CABCA")
(spring-blue "#7FB4CA")
(light-blue "#A3D4D5")
(wave-aqua-2 "#7AA89F") ;; improve lightness: desaturated greenish Aqua
(spring-green "#98BB6C")
(boat-yellow-1 "#938056")
(boat-yellow-2 "#C0A36E")
(carp-yellow "#E6C384")
(sakura-pink "#D27E99")
(wave-red "#E46876")
(peach-red "#FF5D62")
(surimi-orange "#FFA066")
(katana-gray "#717C7C")
(dragon-black-0 "#0d0c0c")
(dragon-black-1 "#12120f")
(dragon-black-2 "#1D1C19")
(dragon-black-3 "#181616")
(dragon-black-4 "#282727")
(dragon-black-5 "#393836")
(dragon-black-6 "#625e5a")
(dragon-white "#c5c9c5")
(dragon-green "#87a987")
(dragon-green-2 "#8a9a7b")
(dragon-pink "#a292a3")
(dragon-orange "#b6927b")
(dragon-orange-2 "#b98d7b")
(dragon-gray "#a6a69c")
(dragon-gray1 "#9e9b93")
(dragon-gray-3 "#7a8382")
(dragon-blue-2 "#8ba4b0")
(dragon-violet "#8992a7")
(dragon-red "#c4746e")
(dragon-aqua "#8ea4a2")
(dragon-ash "#737c73")
(dragon-teal "#949fb5")
(dragon-yellow "#c4b28a")
(lotus-ink-1 "#545464")
(lotus-ink-2 "#43436c")
(lotus-gray "#dcd7ba")
(lotus-gray-2 "#716e61")
(lotus-gray-3 "#8a8980")
(lotus-white-0 "#d5cea3")
(lotus-white-1 "#dcd5ac")
(lotus-white-2 "#e5ddb0")
(lotus-white-3 "#f2ecbc")
(lotus-white-4 "#e7dba0")
(lotus-white-5 "#e4d794")
(lotus-violet-1 "#a09cac")
(lotus-violet-2 "#766b90")
(lotus-violet-3 "#c9cbd1")
(lotus-violet-4 "#624c83")
(lotus-blue-1 "#c7d7e0")
(lotus-blue-2 "#b5cbd2")
(lotus-blue-3 "#9fb5c9")
(lotus-blue-4 "#4d699b")
(lotus-blue-5 "#5d57a3")
(lotus-green "#6f894e")
(lotus-green-2 "#6e915f")
(lotus-green-3 "#b7d0ae")
(lotus-pink "#b35b79")
(lotus-orange "#cc6d00")
(lotus-orange2 "#e98a00")
(lotus-yellow "#77713f")
(lotus-yellow-2 "#836f4a")
(lotus-yellow-3 "#de9800")
(lotus-yellow-4 "#f9d791")
(lotus-red "#c84053")
(lotus-red-2 "#d7474b")
(lotus-red-3 "#e82424")
(lotus-red-4 "#d9a594")
(lotus-aqua "#597b75")
(lotus-aqua-2 "#5e857a")
(lotus-teal-1 "#4e8ca2")
(lotus-teal-2 "#6693bf")
(lotus-teal-3 "#5a7785")
(lotus-cyan "#d7e3d8")))
(cl-loop for (k v) in syd-kanagawa-palette-list
do (puthash k v syd-kanagawa-palette))
(defun syd-kanagawa-get (k)
(gethash k syd-kanagawa-palette nil))
(use-package kanagawa-themes
:config
(load-theme 'kanagawa-wave t))
(provide 'syd/kanagawa)

View File

@@ -0,0 +1,65 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/straight)
(require 'syd/general)
;;; Options
(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")
;;; Define the leader key
;; 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)
(with-eval-after-load 'evil
;; 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)
(provide 'syd/leader)

View File

@@ -0,0 +1,13 @@
;;; line-numbers.el -*- lexical-binding: t -*-
(require 'syd/prelude)
(syd-add-hook 'prog-mode-hook
;; Display line numbers only in prog-mode derivatives.
(defun syd-prog-mode-line-numbers-h ()
(display-line-numbers-mode 1)))
;; Display line numbers relative to the line on which the cursor resides.
(setq display-line-numbers-type 'relative)
(provide 'syd/line-numbers)

View File

@@ -0,0 +1,15 @@
;;; -*- lexical-binding: t; -*-
(setq
;; Always ask "y/n"; never "yes/no".
use-short-answers t
;; Allow new minibuffers to be opened from inside existing minibuffers.
enable-recursive-minibuffers t)
;; Up/down with 'C-k'/'C-j'.
(general-def
:keymaps '(minibuffer-local-map minibuffer-mode-map read--expression-map)
"C-k" #'previous-history-element
"C-j" #'next-history-element)
(provide 'syd/minibuffer)

View File

@@ -0,0 +1,35 @@
;; -*- lexical-binding: t; -*-
(require 'syd/use-package)
(require 'syd/straight)
;; My friend Nova
;; This is my friend Nova. She has to have her own page to spread her spores
;; in. Y^,..,^Y
;;⠀⠀⣄⠀⠀⠀⠀⠀⠀⢠⠖⠒⠒⠒⢄⠀⠀⠀⠀⢀⢖⡆⠀⠀⠀
;;⠀⠀⡇⠑⣄⠀⠀⠀⠀⠯⣀⡀⠀⢀⣨⠆⠀⠀⢀⠎⢸⠀⠀⠀⠀
;;⠀⠀⢹⠀⠈⠓⢄⣀⡠⠤⠤⡇⠀⢸⠤⣄⡀⣠⠎⠀⢸⠀⠀⠀⠀
;;⠀⠀⠸⡀⢀⡔⠉⠹⠄⠀⠴⠧⠤⢼⣀⠀⠈⠳⡄⠀⢸⠀⠀⠀⠀
;;⠀⠀⠀⢣⡞⠀⠀⠀⣀⣀⡀⠀⠀⠀⢀⣄⡀⠀⠘⢦⢸⠀⠀⠀⠀
;;⠀⠀⠀⠀⡇⠀⠀⠐⠁⠀⠙⠀⠀⠀⠋⠀⠙⠀⠀⠈⣿⠄⠀⠀⠀
;;⠀⠀⠀⠀⢳⡀⠀⠀⠀⠀⠀⣠⣄⠀⠀⠀⠀⠀⠀⠈⢹⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⠱⣄⠀⠀⠀⠀⠻⠟⠀⠀⠀⠀⠀⢀⣠⠏⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⢺⡉⠀⠀⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⢠⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⡀⠀⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠞⠀⠀⠀⠀
;; `on.el' provides a collection of utility hooks and functions ported
;; from Doom Emacs. The hooks make it easier to speed up Emacs
;; startup by providing finer-grained control of the timing at which
;; packages are loaded.
(use-package on
:straight (:type git
:host gitlab
:repo "crumbtoo/on.el")
:demand t)
(provide 'syd/on)

View File

@@ -1,8 +1,7 @@
;;; -*- lexical-binding: t; -*-
(eval-when-compile (require 'cl-lib))
(use-package dash :ensure (:wait t))
(require 'dash)
(require 'syd/dash)
(cl-defmacro syd-define-stub
(name &key (desc "implement me!") interactive)
@@ -173,4 +172,4 @@ form."
;; (user-error (concat "Ignoring a call to `lsp-install-server'"
;; " — tell the caller to use Nix!")))
(provide 'syd/init/prelude)
(provide 'syd/prelude)

View File

@@ -0,0 +1,6 @@
;;; -*- lexical-binding: t; -*-
;; Remember risky variables marked as allowed.
(advice-add 'risky-local-variable-p :override #'ignore)
(provide 'syd/risky-variables)

View File

@@ -0,0 +1,20 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/base)
(setq
;; In modes making use of `recenter-top-bottom' (e.g. Comint,
;; Eshell), this will make the command behave more like a plain old
;; `clear` invocation.
recenter-positions '(top)
;; Don't recenter the view after a jump unless >10 lines are scrolled
;; off-screen in a single movement.
scroll-conservatively 10)
;; Smooth scrolling: scroll the view pixel-by-pixel instead of line-by-line.
(use-package ultra-scroll
:init
(setq scroll-margin 0) ; important: scroll-margin>0 not yet supported
:hook (on-init-ui . ultra-scroll-mode))
(provide 'syd/scrolling)

View File

@@ -0,0 +1,41 @@
;;; -*- lexical-binding: t -*-
(require 'syd/disable-package)
(require 'syd/constants)
;;; Installation
;; Code per Straight's installation instructions available at
;; https://github.com/progfolio/elpaca?tab=readme-ov-file#installer.
;; Modified to avoid polluting the Emacs user directory.
(defvar straight-base-dir syd-data-dir)
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name
"straight/repos/straight.el/bootstrap.el"
(or (bound-and-true-p straight-base-dir)
user-emacs-directory)))
(bootstrap-version 7))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
;;; Integration with `use-package'
(straight-use-package 'use-package)
(setq straight-use-package-by-default t)
(provide 'syd/straight)

View File

@@ -0,0 +1,102 @@
;;; base.el -*- lexical-binding: t -*-
;;; This file defines the most common and most general keymaps which are
;;; frequently extended by other modules. Examples include the leader keymap,
;;; local-leader keymap, and the respective keymaps for window, file, and buffer
;;; operations.
(require 'syd/general)
(require 'syd/leader)
(general-def
:prefix-map 'syd-leader-buffer-map
"k" `("Kill buffer" . ,#'kill-current-buffer)
"i" `("IBuffer" . ,#'ibuffer)
"C" `("Clone (indirect) buffer O/W" . ,#'clone-indirect-buffer-other-window)
"c" `("Clone (indirect) buffer" . ,#'clone-indirect-buffer)
"r" `("Revert buffer" . ,#'revert-buffer))
(general-def
:prefix-map 'syd-leader-search-map
"i" `("IMenu" . ,#'consult-imenu))
(general-def
:prefix-map 'syd-leader-file-map
"r" `("Browse recent file" . ,#'consult-recent-file))
(general-def
:prefix-map 'syd-leader-window-map
"h" `("Select window left" . ,#'evil-window-left)
"j" `("Select window below" . ,#'evil-window-down)
"k" `("Select window above" . ,#'evil-window-up)
"l" `("Select window right" . ,#'evil-window-right)
"T" `("Tear off window" . ,#'tear-off-window)
"=" `("Balance windows" . ,#'balance-windows)
"v" `("Vertical split" . ,#'evil-window-vsplit)
"s" `("Horizontal split" . ,#'evil-window-split)
"F" `("Fit window to contents" . ,#'fit-window-to-buffer)
"r" `("Rotate window downwards" . ,#'evil-window-rotate-downwards)
"R" `("Rotate window upwards" . ,#'evil-window-rotate-upwards))
(general-def
:prefix-map 'syd-leader-open-map)
(general-def
:prefix-map 'syd-leader-project-map
"C" `("Compile project" . ,#'project-compile)
"&" `("Async cmd in project root" . ,#'project-async-shell-command)
"p" `("Switch project" . ,#'project-switch-project)
"." `("Browse project from root" . ,#'syd-project-root-find-file))
(general-def
:prefix-map 'syd-leader-help-package-map
"u" `("Temporarily install package" . ,#'straight-use-package)
"v" `("Browse package repo" . ,#'straight-visit-package))
(general-def
:prefix-map 'help-map
"F" #'describe-face
"'" #'describe-char
"T" #'consult-theme
"p" `("Packages" . ,syd-leader-help-package-map))
(general-def
:prefix-map 'syd-leader-notes-map)
(general-def
:prefix-map 'syd-leader-code-map)
(general-def
:prefix-map 'syd-leader-insert-map
"u" #'insert-char
"e" #'emoji-insert)
;; This is necessary to properly rebind `universal-argument'.
;; `universal-argument-more' is a command that provides additional prefixes
;; after the first. Without it, the first 'C-u' will be interpreted as a
;; prefix argument for the second 'C-u'.
(general-def
:keymaps 'universal-argument-map
"SPC u" #'universal-argument-more
"u" #'universal-argument-more)
(general-def
:keymaps 'syd-leader-map
"." #'find-file
"SPC" `("Find file in project" . ,#'project-find-file)
"x" `("Open scratch buffer" . ,#'scratch-buffer)
"u" `("Universal argument" . ,#'universal-argument)
"b" `("Buffer" . ,syd-leader-buffer-map)
"o" `("Open" . ,syd-leader-open-map)
"p" `("Project" . ,syd-leader-project-map)
"w" `("Window" . ,syd-leader-window-map)
"f" `("File" . ,syd-leader-file-map)
"s" `("Search" . ,syd-leader-search-map)
"h" `("Help" . ,help-map)
"n" `("Notes" . ,syd-leader-notes-map)
"i" `("Insert" . ,syd-leader-insert-map)
"c" `("Code" . ,syd-leader-code-map)
"," `("Switch buffer in project" . ,#'consult-project-buffer)
"<" `("Switch buffer" . ,#'consult-buffer))
(provide 'syd/top-level-keymaps)

View File

@@ -101,8 +101,6 @@ If this is a daemon session, load them all immediately instead."
(append targets (list name)))))
(use-package-process-keywords name rest state))))
;; Set `:ensure t` by default.
(require 'use-package-ensure)
(setq use-package-always-ensure t)
(provide 'syd/init/use-package)
(provide 'syd/use-package)

View File

@@ -0,0 +1,9 @@
;;; init.el -*- lexical-binding: t -*-
;; The default value is `ask', meaning that Emacs will ask for confirmation any
;; time you follow a symlink to a file under version control. The documentation
;; claims this is "dangerous, and probably not what you want;" I personally
;; don't see it, and it's usually what I want.
(setq vc-follow-symlinks t)
(provide 'syd/vc)

View File

@@ -0,0 +1,12 @@
;;; -*- lexical-binding: t; -*-
(require 'syd/base)
;; Show possible completions for a partially-entered key sequence.
(use-package which-key
;; BUG: (#4) If the first input is a prefix key, `which-key-mode' won't be
;; activated in time.
:hook (on-first-input . which-key-mode)
:custom ((which-key-allow-evil-operators t)
(which-key-show-operator-state-maps t)))
(provide 'syd/which-key)

View File

@@ -0,0 +1,23 @@
{ config, lib, pkgs, ... }:
let cfg = config.sydnix.bluetooth;
in {
options.sydnix.bluetooth = {
enable = lib.mkEnableOption "BlueTooth";
};
config = lib.mkIf cfg.enable {
services.blueman.enable = true;
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General = {
# Show battery charge of Bluetooth devices
Experimental = true;
};
};
};
};
}