summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLev Lamberov <dogsleg@debian.org>2016-12-10 23:47:22 +0500
committerLev Lamberov <dogsleg@debian.org>2016-12-10 23:47:22 +0500
commit175bf6cd5594847b758b176f51cb2fd174252c27 (patch)
tree2dc5f0768eb74e26c08e1962e983f88f70c2ecbb
New upstream version 0.62
-rw-r--r--.gitignore1
-rw-r--r--Cask8
-rw-r--r--Changes215
-rw-r--r--README.md221
-rw-r--r--anzu.el844
-rw-r--r--image/anzu-any-position.pngbin0 -> 33418 bytes
-rw-r--r--image/anzu-replace-demo-noquery.gifbin0 -> 164247 bytes
-rw-r--r--image/anzu-replace-demo.gifbin0 -> 257182 bytes
-rw-r--r--image/anzu-threshold.pngbin0 -> 40380 bytes
-rw-r--r--image/anzu.gifbin0 -> 867415 bytes
10 files changed, 1289 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..64b1053
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/.cask/
diff --git a/Cask b/Cask
new file mode 100644
index 0000000..3352d70
--- /dev/null
+++ b/Cask
@@ -0,0 +1,8 @@
+(source gnu)
+(source melpa)
+
+(package-file "anzu.el")
+
+(development
+ (depends-on "powerline")
+ (depends-on "migemo"))
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..2029f9e
--- /dev/null
+++ b/Changes
@@ -0,0 +1,215 @@
+Revision history for anzu.el
+
+Revision 0.62 2016/08/18 syohex
+ - Don't search over bounds(#80)
+ - Correct variable type attribute(#76 Thanks Matus Goljer)
+
+Revision 0.61 2016/06/17 syohex
+ - Don't overwrite user's case-fold-search(#75)
+ - Implement anzu's isearch-query-replace commands(#72)
+
+Revision 0.60 2016/01/31 syohex
+ - Add replacement threshold(#66)
+ - Refactoring code
+
+Revision 0.59 2015/10/15 syohex
+ - Fix replacement around region issue(#63 Thanks akicho8)
+
+Revision 0.58 2015/10/09 syohex
+ - Fix byte-compile warning(#63 Thanks tarsius)
+
+Revision 0.57 2015/09/29 syohex
+ - Fix about migemo exception(#62 Reported by kosh04)
+
+Revision 0.56 2015/09/13 syohex
+ - Fix literal replacement issue(#60 Thanks kosh04)
+
+Revision 0.55 2015/09/11 syohex
+ - anzu--status declare as buffer local variable
+
+Revision 0.54 2015/08/03 syohex
+ - Correct removed hook function name. This makes anzu information is shown if anzu-mode
+ is disabled.
+
+Revision 0.53 2015/05/18 syohex
+ - Fix raising invalid regexp error issue(Thanks kosh04)
+ - Valid replaced regular expression in regexp replace commands
+
+Revision 0.52 2015/02/22 syohex
+ - Fix default input issue(Reported by pronobis)
+
+Revision 0.51 2015/02/18 syohex
+ - Improve new history feature of Emacs 25
+ (This feature works on both Emacs 24 and 25)
+
+Revision 0.50 2015/02/11 syohex
+ - Fix Emacs 24 issue(Reported by LefterisJP)
+ Can't use both anzu replace commands and builtin replacements commands
+
+Revision 0.49 2015/02/04 syohex
+ - Fix zero width replacement causes infinite loop issue(Reported by proofit404)
+
+Revision 0.48 2015/01/28 syohex
+ - Fix case when expression(,(...)) cannot be compiled.
+
+Revision 0.47 2015/01/21 syohex
+ - Fix displaying wrong current position in replacement commands
+
+Revision 0.46 2015/01/10 syohex
+ - Refactoring for evil-anzu
+
+Revision 0.45 2015/01/09 syohex
+ - Disable blink-matching-paren in replace commands
+
+Revision 0.44 2014/12/16 syohex
+ - Improve replacement commands
+ - show case sensitive replacement text
+ - Fix storing replacement history format issue
+ - We could not use anzu replace commands with normal replacement
+ commands such as query-replace etc.
+
+Revision 0.43 2014/11/30 syohex
+ - Re-factoring for using migemo variable(Thanks lunaryorn)
+
+Revision 0.42 2014/11/28 syohex
+ - Replacement by case sensitive for at-cursor commands
+
+Revision 0.41 2014/10/06 syohex
+ - Improve checking whether using migemo
+
+Revision 0.40 2014/10/03 syohex
+ - Fix replace command bug when using '^' or 'no' command
+
+Revision 0.39 2014/09/19 syohex
+ - Fix bug case when bounds-of-thing-at-point returns nil
+
+Revision 0.38 2014/09/06 syohex
+ - Improve replace command suggested by DamienCassou
+
+Revision 0.37 2014/08/27 syohex
+ - Fix for isearch toggle commands and symbol search
+ - Improve mode line in replacing commands
+
+Revision 0.36 2014/07/04 syohex
+ - Implement replacement only specified lines
+
+Revision 0.35 2014/04/23 syohex
+ - Change function name for maintenance
+
+Revision 0.34 2014/03/28 syohex
+ - Fix replacement issue
+ Reported by purcell.
+
+Revision 0.33 2014/03/19 syohex
+ - Fix byte compile warnings for Emacs 24.3
+
+Revision 0.32 2014/03/08 syohex
+ - Specify Emacs version
+
+Revision 0.31 2014/03/07 syohex
+ - Enable lexical-binding
+ - Update requirement cl-lib.el version
+
+Revision 0.30 2014/02/02 syohex
+ - Fix wrong prompt issue
+
+Revision 0.29 2014/02/02 syohex
+ - Add no query replace command
+ - Use cl-lib instead of cl.el
+
+Revision 0.28 2014/01/29 syohex
+ - Fix ignore case issue
+
+Revision 0.27 2014/01/27 syohex
+ - Fix non prefix issue
+
+Revision 0.26 2014/01/16 syohex
+ - Fix #13 issue
+ https://github.com/syohex/emacs-anzu/issues/13
+ Reported by fukamachi
+
+Revision 0.25 2014/01/16 syohex
+ - Support backward replacement for Emacs 24.4
+
+Revision 0.24 2013/11/20 syohex
+ - Fix invalid return type of 'anzu-replace-to-string-separator'
+
+Revision 0.23 2013/11/08 syohex
+ - Add 'anzu-replace-to-string-separator' for separator of 'to' string
+
+Revision 0.22 2013/11/06 syohex
+ - Fix issue when using isearch-repeat-{forward,backward}
+
+Revision 0.21 2013/11/05 syohex
+ - Fix different behavior from query-replace-regexp
+
+Revision 0.20 2013/11/01 syohex
+ - Fix case of 0 width match such as '^', '$'
+ - Improve replace commands(We can use \#, \1 in \,(...))
+ - Re-factoring
+
+Revision 0.19 2013/10/30 syohex
+ - Fix autoload cookie
+ - Implement anzu-query-replace-at-cursor-thing
+
+Revision 0.18 2013/10/30 syohex
+ - Add switch of deactivate region feature
+ - Improve anzu-query-replace-at-cursor behavior
+
+Revision 0.17 2013/10/28 syohex
+ - Fix case fold issue
+
+Revision 0.16 2013/10/27 syohex
+ - Improve for performance at not regexp replace command
+
+Revision 0.15 2013/10/26 syohex
+ - Improve replacement commands
+
+Revision 0.14 2013/10/26 syohex
+ - Implement 'anzu-query-replace-at-cursor'
+
+Revision 0.13 2013/10/23 syohex
+ - Add feature like evil's replacement
+
+Revision 0.12 2013/10/21 syohex
+ - Re-factoring: reduce global variables
+
+Revision 0.11 2013/10/21 syohex
+ - Change mode-line message at replace commands
+
+Revision 0.10 2013/10/20 syohex
+ - Add feature that highlight replaced texts
+
+Revision 0.09 2013/10/19 syohex
+ - Implement 'anzu-replace-query' and 'anzu-replace-query-regexp'
+
+Revision 0.08 2013/10/16 syohex
+ - Fix that error message is displayed when regexp validation is failed
+
+Revision 0.07 2013/10/01 syohex
+ - Introduce anzu-search-threshold
+
+Revision 0.06 2013/09/30 syohex
+ - Introduce anzu-minimum-input-length
+ This is useful for migemo users
+
+Revision 0.05 2013/09/28 syohex
+ Thanks Steve Purcell !!
+ - Improve description line
+
+Revision 0.04 2013/09/28 syohex
+ Thanks Bozhidar Batsov!!
+ - Improve documentation
+ - Fix byte compile warning
+
+Revision 0.03 2013/09/22 syohex
+ - Check isearch-regexp value for checking regexp search
+
+Revision 0.02 2013/09/22 syohex
+ - Support display search information at any position in mode-line
+ (Suggest by gvol)
+ - Fix case that input is anchor(Report by dakrone)
+ - Improve non regexp search
+
+Revision 0.01 2013/09/20 syohex
+ - Initial version
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4d63dbe
--- /dev/null
+++ b/README.md
@@ -0,0 +1,221 @@
+# anzu.el [![melpa badge][melpa-badge]][melpa-link] [![melpa stable badge][melpa-stable-badge]][melpa-stable-link]
+
+## Introduction
+
+`anzu.el` is an Emacs port of [anzu.vim](https://github.com/osyo-manga/vim-anzu).
+`anzu.el` provides a minor mode which displays *current match* and *total matches*
+information in the mode-line in various search modes.
+
+
+## Screenshot
+
+![anzu.gif](image/anzu.gif)
+
+
+## Requirements
+
+- Emacs 24 or higher
+- `cl-lib` 0.5 or higher (you don't need to install `cl-lib` if you use Emacs 24.3 or higher)
+
+
+## Installation
+
+You can install `anzu.el` from [MELPA](https://melpa.org/) with `package.el`
+
+```
+ M-x package-install anzu
+```
+
+
+## Basic Usage
+
+##### `global-anzu-mode`
+
+Enable global anzu mode:
+
+```lisp
+(global-anzu-mode +1)
+```
+
+##### `anzu-mode`
+
+Enable anzu minor mode:
+
+```lisp
+(anzu-mode +1)
+```
+
+##### `anzu-query-replace`
+
+Same as `query-replace` except anzu information in mode-line
+
+##### `anzu-query-replace-regexp`
+
+Same as `query-replace-regexp` except anzu information in mode-line
+
+
+Add following S-exp in your configuration if you want to use anzu's replace commands by default.
+
+```lisp
+(global-set-key [remap query-replace] 'anzu-query-replace)
+(global-set-key [remap query-replace-regexp] 'anzu-query-replace-regexp)
+```
+
+[anzu-replace-demo](image/anzu-replace-demo.gif)
+
+
+##### `anzu-query-replace-at-cursor`
+
+Same as `anzu-query-replace` except *from-string* is symbol at cursor
+
+##### `anzu-query-replace-at-cursor-thing`
+
+Same as `anzu-query-replace-at-cursor` except replaced region is
+specified by `anzu-replace-at-cursor-thing`.
+
+##### `anzu-replace-at-cursor-thing`
+
+Same as `anzu-query-replace-at-cursor-thing` except not query.
+This command is useful in refactoring such as changing variable name
+in the function.
+
+![anzu-replace-demo](image/anzu-replace-demo-noquery.gif)
+
+
+##### `anzu-isearch-query-replace`
+
+Anzu version of `isearch-query-replace`
+
+##### `anzu-isearch-query-replace-regexp`
+
+Anzu version of `isearch-query-replace-regexp`
+
+## Customization
+
+##### `anzu-mode-line`
+
+Face of mode-line anzu information
+
+##### `anzu-replace-highlight`
+
+Face of from-string of replacement
+
+##### `anzu-replace-to`
+
+Face of to-string of replacement
+
+##### `anzu-mode-line-update-function`
+
+Function which constructs mode-line string. anzu.el puts its output to mode-line. It is called at searching, inputting replaced word, replacing. This must be non-nil.
+
+The function takes 2 integer arguments, current position and total match number. You can get current-state from `anzu--state`(`'search`, `'replace-query`, `replace`).
+
+```lisp
+(defun my/anzu-update-func (here total)
+ (when anzu--state
+ (let ((status (cl-case anzu--state
+ (search (format "<%d/%d>" here total))
+ (replace-query (format "(%d Replaces)" total))
+ (replace (format "<%d/%d>" here total)))))
+ (propertize status 'face 'anzu-mode-line))))
+
+(custom-set-variables
+ '(anzu-mode-line-update-function #'my/anzu-update-func))
+```
+
+##### `anzu-cons-mode-line-p`(Default is `t`)
+
+Set `nil` if you want to display anzu information at any position in mode-line.
+`anzu.el` cons search information head of `mode-line` as default.
+
+For example, show search information tail of `minor-mode-alist`
+
+```lisp
+(setq anzu-cons-mode-line-p nil)
+(setcar (cdr (assq 'isearch-mode minor-mode-alist))
+ '(:eval (anzu--update-mode-line)))
+```
+
+##### Screenshot
+
+![anzu-any-position](image/anzu-any-position.png)
+
+
+##### `anzu-mode-lighter`
+
+Mode name in `mode-line`. Default is ` Anzu`.
+
+
+##### `anzu-input-idle-delay`(Default is `0.05`)
+
+Delay second of updating mode-line information when you input from-string
+
+##### `anzu-regexp-search-commands`
+
+Commands which have regexp input. If the last command is a member of this list,
+`anzu.el` treats input as regular expression.
+
+The default value is `'(isearch-forward-regexp isearch-backward-regexp)`.
+
+##### `anzu-use-migemo`(Default is `nil`)
+
+Set to `t` if you use [migemo](https://github.com/emacs-jp/migemo).
+
+##### `anzu-search-threshold`(Default is `nil`)
+
+Threshold of searched words. If there are searched word more than this value,
+`anzu.el` stops to search and display total number like `1000+`(as default).
+If this value is `nil`, `anzu.el` counts all words.
+
+![anzu-threshold](image/anzu-threshold.png)
+
+##### `anzu-replace-threshold`(Default is `nil`)
+
+Threshold of replacement overlay. If this value is `nil`,
+
+##### `anzu-minimum-input-length`(Default is 1)
+
+Minimum input length to enable anzu. This parameter is useful for `migemo` users.
+Searching 1 or 2 characters with `migemo` is too heavy if buffer is so large.
+Please set 3 or higher if you frequently edit such file.
+
+##### `anzu-deactivate-region`(Default is `nil`)
+
+Deactivate region at anzu replace command if this value is non-nil.
+It is hard to see with anzu replace command when region is active.
+
+
+##### `anzu-replace-at-cursor-thing`(Default is 'defun)
+
+Thing at point of `anzu-query-replace-at-cursor-thing`.
+This parameter is same as `thing-at-point`.
+
+##### `anzu-replace-to-string-separator`(Default is "")
+
+Separator of `to` string.
+
+
+## Sample Configuration
+
+```lisp
+(require 'anzu)
+(global-anzu-mode +1)
+
+(set-face-attribute 'anzu-mode-line nil
+ :foreground "yellow" :weight 'bold)
+
+(custom-set-variables
+ '(anzu-mode-lighter "")
+ '(anzu-deactivate-region t)
+ '(anzu-search-threshold 1000)
+ '(anzu-replace-threshold 50)
+ '(anzu-replace-to-string-separator " => "))
+
+(define-key isearch-mode-map [remap isearch-query-replace] #'anzu-isearch-query-replace)
+(define-key isearch-mode-map [remap isearch-query-replace-regexp] #'anzu-isearch-query-replace-regexp)
+```
+
+[melpa-link]: https://melpa.org/#/anzu
+[melpa-stable-link]: https://stable.melpa.org/#/anzu
+[melpa-badge]: https://melpa.org/packages/anzu-badge.svg
+[melpa-stable-badge]: https://stable.melpa.org/packages/anzu-badge.svg
diff --git a/anzu.el b/anzu.el
new file mode 100644
index 0000000..8612f4b
--- /dev/null
+++ b/anzu.el
@@ -0,0 +1,844 @@
+;;; anzu.el --- Show number of matches in mode-line while searching -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2016 by Syohei YOSHIDA
+
+;; Author: Syohei YOSHIDA <syohex@gmail.com>
+;; URL: https://github.com/syohex/emacs-anzu
+;; Version: 0.62
+;; Package-Requires: ((cl-lib "0.5") (emacs "24"))
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; `anzu.el' is an Emacs port of `anzu.vim'.
+;;
+;; `anzu.el' provides a minor mode which displays 'current match/total
+;; matches' in the mode-line in various search modes. This makes it
+;; easy to understand how many matches there are in the current buffer
+;; for your search query.
+
+;; To use this package, add following code to your init.el or .emacs
+;;
+;; (global-anzu-mode +1)
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'thingatpt)
+
+(declare-function migemo-forward 'migemo)
+
+(defgroup anzu nil
+ "Show searched position in mode-line"
+ :group 'isearch)
+
+(defcustom anzu-mode-lighter " Anzu"
+ "Lighter of anzu-mode"
+ :type 'string)
+
+(defcustom anzu-cons-mode-line-p t
+ "Set nil if you use your own mode-line setting"
+ :type 'boolean)
+
+(defcustom anzu-minimum-input-length 1
+ "Minimum input length to enable anzu"
+ :type 'integer)
+
+(defcustom anzu-search-threshold nil
+ "Limit of search number"
+ :type '(choice (integer :tag "Threshold of search")
+ (const :tag "No threshold" nil)))
+
+(defcustom anzu-replace-threshold nil
+ "Limit of replacement overlays."
+ :type '(choice (integer :tag "Threshold of replacement overlays")
+ (const :tag "No threshold" nil)))
+
+(defcustom anzu-use-migemo nil
+ "Flag of using migemo"
+ :type 'boolean)
+
+(defcustom anzu-mode-line-update-function #'anzu--update-mode-line-default
+ "Function which return mode-line string. This must be non-nil."
+ :type 'function)
+
+(defcustom anzu-regexp-search-commands '(isearch-forward-regexp
+ isearch-backward-regexp)
+ "Search function which use regexp."
+ :type '(repeat function))
+
+(defcustom anzu-input-idle-delay 0.05
+ "Idle second for updating modeline at replace commands"
+ :type 'number)
+
+(defcustom anzu-deactivate-region nil
+ "Deactive region if you use anzu a replace command with region"
+ :type 'boolean)
+
+(defcustom anzu-replace-at-cursor-thing 'defun
+ "Replace thing. This parameter is same as `thing-at-point'"
+ :type 'symbol)
+
+(defcustom anzu-replace-to-string-separator ""
+ "Separator of `to' string"
+ :type 'string)
+
+(defface anzu-mode-line
+ '((t (:foreground "magenta" :weight bold)))
+ "face of anzu modeline")
+
+(defface anzu-replace-highlight
+ '((t :inherit query-replace))
+ "highlight of replaced string")
+
+(defface anzu-match-1
+ '((((class color) (background light))
+ :background "aquamarine" :foreground "black")
+ (((class color) (background dark))
+ :background "limegreen" :foreground "black")
+ (t :inverse-video t))
+ "First group of match.")
+
+(defface anzu-match-2
+ '((((class color) (background light))
+ :background "springgreen" :foreground "black")
+ (((class color) (background dark))
+ :background "yellow" :foreground "black")
+ (t :inverse-video t))
+ "Second group of match.")
+
+(defface anzu-match-3
+ '((((class color) (background light))
+ :background "yellow" :foreground "black")
+ (((class color) (background dark))
+ :background "aquamarine" :foreground "black")
+ (t :inverse-video t))
+ "Third group of match.")
+
+(defface anzu-replace-to
+ '((((class color) (background light))
+ :foreground "red")
+ (((class color) (background dark))
+ :foreground "yellow"))
+ "highlight of replace string")
+
+(defvar anzu--total-matched 0)
+(defvar anzu--current-position 0)
+(defvar anzu--overflow-p nil)
+(defvar anzu--last-isearch-string nil)
+(defvar anzu--cached-positions nil)
+(defvar anzu--last-command nil)
+(defvar anzu--state nil)
+(defvar anzu--cached-count 0)
+(defvar anzu--last-replace-input "")
+(defvar anzu--last-search-state nil)
+(defvar anzu--last-replaced-count nil)
+(defvar anzu--outside-point nil)
+(defvar anzu--history nil)
+(defvar anzu--query-defaults nil)
+
+(defun anzu--validate-regexp (regexp)
+ (condition-case nil
+ (progn
+ (string-match-p regexp "")
+ t)
+ (invalid-regexp nil)))
+
+(defsubst anzu--construct-position-info (count overflow positions)
+ (list :count count :overflow overflow :positions positions))
+
+(defsubst anzu--case-fold-search (input)
+ (when case-fold-search
+ (let ((case-fold-search nil))
+ (not (string-match-p "[A-Z]" input)))))
+
+(defsubst anzu--word-search-p ()
+ (and (not (memq anzu--last-command anzu-regexp-search-commands))
+ (not isearch-regexp)))
+
+(defun anzu--transform-input (str)
+ (cond ((eq isearch-word 'isearch-symbol-regexp)
+ (setq str (isearch-symbol-regexp str)))
+ ((anzu--word-search-p)
+ (setq str (regexp-quote str)))
+ (t str)))
+
+(defsubst anzu--use-migemo-p ()
+ (when anzu-use-migemo
+ (unless (featurep 'migemo)
+ (error "Error: migemo is not loaded"))
+ (bound-and-true-p migemo-isearch-enable-p)))
+
+(defun anzu--search-all-position (str)
+ (unless anzu--last-command
+ (setq anzu--last-command last-command))
+ (let ((input (anzu--transform-input str)))
+ (if (not (anzu--validate-regexp input))
+ anzu--cached-positions
+ (save-excursion
+ (goto-char (point-min))
+ (let ((positions '())
+ (count 0)
+ (overflow nil)
+ (finish nil)
+ (search-func (if (anzu--use-migemo-p)
+ (lambda (word &optional bound noerror count)
+ (ignore-errors
+ (migemo-forward word bound noerror count)))
+ #'re-search-forward))
+ (case-fold-search (anzu--case-fold-search input)))
+ (while (and (not finish) (funcall search-func input nil t))
+ (push (cons (match-beginning 0) (match-end 0)) positions)
+ (cl-incf count)
+ (when (= (match-beginning 0) (match-end 0)) ;; Case of anchor such as "^"
+ (if (eobp)
+ (setq finish t)
+ (forward-char 1)))
+ (when (and anzu-search-threshold (>= count anzu-search-threshold))
+ (setq overflow t finish t)))
+ (let ((result (anzu--construct-position-info count overflow (reverse positions))))
+ (setq anzu--cached-positions (copy-sequence result))
+ result))))))
+
+(defun anzu--where-is-here (positions here)
+ (cl-loop for (start . end) in positions
+ for i = 1 then (1+ i)
+ when (and (>= here start) (<= here end))
+ return i
+ finally return 0))
+
+(defun anzu--use-result-cache-p (input)
+ (and (eq isearch-word (car anzu--last-search-state))
+ (eq isearch-regexp (cdr anzu--last-search-state))
+ (string= input anzu--last-isearch-string)))
+
+(defun anzu--update (query)
+ (when (>= (length query) anzu-minimum-input-length)
+ (let ((result (if (anzu--use-result-cache-p query)
+ anzu--cached-positions
+ (anzu--search-all-position query))))
+ (let ((curpos (anzu--where-is-here (plist-get result :positions) (point))))
+ (setq anzu--total-matched (plist-get result :count)
+ anzu--overflow-p (plist-get result :overflow)
+ anzu--current-position curpos
+ anzu--last-search-state (cons isearch-word isearch-regexp)
+ anzu--last-isearch-string query)
+ (force-mode-line-update)))))
+
+(defun anzu--update-post-hook ()
+ (anzu--update isearch-string))
+
+(defconst anzu--mode-line-format '(:eval (anzu--update-mode-line)))
+
+(defsubst anzu--mode-line-not-set-p ()
+ (and (listp mode-line-format)
+ (member anzu--mode-line-format mode-line-format)))
+
+(defun anzu--cons-mode-line-search ()
+ (anzu--cons-mode-line 'search))
+
+(defun anzu--cons-mode-line (state)
+ (setq anzu--state state)
+ (when (and anzu-cons-mode-line-p (not (anzu--mode-line-not-set-p)))
+ (setq mode-line-format (cons anzu--mode-line-format mode-line-format))))
+
+(defsubst anzu--reset-status ()
+ (setq anzu--total-matched 0
+ anzu--current-position 0
+ anzu--state nil
+ anzu--last-command nil
+ anzu--last-isearch-string nil
+ anzu--overflow-p nil))
+
+(defun anzu--reset-mode-line ()
+ (anzu--reset-status)
+ (when (and anzu-cons-mode-line-p (anzu--mode-line-not-set-p))
+ (setq mode-line-format (delete anzu--mode-line-format mode-line-format))))
+
+(defsubst anzu--format-here-position (here total)
+ (if (and anzu--overflow-p (zerop here))
+ (format "%d+" total)
+ here))
+
+(defun anzu--update-mode-line-default (here total)
+ (when anzu--state
+ (let ((status (cl-case anzu--state
+ (search (format "(%s/%d%s)"
+ (anzu--format-here-position here total)
+ total (if anzu--overflow-p "+" "")))
+ (replace-query (format "(%d replace)" total))
+ (replace (format "(%d/%d)" here total)))))
+ (propertize status 'face 'anzu-mode-line))))
+
+(defun anzu--update-mode-line ()
+ (funcall anzu-mode-line-update-function anzu--current-position anzu--total-matched))
+
+;;;###autoload
+(define-minor-mode anzu-mode
+ "minor-mode which display search information in mode-line."
+ :init-value nil
+ :global nil
+ :lighter anzu-mode-lighter
+ (if anzu-mode
+ (progn
+ (set (make-local-variable 'anzu--state) nil)
+ (add-hook 'isearch-update-post-hook #'anzu--update-post-hook nil t)
+ (add-hook 'isearch-mode-hook #'anzu--cons-mode-line-search nil t)
+ (add-hook 'isearch-mode-end-hook #'anzu--reset-mode-line nil t))
+ (remove-hook 'isearch-update-post-hook #'anzu--update-post-hook t)
+ (remove-hook 'isearch-mode-hook #'anzu--cons-mode-line-search t)
+ (remove-hook 'isearch-mode-end-hook #'anzu--reset-mode-line t)
+ (anzu--reset-mode-line)))
+
+(defun anzu--turn-on ()
+ (unless (minibufferp)
+ (anzu-mode +1)))
+
+;;;###autoload
+(define-globalized-minor-mode global-anzu-mode anzu-mode anzu--turn-on)
+
+(defsubst anzu--query-prompt-base (use-region use-regexp)
+ (concat "Query replace"
+ (if current-prefix-arg " word" "")
+ (if use-regexp " regexp" "")
+ (if use-region " in region" "")) )
+
+(defun anzu--query-prompt (use-region use-regexp at-cursor isearch-p)
+ (let ((prompt (anzu--query-prompt-base use-region use-regexp)))
+ (if (and anzu--query-defaults (not at-cursor) (not isearch-p))
+ (format "%s (default %s -> %s) "
+ prompt
+ (query-replace-descr (caar anzu--query-defaults))
+ (query-replace-descr (cdar anzu--query-defaults)))
+ prompt)))
+
+(defvar anzu--replaced-markers nil)
+(defsubst anzu--set-marker (beg buf)
+ (let ((m (make-marker)))
+ (set-marker m beg buf)
+ (push m anzu--replaced-markers)))
+
+(defun anzu--make-overlay (begin end face prio)
+ (let ((ov (make-overlay begin end)))
+ (overlay-put ov 'face face)
+ (overlay-put ov 'priority prio)
+ (overlay-put ov 'anzu-overlay t)
+ ov))
+
+(defun anzu--add-match-group-overlay (match-data groups)
+ (when (>= groups 3)
+ (anzu--make-overlay (cl-fifth match-data) (cl-sixth match-data)
+ 'anzu-match-3 1001))
+ (when (>= groups 2)
+ (anzu--make-overlay (cl-third match-data) (cl-fourth match-data)
+ 'anzu-match-2 1001))
+ (anzu--make-overlay (cl-first match-data) (cl-second match-data)
+ 'anzu-match-1 1001))
+
+(defun anzu--add-overlay (beg end)
+ (let* ((match-data (match-data))
+ (groups (/ (- (length match-data) 2) 2)))
+ (when (>= groups 1)
+ (anzu--add-match-group-overlay (cddr match-data) groups))
+ (let ((ov (anzu--make-overlay beg end 'anzu-replace-highlight 1000)))
+ (overlay-put ov 'from-string (buffer-substring-no-properties beg end))
+ (overlay-put ov 'anzu-replace t))))
+
+(defsubst anzu--cleanup-markers ()
+ (mapc (lambda (m) (set-marker m nil)) anzu--replaced-markers)
+ (setq anzu--replaced-markers nil))
+
+;; Return highlighted count
+(defun anzu--count-and-highlight-matched (buf str replace-beg replace-end
+ use-regexp overlay-limit case-sensitive)
+ (anzu--cleanup-markers)
+ (when (not use-regexp)
+ (setq str (regexp-quote str)))
+ (if (not (anzu--validate-regexp str))
+ anzu--cached-count
+ (with-current-buffer buf
+ (save-excursion
+ (let* ((overlay-beg replace-beg)
+ (overlay-end (min replace-end overlay-limit)))
+ (goto-char overlay-beg)
+ (let ((count 0)
+ (overlayed 0)
+ (finish nil)
+ (case-fold-search (if case-sensitive
+ nil
+ (anzu--case-fold-search str))))
+ (while (and (not finish) (re-search-forward str replace-end t))
+ (cl-incf count)
+ (let ((beg (match-beginning 0))
+ (end (match-end 0)))
+ (when (= beg end)
+ (if (eobp)
+ (setq finish t)
+ (forward-char 1)))
+ (when (and replace-end (> (point) replace-end))
+ (setq finish t))
+ (when (and (>= beg overlay-beg) (<= end overlay-end) (not finish))
+ (cl-incf overlayed)
+ (anzu--add-overlay beg end))))
+ (setq anzu--cached-count count)
+ overlayed))))))
+
+(defun anzu--search-outside-visible (buf input beg end use-regexp)
+ (let ((searchfn (if use-regexp #'re-search-forward #'search-forward)))
+ (when (or (not use-regexp) (anzu--validate-regexp input))
+ (with-selected-window (get-buffer-window buf)
+ (goto-char beg)
+ (when (funcall searchfn input end t)
+ (setq anzu--outside-point (match-beginning 0))
+ (let ((overlay-limit (anzu--overlay-limit)))
+ (anzu--count-and-highlight-matched buf input beg end use-regexp
+ overlay-limit nil)))))))
+
+(defconst anzu--from-to-separator
+ (propertize
+ (or (ignore-errors
+ (if (char-displayable-p ?\u2192) " \u2192 " " -> "))
+ " -> ")
+ 'face 'minibuffer-prompt))
+
+(defsubst anzu--separator ()
+ (propertize "\0" 'display anzu--from-to-separator 'separator t))
+
+(defun anzu--check-minibuffer-input (buf beg end use-regexp overlay-limit)
+ (let* ((content (minibuffer-contents))
+ (to (when (and (string-match (anzu--separator) content)
+ (get-text-property (match-beginning 0) 'separator content))
+ (substring-no-properties content (match-end 0))))
+ (from (or (and to (substring-no-properties content 0 (match-beginning 0)))
+ content))
+ (empty-p (string= from ""))
+ (overlayed (if empty-p
+ (setq anzu--cached-count 0)
+ (anzu--count-and-highlight-matched buf from beg end use-regexp
+ overlay-limit nil))))
+ (when anzu--outside-point
+ (setq anzu--outside-point nil)
+ (with-selected-window (get-buffer-window buf)
+ (goto-char beg)))
+ (when (and (not empty-p) (zerop overlayed))
+ (anzu--search-outside-visible buf from beg end use-regexp))
+ (when to
+ (setq anzu--last-replace-input "")
+ (anzu--append-replaced-string to buf beg end use-regexp overlay-limit from))
+ (setq anzu--total-matched anzu--cached-count)
+ (force-mode-line-update)))
+
+(defun anzu--clear-overlays (buf beg end)
+ (with-current-buffer buf
+ (dolist (ov (overlays-in (or beg (point-min)) (or end (point-max))))
+ (when (overlay-get ov 'anzu-overlay)
+ (delete-overlay ov)))))
+
+(defun anzu--transform-from-to-history ()
+ (let ((separator (anzu--separator)))
+ (append (mapcar (lambda (from-to)
+ (concat (query-replace-descr (car from-to))
+ separator
+ (query-replace-descr (cdr from-to))))
+ anzu--query-defaults)
+ (symbol-value query-replace-from-history-variable))))
+
+(defun anzu--read-from-string (prompt beg end use-regexp overlay-limit)
+ (let ((curbuf (current-buffer))
+ (blink-matching-paren nil)
+ (anzu--history (anzu--transform-from-to-history))
+ timer is-input)
+ (unwind-protect
+ (minibuffer-with-setup-hook
+ #'(lambda ()
+ (setq timer (run-with-idle-timer
+ (max anzu-input-idle-delay 0.01)
+ 'repeat
+ (lambda ()
+ (anzu--clear-overlays curbuf nil nil)
+ (with-selected-window (or (active-minibuffer-window)
+ (minibuffer-window))
+ (anzu--check-minibuffer-input
+ curbuf beg end use-regexp overlay-limit))))))
+ (prog1 (read-from-minibuffer (format "%s: " prompt)
+ nil nil nil 'anzu--history nil t)
+ (setq is-input t)))
+ (when timer
+ (cancel-timer timer)
+ (setq timer nil)
+ (unless is-input
+ (goto-char beg))))))
+
+(defun anzu--query-validate-from-regexp (from)
+ (when (string-match "\\(?:\\`\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(\\\\[nt]\\)" from)
+ (let ((match (match-string 1 from)))
+ (cond
+ ((string= match "\\n")
+ (message "`\\n' here doesn't match a newline; type C-q C-j instead!!"))
+ ((string= match "\\t")
+ (message "\\t' here doesn't match a tab; to do that, just type TAB!!")))
+ (sit-for 2))))
+
+(defun anzu--query-from-string (prompt beg end use-regexp overlay-limit)
+ (let* ((from (anzu--read-from-string prompt beg end use-regexp overlay-limit))
+ (is-empty (string= from "")))
+ (when (and (not is-empty) (not anzu--query-defaults))
+ (setq anzu--last-replaced-count anzu--total-matched))
+ (if (and is-empty anzu--query-defaults)
+ (cons (query-replace-descr (caar anzu--query-defaults))
+ (query-replace-compile-replacement
+ (query-replace-descr (cdar anzu--query-defaults)) use-regexp))
+ (add-to-history query-replace-from-history-variable from nil t)
+ (when use-regexp
+ (unless (anzu--validate-regexp from)
+ (error "'%s' is invalid regexp." from))
+ (anzu--query-validate-from-regexp from))
+ from)))
+
+(defun anzu--compile-replace-text (str)
+ (let ((compiled (ignore-errors
+ (query-replace-compile-replacement str t))))
+ (when compiled
+ (cond ((stringp compiled) compiled)
+ ((and (consp compiled) (functionp (car compiled)))
+ compiled)
+ ((and (consp compiled) (stringp (car compiled)))
+ (car compiled))))))
+
+(defun anzu--evaluate-occurrence (ov to-regexp replacements fixed-case from-regexp)
+ (let ((from-string (overlay-get ov 'from-string))
+ (compiled (anzu--compile-replace-text to-regexp)))
+ (if (not compiled)
+ ""
+ (with-temp-buffer
+ (insert from-string)
+ (goto-char (point-min))
+ (when (re-search-forward from-regexp nil t)
+ (or (ignore-errors
+ (if (consp compiled)
+ (replace-match (funcall (car compiled) (cdr compiled)
+ replacements) fixed-case)
+ (replace-match compiled fixed-case))
+ (buffer-substring (point-min) (point-max)))
+ ""))))))
+
+(defun anzu--overlay-sort (a b)
+ (< (overlay-start a) (overlay-start b)))
+
+(defsubst anzu--overlays-in-range (beg end)
+ (cl-loop for ov in (overlays-in beg end)
+ when (overlay-get ov 'anzu-replace)
+ collect ov into anzu-overlays
+ finally
+ return
+ (let ((sorted (sort anzu-overlays 'anzu--overlay-sort)))
+ (if anzu-replace-threshold
+ (cl-subseq sorted 0 (min (length sorted) anzu-replace-threshold))
+ sorted))))
+
+(defsubst anzu--propertize-to-string (str)
+ (let ((separator (or anzu-replace-to-string-separator "")))
+ (propertize (concat separator str) 'face 'anzu-replace-to)))
+
+(defsubst anzu--replaced-literal-string (ov replaced from)
+ (let ((str (buffer-substring-no-properties
+ (overlay-start ov) (overlay-end ov))))
+ (when (string-match (regexp-quote str) from)
+ (replace-match replaced (not case-fold-search) t str))))
+
+(defun anzu--append-replaced-string (content buf beg end use-regexp overlay-limit from)
+ (let ((replacements 0))
+ (unless (string= content anzu--last-replace-input)
+ (setq anzu--last-replace-input content)
+ (with-current-buffer buf
+ (let ((case-fold-search (anzu--case-fold-search from)))
+ (dolist (ov (anzu--overlays-in-range beg (min end overlay-limit)))
+ (let ((replace-evaled
+ (if (not use-regexp)
+ (anzu--replaced-literal-string ov content from)
+ (prog1 (anzu--evaluate-occurrence ov content replacements
+ (not case-fold-search) from)
+ (cl-incf replacements)))))
+ (overlay-put ov 'after-string (anzu--propertize-to-string replace-evaled)))))))))
+
+(defsubst anzu--outside-overlay-limit (orig-beg orig-limit)
+ (save-excursion
+ (goto-char (+ anzu--outside-point (- orig-limit orig-beg)))
+ (line-end-position)))
+
+(defun anzu--read-to-string (from prompt beg end use-regexp overlay-limit)
+ (let ((curbuf (current-buffer))
+ (orig-beg beg)
+ (to-prompt (format "%s %s with: " prompt (query-replace-descr from)))
+ (history-add-new-input nil)
+ (blink-matching-paren nil)
+ timer is-input)
+ (setq anzu--last-replace-input "")
+ (when anzu--outside-point
+ (setq beg anzu--outside-point
+ overlay-limit (anzu--outside-overlay-limit orig-beg overlay-limit)
+ anzu--outside-point nil))
+ (unwind-protect
+ (minibuffer-with-setup-hook
+ #'(lambda ()
+ (setq timer (run-with-idle-timer
+ (max anzu-input-idle-delay 0.01)
+ 'repeat
+ (lambda ()
+ (with-selected-window (or (active-minibuffer-window)
+ (minibuffer-window))
+ (anzu--append-replaced-string
+ (minibuffer-contents)
+ curbuf beg end use-regexp overlay-limit from))))))
+ (prog1 (read-from-minibuffer to-prompt
+ nil nil nil
+ query-replace-from-history-variable nil t)
+ (setq is-input t)))
+ (when timer
+ (cancel-timer timer)
+ (setq timer nil)
+ (unless is-input
+ (goto-char orig-beg))))))
+
+(defun anzu--query-replace-read-to (from prompt beg end use-regexp overlay-limit)
+ (query-replace-compile-replacement
+ (let ((to (anzu--read-to-string from prompt beg end use-regexp overlay-limit)))
+ (add-to-history query-replace-to-history-variable to nil t)
+ (add-to-history 'anzu--query-defaults (cons from to) nil t)
+ to)
+ use-regexp))
+
+(defun anzu--overlay-limit ()
+ (save-excursion
+ (move-to-window-line -1)
+ (forward-line 1)
+ (point)))
+
+(defun anzu--query-from-at-cursor (buf beg end overlay-limit)
+ (let ((symbol (thing-at-point 'symbol)))
+ (unless symbol
+ (error "No symbol at cursor!!"))
+ (let ((symbol-regexp (concat "\\_<" (regexp-quote symbol) "\\_>")))
+ (anzu--count-and-highlight-matched buf symbol-regexp beg end t overlay-limit t)
+ (setq anzu--total-matched anzu--cached-count)
+ (force-mode-line-update)
+ symbol-regexp)))
+
+(defun anzu--query-from-isearch-string (buf beg end use-regexp overlay-limit)
+ (anzu--count-and-highlight-matched buf isearch-string beg end use-regexp overlay-limit t)
+ (setq anzu--total-matched anzu--cached-count)
+ (force-mode-line-update)
+ (add-to-history query-replace-from-history-variable isearch-string nil t)
+ isearch-string)
+
+(defun anzu--thing-begin (thing)
+ (let ((bound (bounds-of-thing-at-point thing)))
+ (if bound
+ (car bound)
+ (let ((fallback-bound (bounds-of-thing-at-point 'symbol)))
+ (if fallback-bound
+ (car fallback-bound)
+ (point))))))
+
+(defsubst anzu--thing-end (thing)
+ (let ((bound (bounds-of-thing-at-point thing)))
+ (if bound
+ (cdr bound)
+ (point-max))))
+
+(defun anzu--region-begin (use-region thing backward)
+ (cond (use-region (region-beginning))
+ (current-prefix-arg (line-beginning-position))
+ (thing (anzu--thing-begin thing))
+ (backward (point-min))
+ (t (point))))
+
+(defsubst anzu--line-end-position (num)
+ (save-excursion
+ (forward-line (1- num))
+ (line-end-position)))
+
+(defun anzu--region-end (use-region thing)
+ (cond (use-region (region-end))
+ (current-prefix-arg
+ (anzu--line-end-position (prefix-numeric-value current-prefix-arg)))
+ (thing (anzu--thing-end thing))
+ (t (point-max))))
+
+(defun anzu--begin-thing (at-cursor thing)
+ (cond ((and at-cursor thing) thing)
+ ((and at-cursor (not thing)) 'symbol)
+ (t nil)))
+
+(defun anzu--replace-backward-p (prefix)
+ ;; This variable is introduced at Emacs 24.4, I should fix this variable to
+ ;; version variable
+ (and (boundp 'list-matching-lines-prefix-face)
+ (and prefix (< prefix 0))))
+
+(defun anzu--construct-perform-replace-arguments (from to delimited beg end backward query)
+ (if backward
+ (list from to query t delimited nil nil beg end backward)
+ (list from to query t delimited nil nil beg end)))
+
+(defun anzu--construct-query-replace-arguments (from to delimited beg end backward)
+ (if backward
+ (list from to delimited beg end backward)
+ (list from to delimited beg end)))
+
+(defsubst anzu--current-replaced-index (curpoint)
+ (cl-loop for m in anzu--replaced-markers
+ for i = 1 then (1+ i)
+ for pos = (marker-position m)
+ when (= pos curpoint)
+ return i))
+
+(defadvice replace-highlight (before anzu-replace-highlight activate)
+ (when (and (eq anzu--state 'replace) anzu--replaced-markers)
+ (let ((index (anzu--current-replaced-index (ad-get-arg 0))))
+ (when (or (not index) (/= index anzu--current-position))
+ (force-mode-line-update)
+ (setq anzu--current-position (or index 1))))))
+
+(defun anzu--set-replaced-markers (from beg end use-regexp)
+ (save-excursion
+ (goto-char beg)
+ (cl-loop with curbuf = (current-buffer)
+ with search-func = (if use-regexp #'re-search-forward #'search-forward)
+ while (funcall search-func from end t)
+ do
+ (progn
+ (anzu--set-marker (match-beginning 0) curbuf)
+ (when (= (match-beginning 0) (match-end 0))
+ (if (eobp)
+ (cl-return nil)
+ (forward-char 1)))
+ (when (and end (> (point) end))
+ (cl-return nil))))))
+
+(cl-defun anzu--query-replace-common (use-regexp
+ &key at-cursor thing prefix-arg (query t) isearch-p)
+ (anzu--cons-mode-line 'replace-query)
+ (let* ((use-region (use-region-p))
+ (orig-point (point))
+ (backward (anzu--replace-backward-p prefix-arg))
+ (overlay-limit (anzu--overlay-limit))
+ (beg (anzu--region-begin use-region (anzu--begin-thing at-cursor thing) backward))
+ (end (anzu--region-end use-region thing))
+ (prompt (anzu--query-prompt use-region use-regexp at-cursor isearch-p))
+ (delimited (and current-prefix-arg (not (eq current-prefix-arg '-))))
+ (curbuf (current-buffer))
+ (clear-overlay nil))
+ (when (and anzu-deactivate-region use-region)
+ (deactivate-mark t))
+ (unwind-protect
+ (let* ((from (cond ((and at-cursor beg)
+ (setq delimited nil)
+ (anzu--query-from-at-cursor curbuf beg end overlay-limit))
+ (isearch-p
+ (anzu--query-from-isearch-string
+ curbuf beg end use-regexp overlay-limit))
+ (t (anzu--query-from-string
+ prompt beg end use-regexp overlay-limit))))
+ (to (cond ((consp from)
+ (prog1 (cdr from)
+ (setq from (car from)
+ anzu--total-matched anzu--last-replaced-count)))
+ ((string-match "\0" from)
+ (prog1 (substring-no-properties from (match-end 0))
+ (setq from (substring-no-properties from 0 (match-beginning 0)))))
+ (t
+ (anzu--query-replace-read-to
+ from prompt beg end use-regexp overlay-limit)))))
+ (anzu--clear-overlays curbuf beg end)
+ (anzu--set-replaced-markers from beg end use-regexp)
+ (setq anzu--state 'replace anzu--current-position 0
+ anzu--replaced-markers (reverse anzu--replaced-markers)
+ clear-overlay t)
+ (let ((case-fold-search (and case-fold-search (not at-cursor))))
+ (if use-regexp
+ (apply #'perform-replace (anzu--construct-perform-replace-arguments
+ from to delimited beg end backward query))
+ (apply #'query-replace (anzu--construct-query-replace-arguments
+ from to delimited beg end backward)))))
+ (progn
+ (unless clear-overlay
+ (anzu--clear-overlays curbuf beg end))
+ (when (zerop anzu--current-position)
+ (goto-char orig-point))
+ (anzu--cleanup-markers)
+ (anzu--reset-mode-line)
+ (force-mode-line-update)))))
+
+;;;###autoload
+(defun anzu-query-replace-at-cursor ()
+ (interactive)
+ (anzu--query-replace-common t :at-cursor t))
+
+;;;###autoload
+(defun anzu-query-replace-at-cursor-thing ()
+ (interactive)
+ (anzu--query-replace-common t :at-cursor t :thing anzu-replace-at-cursor-thing))
+
+;;;###autoload
+(defun anzu-query-replace (arg)
+ (interactive "p")
+ (anzu--query-replace-common nil :prefix-arg arg))
+
+;;;###autoload
+(defun anzu-query-replace-regexp (arg)
+ (interactive "p")
+ (anzu--query-replace-common t :prefix-arg arg))
+
+;;;###autoload
+(defun anzu-replace-at-cursor-thing ()
+ (interactive)
+ (let ((orig (point-marker)))
+ (anzu--query-replace-common t
+ :at-cursor t
+ :thing anzu-replace-at-cursor-thing
+ :query nil)
+ (goto-char (marker-position orig))
+ (set-marker orig nil)))
+
+(defun anzu--isearch-query-replace-common (use-regexp arg)
+ (isearch-done nil t)
+ (isearch-clean-overlays)
+ (let ((isearch-recursive-edit nil)
+ (backward (< (prefix-numeric-value arg) 0)))
+ (when (and isearch-other-end
+ (if backward
+ (> isearch-other-end (point))
+ (< isearch-other-end (point)))
+ (not (and transient-mark-mode mark-active
+ (if backward
+ (> (mark) (point))
+ (< (mark) (point))))))
+ (goto-char isearch-other-end))
+ (anzu--query-replace-common use-regexp :prefix-arg arg :isearch-p t)))
+
+;;;###autoload
+(defun anzu-isearch-query-replace (arg)
+ (interactive "p")
+ (anzu--isearch-query-replace-common nil arg))
+
+;;;###autoload
+(defun anzu-isearch-query-replace-regexp (arg)
+ (interactive "p")
+ (anzu--isearch-query-replace-common t arg))
+
+(provide 'anzu)
+;;; anzu.el ends here
diff --git a/image/anzu-any-position.png b/image/anzu-any-position.png
new file mode 100644
index 0000000..cf14612
--- /dev/null
+++ b/image/anzu-any-position.png
Binary files differ
diff --git a/image/anzu-replace-demo-noquery.gif b/image/anzu-replace-demo-noquery.gif
new file mode 100644
index 0000000..1da15a9
--- /dev/null
+++ b/image/anzu-replace-demo-noquery.gif
Binary files differ
diff --git a/image/anzu-replace-demo.gif b/image/anzu-replace-demo.gif
new file mode 100644
index 0000000..b1181da
--- /dev/null
+++ b/image/anzu-replace-demo.gif
Binary files differ
diff --git a/image/anzu-threshold.png b/image/anzu-threshold.png
new file mode 100644
index 0000000..eeb4347
--- /dev/null
+++ b/image/anzu-threshold.png
Binary files differ
diff --git a/image/anzu.gif b/image/anzu.gif
new file mode 100644
index 0000000..d3b2458
--- /dev/null
+++ b/image/anzu.gif
Binary files differ