(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))
(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
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))))))))
(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
: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
;; - 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))
(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)