feat: Lookup docs

This commit is contained in:
Madeleine Sydney
2025-01-31 16:45:37 -07:00
parent 73268a62a8
commit aa1cd2c69f
7 changed files with 245 additions and 11 deletions

View File

@@ -204,6 +204,16 @@ Disassemble project-ideas.org and reading-list.org into a individual roam nodes.
**** TODO Capture templates
***** IDEA Export to GitLab issue?
***** TODO Config TODO list / pain-point list
*** TODO Default fonts
- fixed-pitch: Victor Mono NF
- variable-pitch: Overpass
- backup: Julia Mono
*** DONE project.el
CLOSED: [2025-01-16 Thu 18:19]
@@ -219,20 +229,41 @@ CLOSED: [2025-01-16 Thu 18:19]
*** TODO Lookup handlers
*** DONE Repl-handling
CLOSED: [2025-01-31 Fri]
*** TODO Comint
*** TODO Eshell
**** TODO Prompt
**** TODO Greeting
**** TODO Aliases
**** TODO Evil
**** TODO Project integration
**** TODO Syntax highlighting
**** TODO ~C-d~
*** TODO Snippets
**** TODO File templates
*** TODO File templates
**** TODO Project templates
*** TODO Project templates
*** TODO Magit
**** TODO Forges
*** TODO Prettier Vertico
Doom has some nice output when viewing files in Vertico. I'm not sure how this is achieved.
*** TODO Dired/Dirvish
*** TODO [[kbd:][SPC i]]
@@ -257,10 +288,11 @@ CLOSED: [2025-01-16 Thu 18:19]
**** TODO Nix
**** TODO Open repl
**** TODO Elisp
*** TODO Tune GC w/ ~gcmh~
*** IDEA Email?
*** IDEA =map!= macro

View File

@@ -1,21 +1,43 @@
;; -*- lexical-binding: t; -*-
;; Initialise Straight.el.
;; Initialise Straight.el
(load (locate-user-emacs-file "init-straight"))
(syd-initialise-straight)
;; Personal modules.
;; My friend Nova
;; This is my friend Nova. She has to have her own page to spread her spores
;; in. Y^,..,^Y
;;⠀⠀⣄⠀⠀⠀⠀⠀⠀⢠⠖⠒⠒⠒⢄⠀⠀⠀⠀⢀⢖⡆⠀⠀⠀
;;⠀⠀⡇⠑⣄⠀⠀⠀⠀⠯⣀⡀⠀⢀⣨⠆⠀⠀⢀⠎⢸⠀⠀⠀⠀
;;⠀⠀⢹⠀⠈⠓⢄⣀⡠⠤⠤⡇⠀⢸⠤⣄⡀⣠⠎⠀⢸⠀⠀⠀⠀
;;⠀⠀⠸⡀⢀⡔⠉⠹⠄⠀⠴⠧⠤⢼⣀⠀⠈⠳⡄⠀⢸⠀⠀⠀⠀
;;⠀⠀⠀⢣⡞⠀⠀⠀⣀⣀⡀⠀⠀⠀⢀⣄⡀⠀⠘⢦⢸⠀⠀⠀⠀
;;⠀⠀⠀⠀⡇⠀⠀⠐⠁⠀⠙⠀⠀⠀⠋⠀⠙⠀⠀⠈⣿⠄⠀⠀⠀
;;⠀⠀⠀⠀⢳⡀⠀⠀⠀⠀⠀⣠⣄⠀⠀⠀⠀⠀⠀⠈⢹⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⠱⣄⠀⠀⠀⠀⠻⠟⠀⠀⠀⠀⠀⢀⣠⠏⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⢺⡉⠀⠀⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⢠⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠳⡀⠀⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⡞⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢳⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀
;;⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠞⠀⠀⠀⠀
;; Personal modules
(add-to-list 'load-path (file-name-concat user-emacs-directory "modules"))
;; Must come before the rest!
(require 'syd-use-package)
(require 'syd-general)
;; `on.el' provies 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.
;; `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

View File

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

View File

@@ -0,0 +1,81 @@
;;; syd-handle-lookup.el -*- lexical-binding: t; -*-
(require 'syd-text)
(use-package better-jumper)
(require 'better-jumper)
(defvar syd-lookup-documentation-handlers '()
"An list of lookup handlers used to find documentation. A lookup handler
receives an identifier, and is expected to return nil on failure, and non-nil on
success. The specific return value is unused outside of the test for nil.")
;;;###autoload
(defun syd-lookup-documentation (identifier)
"Try to find documentation on IDENTIFIER, and "
(interactive (list (syd-thing-at-point-or-region)))
(if-let ((r (syd-lookup--jump-to 'documentation identifier
:display-fn #'pop-to-buffer)))
r
((user-error "Couldn't find documentation on %S"
(substring-no-properties identifier)))))
(defvar syd-lookup--handlers-by-category
'((documentation . syd-lookup-documentation-handlers)))
(cl-defun syd-lookup--jump-to
(category identifier &key (display-fn #'switch-to-buffer))
(let* ((handlers (alist-get category syd-lookup--handlers-by-category))
(origin (point-marker))
(result (run-hook-wrapped handlers #'syd-lookup--run-handler
identifier origin)))
(message "result wrap hok: %S" result)
(unwind-protect
(when (cond ((null result)
(message "No lookup handler could find %S" identifier)
nil)
((markerp result)
(funcall display-fn (marker-buffer result))
(goto-char result)
result)
(result))
(with-current-buffer (marker-buffer origin)
(better-jumper-set-jump (marker-position origin)))
result))
(set-marker origin nil)))
(defun syd-lookup--run-handler (handler identifier origin)
(condition-case-unless-debug e
(let ((wconf (current-window-configuration))
(result (condition-case-unless-debug e
(if (commandp handler)
(call-interactively handler)
(funcall handler identifier))
(error
(message "Lookup handler %S threw an error: %s" handler e)
'fail))))
(message "result %S" result)
(cond ((eq result 'fail)
(set-window-configuration wconf)
nil)
((or (get handler 'syd-lookup-async)
(eq result 'deferred)))
((bufferp result)
(with-current-buffer result
(point-marker)))
((or result
(null origin)
(/= (point-marker) origin))
(prog1 (point-marker)
(set-window-configuration wconf)))))
((error user-error)
(message "Lookup handler %S: %s" handler e)
nil)))
(general-def
:states 'normal
"K" #'syd-lookup-documentation)
(provide 'syd-handle-lookup)
;;; syd-handle-lookup.el ends here

View File

@@ -64,7 +64,7 @@ recognized:
or `+eval/send-region-to-repl'."
(declare (indent defun))
(dolist (mode (ensure-list modes))
(setf (alist-get mode +eval-repls)
(setf (alist-get mode +syd-major-mode-repl-alist)
(cons command plist))))

View File

@@ -0,0 +1,71 @@
;;; syd-text.el -*- lexical-binding: t; -*-
;;;###autoload
(defun syd-region-active-p ()
"Return non-nil if selection is active.
Detects evil visual mode as well."
(declare (side-effect-free t))
(or (use-region-p)
(and (bound-and-true-p evil-local-mode)
(evil-visual-state-p))))
;;;###autoload
(defun syd-region-beginning ()
"Return beginning position of selection.
Uses `evil-visual-beginning' if available."
(declare (side-effect-free t))
(or (and (bound-and-true-p evil-local-mode)
(evil-visual-state-p)
(markerp evil-visual-beginning)
(marker-position evil-visual-beginning))
(region-beginning)))
;;;###autoload
(defun syd-region-end ()
"Return end position of selection.
Uses `evil-visual-end' if available."
(declare (side-effect-free t))
(or (and (bound-and-true-p evil-local-mode)
(evil-visual-state-p)
(markerp evil-visual-end)
(marker-position evil-visual-end))
(region-end)))
;;;###autoload
(cl-defun syd-thing-at-point-or-region (&optional thing &key prompt)
"Grab the current selection, THING at point, or xref identifier at point.
Returns THING if it is a string. Otherwise, if nothing is found at point and
PROMPT is non-nil, prompt for a string (if PROMPT is a string it'll be used as
the prompting string). Returns nil if all else fails.
NOTE: Don't use THING for grabbing symbol-at-point. The xref fallback is smarter
in some cases."
(declare (side-effect-free t))
(cond ((stringp thing)
thing)
((syd-region-active-p)
(buffer-substring-no-properties
(syd-region-beginning)
(syd-region-end)))
(thing
(thing-at-point thing t))
((require 'xref nil t)
;; Eglot, nox (a fork of eglot), and elpy implementations for
;; `xref-backend-identifier-at-point' betray the documented purpose of
;; the interface. Eglot/nox return a hardcoded string and elpy
;; prepends the line number to the symbol.
(let ((backend (xref-find-backend)))
(if (memq backend '(eglot elpy nox))
(thing-at-point 'symbol t)
;; A little smarter than using `symbol-at-point', though in most
;; cases, xref ends up using `symbol-at-point' anyway.
(if-let ((ident (xref-backend-identifier-at-point backend)))
;; REVIEW: `xref-backend-identifier' seems to have some special
;; uses of text properties. Are we sure we want to remove
;; them?
(substring-no-properties ident)))))
(prompt
(read-string (if (stringp prompt) prompt "")))))
(provide 'syd-text)

View File

@@ -1,6 +1,8 @@
;;; emacs-lisp.el -*- lexical-binding: t; -*-
(require 'syd-handle-repl)
(require 'syd-handle-lookup)
;; (require 'handle)
;; Don't `use-package' `ielm', since it's loaded by Emacs. You'll get weird
;; autoload errors if you do.
@@ -20,7 +22,25 @@
(bury-buffer b)
b)))))
(add-to-list '+syd-major-mode-repl-alist
'(emacs-lisp-mode syd/open-emacs-lisp-repl))
(defun syd-emacs-lisp-lookup-documentation (identifier)
"Lookup IDENTIFIER with `describe-symbol'"
;; HACK: Much to my frustration, `describe-symbol' has no defined
;; return value. To test if the call was successful or not, we
;; check if any window is displaying the help buffer. This probably
;; breaks if `syd-emacs-lisp-lookup-documentation' is called while
;; the help buffer is already open.
(describe-symbol (intern identifier))
(let ((buffer (get-buffer (help-buffer))))
(and (get-buffer-window-list buffer)
buffer)))
(set-repl-handler! 'emacs-lisp-mode
#'syd/open-emacs-lisp-repl)
(defun syd-emacs-set-handlers ()
(setq-local syd-lookup-documentation-handlers
(list #'syd-emacs-lisp-lookup-documentation)))
(add-hook 'emacs-lisp-mode-hook #'syd-emacs-set-handlers)
(provide 'syd-lang-emacs-lisp)