(let ((map (make-sparse-keymap)))
(define-key map (kbd "M-q") 'swiper-query-replace)
(define-key map (kbd "C-l") 'swiper-recenter-top-bottom)
+ (define-key map (kbd "C-'") 'swiper-avy)
map)
"Keymap for swiper.")
+(defvar swiper--window nil
+ "Store the current window.")
+
(defun swiper-query-replace ()
"Start `query-replace' with string to replace from last search string."
(interactive)
(from (ivy--regex ivy-text))
(to (query-replace-read-to from "Query replace" t)))
(delete-minibuffer-contents)
- (ivy-set-action (lambda ()
+ (ivy-set-action (lambda (_)
(with-selected-window swiper--window
(perform-replace from to
t t nil))))
(swiper--cleanup)
(exit-minibuffer))))
-(defvar swiper--window nil
- "Store the current window.")
+(defvar avy-background)
+(declare-function avy--regex-candidates "ext:avy")
+(declare-function avy--process "ext:avy")
+(declare-function avy--overlay-post "ext:avy")
+(declare-function avy--goto "ext:avy")
+
+;;;###autoload
+(defun swiper-avy ()
+ "Jump to one of the current swiper candidates."
+ (interactive)
+ (with-selected-window (ivy-state-window ivy-last)
+ (let* ((candidates
+ (avy--regex-candidates
+ (ivy--regex ivy-text)))
+ (avy-background nil)
+ (candidate
+ (avy--process candidates #'avy--overlay-post)))
+ (ivy-quit-and-run
+ (avy--goto candidate)))))
(defun swiper-recenter-top-bottom (&optional arg)
"Call (`recenter-top-bottom' ARG) in `swiper--window'."
org-agenda-mode
dired-mode
jabber-chat-mode
- elfeed-search-mode)))
+ elfeed-search-mode
+ fundamental-mode)))
(unless (> (buffer-size) 100000)
(if (fboundp 'font-lock-ensure)
(font-lock-ensure)
(setq swiper--opoint (point))
(setq swiper--len 0)
(setq swiper--anchor (line-number-at-pos))
- (setq swiper--window (selected-window))
- (setq ivy--regex-function
- (cdr (assoc t ivy-re-builders-alist))))
+ (setq swiper--window (selected-window)))
+
+(defun swiper--re-builder (str)
+ "Transform STR into a swiper regex.
+This is the regex used in the minibuffer, since the candidates
+there have line numbers. In the buffer, `ivy--regex' should be used."
+ (cond
+ ((equal str "")
+ "")
+ ((equal str "^")
+ ".")
+ ((string-match "^\\^" str)
+ (setq ivy--old-re "")
+ (let ((re (ivy--regex-plus (substring str 1))))
+ (format "^[0-9][0-9 ]\\{%d\\}%s"
+ swiper--width
+ (if (zerop ivy--subexps)
+ (prog1 (format "\\(%s\\)" re)
+ (setq ivy--subexps 1))
+ re))))
+ (t
+ (ivy--regex-plus str))))
(defun swiper--ivy (&optional initial-input)
"`isearch' with an overview using `ivy'.
:preselect preselect
:require-match t
:update-fn #'swiper--update-input-ivy
- :unwind #'swiper--cleanup))
+ :unwind #'swiper--cleanup
+ :re-builder #'swiper--re-builder))
(if (null ivy-exit)
(goto-char swiper--opoint)
(swiper--action res ivy-text)))))
(defun swiper--update-input-ivy ()
"Called when `ivy' input is updated."
(swiper--cleanup)
- (let* ((re (funcall ivy--regex-function ivy-text))
+ (let* ((re (ivy--regex ivy-text))
(str ivy--current)
(num (if (string-match "^[0-9]+" str)
(string-to-number (match-string 0 str))
(goto-char (point-min))
(forward-line (1- (read x)))
(re-search-forward
- (funcall ivy--regex-function input) (line-end-position) t)
+ (ivy--regex input) (line-end-position) t)
(swiper--ensure-visible)
(when (/= (point) swiper--opoint)
(unless (and transient-mark-mode mark-active)