|
78 | 78 | (set-window-configuration wnd) |
79 | 79 | conn)))) |
80 | 80 |
|
| 81 | +(defun lispy--find-lisp-package (package-name) |
| 82 | + "Return either a CL expression to find the given package, or if |
| 83 | +PACKAGE-NAME is nil the package we found in the Lisp buffer." |
| 84 | + (let ((package-via-buffer |
| 85 | + (upcase (string-replace |
| 86 | + "#:" "" |
| 87 | + (if (lispy--use-sly-p) |
| 88 | + (sly-current-package) |
| 89 | + (slime-current-package)))))) |
| 90 | + (if (null package-name) |
| 91 | + package-via-buffer |
| 92 | + ;; The package local nickname is either defined in our current package or |
| 93 | + ;; from a different "home package". In case of the latter we can simply |
| 94 | + ;; rely on `cl:define-package' to figure it out for us. Note that we use |
| 95 | + ;; `cl:ignore-errors' for when a package either can't be found or might |
| 96 | + ;; not have been loaded yet. |
| 97 | + `(cl:or (cl:ignore-errors |
| 98 | + (,(if (lispy--use-sly-p) 'slynk-backend:find-locally-nicknamed-package |
| 99 | + 'swank/backend:find-locally-nicknamed-package) |
| 100 | + ,(upcase package-name) |
| 101 | + (cl:find-package ,package-via-buffer))) |
| 102 | + (cl:find-package ,(upcase package-name)))))) |
| 103 | + |
81 | 104 | (defun lispy--lisp-args (symbol) |
82 | 105 | "Return a pretty string with arguments for SYMBOL." |
83 | | - (let ((args |
84 | | - (list |
85 | | - (mapconcat |
86 | | - #'prin1-to-string |
87 | | - (read (lispy--eval-lisp |
88 | | - (format (if (lispy--use-sly-p) |
89 | | - "(slynk-backend:arglist #'%s)" |
90 | | - "(swank-backend:arglist #'%s)") |
91 | | - symbol))) |
92 | | - " ")))) |
93 | | - (if (listp args) |
94 | | - (format |
95 | | - "(%s %s)" |
96 | | - (propertize symbol 'face 'lispy-face-hint) |
97 | | - (mapconcat |
98 | | - #'identity |
99 | | - (mapcar (lambda (x) (propertize (downcase x) |
100 | | - 'face 'lispy-face-req-nosel)) |
101 | | - args) |
102 | | - (concat "\n" |
103 | | - (make-string (+ 2 (length symbol)) ?\ )))) |
104 | | - (propertize args 'face 'lispy-face-hint)))) |
| 106 | + (if-let* ((lisp-arglist |
| 107 | + (if (lispy--use-sly-p) |
| 108 | + (sly-eval |
| 109 | + `(slynk:operator-arglist |
| 110 | + ,(sly-cl-symbol-name symbol) |
| 111 | + ,(lispy--find-lisp-package (sly-cl-symbol-package symbol)))) |
| 112 | + (slime-eval |
| 113 | + `(swank:operator-arglist |
| 114 | + ,(slime-cl-symbol-name symbol) |
| 115 | + ,(lispy--find-lisp-package (slime-cl-symbol-package symbol)))))) |
| 116 | + (args (list (mapconcat #'prin1-to-string (read lisp-arglist) " ")))) |
| 117 | + (let* ((symbol-package (if (lispy--use-sly-p) (sly-cl-symbol-package symbol) |
| 118 | + (slime-cl-symbol-package symbol))) |
| 119 | + (package-prefixed-arglist (format "(%s:" symbol-package))) |
| 120 | + ;; In Lisp, it is often the case we prefix low level packages with a `%' |
| 121 | + ;; symbol. This is problematic in Elisp with `format'. For example, `%g' |
| 122 | + ;; can have special meaning. We can eliminate this edge case by always |
| 123 | + ;; concatenating. |
| 124 | + (concat |
| 125 | + (if symbol-package package-prefixed-arglist "(") |
| 126 | + (format "%s" |
| 127 | + (mapconcat |
| 128 | + #'identity |
| 129 | + (mapcar (lambda (x) |
| 130 | + (propertize (downcase x) |
| 131 | + 'face 'lispy-face-req-nosel)) |
| 132 | + args) |
| 133 | + (concat "\n" (make-string (+ 2 (length symbol)) ?\ )))) |
| 134 | + ")")) |
| 135 | + (format "Could not find symbol %s" (upcase symbol)))) |
105 | 136 |
|
106 | 137 | (defun lispy--lisp-describe (symbol) |
107 | 138 | "Return documentation for SYMBOL." |
|
0 commit comments