]> git.eshelyaron.com Git - emacs.git/commitdiff
More improvements for new search commands
authorEshel Yaron <me@eshelyaron.com>
Fri, 12 Jul 2024 10:43:46 +0000 (12:43 +0200)
committerEshel Yaron <me@eshelyaron.com>
Fri, 12 Jul 2024 10:43:46 +0000 (12:43 +0200)
lisp/minibuffer.el
lisp/search.el

index cdd25bdb46aa9c6ef88aab60f2fd5997ee997943..d4570d36a5a1185949d69f45420e980a199e96cc 100644 (file)
@@ -2013,6 +2013,7 @@ Interactively, ARG is the prefix argument, and it defaults to 1."
         (completion--replace base end cur)
         (setq end (+ base (length cur)))
         (completion--done (buffer-substring-no-properties start (point)) 'sole
+                          ;; TODO: Maybe use prompt indicator instead.
                           (propertize
                            (concat "/" (number-to-string
                                         (let ((all all) (n 1))
@@ -2027,8 +2028,7 @@ Interactively, ARG is the prefix argument, and it defaults to 1."
           (setq completion-all-sorted-completions (cdr all)))
         (set-transient-map
          (let ((map (make-sparse-keymap)))
-           (define-key map (vector last-command-event)
-                       #'minibuffer-cycle-completion)
+           (define-key map (vector last-command-event) this-command)
            map)
          (lambda ()
            (member this-command
@@ -2036,7 +2036,8 @@ Interactively, ARG is the prefix argument, and it defaults to 1."
                      negative-argument
                      digit-argument
                      minibuffer-cycle-completion
-                     minibuffer-apply-and-cycle-completion)))
+                     minibuffer-apply-and-cycle-completion
+                     minibuffer-cycle-completion-and-apply)))
          (lambda ()
            (setq completion-all-sorted-completions nil))))))))
 
@@ -2047,6 +2048,13 @@ Interactively, ARG is the prefix argument, and it defaults to 1."
     (minibuffer-apply (car input-prefix) (cdr input-prefix)))
   (minibuffer-cycle-completion n))
 
+(defun minibuffer-cycle-completion-and-apply (n)
+  "Cycle N candidates forward and apply minibuffer action to that candidate."
+  (interactive "p" minibuffer-mode)
+  (minibuffer-cycle-completion n)
+  (let ((input-prefix (minibuffer-current-input)))
+    (minibuffer-apply (car input-prefix) (cdr input-prefix))))
+
 (defvar minibuffer-confirm-exit-commands
   '(completion-at-point minibuffer-complete)
   "List of commands which cause an immediately following
@@ -3509,7 +3517,8 @@ The completion method is determined by `completion-at-point-functions'."
   :parent minibuffer-local-map
   "TAB"       #'minibuffer-complete
   "C-o"       #'minibuffer-cycle-completion
-  "C-M-o"     #'minibuffer-apply-and-cycle-completion
+  "C-M-o"     #'minibuffer-cycle-completion-and-apply
+  "C-M-S-o"   #'minibuffer-apply-and-cycle-completion
   "C-l"       #'minibuffer-restore-completion-input
   "C-S-a"     #'minibuffer-toggle-completion-ignore-case
   "?"         #'minibuffer-completion-help
index 553eb6a9e437f0e545d9c72bdd7f0337b12c60f5..84044cc0b20a7d0984c179bc869a7506645c2a38 100644 (file)
 
 ;; - Support multi-buffer `search'.
 ;; - Add regexp completion style and use it for `search' completion.
-;; - Restore initial position on quit.
-;; - Place mark at initial position.
 ;; - Add replace support.
 ;; - Isearch-to-search and vice versa.
 ;; - Search non-matches.
 ;; - Highlight subgroups in matches.
 ;; - Improve documentation.
-;; - In minibuffer, on `C-M-o', cycle forward first and then act.
-;; - Pulse final selection.
 
 ;;; Code:
 
   '((t :inherit highlight :foreground "black"))
   "Foo.")
 
+(defun search--go-to (target)
+  "Go to TARGET."
+  (let ((pos (string-to-number target)))
+    (unless (zerop pos) (goto-char pos))))
+
 (defun search-read-target (&optional beg end re-or-fn)
   "Prompt for \\[search] target between BEG and END matching RE-OR-FN."
   (let* ((buffer (current-buffer))
@@ -86,7 +87,7 @@
                       (cons
                        (lambda (c)
                          (with-selected-window (minibuffer-selected-window)
-                           (search c)
+                           (unless (search--go-to c) (user-error "Invalid search target"))
                            (when (overlayp cur) (overlay-put cur 'face 'lazy-highlight))
                            (setq cur (seq-some
                                       (lambda (ov) (and (overlay-get ov 'search) ov))
                        "search"))
                 (let ((hook-fn
                        (lambda (input)
-                         (mapc #'delete-overlay ovz)
-                         (setq ovz nil)
-                         (with-current-buffer buffer
-                           (dolist (ov ovs)
-                             (save-excursion
-                               (goto-char (overlay-start ov))
-                               (let ((r (regexp-quote input))
-                                     (e (overlay-end ov)))
-                                 (while (re-search-forward r e t)
-                                   (push (make-overlay (match-beginning 0)
-                                                       (match-end 0))
-                                         ovz)
-                                   (overlay-put (car ovz) 'face 'search-highlight)
-                                   (overlay-put (car ovz) 'search-input t)
-                                   (overlay-put (car ovz) 'priority '(nil . 10))))))))))
+                         (unless (string-empty-p input)
+                           (mapc #'delete-overlay ovz)
+                           (setq ovz nil)
+                           (with-current-buffer buffer
+                             (dolist (ov ovs)
+                               (save-excursion
+                                 (goto-char (overlay-start ov))
+                                 (let ((r (regexp-quote input))
+                                       (e (overlay-end ov)))
+                                   (while (re-search-forward r e t)
+                                     (push (make-overlay (match-beginning 0)
+                                                         (match-end 0))
+                                           ovz)
+                                     (overlay-put (car ovz) 'face 'search-highlight)
+                                     (overlay-put (car ovz) 'search-input t)
+                                     (overlay-put (car ovz) 'priority '(nil . 10)))))))))))
                   (add-hook 'minibuffer-new-completion-input-hook
                             (lambda () (funcall hook-fn (caar completion-history)))
                             nil t)
 (defun search (target)
   "Search for TARGET."
   (interactive
-   (list (search-read-target (use-region-beginning) (use-region-end))))
-  (let ((pos (string-to-number target)))
-    (if (zerop pos)
-        (user-error "Invalid search target")
-      (goto-char pos))))
+   (list
+    (save-excursion (search-read-target (use-region-beginning) (use-region-end)))))
+  (push-mark)
+  (unless (search--go-to target) (user-error "Invalid search target"))
+  (seq-let (beg end _) (split-string target ":")
+    (pulse-momentary-highlight-region (string-to-number beg)
+                                      (string-to-number end)
+                                      'isearch)))
 
 ;;;###autoload
 (defun search-lines (target)
   "Search for TARGET line."
   (interactive
-   (list (search-read-target (use-region-beginning) (use-region-end) ".*")))
+   (list (save-excursion
+           (search-read-target (use-region-beginning) (use-region-end) ".*"))))
   (search target))
 
 (provide 'search)