diff --git a/README.md b/README.md index 5945815..95c1b3f 100644 --- a/README.md +++ b/README.md @@ -149,12 +149,28 @@ document and interactively substitute them: ![Construct Example](media/construct.gif) -If the `ocaml-eglot-construct` command is prefixed by an argument, ie: -`C-u M-x ocaml-eglot-construct`, the command will also search for -valid candidates in the current environment: +If the `ocaml-eglot-construct` (C-c \) command +is prefixed by an argument, ie: `C-u M-x ocaml-eglot-construct`, the +command will also search for valid candidates in the current +environment: ![Construct with prefix-arg Example](media/construct2.gif) +### Destruct (or case-anlysis) + +Destruct, `ocaml-eglot-destruct` (C-c |) is a +powerful feature that allows one to generate and manipulate pattern +matching expressions. It behaves differently depending on the cursor’s +context: + +- on an expression: it replaces it by a pattern matching over it’s + constructors +- on a wildcard pattern: it will refine it if possible +- on a pattern of a non-exhaustive matching: it will make the pattern + matching exhaustive by adding missing cases + +![Destruct Example](media/destruct.gif) + ### Source Browsing OCaml-eglot allows you to navigate semantically in a buffer, passing diff --git a/media/destruct.gif b/media/destruct.gif new file mode 100644 index 0000000..3a89d09 Binary files /dev/null and b/media/destruct.gif differ diff --git a/ocaml-eglot-req.el b/ocaml-eglot-req.el index e2e56ad..9a32a5f 100644 --- a/ocaml-eglot-req.el +++ b/ocaml-eglot-req.el @@ -175,5 +175,14 @@ VERBOSITY is a potential verbosity index." (let ((params (ocaml-eglot-req--TypeEnclosingParams at index verbosity))) (ocaml-eglot-req--send :ocamllsp/typeEnclosing params))) +(defun ocaml-eglot-req--call-code-action (action-kind) + "Call ACTION-KIND promptly." + (eglot-code-actions nil nil action-kind t)) + +(defun ocaml-eglot-req--destruct () + "Call code-action `destruct' for a given position." + (let ((action-kind "destruct (enumerate cases)")) + (ocaml-eglot-req--call-code-action action-kind))) + (provide 'ocaml-eglot-req) ;;; ocaml-eglot-req.el ends here diff --git a/ocaml-eglot.el b/ocaml-eglot.el index 6febcc3..3d05848 100644 --- a/ocaml-eglot.el +++ b/ocaml-eglot.el @@ -404,8 +404,7 @@ of result (LIMIT)." It use the ARG to use local values or not." (interactive "P") (eglot--server-capable-or-lose :experimental :ocamllsp :handleConstruct) - (let* ((_with-local-values (ocaml-eglot--construct-local-values arg)) - (current-range (ocaml-eglot-util--current-range)) + (let* ((current-range (ocaml-eglot-util--current-range)) (start (cl-getf current-range :start)) (end (cl-getf current-range :end)) (hole (ocaml-eglot--get-first-hole-in start end))) @@ -458,6 +457,13 @@ If called repeatedly, increase the verbosity of the type shown." (interactive) (ocaml-eglot-type-enclosing--call)) +;; Case Analysis + +(defun ocaml-eglot-destruct () + "Perform case-analysis at the current point." + (interactive) + (ocaml-eglot-req--destruct)) + ;;; Mode (defvar ocaml-eglot-map @@ -469,6 +475,8 @@ If called repeatedly, increase the verbosity of the type shown." (define-key ocaml-eglot-keymap (kbd "C-c C-a") #'ocaml-eglot-alternate-file) (define-key ocaml-eglot-keymap (kbd "C-c C-d") #'ocaml-eglot-document) (define-key ocaml-eglot-keymap (kbd "C-c C-t") #'ocaml-eglot-type-enclosing) + (define-key ocaml-eglot-keymap (kbd "C-c |") #'ocaml-eglot-destruct) + (define-key ocaml-eglot-keymap (kbd "C-c \\") #'ocaml-eglot-construct) ocaml-eglot-keymap) "Keymap for OCaml-eglot minor mode.")