feat(emacs): Set nix-mode syntax table

This commit is contained in:
Madeleine Sydney
2025-02-20 17:17:31 -07:00
15 changed files with 180 additions and 61 deletions

View File

@@ -643,6 +643,29 @@ Run various checks on the system.
List persistent files per user, and show their mount strategy.
- Show info about ~sydnix.impermanence.cache~ values. Extend that option to have "description" and "consequences" fields, which are shown to users before clearing them. e.g.
#+begin_src nix
{
sydnix.impermanence.cache.directories.".local/share/emacs/cache" = {
description = "Root of all caches for Emacs and Emacs packages.";
consequences = [
"All known projects will be forgotten"
"All trusted .dir-locals.el files and values will be forgotten"
];
};
}
#+end_src
#+begin_example
$ sydnix cache clear
Recursively remove `~/.local/share/emacs/cache'?
- All known projects will be forgotten
- All trusted .dir-locals.el files and values will be forgotten
[y/n]
«more caches…»
#+end_example
* References
Following is a subset of the many places I've learnt from. Most important of all are Doom Emacs and Faye's Wishsys.

View File

@@ -1,35 +0,0 @@
;;; syd-search.el --- Description -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2025 Madeleine Sydney
;;
;; Author: Madeleine Sydney <lomiskiam@gmail.com>
;; Maintainer: Madeleine Sydney <lomiskiam@gmail.com>
;; Created: January 12, 2025
;; Modified: January 12, 2025
;; Version: 0.0.1
;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex text tools unix vc
;; Homepage: https://github.com/crumb/syd-search
;; Package-Requires: ((emacs "24.3"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;; Description
;;
;;; Code:
(syd-define-stub
syd/search-buffer
"Conduct a text search on the current buffer.
If a selection is active and multi-line, perform a search restricted to that
region.
If a selection is active and not multi-line, use the selection as the initial
input and search the whole buffer for it.
See `+default/search-buffer'.")
(provide 'syd-search)
;;; syd-search.el ends here

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
src:/home/crumb/.m2/repository/cider/cider-nrepl/0.52.0/cider-nrepl-0.52.0.jar:/home/crumb/.m2/repository/http-kit/http-kit/2.8.0/http-kit-2.8.0.jar:/home/crumb/.m2/repository/nrepl/nrepl/1.3.1/nrepl-1.3.1.jar:/home/crumb/.m2/repository/org/babashka/cli/0.8.62/cli-0.8.62.jar:/home/crumb/.m2/repository/org/clojars/pntblnk/clj-ldap/0.0.17/clj-ldap-0.0.17.jar:/home/crumb/.m2/repository/org/clojure/clojure/1.12.0/clojure-1.12.0.jar:/home/crumb/.m2/repository/cider/orchard/0.30.0/orchard-0.30.0.jar:/home/crumb/.m2/repository/mx/cider/logjam/0.3.0/logjam-0.3.0.jar:/home/crumb/.m2/repository/com/unboundid/unboundid-ldapsdk/5.1.1/unboundid-ldapsdk-5.1.1.jar:/home/crumb/.m2/repository/org/clojure/core.specs.alpha/0.4.74/core.specs.alpha-0.4.74.jar:/home/crumb/.m2/repository/org/clojure/spec.alpha/0.5.238/spec.alpha-0.5.238.jar

View File

@@ -0,0 +1,4 @@
-m
nrepl.cmdline
--middleware
[cider.nrepl/cider-middleware]

View File

@@ -0,0 +1 @@
/nix/store/4ir60qbhfgrf1r9xa1dnig13x4clhir0-ldap-nginx-plumber-1.0.0

View File

@@ -63,15 +63,13 @@ If FORCE-P, delete without confirmation."
:desc "Move current file. See `doom/move-this-file'."
:interactive t)
(syd-define-stub
syd/find-file-under-emacs-user-directory
:desc "Find under `emacs-user-directory'. See `doom/find-file-in-private-config'."
:interactive t)
(syd-define-stub
syd/find-file-under-here
:desc "Find under CWD. See `+default/find-file-under-here'."
:interactive t)
(defun syd-find-file-in (root)
(interactive (list (read-directory-name
"Find file in: " default-directory nil t)))
;; HACK: To avoid reimplementation, we pretend `root' is a project and
;; delegate the work to project.el.
(syd-with-project-root root
(project-find-file)))
(syd-define-stub
syd/yank-buffer-path
@@ -81,11 +79,21 @@ If FORCE-P, delete without confirmation."
(defun syd/find-file-in-emacs-user-directory ()
(interactive)
(unless (file-directory-p user-emacs-directory)
(user-error "`emacs-user-directory' doesn't exist! (%s)"
(abbreviate-file-name emacs-user-directory)))
(user-error "`user-emacs-directory' doesn't exist! (%s)"
(abbreviate-file-name user-emacs-directory)))
(let ((default-directory user-emacs-directory))
(call-interactively #'find-file)))
(defun syd-switch-to-emacs-user-directory ()
"Switch project to `user-emacs-directory' via `project-switch-project'."
(interactive)
(require 'syd-project)
(if (file-directory-p user-emacs-directory)
(syd-with-project-root user-emacs-directory
(project-switch-project user-emacs-directory))
(user-error "`user-emacs-directory' (%s) does not exist or is not a directory!"
(abbreviate-file-name user-emacs-directory))))
(syd-define-stub
syd/open-this-file-as-root
:desc "Open current file as root. See `doom/sudo-this-file'."
@@ -137,6 +145,7 @@ If FORCE-P, delete without confirmation."
base-file
conflict-file)))
;;;###autoload
(defun syd-split-tramp-file-name (file-name)
"Split FILE-NAME into (TRAMP-PREFIX . LOCAL-NAME). Returns (nil . FILE-NAME)
if FILE-NAME has no TRAMP prefix."

View File

@@ -8,9 +8,32 @@
(when-let* ((project (project-current nil dir)))
(project-root project)))
(defun syd-cd-project ()
(defun syd-project-cd ()
"Change the working directory to the root of the current project."
(cd (syd-project-root)))
(define-obsolete-function-alias 'syd-cd-project 'syd-project-cd
"2025-02-20")
(defmacro syd-with-project-root (root &rest body)
"Execute BODY with ROOT recognised as what project.el calls a \"transient
project\"."
(declare (indent defun))
(let ((root* (gensym "root"))
(forget-after-p (gensym "forget-after-p")))
`(let* ((,root* ,root)
(,forget-after-p
(not (member ,root* (project-known-project-roots)))))
(let ((project-find-functions (lambda (_) (cons 'transient ,root*))))
,@body)
(when ,forget-after-p
(project-forget-project ,root*)))))
(defun syd-project-search ()
(interactive)
(require 'syd-file)
;; TODO: Prompt for path project root is not found.
(syd-search-directory (syd-project-root)))
(provide 'syd-project)
;;; syd-project.el ends here

View File

@@ -0,0 +1,55 @@
;;; syd-search.el -*- lexical-binding: t; -*-
(cl-defun syd-search-region (beg end &key initial)
(save-restriction
(narrow-to-region beg end)
(consult-line initial)))
(defun syd-search--escape-regexp (str)
(require 'syd-text)
(replace-regexp-in-string " " "\\\\ "
(syd-pcre-quote str)))
(defun syd-search-buffer (buffer)
"Conduct a text search on BUFFER.
If a selection is active and multi-line, perform a search restricted to that
region.
If a selection is active and not multi-line, use the selection as the initial
input and search the whole buffer for it."
(interactive (list (current-buffer)))
(save-restriction
(let* ((beg (region-beginning))
(end (region-end))
(multiline-p (/= (line-number-at-pos beg)
(line-number-at-pos end))))
(if (and beg end (region-active-p))
(progn (deactivate-mark)
(if multiline-p
(syd-search-region beg end)
;; Treat as a single pattern, not several
;; space-separated patterns.
(consult-line (syd-search--escape-regexp
(buffer-substring-no-properties beg end)))))
(consult-line)))))
;;;###autoload
(defun syd-search-directory (dir)
(interactive (list (read-directory-name
"Search directory: "
default-directory nil t)))
(cond ((executable-find "rg")
(consult-ripgrep dir))
((executable-find "grep")
(message "Couldn't find ripgrep; using grep")
(consult-grep dir))))
;;;###autoload
(defun syd-search-current-directory ()
(interactive)
(syd-search-directory default-directory))
(provide 'syd-search)
;;; syd-search.el ends here

View File

@@ -120,4 +120,16 @@ in some cases."
(interactive "P<x><y>")
(syd-evil-paste t arg register yank-handler))
;;;###autoload
(defun syd-pcre-quote (str)
"Like `reqexp-quote', but for PCREs."
(let ((special '(?. ?^ ?$ ?* ?+ ?? ?{ ?\\ ?\[ ?\| ?\())
(quoted nil))
(mapc (lambda (c)
(when (memq c special)
(push ?\\ quoted))
(push c quoted))
str)
(concat (nreverse quoted))))
(provide 'syd-text)

View File

@@ -23,7 +23,9 @@
'js-mode)))
:config
(add-hook 'nix-mode-hook #'lsp)
(set-popup-rule! "^\\*nixos-options-doc\\*$" :ttl 0 :quit t)
(set-repl-handler! 'nix-mode #'syd-nix-open-nix-repl))
(set-popup-rule! (rx bol "*nixos-options-doc*" eol) :ttl 0 :quit t)
(set-repl-handler! 'nix-mode #'syd-nix-open-nix-repl)
(dolist (c '(?- ?_))
(modify-syntax-entry c "w" nix-mode-syntax-table)))
(provide 'syd-lang-nix)

View File

@@ -3,6 +3,7 @@
(use-package age
:hook (on-first-file . age-file-enable)
:custom
;; We use rage over age, as the former supports pinentry.
((age-program "rage")
(age-default-identity (expand-file-name "~/private-keys/age/crumb.age"))
(age-default-recipient (expand-file-name "~/public-keys/age/crumb.pub"))))

View File

@@ -23,10 +23,12 @@
"r" `("Revert buffer" . ,#'revert-buffer))
;; Search
(require 'syd-search)
(general-def
:prefix-map 'syd-leader-search-map
"i" `("IMenu" . ,#'consult-imenu)
"b" `("Search buffer" . ,#'syd/search-buffer))
"b" `("Search buffer" . ,#'syd-search-buffer)
"d" `("Search directory" . ,#'syd-search-directory))
;; File
(require 'syd-file)
@@ -35,9 +37,8 @@
"D" `("Delete file" . ,#'syd/delete-this-file)
"R" `("Move file" . ,#'syd/move-this-file)
"C" `("Copy file" . ,#'syd/copy-this-file)
;; "F" `("Find file under here" . ,#'syd/find-file-under-here)
;; "p" `("Find under Emacs config" . ,#'syd/find-file-under-emacs-user-directory)
"P" `("Browse Emacs config" . ,#'syd/find-file-in-emacs-user-directory)
"F" `("Find file in" . ,#'syd-find-file-in)
"P" `("Browse Emacs config" . ,#'syd-switch-to-emacs-user-directory)
"u" `("Find file as root" . ,#'syd/find-file-as-root)
"U" `("Open this file as root" . ,#'syd/open-this-file-as-root)
"y" `("Yank buffer path" . ,#'syd/yank-buffer-path)
@@ -81,6 +82,7 @@
"C" `("Compile project" . ,#'project-compile)
"&" `("Async cmd in project root" . ,#'project-async-shell-command)
"p" `("Switch project" . ,#'project-switch-project))
"." `("Browse project from root" . ,#'project-root-find-file))
(general-def
:prefix-map 'syd-leader-help-package-map
@@ -142,7 +144,9 @@
"s" `("Search" . ,syd-leader-search-map)
"h" `("Help" . ,help-map)
"n" `("Notes" . ,syd-leader-notes-map)
"i" `("Insert" . ,syd-leader-insert-map)))
"i" `("Insert" . ,syd-leader-insert-map)
"," `("Switch buffer in project" . ,#'consult-project-buffer)
"<" `("Switch buffer" . ,#'consult-buffer)))
(syd-keybinds-initialise)

View File

@@ -1,7 +1,5 @@
;;; syd-org.el -*- lexical-binding: t; -*-
(require 'syd-prose)
(with-eval-after-load 'org
(syd-add-hook 'org-tab-first-hook
(defun syd-org-cycle-only-current-subtree-h (&optional arg)
@@ -306,9 +304,10 @@ See https://lists.gnu.org/archive/html/emacs-orgmode/2019-07/msg00081.html."
;; ol-rmail
;; ol-eww
))
(syd-add-hook 'org-load-hook
(add-hook 'org-load-hook
#'syd-org-init-popup-rules-h)
:config
(require 'syd-prose)
(syd-add-hook 'org-mode-hook
#'org-indent-mode
#'syd-prose-mode)

View File

@@ -2,9 +2,28 @@
(require 'syd-constants)
(use-package project
:custom ((project-list-file (file-name-concat syd-cache-dir
"known-projects"))))
(with-eval-after-load 'project ; Built-in
;; Stay out of my config directory!
(setq project-list-file (file-name-concat syd-cache-dir "known-projects"))
;; For each command in `project-switch-commands' will assign it the key found
;; in `project-prefix-map'. We emulate that behaviour but for our own
;; `syd-leader-project-map'.
(let* ((project-key
(lambda (f)
(key-description
(where-is-internal
f
;; If the keymap is not wrapped in a list,
;; `where-is-internal' will also search the
;; global ;; keymaps
(list syd-leader-project-map)
;; First result only.
t))))
(switch-cmd (lambda (command name &optional key)
(append (list command name)
(list (or key (funcall project-key command)))))))
(add-to-list 'project-switch-commands
(funcall switch-cmd #'project-root-find-file "Browse"))))
;; Projection provides a Projectile-like project management library atop
;; Emacs built-in project.el. It's more lightweight, while still featureful.