From bc32473147e21d769447e87306b13ffd4aa1fc65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Thu, 29 Nov 2018 22:36:03 +0000 Subject: [PATCH] Per #171,#156: Introduce eglot--dcase (tests pending) * eglot.el (eglot--dcase): New macro. --- eglot.el | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/eglot.el b/eglot.el index 594a638a..ed782544 100644 --- a/eglot.el +++ b/eglot.el @@ -281,6 +281,44 @@ Honour `eglot-strict-mode'." (let ((e (cl-gensym "jsonrpc-lambda-elem"))) `(lambda (,e) (eglot--dbind ,cl-lambda-list ,e ,@body)))) +(cl-defmacro eglot--dcase (obj &rest clauses) + (let ((obj-once (make-symbol "obj-once"))) + `(let ((,obj-once ,obj)) + (cond + ,@(cl-loop + for (vars . body) in clauses + for vars-as-keywords = (mapcar (lambda (var) + (intern (format ":%s" var))) + vars) + for interface-name = (if (consp (car vars)) + (car (pop vars))) + for condition = + (if interface-name + `(let* ((interface + (or (assoc ',interface-name eglot--lsp-interface-alist) + (eglot--error "Unknown interface %s"))) + (object-keys (plist-keys ,obj-once)) + (required-keys (car (cdr interface)))) + (and (null (cl-set-difference required-keys object-keys)) + (or (null (memq 'disallow-non-standard-keys + eglot-strict-mode)) + (null (cl-set-difference + (cl-set-difference object-keys required-keys) + (cadr (cdr interface))))))) + ;; In this interface-less mode we don't check + ;; `eglot-strict-mode' at all. + `(null (cl-set-difference + ',vars-as-keywords + (eglot--plist-keys ,obj-once)))) + collect `(,condition + (cl-destructuring-bind (&key ,@vars &allow-other-keys) + ,obj-once + ,@body))) + (t + (eglot--error "%s didn't match any of %s" + ,obj-once + ',(mapcar #'car clauses))))))) + ;;; API (WORK-IN-PROGRESS!) ;;;