From 1ce40ad71aac540c152cb4352e77a2606b0e5f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Fri, 22 Jan 2021 11:53:37 +0100 Subject: [PATCH 1/2] Simple emacs construct bindings - Replace immediately when only one result - Jump to the first hole of the constructed expression --- emacs/merlin.el | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/emacs/merlin.el b/emacs/merlin.el index a18d50ffb6..050990dc66 100644 --- a/emacs/merlin.el +++ b/emacs/merlin.el @@ -1308,6 +1308,18 @@ strictly within, or nil if there is no such element." (merlin--goto-point start) (message "%s" typ))))))) +(defun merlin--first-hole-between (pmin pmax) + "Jump to the first hole in the given range and prints its type" + (let* ((hole (merlin--first-hole (merlin--holes) pmin '>))) + (when hole + (let* ((start (merlin-lookup 'start hole)) + (typ (merlin-lookup 'type hole)) + (hole-point (merlin-make-point start))) + (if (<= hole-point pmax) + (progn + (merlin--goto-point start) + (message "%s" typ))))))) + (defun merlin-next-hole () "Jump to the next hole and print its type" (interactive) @@ -1358,6 +1370,45 @@ strictly within, or nil if there is no such element." (cons (region-beginning) (region-end)) (cons (point) (point))))) +;;;;;;;;;;;;;;; +;; CONSTRUCT ;; +;;;;;;;;;;;;;;; + + +(defun merlin--construct-complete (start stop results) + (let ((start (merlin--point-of-pos start)) + (stop (merlin--point-of-pos stop))) + (cl-labels ((insert-choice (_b _e newtext) + (completion--replace start stop newtext) + (merlin--first-hole-between start (+ start (length newtext))))) + (if (= (length results) 1) + (insert-choice 0 0 (car results)) + (with-output-to-temp-buffer "*Constructions*" + (progn + (with-current-buffer "*Constructions*" + (setq-local + completion-list-insert-choice-function + #'insert-choice)) + (display-completion-list results))))))) + +(defun merlin--construct-point (point) + "Execute a construct on POINT" + (progn + (ignore point) ; Without this Emacs bytecode compiler complains about an + ; unused variable. This may be a bug in the compiler + (let ((result (merlin-call "construct" + "-position" (merlin-unmake-point (point))))) + (when result + (let* ((loc (car result)) + (start (cdr (assoc 'start loc))) + (stop (cdr (assoc 'end loc)))) + (merlin--construct-complete start stop (cadr result))))))) + +(defun merlin-construct () + "Construct over the current hole" + (interactive) + (merlin--construct-point (cons (point) (point)))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; PACKAGE, PROJECT AND FLAGS MANAGEMENT ;; From f3f7dac1597b898f3f38241e73a9b51788342c43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Tue, 15 Jun 2021 15:36:02 +0200 Subject: [PATCH 2/2] Add changelog entry --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d0075aba35..f1b2f1adef 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,8 @@ git version - vim: add a simple interface to the new `construct` command: `MerlinConstruct`. When several results are suggested, `` and `` to show more or less deep results. (#1318) + - emacs: add a simple interface to the new `construct` command: + `merlin-construct`. (#1352) + test suite - cover the new `construct` command (#1318)