From d70b1e1571ef1f0fd73db45e8cd169fa4aa1becb Mon Sep 17 00:00:00 2001 From: zyd Date: Wed, 25 Sep 2024 22:24:28 -0600 Subject: [PATCH 1/2] Fix the display of inline arglist --- le-lisp.el | 75 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 22 deletions(-) diff --git a/le-lisp.el b/le-lisp.el index ab8061ea..4286d363 100644 --- a/le-lisp.el +++ b/le-lisp.el @@ -78,30 +78,61 @@ (set-window-configuration wnd) conn)))) +(defun lispy--find-lisp-package (package-name) + "Return either a CL expression to find the given package, or if +PACKAGE-NAME is nil the package we found in the Lisp buffer." + (let ((package-via-buffer + (upcase (string-replace + "#:" "" + (if (lispy--use-sly-p) + (sly-current-package) + (slime-current-package)))))) + (if (null package-name) + package-via-buffer + ;; The package local nickname is either defined in our current package or + ;; from a different "home package". In case of the latter we can simply + ;; rely on `cl:define-package' to figure it out for us. Note that we use + ;; `cl:ignore-errors' for when a package either can't be found or might + ;; not have been loaded yet. + `(cl:or (cl:ignore-errors + (,(if (lispy--use-sly-p) 'slynk-backend:find-locally-nicknamed-package + 'swank/backend:find-locally-nicknamed-package) + ,(upcase package-name) + (cl:find-package ,package-via-buffer))) + (cl:find-package ,(upcase package-name)))))) + (defun lispy--lisp-args (symbol) "Return a pretty string with arguments for SYMBOL." - (let ((args - (list - (mapconcat - #'prin1-to-string - (read (lispy--eval-lisp - (format (if (lispy--use-sly-p) - "(slynk-backend:arglist #'%s)" - "(swank-backend:arglist #'%s)") - symbol))) - " ")))) - (if (listp args) - (format - "(%s %s)" - (propertize symbol 'face 'lispy-face-hint) - (mapconcat - #'identity - (mapcar (lambda (x) (propertize (downcase x) - 'face 'lispy-face-req-nosel)) - args) - (concat "\n" - (make-string (+ 2 (length symbol)) ?\ )))) - (propertize args 'face 'lispy-face-hint)))) + (if-let* ((lisp-arglist + (if (lispy--use-sly-p) + (sly-eval + `(slynk:operator-arglist + ,(sly-cl-symbol-name symbol) + ,(lispy--find-lisp-package (sly-cl-symbol-package symbol)))) + (slime-eval + `(swank:operator-arglist + ,(slime-cl-symbol-name symbol) + ,(lispy--find-lisp-package (slime-cl-symbol-package symbol)))))) + (args (list (mapconcat #'prin1-to-string (read lisp-arglist) " ")))) + (let* ((symbol-package (if (lispy--use-sly-p) (sly-cl-symbol-package symbol) + (slime-cl-symbol-package symbol))) + (package-prefixed-arglist (format "(%s:" symbol-package))) + ;; In Lisp, it is often the case we prefix low level packages with a `%' + ;; symbol. This is problematic in Elisp with `format'. For example, `%g' + ;; can have special meaning. We can eliminate this edge case by always + ;; concatenating. + (concat + (if symbol-package package-prefixed-arglist "(") + (format "%s" + (mapconcat + #'identity + (mapcar (lambda (x) + (propertize (downcase x) + 'face 'lispy-face-req-nosel)) + args) + (concat "\n" (make-string (+ 2 (length symbol)) ?\ )))) + ")")) + (format "Could not find symbol %s" (upcase symbol)))) (defun lispy--lisp-describe (symbol) "Return documentation for SYMBOL." From b462d67fc7e81c722aeef2b5dec1baeacbe581df Mon Sep 17 00:00:00 2001 From: zyd Date: Tue, 1 Oct 2024 18:25:47 -0600 Subject: [PATCH 2/2] Do nothing when there isn't a symbol at point --- lispy-inline.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lispy-inline.el b/lispy-inline.el index 7b019234..ce98907e 100644 --- a/lispy-inline.el +++ b/lispy-inline.el @@ -176,8 +176,9 @@ The caller of `lispy--show' might use a substitute e.g. `describe-function'." ((eq major-mode 'lisp-mode) (require 'le-lisp) - (setq lispy-hint-pos (point)) - (lispy--show (lispy--lisp-args (lispy--current-function)))) + (when-let ((sym (lispy--current-function))) + (setq lispy-hint-pos (point)) + (lispy--show (lispy--lisp-args sym)))) ((eq major-mode 'python-mode) (require 'le-python)