This is a mess

I'm sorry.  I really wanted to improve my commit discipline.  I know.  I can't
be fucked to comb this diff and split it into 8 properly-ordered commits, like I
know I should.  I'm not having a good time right now.  We'll do better moving
forward.
This commit is contained in:
Madeleine Sydney
2025-01-31 16:45:37 -07:00
parent f247599853
commit d59c79a8d4
16 changed files with 721 additions and 33 deletions

View File

@@ -2,6 +2,7 @@
(require 'syd-handle-repl)
(require 'syd-handle-lookup)
(require 'syd-handle-eval)
;; (require 'handle)
;; Don't `use-package' `ielm', since it's loaded by Emacs. You'll get weird
@@ -37,6 +38,31 @@
(set-repl-handler! 'emacs-lisp-mode
#'syd/open-emacs-lisp-repl)
;;;###autoload
(defun syd-emacs-lisp-eval (beg end)
"Evaluate a region and print it to the echo area (if one line long), otherwise
to a pop up buffer."
(syd-eval-display-results
(string-trim-right
(let ((buffer (generate-new-buffer " *eval-output*"))
(debug-on-error t))
(unwind-protect
(condition-case-unless-debug e
(progn (eval-region beg end buffer load-read-function)
(with-current-buffer buffer
(let ((pp-max-width nil))
(require 'pp)
(pp-buffer)
(replace-regexp-in-string
"\\\\n" "\n" (string-trim-left (buffer-string))))))
(error (format "ERROR: %s" e)))
(kill-buffer buffer))))
:source-buffer (current-buffer)
:force-popup current-prefix-arg))
(set-eval-handler! 'emacs-lisp-mode
#'syd-emacs-lisp-eval)
(defun syd-emacs-set-handlers ()
(setq-local syd-lookup-documentation-handlers
(list #'syd-emacs-lisp-lookup-documentation)))

View File

@@ -1,7 +1,5 @@
;;; syd-completion.el -*- lexical-binding: t; -*-
(require 'syd-general)
(use-package emacs
:custom
;; Allow the opening of new minibuffers from inside existing minibuffers.

View File

@@ -0,0 +1,110 @@
;;; syd-eshell.el -*- lexical-binding: t; -*-
(defvar eshell-buffer-name "*eshell*")
(defvar syd-eshell-buffers (make-ring 25)
"List of open eshell buffers.")
(defun syd-eshell-buffers ()
"TODO"
(ring-elements syd-eshell-buffers))
;;;###autoload
(defun syd-eshell-run-command (command &optional buffer)
"TODO"
(let ((buffer
(or buffer
(if (eq major-mode 'eshell-mode)
(current-buffer)
(cl-find-if #'buffer-live-p (syd-eshell-buffers))))))
(unless buffer
(user-error "No living eshell buffers available"))
(unless (buffer-live-p buffer)
(user-error "Cannot operate on a dead buffer"))
(with-current-buffer buffer
(goto-char eshell-last-output-end)
(goto-char (line-end-position))
(insert command)
(eshell-send-input nil t))))
;;;###autoload
(defun syd-eshell/toggle (arg &optional command)
"Toggle eshell popup window."
(interactive "P")
(let ((eshell-buffer
(get-buffer-create
(format "*eshell-popup:%s*"
(if (bound-and-true-p persp-mode)
(safe-persp-name (get-current-persp))
"main"))))
confirm-kill-processes
current-prefix-arg)
(when arg
(when-let* ((win (get-buffer-window eshell-buffer)))
(delete-window win))
(when (buffer-live-p eshell-buffer)
(with-current-buffer eshell-buffer
(fundamental-mode)
(erase-buffer))))
(if-let* ((win (get-buffer-window eshell-buffer)))
(let (confirm-kill-processes)
(delete-window win)
(ignore-errors (kill-buffer eshell-buffer)))
(with-current-buffer eshell-buffer
(syd-mark-buffer-as-real)
(if (eq major-mode 'eshell-mode)
(run-hooks 'eshell-mode-hook)
(eshell-mode))
(when command
(syd-eshell-run-command command eshell-buffer)))
(pop-to-buffer eshell-buffer))))
(use-package eshell
:custom
((eshell-banner-message
'(format "🦌 %s %s }:3\n"
(propertize (format " %s " (string-trim (buffer-name)))
'face 'mode-line-highlight)
(propertize (current-time-string)
'face 'font-lock-keyword-face)))
(eshell-scroll-to-bottom-on-input 'all)
(eshell-scroll-to-bottom-on-output 'all)
(eshell-kill-processes-on-exit t)
(eshell-hist-ignoredups t)
(eshell-glob-case-insensitive t)
(eshell-error-if-no-glob t))
:general
(:keymaps 'syd-leader-open-map
"e" #'syd-eshell/toggle)
(:keymaps 'eshell-mode-map
:states '(normal insert)
"C-j" #'eshell-next-matching-input-from-input
"C-k" #'eshell-previous-matching-input-from-input)
:config
(require 'syd-buffers)
(add-hook 'eshell-mode-hook #'syd-mark-buffer-as-real)
;; UI enhancements.
(defun syd-eshell-remove-fringes-h ()
(set-window-fringes nil 0 0)
(set-window-margins nil 1 nil))
(defun syd-eshell-enable-text-wrapping-h ()
(visual-line-mode +1)
(set-display-table-slot standard-display-table 0 ?\ ))
(add-hook 'eshell-mode-hook #'syd-eshell-remove-fringes-h)
(add-hook 'eshell-mode-hook #'syd-eshell-enable-text-wrapping-h)
(with-eval-after-load 'hide-mode-line
(add-hook 'eshell-mode-hook #'hide-mode-line-mode))
;; Remove hscroll-margin in shells, otherwise you get jumpiness when the
;; cursor comes close to the left/right edges of the window.
(defun syd-eshell-disable-hscroll-margin ()
(setq hscroll-margin 0))
(add-hook 'eshell-mode-hook #'syd-eshell-disable-hscroll-margin))
(set-popup-rule! "^\\*eshell-popup"
:vslot -5 :size 0.35 :select t :modeline nil :quit nil :ttl nil)
(provide 'syd-eshell)

View File

@@ -33,24 +33,168 @@
;; These two are required for evil-collection.
(setq evil-want-keybinding nil
evil-want-integration t)
:config
;; 'M-:' starts off in insert mode, yet initialises with the normal mode
;; cursor. Quick fix! }:P
(add-hook 'minibuffer-setup-hook
#'evil-refresh-cursor)
;; Unbind 'C-k'. Normally, it inserts digraphs; I have a compose key. It
;; often gets in the way of buffers with navigation, e.g. scrolling through
;; shell/REPL history, navigating Vertico completions, etc.
(keymap-set evil-insert-state-map "C-k" nil)
;; In imitation of Vim's :mes[sages] command, define an Evil analogue to show
;; the echo area.
(evil-ex-define-cmd "mes[sages]"
#'view-echo-area-messages)
(evil-mode 1))
(defvar evil-collection-key-blacklist)
;; A large, community-sourced collection of preconfigured Evil-mode
;; integrations.
(use-package evil-collection
:after evil
:defer t
:custom (evil-collection-setup-minibuffer t)
:config
(evil-collection-init))
(unless noninteractive
(defvar syd-evil-collection-disabled-list
'(anaconda-mode buff-menu calc comint company custom eldoc elisp-mode ert
free-keys helm help image indent kmacro kotlin-mode lispy outline
replace shortdoc simple slime tab-bar)
"A list of `evil-collection' modules to ignore. See
`evil-collection-mode-list' for a list of available options.")
;; We do this ourselves.
(defvar evil-collection-want-unimpaired-p nil)
;; We binds goto-reference on gD and goto-assignments on gA ourselves
(defvar evil-collection-want-find-usages-bindings-p nil)
;; Reduces keybind conflicts between outline-mode and org-mode (which is
;; derived from outline-mode).
(defvar evil-collection-outline-enable-in-minor-mode-p nil)
;; We handle loading evil-collection ourselves
(defvar evil-collection--supported-modes nil)
;; This has to be defined here since evil-collection doesn't autoload its own.
;; It must be updated whenever evil-collection updates theirs. Here's an easy
;; way to update it:
(defvar evil-collection-mode-list
`(2048-game ag alchemist anaconda-mode apropos arc-mode atomic-chrome
auto-package-update beginend bluetooth bm bookmark
(buff-menu "buff-menu") bufler calc calendar cider citre cmake-mode
color-rg comint company compile consult corfu crdt (csv "csv-mode")
(custom cus-edit) cus-theme dape dashboard daemons deadgrep debbugs
debug devdocs dictionary diff-hl diff-mode dired dired-sidebar
disk-usage distel doc-view docker eat ebib ebuku edbi edebug ediff eglot
elpaca ement explain-pause-mode eldoc elfeed elisp-mode elisp-refs
elisp-slime-nav embark emms ,@(if (> emacs-major-version 28) '(emoji))
epa ert eshell eval-sexp-fu evil-mc eww fanyi finder flycheck flymake
forge free-keys geiser ggtags git-timemachine gited gnus go-mode gptel
grep guix hackernews helm help helpful hg-histedit hungry-delete hyrolo
ibuffer (image image-mode) image-dired image+ imenu imenu-list
(indent "indent") indium info ivy js2-mode
,@(if (>= emacs-major-version 30) '(kmacro)) leetcode lispy lms log-edit
log-view lsp-ui-imenu lua-mode kotlin-mode macrostep man
(magit magit-repos magit-submodule) magit-repos magit-section
magit-todos markdown-mode monky mpc mpdel mu4e mu4e-conversation neotree
newsticker notmuch nov omnisharp org org-present org-roam osx-dictionary
outline p4 (package-menu package) pass (pdf pdf-tools) popup proced
prodigy profiler p-search python quickrun racer racket-describe realgud
reftex replace restclient rg ripgrep rjsx-mode robe rtags ruby-mode
scheme scroll-lock selectrum sh-script
,@(if (> emacs-major-version 27) '(shortdoc)) simple simple-mpc slime
sly smerge-mode snake so-long speedbar tab-bar tablist tar-mode telega
(term term ansi-term multi-term) tetris thread tide timer-list
transmission trashed tuareg typescript-mode vc-annotate vc-dir vc-git
vdiff vertico view vlf vterm vundo w3m wdired wgrep which-key
with-editor woman xref xwidget yaml-mode youtube-dl zmusic
(ztree ztree-diff)))
(cl-defun syd-evil-collection-init (module &key disabled-modules)
"Initialise evil-collection-MODULE.
A wrapper for `evil-collection-init' that respects a given list of disabled
modules."
(let ((module* (or (car-safe module) module)))
(unless (memq module* disabled-modules)
(message "Loading evil-collection-%s%s"
module*
(if after-init-time "" " too early! }:("))
(with-demoted-errors "error loading evil-collection: %s"
(evil-collection-init (list module))))))
(defun syd-evil-collection-disable-blacklist-a (fn)
(let (evil-collection-key-blacklist)
(funcall-interactively fn)))
;; Allow binding to ESC.
(advice-add #'evil-collection-vterm-toggle-send-escape
:around #'syd-evil-collection-disable-blacklist-a)
;; These modes belong to packages that Emacs always loads at startup, causing
;; evil-collection and it's co-packages to all load immediately. We avoid
;; this by loading them after evil-collection has first loaded...
(with-eval-after-load 'evil-collection
(require 'syd-prelude)
(require 'syd-keybinds)
;; Don't let evil-collection interfere with certain keys
(setq evil-collection-key-blacklist
(append (list syd-leader-key syd-localleader-key
syd-alt-leader-key)
evil-collection-key-blacklist
;; Reserved for goto definition; lookup docs; eval; eval
;; buffer; movement prefix; movement prefix; escaping };).
'("gd" "K" "gr" "gR" "[" "]" "<escape>")))
(mapc #'syd-evil-collection-init '(comint custom))
(with-eval-after-load 'evil
;; Emacs loads these two packages immediately, at startup, which needlessly
;; convolutes load order for evil-collection-help.
(with-transient-after 'help-mode
(syd-evil-collection-init 'help))
(with-transient-after 'Buffer-menu-mode
(syd-evil-collection-init '(buff-menu "buff-menu")))
(with-transient-after 'calc-mode
(syd-evil-collection-init 'calc))
(with-transient-after 'image-mode
(syd-evil-collection-init 'image))
(with-transient-after 'emacs-lisp-mode
(syd-evil-collection-init 'elisp-mode))
(with-transient-after 'occur-mode
(syd-evil-collection-init 'replace))
(with-transient-after 'indent-rigidly
(syd-evil-collection-init '(indent "indent")))
(when (>= emacs-major-version 30)
(with-transient-after 'kmacro-menu-mode
(syd-evil-collection-init 'kmacro)))
(with-transient-after 'minibuffer-setup-hook
(when evil-collection-setup-minibuffer
(syd-evil-collection-init 'minibuffer)
(evil-collection-minibuffer-insert)))
(with-transient-after 'process-menu-mode
(syd-evil-collection-init '(process-menu simple)))
(with-transient-after 'shortdoc-mode
(syd-evil-collection-init 'shortdoc))
(with-transient-after 'tabulated-list-mode
(syd-evil-collection-init 'tabulated-list))
(with-transient-after 'tab-bar-mode
(syd-evil-collection-init 'tab-bar))
;; HACK: Do this ourselves because evil-collection break's
;; `eval-after-load' load order by loading their target plugin before
;; applying keys. This makes it hard for end-users to overwrite these
;; keybinds with a simple `after!' or `with-eval-after-load'.
(dolist (mode evil-collection-mode-list)
(dolist (req (or (cdr-safe mode) (list mode)))
(with-eval-after-load req
(syd-evil-collection-init
mode
:disabled-modules syd-evil-collection-disabled-list))))))))
;; Tim Pope's famous `surround.vim' for Evil.
(use-package evil-surround

View File

@@ -1,8 +0,0 @@
;;; syd-general.el -*- lexical-binding: t; -*-
(use-package general
:custom (general-use-package-emit-autoloads t))
(require 'general)
(provide 'syd-general)

View File

@@ -1,8 +1,6 @@
;;; syd-keybinds.el -*- lexical-binding: t; -*-
;;; Universal keybindings, not /too/ tied to any particular packages.
(require 'syd-general)
(defvar syd-leader-key "SPC"
"A prefix key akin to Vim's <Leader>.")
@@ -54,9 +52,9 @@ are active.")
(general-override-mode 1))
(defvar syd-escape-hook nil
"A hook run when C-g is pressed (or ESC in normal mode, for evil users).
"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,
More specifically, when `syd/escape' is pressed. If any hook returns non-nil,
all hooks after it are ignored.")
;;
@@ -111,6 +109,13 @@ all hooks after it are ignored.")
(global-set-key [remap keyboard-quit] #'syd/escape)
(general-def
:states 'motion
"/" #'evil-ex-search-forward
"?" #'evil-ex-search-backward
"n" #'evil-ex-search-next
"N" #'evil-ex-search-previous)
;; Buffer
(require 'syd-buffers)
(general-def
@@ -138,7 +143,7 @@ all hooks after it are ignored.")
"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 current" . ,#'syd/find-file-under-here)
;; "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)
"u" `("Find file as root" . ,#'syd/find-file-as-root)

View File

@@ -11,13 +11,8 @@
(popper-mode 1))
(use-package doom-popup
;; :after popper
;; :load-path "/persist/dots/users/crumb/programs/emacs/lib/doom-popup"
;; :straight nil
:straight
(:type git
:host gitlab
:repo "crumbtoo/doom-popup"))
:straight (:type git
:host gitlab
:repo "crumbtoo/doom-popup"))
(provide 'syd-popups)
;;; syd-popups.el ends here

View File

@@ -7,6 +7,8 @@
;; activated.
(use-package smartparens
:hook (on-first-buffer . smartparens-global-mode)
:commands (sp-pair sp-local-pair sp-with-modes sp-point-in-comment
sp-point-in-string)
:custom
;; Overlays are too distracting and not terribly helpful. show-parens does
;; this for us already (and is faster), so...

View File

@@ -17,14 +17,34 @@
;; 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))
;; 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))
:config
;; Disable the menu bar, scroll bar, and tool bar.
(menu-bar-mode -1)
(scroll-bar-mode -1)
(tool-bar-mode -1))
(use-package persp-mode
:unless noninteractive
:commands persp-switch-to-buffer
:hook (on-init-ui . persp-mode)
:config
(setq persp-autokill-buffer-on-remove 'kill-weak
persp-reset-windows-on-nil-window-conf nil
persp-nil-hidden t
persp-auto-save-fname "autosave"
persp-save-dir (concat syd-data-dir "workspaces/")
persp-set-last-persp-for-new-frames t
persp-switch-to-added-buffer nil
persp-kill-foreign-buffer-behaviour 'kill
persp-remove-buffers-from-nil-persp-behaviour nil
persp-auto-resume-time -1 ; Don't auto-load on startup
persp-auto-save-opt (if noninteractive 0 1)))
(provide 'syd-ui)