branch: elpa/idris-mode
commit 7c0cbfa11b2e030ddf125be29af0cb70cc305edd
Author: Marek L <[email protected]>
Commit: Marek L <[email protected]>

    Improve repl completion by complete only current word in
    
    multi-token input, not whole input
    Previously, completion always sent the entire REPL input to the
    compiler.
    For example:
    
    ```
    Idris>
    Idris> :doc prin
    ```
    When we try to complete `prin` we used to send to Idris
    `(:repl-completions ":doc prin")` which fails.
    
    Now, when the input contains whitespace, completion operates
    on the identifier at point instead.
    After change we send only `(:repl-completions "prin")`
    which gives us back `(:ok (("printLn" "print") ""))`.
---
 idris-repl.el | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/idris-repl.el b/idris-repl.el
index aa5fbadd88..add8346f19 100644
--- a/idris-repl.el
+++ b/idris-repl.el
@@ -334,12 +334,28 @@ Invokes `idris-repl-mode-hook'."
 (defun idris-repl-complete ()
   "Completion of the current input."
   (when idris-completion-via-compiler
-    (let* ((input (idris-repl-current-input))
-           (result (idris-eval `(:repl-completions ,input))))
-      (cl-destructuring-bind (completions partial) (car result)
-        (if (null completions)
-            nil
-          (list (+ idris-input-start (length partial)) (point-max) 
completions))))))
+    (when-let* ((thing (idris-repl--thing-to-complete))
+                (result (idris-eval `(:repl-completions ,(car thing)))))
+      (pcase (car result)
+        (`(,completions ,partial)
+         (when completions
+           (list (+ (cdr thing) (length partial)) (point-max) 
completions)))))))
+
+(defun idris-repl--thing-to-complete ()
+  (let ((input (idris-repl-current-input)))
+    (if (string-match-p "\\s-" input)
+        (when-let* ((bounds (idris-repl--word-bounds)))
+          (cons (buffer-substring-no-properties (car bounds) (cdr bounds))
+                (car bounds)))
+      (cons input idris-input-start))))
+
+(defun idris-repl--word-bounds ()
+  "Return (START . END) of the Idris identifier at point, or nil."
+  (save-excursion
+    (let ((end (point)))
+      (skip-chars-backward "[:alnum:]_.'")
+      (unless (= (point) end)
+        (cons (point) end)))))
 
 (defun idris-repl-begin-of-prompt ()
   "Go to the beginning of line or the prompt."

Reply via email to