diff options
| author | Nicolas Richard | 2015-05-29 10:32:05 +0200 |
|---|---|---|
| committer | Nicolas Richard | 2015-06-02 10:51:27 +0200 |
| commit | bc9d9bc7a8d56303595899cd66db67ef90d3a4cd (patch) | |
| tree | 6dc8abefa17c3e99f23a208179b53700b4a6200f /lisp/replace.el | |
| parent | 59db4308b546cbe32d3bfe6e23dbc1899d511975 (diff) | |
| download | emacs-bc9d9bc7a8d56303595899cd66db67ef90d3a4cd.tar.gz emacs-bc9d9bc7a8d56303595899cd66db67ef90d3a4cd.zip | |
Avoid confusion in query-replace history when replacing NUL chars
* lisp/replace.el (query-replace--split-string): New function.
(query-replace-read-from): Rely on the 'separator' property
instead of searching for the NUL character (Bug#20690).
Diffstat (limited to 'lisp/replace.el')
| -rw-r--r-- | lisp/replace.el | 52 |
1 files changed, 30 insertions, 22 deletions
diff --git a/lisp/replace.el b/lisp/replace.el index 8e71615ca14..1bf134302e4 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -136,6 +136,16 @@ See `replace-regexp' and `query-replace-regexp-eval'.") | |||
| 136 | (defun query-replace-descr (string) | 136 | (defun query-replace-descr (string) |
| 137 | (mapconcat 'isearch-text-char-description string "")) | 137 | (mapconcat 'isearch-text-char-description string "")) |
| 138 | 138 | ||
| 139 | (defun query-replace--split-string (string) | ||
| 140 | "Split string STRING at a character with property `separator'" | ||
| 141 | (let* ((length (length string)) | ||
| 142 | (split-pos (text-property-any 0 length 'separator t string))) | ||
| 143 | (if (not split-pos) | ||
| 144 | (substring-no-properties string) | ||
| 145 | (cl-assert (not (text-property-any (1+ split-pos) length 'separator t string))) | ||
| 146 | (cons (substring-no-properties string 0 split-pos) | ||
| 147 | (substring-no-properties string (1+ split-pos) length))))) | ||
| 148 | |||
| 139 | (defun query-replace-read-from (prompt regexp-flag) | 149 | (defun query-replace-read-from (prompt regexp-flag) |
| 140 | "Query and return the `from' argument of a query-replace operation. | 150 | "Query and return the `from' argument of a query-replace operation. |
| 141 | The return value can also be a pair (FROM . TO) indicating that the user | 151 | The return value can also be a pair (FROM . TO) indicating that the user |
| @@ -174,32 +184,30 @@ wants to replace FROM with TO." | |||
| 174 | (read-regexp prompt nil 'query-replace-from-to-history) | 184 | (read-regexp prompt nil 'query-replace-from-to-history) |
| 175 | (read-from-minibuffer | 185 | (read-from-minibuffer |
| 176 | prompt nil nil nil 'query-replace-from-to-history | 186 | prompt nil nil nil 'query-replace-from-to-history |
| 177 | (car (if regexp-flag regexp-search-ring search-ring)) t))))) | 187 | (car (if regexp-flag regexp-search-ring search-ring)) t)))) |
| 188 | (to)) | ||
| 178 | (if (and (zerop (length from)) query-replace-defaults) | 189 | (if (and (zerop (length from)) query-replace-defaults) |
| 179 | (cons (caar query-replace-defaults) | 190 | (cons (caar query-replace-defaults) |
| 180 | (query-replace-compile-replacement | 191 | (query-replace-compile-replacement |
| 181 | (cdar query-replace-defaults) regexp-flag)) | 192 | (cdar query-replace-defaults) regexp-flag)) |
| 182 | (let* ((to (if (and (string-match separator from) | 193 | (setq from (query-replace--split-string from)) |
| 183 | (get-text-property (match-beginning 0) 'separator from)) | 194 | (when (consp from) (setq to (cdr from) from (car from))) |
| 184 | (substring-no-properties from (match-end 0)))) | 195 | (add-to-history query-replace-from-history-variable from nil t) |
| 185 | (from (if to (substring-no-properties from 0 (match-beginning 0)) | 196 | ;; Warn if user types \n or \t, but don't reject the input. |
| 186 | (substring-no-properties from)))) | 197 | (and regexp-flag |
| 187 | (add-to-history query-replace-from-history-variable from nil t) | 198 | (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from) |
| 188 | ;; Warn if user types \n or \t, but don't reject the input. | 199 | (let ((match (match-string 3 from))) |
| 189 | (and regexp-flag | 200 | (cond |
| 190 | (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from) | 201 | ((string= match "\\n") |
| 191 | (let ((match (match-string 3 from))) | 202 | (message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead")) |
| 192 | (cond | 203 | ((string= match "\\t") |
| 193 | ((string= match "\\n") | 204 | (message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) |
| 194 | (message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead")) | 205 | (sit-for 2))) |
| 195 | ((string= match "\\t") | 206 | (if (not to) |
| 196 | (message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) | 207 | from |
| 197 | (sit-for 2))) | 208 | (add-to-history query-replace-to-history-variable to nil t) |
| 198 | (if (not to) | 209 | (add-to-history 'query-replace-defaults (cons from to) nil t) |
| 199 | from | 210 | (cons from (query-replace-compile-replacement to regexp-flag))))))) |
| 200 | (add-to-history query-replace-to-history-variable to nil t) | ||
| 201 | (add-to-history 'query-replace-defaults (cons from to) nil t) | ||
| 202 | (cons from (query-replace-compile-replacement to regexp-flag)))))))) | ||
| 203 | 211 | ||
| 204 | (defun query-replace-compile-replacement (to regexp-flag) | 212 | (defun query-replace-compile-replacement (to regexp-flag) |
| 205 | "Maybe convert a regexp replacement TO to Lisp. | 213 | "Maybe convert a regexp replacement TO to Lisp. |