Skip to content

Commit

Permalink
Provide a unified (lsp-interface INTERFACE ...) pcase form
Browse files Browse the repository at this point in the history
This commit provides a new unified pcase form (lsp-interface INTERFACE ...) to
replace the old per-interface (INTERFACE ...) forms -- the latter are now
deprecated. (Unfortunately, I don't think there's a way to mark a pcase form as
obsolete.)

I've turned the existing pcase-defmacro definition into a helper function. The
new pcase form delegates to that helper function, and the old pcase forms now
delegate to the new form.

This change addresses a few issues, which are detailed in emacs-lsp#4430. In short:

* The existing forms aren't namespaced.
* The lsp-mode package adds hundreds of forms, which each add several lines to
  pcase's generated docstring, adding up to over 1000 lines.
* Starting in Emacs 31, the number of forms added by lsp-mode causes a
  noticeable slowdown when loading the interactive help for pcase.
  • Loading branch information
chrisbouchard committed Sep 24, 2024
1 parent 6447c32 commit 2a4fa1f
Showing 1 changed file with 18 additions and 1 deletion.
19 changes: 18 additions & 1 deletion lsp-protocol.el
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Allowed params: %s" interface (reverse (-map #'cl-first params)))
$$result))
(-partition 2 plist))
$$result)))
`(pcase-defmacro ,interface (&rest property-bindings)
`(cl-defun ,(intern (format "lsp--pcase-macroexpander-%s" interface)) (&rest property-bindings)
,(if lsp-use-plists
``(and
(pred listp)
Expand Down Expand Up @@ -225,6 +225,8 @@ Allowed params: %s" interface (reverse (-map #'cl-first params)))
output-bindings)
(setf current-list (cddr current-list))))))
output-bindings))))
`(pcase-defmacro ,interface (&rest property-bindings)
`(lsp-interface ,',interface ,@property-bindings))
(-mapcat (-lambda ((label . name))
(list
`(defun ,(intern (format "lsp:%s-%s"
Expand All @@ -246,6 +248,21 @@ Allowed params: %s" interface (reverse (-map #'cl-first params)))
(apply #'append)
(cl-list* 'progn))))

(pcase-defmacro lsp-interface (interface &rest property-bindings)
"If EXPVAL is an instance of the LSP interface INTERFACE, destructure its
properties.
Each :PROPERTY key may be followed by an optional PATTERN, which is a `pcase'
pattern to apply to the property value. Otherwise, PROPERTY is bound to the
property value.
\(fn INTERFACE [:PROPERTY [PATTERN]]...)"
(cl-check-type interface symbol)
(let ((lsp-pcase-macroexpander
(intern (format "lsp--pcase-macroexpander-%s" interface))))
(cl-assert (fboundp lsp-pcase-macroexpander) "not a known LSP interface: %s" interface)
(apply lsp-pcase-macroexpander property-bindings)))

(if lsp-use-plists
(progn
(defun lsp-get (from key)
Expand Down

0 comments on commit 2a4fa1f

Please sign in to comment.