;;; 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