emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/capf-autosuggest 7085c0a 02/63: Improve


From: ELPA Syncer
Subject: [elpa] externals/capf-autosuggest 7085c0a 02/63: Improve
Date: Wed, 27 Oct 2021 14:57:53 -0400 (EDT)

branch: externals/capf-autosuggest
commit 7085c0a47d047b23d0bbb94a755455aefe9858c0
Author: jakanakaevangeli <jakanakaevangeli@chiru.no>
Commit: jakanakaevangeli <jakanakaevangeli@chiru.no>

    Improve
---
 capf-autosuggest.el | 149 +++++++++++++++++++++++++++++++---------------------
 1 file changed, 89 insertions(+), 60 deletions(-)

diff --git a/capf-autosuggest.el b/capf-autosuggest.el
index 8c23229..324931a 100644
--- a/capf-autosuggest.el
+++ b/capf-autosuggest.el
@@ -29,7 +29,7 @@
 
 (defcustom capf-autosuggest-partial-accept-cmds
   '(forward-word
-    forward-char end-of-line end-of-visual-line
+    forward-char end-of-line move-end-of-line end-of-visual-line
     evil-forward-char evil-end-of-line evil-end-of-visual-line
     evil-end-of-line-or-visual-line evil-middle-of-visual-line
     evil-last-non-blank evil-forward-word-begin evil-forward-word-end
@@ -50,85 +50,114 @@ will use this variable.")
 
 (defvar capf-autosuggest-all-completions-only-one nil
   "Non-nil if only the first result of `all-completions' is of interest.
-capf-autosuggest binds this to t around calls to `all-completions'. Dynamic
+capf-autosuggest binds this to t around calls to `all-completions'. A dynamic
 completion table can take this as a hint to only return a list of one element
 for optimization.")
 
 (defvar-local capf-autosuggest--overlay nil)
 (defvar-local capf-autosuggest--str "")
-(defvar-local capf-autosuggest--end-boundary nil
+(defvar-local capf-autosuggest--region '(nil)
+  "Region of `completion-at-point'.")
+(defvar-local capf-autosuggest--end-inserted nil
   "End boundary of text inserted `capf-autosuggest--pre-h'.
 `capf-autosuggest--post-h' will remove text from point to this boundary if
 point is placed before it.")
 
 (defun capf-autosuggest--pre-h ()
-  "Remove autosuggest overlay.
-If `this-command' is a member of
-`capf-autosuggest-partial-accept-cmds', replace it with actual
-text so that the command that is about to be executed, can move
-point into the text. `capf-autosuggest--post-h' will arrange for
-the appropriate remaining text to be removed and replaced with an
-overlay again."
-  ;; TODO: `buffer-modified-tick'
-  (when-let* (((memq this-command capf-autosuggest-partial-accept-cmds))
-              (overlay capf-autosuggest--overlay)
-              ((overlay-buffer capf-autosuggest--overlay)))
-    (save-excursion
-      (goto-char (overlay-start overlay))
-      (insert capf-autosuggest--str)
-      (if capf-autosuggest--end-boundary
-          (set-marker capf-autosuggest--end-boundary (point))
-        (setq capf-autosuggest--end-boundary (point-marker))))
-    (delete-overlay overlay)))
+  "Insert suggested text if appropriate."
+  (and capf-autosuggest-active-mode
+       (memq this-command capf-autosuggest-partial-accept-cmds)
+       (save-excursion
+         (goto-char (overlay-start capf-autosuggest--overlay))
+         (insert capf-autosuggest--str)
+         (set-marker capf-autosuggest--end-inserted (point)))))
 
 (defun capf-autosuggest--post-h ()
-  "Create autosuggest overlay.
-Remove the actual buffer text prepared by
-`capf-autosuggest--pre-h'."
-  (when-let* ((end-boundary capf-autosuggest--end-boundary)
-              (pos (marker-position end-boundary))
-              ((< (point) pos)))
-    (delete-region (point) pos)
-    (set-marker end-boundary nil))
-  (unless completion-in-region-mode
-    (pcase (run-hook-wrapped (if (eq capf-autosuggest-capf t)
-                                 'completion-at-point-functions
-                               'capf-autosuggest-capf)
-                             #'completion--capf-wrapper 'all)
-      (`(,_fun ,beg ,end ,table . ,plist)
-       (if-let* ((completions
-                  (let ((capf-autosuggest-all-completions-only-one t))
-                    ;; Use `all-completions' rather than
-                    ;; `completion-all-completions' to bypass completion
-                    ;; styles and perform only prefix completions. This makes
-                    ;; sense here as we only use the string without the
-                    ;; prefix for the overlay.
-                    (all-completions (buffer-substring-no-properties beg end)
-                                     table (plist-get plist :predicate)))))
-           (progn
-             (if capf-autosuggest--overlay
-                 (move-overlay capf-autosuggest--overlay end end)
-               (setq capf-autosuggest--overlay (make-overlay end end nil t t)))
-             (let ((str (substring (car completions) (- end beg))))
-               (if (= 0 (length str))
-                   (delete-overlay capf-autosuggest--overlay)
-                 (setq capf-autosuggest--str (copy-sequence str))
-                 (add-text-properties 0 1 (list 'cursor (length str)) str)
-                 (add-face-text-property 0 (length str)
-                                         'capf-autosuggest-face t str)
-                 (overlay-put capf-autosuggest--overlay 'after-string
-                              str))))
-         (delete-overlay capf-autosuggest--overlay))))))
-
+  "Create an auto-suggest overlay.
+Remove text inserted by `capf-autosuggest--pre-h', but only from
+point forward."
+  (let ((end-inserted capf-autosuggest--end-inserted))
+    (when-let* ((pos (marker-position end-inserted))
+                ((< (point) pos)))
+      (delete-region (point) pos))
+    (set-marker end-inserted nil))
+
+  (if completion-in-region-mode
+      (capf-autosuggest-active-mode -1)
+    (when capf-autosuggest-active-mode
+      (unless (< (car capf-autosuggest--region) (point)
+                 (cdr capf-autosuggest--region))
+        (capf-autosuggest-active-mode -1)))
+
+    (unless capf-autosuggest-active-mode
+      (pcase (run-hook-wrapped (if (eq capf-autosuggest-capf t)
+                                   'completion-at-point-functions
+                                 'capf-autosuggest-capf)
+                               #'completion--capf-wrapper 'all)
+        (`(,_fun ,beg ,end ,table . ,plist)
+         (when-let*
+             ((completions
+               (let ((capf-autosuggest-all-completions-only-one t))
+                 ;; Use `all-completions' rather than
+                 ;; `completion-all-completions' to bypass completion
+                 ;; styles and perform only prefix completions. This makes
+                 ;; sense here as we only use the string without the
+                 ;; prefix for the overlay.
+                 (all-completions (buffer-substring-no-properties beg end)
+                                  table (plist-get plist :predicate))))
+              (str (substring (car completions) (- end beg)))
+              ((/= 0 (length str))))
+           (setq capf-autosuggest--region (cons beg end)
+                 capf-autosuggest--str (copy-sequence str))
+           (move-overlay capf-autosuggest--overlay end end)
+           (add-text-properties 0 1 (list 'cursor (length str)) str)
+           (add-face-text-property 0 (length str) 'capf-autosuggest-face t str)
+           (overlay-put capf-autosuggest--overlay 'after-string str)
+           (capf-autosuggest-active-mode)))))))
+
+;;;###autoload
 (define-minor-mode capf-autosuggest-mode
-  "Auto-suggest first completion with an overlay."
+  "Auto-suggest first completion at point with an overlay."
   :group 'completion
   (if capf-autosuggest-mode
       (progn
+        (setq capf-autosuggest--overlay (make-overlay (point) (point) nil t t))
+        (setq capf-autosuggest--end-inserted (make-marker))
         (add-hook 'pre-command-hook #'capf-autosuggest--pre-h nil t)
         (add-hook 'post-command-hook #'capf-autosuggest--post-h nil t))
     (remove-hook 'pre-command-hook #'capf-autosuggest--pre-h t)
     (remove-hook 'post-command-hook #'capf-autosuggest--post-h t)
+    (capf-autosuggest-active-mode -1)
+    (set-marker capf-autosuggest--end-inserted nil)))
+
+(defvar capf-autosuggest-active-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [remap end-of-line] #'capf-autosuggest-accept)
+    (define-key map [remap move-end-of-line] #'capf-autosuggest-accept)
+    (define-key map [remap end-of-visual-line] #'capf-autosuggest-accept)
+    map)
+  "Keymap active when an auto-suggestion is shown.")
+
+(defun capf-autosuggest-accept ()
+  "Accept current auto-suggestion."
+  (interactive)
+  (goto-char (cdr capf-autosuggest--region)))
+
+(defun capf-autosuggest--active-acf (beg end _length)
+  "Deactivate auto-suggestion on completion region changes."
+  ;; `identity' is used to generate slightly faster byte-code
+  (when (pcase-let ((`(,beg1 . ,end1) (identity capf-autosuggest--region)))
+          (if (< beg beg1)
+              (>= end beg1)
+            (<= beg end1)))
+    (capf-autosuggest-active-mode -1)))
+
+(define-minor-mode capf-autosuggest-active-mode
+  "Active when auto-suggested overlay is shown."
+  :group 'completion
+  (if capf-autosuggest-active-mode
+      (add-hook 'after-change-functions #'capf-autosuggest--active-acf nil t)
+    (remove-hook 'after-change-functions #'capf-autosuggest--active-acf t)
     (delete-overlay capf-autosuggest--overlay)))
 
 (provide 'capf-autosuggest)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]