diff --git a/hosts/fruitbook/configuration.nix b/hosts/fruitbook/configuration.nix index 17f6c4d..69cba72 100644 --- a/hosts/fruitbook/configuration.nix +++ b/hosts/fruitbook/configuration.nix @@ -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 ]; diff --git a/hosts/fruitbook/filesystems.nix b/hosts/fruitbook/filesystems.nix index e62635b..f5ab04f 100644 --- a/hosts/fruitbook/filesystems.nix +++ b/hosts/fruitbook/filesystems.nix @@ -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"; -} diff --git a/modules/home/users/crumb/emacs/init.el b/modules/home/users/crumb/emacs/init.el index f71884b..c877eed 100755 --- a/modules/home/users/crumb/emacs/init.el +++ b/modules/home/users/crumb/emacs/init.el @@ -69,3 +69,4 @@ (require 'syd-tramp) (require 'syd-trust) (require 'syd-ui) +(put 'narrow-to-region 'disabled nil) diff --git a/modules/home/users/crumb/emacs/modules/syd-org.el b/modules/home/users/crumb/emacs/modules/syd-org.el index 445b4b0..6dfa0f3 100755 --- a/modules/home/users/crumb/emacs/modules/syd-org.el +++ b/modules/home/users/crumb/emacs/modules/syd-org.el @@ -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) diff --git a/modules/home/users/crumb/niri.nix b/modules/home/users/crumb/niri.nix index 975a48d..3793a4f 100644 --- a/modules/home/users/crumb/niri.nix +++ b/modules/home/users/crumb/niri.nix @@ -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 = diff --git a/modules/home/users/msyds/emacs/early-init.el b/modules/home/users/msyds/emacs/early-init.el index dbec714..0ed7bff 100644 --- a/modules/home/users/msyds/emacs/early-init.el +++ b/modules/home/users/msyds/emacs/early-init.el @@ -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) diff --git a/modules/home/users/msyds/emacs/init.el b/modules/home/users/msyds/emacs/init.el index 2ce9a20..6830501 100644 --- a/modules/home/users/msyds/emacs/init.el +++ b/modules/home/users/msyds/emacs/init.el @@ -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)) diff --git a/modules/home/users/msyds/emacs/lisp/syd/base.el b/modules/home/users/msyds/emacs/lisp/syd/base.el new file mode 100644 index 0000000..c7e7e77 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/base.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/50-comint.el b/modules/home/users/msyds/emacs/lisp/syd/comint.el similarity index 70% rename from modules/home/users/msyds/emacs/lisp/syd/init/50-comint.el rename to modules/home/users/msyds/emacs/lisp/syd/comint.el index a3168f0..01cc347 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/init/50-comint.el +++ b/modules/home/users/msyds/emacs/lisp/syd/comint.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/compilation.el b/modules/home/users/msyds/emacs/lisp/syd/compilation.el new file mode 100644 index 0000000..40ae77c --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/compilation.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/completion.el b/modules/home/users/msyds/emacs/lisp/syd/completion.el new file mode 100644 index 0000000..2a0f6fb --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/completion.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/constants.el b/modules/home/users/msyds/emacs/lisp/syd/constants.el new file mode 100644 index 0000000..333249b --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/constants.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/dash.el b/modules/home/users/msyds/emacs/lisp/syd/dash.el new file mode 100644 index 0000000..9787723 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/dash.el @@ -0,0 +1,8 @@ +;;; -*- lexical-binding: t; -*- + +(require 'syd/straight) +(require 'syd/use-package) + +(use-package dash) + +(provide 'syd/dash) diff --git a/modules/home/users/msyds/emacs/lisp/syd/early-init/01-disable-package.el b/modules/home/users/msyds/emacs/lisp/syd/disable-package.el similarity index 62% rename from modules/home/users/msyds/emacs/lisp/syd/early-init/01-disable-package.el rename to modules/home/users/msyds/emacs/lisp/syd/disable-package.el index e1a39ce..e405529 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/early-init/01-disable-package.el +++ b/modules/home/users/msyds/emacs/lisp/syd/disable-package.el @@ -2,4 +2,4 @@ (setq package-enable-at-startup nil) -(provide 'syd/early-init/disable-package) +(provide 'syd/disable-package) diff --git a/modules/home/users/msyds/emacs/lisp/syd/early-init/00-define-constants.el b/modules/home/users/msyds/emacs/lisp/syd/early-init/00-define-constants.el deleted file mode 100644 index f89b4de..0000000 --- a/modules/home/users/msyds/emacs/lisp/syd/early-init/00-define-constants.el +++ /dev/null @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/10-elpaca.el b/modules/home/users/msyds/emacs/lisp/syd/elpaca.el similarity index 94% rename from modules/home/users/msyds/emacs/lisp/syd/init/10-elpaca.el rename to modules/home/users/msyds/emacs/lisp/syd/elpaca.el index ccc2c9f..0e89e33 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/init/10-elpaca.el +++ b/modules/home/users/msyds/emacs/lisp/syd/elpaca.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/50-emacs-lisp-mode.el b/modules/home/users/msyds/emacs/lisp/syd/emacs-lisp.el similarity index 78% rename from modules/home/users/msyds/emacs/lisp/syd/init/50-emacs-lisp-mode.el rename to modules/home/users/msyds/emacs/lisp/syd/emacs-lisp.el index 413d908..2ae1e1c 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/init/50-emacs-lisp-mode.el +++ b/modules/home/users/msyds/emacs/lisp/syd/emacs-lisp.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/escape.el b/modules/home/users/msyds/emacs/lisp/syd/escape.el new file mode 100644 index 0000000..03d0da3 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/escape.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/40-evil.el b/modules/home/users/msyds/emacs/lisp/syd/evil.el similarity index 87% rename from modules/home/users/msyds/emacs/lisp/syd/init/40-evil.el rename to modules/home/users/msyds/emacs/lisp/syd/evil.el index cd5d138..0ef781f 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/init/40-evil.el +++ b/modules/home/users/msyds/emacs/lisp/syd/evil.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/50-fonts.el b/modules/home/users/msyds/emacs/lisp/syd/fonts.el similarity index 92% rename from modules/home/users/msyds/emacs/lisp/syd/init/50-fonts.el rename to modules/home/users/msyds/emacs/lisp/syd/fonts.el index 61932d5..4792d58 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/init/50-fonts.el +++ b/modules/home/users/msyds/emacs/lisp/syd/fonts.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/form-feeds.el b/modules/home/users/msyds/emacs/lisp/syd/form-feeds.el new file mode 100644 index 0000000..5d9fbf9 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/form-feeds.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/frame.el b/modules/home/users/msyds/emacs/lisp/syd/frame.el new file mode 100644 index 0000000..983471c --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/frame.el @@ -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 diff --git a/modules/home/users/msyds/emacs/lisp/syd/general.el b/modules/home/users/msyds/emacs/lisp/syd/general.el new file mode 100644 index 0000000..ab05759 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/general.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/grep.el b/modules/home/users/msyds/emacs/lisp/syd/grep.el new file mode 100644 index 0000000..08f0339 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/grep.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/15-general.el b/modules/home/users/msyds/emacs/lisp/syd/init/15-general.el deleted file mode 100644 index b54c968..0000000 --- a/modules/home/users/msyds/emacs/lisp/syd/init/15-general.el +++ /dev/null @@ -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 .") - -(defvar syd-localleader-key "SPC m" - "A prefix key akin to Vim's .") - -(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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/50-default-frame.el b/modules/home/users/msyds/emacs/lisp/syd/init/50-default-frame.el deleted file mode 100644 index 53c445d..0000000 --- a/modules/home/users/msyds/emacs/lisp/syd/init/50-default-frame.el +++ /dev/null @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/50-kanagawa.el b/modules/home/users/msyds/emacs/lisp/syd/init/50-kanagawa.el deleted file mode 100644 index 290ad75..0000000 --- a/modules/home/users/msyds/emacs/lisp/syd/init/50-kanagawa.el +++ /dev/null @@ -1,7 +0,0 @@ -;;; syd-ui.el -*- lexical-binding: t; -*- - -(use-package kanagawa-themes - :config - (load-theme 'kanagawa-wave t)) - -(provide 'syd/init/kanagawa) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/50-ui.el b/modules/home/users/msyds/emacs/lisp/syd/init/50-ui.el deleted file mode 100644 index a05285c..0000000 --- a/modules/home/users/msyds/emacs/lisp/syd/init/50-ui.el +++ /dev/null @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/kanagawa-palette.el b/modules/home/users/msyds/emacs/lisp/syd/kanagawa-palette.el new file mode 100644 index 0000000..ff9cfa0 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/kanagawa-palette.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/kanagawa.el b/modules/home/users/msyds/emacs/lisp/syd/kanagawa.el index 94a1514..dc8ccdb 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/kanagawa.el +++ b/modules/home/users/msyds/emacs/lisp/syd/kanagawa.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/leader.el b/modules/home/users/msyds/emacs/lisp/syd/leader.el new file mode 100644 index 0000000..bc3835c --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/leader.el @@ -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 .") + +(defvar syd-localleader-key "SPC m" + "A prefix key akin to Vim's .") + +(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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/line-numbers.el b/modules/home/users/msyds/emacs/lisp/syd/line-numbers.el new file mode 100644 index 0000000..6491913 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/line-numbers.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/minibuffer.el b/modules/home/users/msyds/emacs/lisp/syd/minibuffer.el new file mode 100644 index 0000000..a62423b --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/minibuffer.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/on.el b/modules/home/users/msyds/emacs/lisp/syd/on.el new file mode 100644 index 0000000..17166cc --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/on.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/20-prelude.el b/modules/home/users/msyds/emacs/lisp/syd/prelude.el similarity index 98% rename from modules/home/users/msyds/emacs/lisp/syd/init/20-prelude.el rename to modules/home/users/msyds/emacs/lisp/syd/prelude.el index 80ed273..41bf7b9 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/init/20-prelude.el +++ b/modules/home/users/msyds/emacs/lisp/syd/prelude.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/risky-variables.el b/modules/home/users/msyds/emacs/lisp/syd/risky-variables.el new file mode 100644 index 0000000..21a8845 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/risky-variables.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/scrolling.el b/modules/home/users/msyds/emacs/lisp/syd/scrolling.el new file mode 100644 index 0000000..9d0e8ff --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/scrolling.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/straight.el b/modules/home/users/msyds/emacs/lisp/syd/straight.el new file mode 100644 index 0000000..1e92a94 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/straight.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/top-level-keymaps.el b/modules/home/users/msyds/emacs/lisp/syd/top-level-keymaps.el new file mode 100644 index 0000000..d924930 --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/top-level-keymaps.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/init/10-use-package.el b/modules/home/users/msyds/emacs/lisp/syd/use-package.el similarity index 97% rename from modules/home/users/msyds/emacs/lisp/syd/init/10-use-package.el rename to modules/home/users/msyds/emacs/lisp/syd/use-package.el index 4f30712..ac94e96 100644 --- a/modules/home/users/msyds/emacs/lisp/syd/init/10-use-package.el +++ b/modules/home/users/msyds/emacs/lisp/syd/use-package.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/vc.el b/modules/home/users/msyds/emacs/lisp/syd/vc.el new file mode 100644 index 0000000..46cce8d --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/vc.el @@ -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) diff --git a/modules/home/users/msyds/emacs/lisp/syd/which-key.el b/modules/home/users/msyds/emacs/lisp/syd/which-key.el new file mode 100644 index 0000000..af7d2dd --- /dev/null +++ b/modules/home/users/msyds/emacs/lisp/syd/which-key.el @@ -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) diff --git a/modules/nixos/bluetooth.nix b/modules/nixos/bluetooth.nix new file mode 100644 index 0000000..9338ece --- /dev/null +++ b/modules/nixos/bluetooth.nix @@ -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; + }; + }; + }; + }; +}