Commit d5a36a0d authored by Sean Whitton's avatar Sean Whitton

Merge tag 'v1.1.1'

v1.1.1
parents 4c1fedc6 b3096c2d
;;; visual-regexp.el --- A regexp/replace command for Emacs with interactive visual feedback
;; Copyright (C) 2013-2016 Marko Bencun
;; Copyright (C) 2013-2017 Marko Bencun
;; Author: Marko Bencun <mbencun@gmail.com>
;; URL: https://github.com/benma/visual-regexp.el/
;; Version: 1.0
;; Version: 1.1
;; Package-Requires: ((cl-lib "0.2"))
;; Keywords: regexp, replace, visual, feedback
......@@ -24,6 +24,7 @@
;; along with visual-regexp. If not, see <http://www.gnu.org/licenses/>.
;;; WHAT'S NEW
;; 1.1: Add new customization: vr/plain
;; 1.0: Add support for one prompt for search/replace, using query-replace-from-to-separator
;; (query-replace history like in Emacs 25).
;; Breaking changes:
......@@ -211,6 +212,12 @@ If nil, don't limit the number of matches shown in visual feedback."
:type 'symbol
:group 'visual-regexp)
(defcustom vr/plain nil
"If non-nil, use plain search/replace instead of regexp search/replace."
:type 'boolean
:group 'visual-regexp)
(defvar vr/initialize-hook nil
"Hook called before vr/replace and vr/query-replace")
......@@ -311,7 +318,7 @@ If nil, don't limit the number of matches shown in visual feedback."
(equal vr--in-minibuffer 'vr--minibuffer-regexp))
(defun vr--in-replace ()
"Returns t if we are either in the replace prompt, or in the regexp prompt containing a replacement (separated by query-replace-from-to-separator)"
"Returns t if we are either in the replace prompt, or in the regexp prompt containing a replacement (separated by vr/match-separator-string)"
(or (not (vr--in-from))
(consp (vr--query-replace--split-string (vr--get-regexp-string-full)))))
......@@ -378,7 +385,7 @@ visible all the time in the minibuffer."
(defun vr--minibuffer-help-text ()
(let ((help ""))
(setq help (concat help (substitute-command-keys "\\<vr/minibuffer-keymap>\\[vr--minibuffer-help]: help, \\[vr--shortcut-toggle-limit]: toggle show all")))
(setq help (concat help (substitute-command-keys "\\<vr/minibuffer-keymap>\\[vr--minibuffer-help]: help, \\[vr--shortcut-toggle-limit]: toggle show all, \\[previous-history-element]: previous")))
(when (vr--in-replace)
(setq help (concat help (substitute-command-keys ", \\[vr--shortcut-toggle-preview]: toggle preview"))))
help
......@@ -478,8 +485,8 @@ visible all the time in the minibuffer."
(while (and looping
(condition-case err
(if forward
(re-search-forward regexp-string vr--target-buffer-end t)
(re-search-backward regexp-string vr--target-buffer-start t))
(funcall (if vr/plain 'search-forward 're-search-forward) regexp-string vr--target-buffer-end t)
(funcall (if vr/plain 'search-backward 're-search-backward) regexp-string vr--target-buffer-start t))
(invalid-regexp (progn (setq message-line (car (cdr err))) nil))))
(when (or (not feedback-limit) (< i feedback-limit)) ;; let outer loop finish so we can get the matches count
(cl-loop for (start end) on (match-data) by 'cddr
......@@ -540,8 +547,8 @@ visible all the time in the minibuffer."
;; (match-data) could have been modified in the meantime, e.g. by vr--get-regexp-string->pcre-to-elisp.
(set-match-data match-data)
(if (stringp replacement)
(match-substitute-replacement replacement nocasify)
(match-substitute-replacement (funcall (car replacement) (cdr replacement) i) nocasify)))))
(match-substitute-replacement replacement nocasify vr/plain)
(match-substitute-replacement (funcall (car replacement) (cdr replacement) i) nocasify vr/plain)))))
(defun vr--do-replace-feedback-match-callback (replacement match-data i)
(let ((begin (cl-first match-data))
......@@ -565,6 +572,9 @@ visible all the time in the minibuffer."
(propertize replacement 'face current-face)))
(overlay-put overlay 'priority (+ vr--overlay-priority 0))))))))
(defun vr--mapcar-nonnil (rep list)
(mapcar (lambda (it) (when it (funcall rep it))) list))
(defun vr--get-replacements (feedback feedback-limit)
"Get replacements using emacs-style regexp."
(setq vr--limit-reached nil)
......@@ -588,13 +598,13 @@ visible all the time in the minibuffer."
(while (and
looping
(condition-case err
(re-search-forward regexp-string vr--target-buffer-end t)
(funcall (if vr/plain 'search-forward 're-search-forward) regexp-string vr--target-buffer-end t)
('invalid-regexp (progn (setq message-line (car (cdr err))) nil))))
(condition-case err
(progn
(if (or (not feedback) (not feedback-limit) (< i feedback-limit))
(setq replacements (cons
(let ((match-data (mapcar 'marker-position (match-data))))
(let ((match-data (vr--mapcar-nonnil 'marker-position (match-data))))
(list (query-replace-compile-replacement replace-string t) match-data i))
replacements))
(setq vr--limit-reached t))
......@@ -618,7 +628,6 @@ visible all the time in the minibuffer."
(defun vr--do-replace-feedback ()
"Show visual feedback for replacements."
(vr--feedback t) ;; only really needed when regexp has not been changed from default (=> no overlays have been created)
(custom-reevaluate-setting 'vr/match-separator-string)
(cl-multiple-value-bind (replacements message-line) (vr--get-replacements t vr--feedback-limit)
;; visual feedback for matches
(condition-case err
......@@ -659,7 +668,7 @@ visible all the time in the minibuffer."
(unless (or silent (string= "" message-line))
(vr--minibuffer-message message-line))
;; needed to correctly position the mark after query replace (finished with 'automatic ('!'))
(set-match-data (mapcar (lambda (el) (+ cumulative-offset el)) last-match-data))
(set-match-data (vr--mapcar-nonnil (lambda (el) (+ cumulative-offset el)) last-match-data))
replace-count)))
(defun vr--set-target-buffer-start-end ()
......@@ -676,16 +685,16 @@ visible all the time in the minibuffer."
(deactivate-mark)
(setq vr--in-minibuffer 'vr--minibuffer-regexp)
(setq vr--last-minibuffer-contents "")
(custom-reevaluate-setting 'query-replace-from-to-separator)
(custom-reevaluate-setting 'vr/match-separator-string)
(let* ((minibuffer-allow-text-properties t)
(history-add-new-input nil)
(text-property-default-nonsticky
(cons '(separator . t) text-property-default-nonsticky))
;; seperator and query-replace-from-to-history copy/pasted from replace.el
(separator
(when query-replace-from-to-separator
(when vr/match-separator-string
(propertize "\0"
'display query-replace-from-to-separator
'display vr/match-separator-string
'separator t)))
(query-replace-from-to-history
(append
......@@ -784,14 +793,15 @@ visible all the time in the minibuffer."
(deactivate-mark nil)
(first-fake-cursor nil))
(vr--feedback-function (vr--get-regexp-string) t nil (lambda (i j begin end)
(with-current-buffer vr--target-buffer
(goto-char end)
(push-mark begin)
;; temporarily enable transient mark mode
(activate-mark)
(let ((fc (mc/create-fake-cursor-at-point)))
(unless first-fake-cursor
(setq first-fake-cursor fc))))))
(when (zerop j)
(with-current-buffer vr--target-buffer
(goto-char end)
(push-mark begin)
;; temporarily enable transient mark mode
(activate-mark)
(let ((fc (mc/create-fake-cursor-at-point)))
(unless first-fake-cursor
(setq first-fake-cursor fc)))))))
;; one fake cursor too many, replace first one with
;; the regular cursor.
......@@ -903,7 +913,7 @@ E [not supported in visual-regexp]"
(while (and keep-going vr--query-replacements)
;; Advance replacement list
(cl-multiple-value-bind (replacement match-data i) (car vr--query-replacements)
(setq match-data (mapcar (lambda (el) (+ cumulative-offset el)) match-data))
(setq match-data (vr--mapcar-nonnil (lambda (el) (+ cumulative-offset el)) match-data))
(let ((begin (cl-first match-data))
(end (cl-second match-data))
(next-replacement-orig replacement))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment