branch: externals/dape
commit a55f8d7196afd9f92b1bf2e600c799e4acf709c9
Author: Daniel Pettersson <[email protected]>
Commit: Daniel Pettersson <[email protected]>

    Rework `dape--read-config'
    
    When using default `completing-read-default' function it was not
    possible to add args to mini buffer read. It worked great with stuff
    like vertico. Instead use custom read function with
    completion-at-point.
---
 dape.el | 111 ++++++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 81 insertions(+), 30 deletions(-)

diff --git a/dape.el b/dape.el
index 7099a80ef0..2a6672dc2b 100644
--- a/dape.el
+++ b/dape.el
@@ -303,9 +303,6 @@ The hook is run with one argument, the compilation buffer."
 (defvar dape--repl-insert-text-guard nil
   "Guard var for *dape-repl* buffer text updates.")
 
-(defvar dape--config-history nil
-  "History of used dape configs.  See `dape--read-config'.")
-
 
 ;;; Utils
 
@@ -2526,6 +2523,9 @@ Empty input will rerun last command.\n\n\n"
 
 (defvar dape-history nil
   "History variable for `dape'.")
+(defvar dape-session-history nil
+  "Current sessions `dape--read-config' history.
+Used to derive initial-contents in `dape--read-config'.")
 
 (defun dape--config-eval-value (value &optional skip-function for-adapter)
   "Evaluate dape config VALUE.
@@ -2537,8 +2537,8 @@ apply."
                           (funcall-interactively value)))
    ((plistp value) (dape--config-eval-1 value skip-function for-adapter))
    ((vectorp value) (cl-map 'vector
-                            (lambda (v)
-                              (dape--config-eval-value v
+                            (lambda (value)
+                              (dape--config-eval-value value
                                                        skip-function
                                                        for-adapter))
                             value))
@@ -2626,32 +2626,83 @@ arrays [%S ...], if meant as an object replace (%S ...) 
with (:%s ...)"
                         (memql mode (plist-get dape--config 'modes)))
                       modes)))))
 
+(defun dape--config-completion-at-point ()
+  "Function for `completion-at-point' fn for `dape--read-config'."
+  (pcase-let ((`(,key . ,args) (ignore-errors
+                                 (read (format "(%s)" (thing-at-point 
'line)))))
+              (symbol-bounds (bounds-of-thing-at-point 'symbol))
+              (line-bounds (bounds-of-thing-at-point 'line))
+              (whitespace-bounds (bounds-of-thing-at-point 'whitespace)))
+    (cond
+     ;; Complete config key
+     ((or (not key)
+          (and (not args) symbol-bounds))
+      (let ((bounds (or line-bounds (cons (point) (point)))))
+      (list (car bounds) (cdr bounds)
+            (mapcar (lambda (name) (format "%s " name))
+                    dape--minibuffer-suggested-configs))))
+     ;; Complete config args
+     ((and (alist-get key dape-configs)
+           (or (and (not (plistp args))
+                    symbol-bounds)
+               (and (plistp args)
+                    whitespace-bounds)))
+      (let ((args (if symbol-bounds
+                      (nreverse (cdr (nreverse args)))
+                    args))
+            (bounds (or symbol-bounds (cons (point) (point))))
+            (base-config (append (alist-get key dape-configs)
+                                 (cons 'compile nil))))
+        (list (car bounds) (cdr bounds)
+              (cl-loop for (key value) on base-config by 'cddr
+                       unless (plist-member args key)
+                       when (or (eq key 'compile) (keywordp key))
+                       collect (format "%s " key))))))))
+
+(defvar dape--minibuffer-suggested-configs nil
+  "Suggested configurations in minibuffer.")
+
 (defun dape--read-config ()
-  "Read Dape config."
-  (if (null dape-configs)
-      (customize-variable 'dape-configs)
-    (let ((candidate
-           (completing-read "Run adapter: "
-                             (mapcan
-                              (lambda (name-config)
-                                (let* ((config (cdr-safe name-config)))
-                                  (when (dape--config-mode-p config)
-                                    (list (car name-config)))))
-                              (append dape--config-history dape-configs))
-                            nil nil nil 'dape-history))
-          name config)
-      (if-let ((base-config (alist-get (intern candidate) dape-configs)))
-          (setq name (intern candidate)
-                config base-config)
-        (pcase-let ((`(,p-name ,p-config)
-                     (dape--config-from-string candidate)))
-          (setq name p-name
-                config p-config)))
-      (let* ((evaled-config (dape--config-eval name config))
-             (string-repr (dape--config-to-string name evaled-config)))
-        ;; HACK Set evaled config as the first history element
-        (setq dape-history (cons string-repr dape-history))
-        (push (cons string-repr evaled-config) dape--config-history)
+  "Read config from minibuffer.
+Initial contents defaults to valid configuration if there is only one
+or last mode valid history item from this session.
+
+See `dape--config-mode-p' how \"valid\" is defined."
+  (let* ((suggested-configs
+          (cl-loop for (key . config) in dape-configs
+                   if (dape--config-mode-p config)
+                   collect key))
+         (initial-contents
+          (or
+           ;; Take first valid history item from session
+           (seq-find (lambda (str)
+                          (ignore-errors
+                            (memql (car (dape--config-from-string str))
+                                   suggested-configs)))
+                        dape-session-history)
+           ;; Take first suggested config if only one exist
+           (and (length= suggested-configs 1)
+                (symbol-name (car suggested-configs))))))
+    (minibuffer-with-setup-hook
+        (lambda ()
+          (setq-local dape--minibuffer-suggested-configs suggested-configs)
+          (set-syntax-table emacs-lisp-mode-syntax-table)
+          (add-hook 'completion-at-point-functions
+                    #'dape--config-completion-at-point nil t))
+      (pcase-let* ((str (read-from-minibuffer "Run adapter: "
+                                              initial-contents
+                                              read--expression-map nil
+                                              'dape-history
+                                              initial-contents))
+                   (`(,key ,config) (dape--config-from-string
+                                     (substring-no-properties str)))
+                   (evaled-config (dape--config-eval key config)))
+        (setq dape-session-history
+              (cons (dape--config-to-string key evaled-config)
+                    dape-session-history))
+        (setq dape-history
+              (cons (dape--config-to-string key evaled-config)
+                    dape-history))
         evaled-config))))
 
 

Reply via email to