aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Nazarewicz2014-06-05 16:42:07 +0200
committerMichal Nazarewicz2014-06-05 16:42:07 +0200
commit03d7d160c3c7f31f1fee84b1bdcd252a8cec7b99 (patch)
treea173a51f3eee0e4ab48b6770961819a95ebb9af1
parentdf344ab435c04aea5bb9261e6d2c349ab8f4fcea (diff)
downloademacs-03d7d160c3c7f31f1fee84b1bdcd252a8cec7b99.tar.gz
emacs-03d7d160c3c7f31f1fee84b1bdcd252a8cec7b99.zip
tildify.el: Rewrite `tildify-region' and co., add foreach function.
* lisp/textmodes/tildify.el (tildify-foreach-region-outside-env): New function which calls a callback on portions of the buffer that are outside of ignored environments. (tildify-build-regexp): Remove function since it is now incorporated in `tildify-foreach-region-outside-env' where it is optimised and simplified by the use of `mapconcat'. (tildify-tildify): Return number of substitutions made so that… (tildify-count): …can be removed. (tildify-find-env): Accept a new PAIRS argument which was previously looked up in `tildify-ignored-environments-alist' each time the function was called. With this change, the lookup is performed only once in `tildify-foreach-region-outside-env'. (tildify-region): Greatly simplify the function since now most of the work is done by `tildify-foreach-region-outside-env'. (tildify-mode-alist): Simplify slightly by avoiding if and setq and instead using or. * tests/automated/tildify-tests.el (tildify-test-find-env-end-re-bug) (tildify-test-find-env-group-index-bug): Update to support new signature of the `tildify-foreach-region-outside-env' function. Namely, it now takes pairs as an argument instead of looking it up in `tildify-ignored-environments-alist'.
-rw-r--r--lisp/ChangeLog17
-rw-r--r--lisp/textmodes/tildify.el145
-rw-r--r--test/ChangeLog6
-rw-r--r--test/automated/tildify-tests.el17
4 files changed, 92 insertions, 93 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 1a6b1cd517c..0abb367f5b8 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,22 @@
12014-06-05 Michal Nazarewicz <mina86@mina86.com> 12014-06-05 Michal Nazarewicz <mina86@mina86.com>
2 2
3 * textmodes/tildify.el (tildify-foreach-region-outside-env): New
4 function which calls a callback on portions of the buffer that are
5 outside of ignored environments.
6 (tildify-build-regexp): Remove function since it is now
7 incorporated in `tildify-foreach-region-outside-env' where it is
8 optimised and simplified by the use of `mapconcat'.
9 (tildify-tildify): Return number of substitutions made so that…
10 (tildify-count): …can be removed.
11 (tildify-find-env): Accept a new PAIRS argument which was
12 previously looked up in `tildify-ignored-environments-alist' each
13 time the function was called. With this change, the lookup is
14 performed only once in `tildify-foreach-region-outside-env'.
15 (tildify-region): Greatly simplify the function since now most of
16 the work is done by `tildify-foreach-region-outside-env'.
17 (tildify-mode-alist): Simplify slightly by avoiding if and setq
18 and instead using or.
19
3 * textmodes/tildify.el (tildify-ignored-environments-alist): 20 * textmodes/tildify.el (tildify-ignored-environments-alist):
4 Optimise environments regexes 21 Optimise environments regexes
5 22
diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el
index 39ccad717d4..50fee2f4b84 100644
--- a/lisp/textmodes/tildify.el
+++ b/lisp/textmodes/tildify.el
@@ -3,7 +3,8 @@
3;; Copyright (C) 1997-2014 Free Software Foundation, Inc. 3;; Copyright (C) 1997-2014 Free Software Foundation, Inc.
4 4
5;; Author: Milan Zamazal <pdm@zamazal.org> 5;; Author: Milan Zamazal <pdm@zamazal.org>
6;; Version: 4.5.2 6;; Michal Nazarewicz <mina86@mina86.com>
7;; Version: 4.5.3
7;; Keywords: text, TeX, SGML, wp 8;; Keywords: text, TeX, SGML, wp
8 9
9;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -187,12 +188,6 @@ END-REGEX defines end of the corresponding text part and can be either:
187 (symbol :tag "Like other"))))) 188 (symbol :tag "Like other")))))
188 189
189 190
190;;; *** Internal variables ***
191
192(defvar tildify-count nil
193 "Counter for replacements.")
194
195
196;;; *** Interactive functions *** 191;;; *** Interactive functions ***
197 192
198;;;###autoload 193;;;###autoload
@@ -205,51 +200,16 @@ This function performs no refilling of the changed text.
205If DONT-ASK is set, or called interactively with prefix argument, user 200If DONT-ASK is set, or called interactively with prefix argument, user
206won't be prompted for confirmation of each substitution." 201won't be prompted for confirmation of each substitution."
207 (interactive "*rP") 202 (interactive "*rP")
208 (setq tildify-count 0) 203 (let (case-fold-search (count 0) (ask (not dont-ask)))
209 (let (a 204 (tildify-foreach-region-outside-env beg end
210 z 205 (lambda (beg end)
211 (marker-end (copy-marker end)) 206 (let ((aux (tildify-tildify beg end ask)))
212 end-env 207 (setq count (+ count (car aux)))
213 finish 208 (if (not (eq (cdr aux) 'force))
214 (ask (not dont-ask)) 209 (cdr aux)
215 (case-fold-search nil) 210 (setq ask nil)
216 (regexp (tildify-build-regexp)) ; beginnings of environments 211 t))))
217 aux) 212 (message "%d spaces replaced." count)))
218 (if regexp
219 ;; Yes, ignored environments exist for the current major mode,
220 ;; tildify just texts outside them
221 (save-excursion
222 (save-restriction
223 (widen)
224 (goto-char (point-min))
225 (while (not finish)
226 (setq a (point))
227 (setq end-env (tildify-find-env regexp))
228 (setq z (copy-marker (if end-env (1- (point)) (point-max))))
229 (if (>= (marker-position z) beg)
230 (progn
231 (or (>= a beg) (setq a beg))
232 (or (<= (marker-position z) (marker-position marker-end))
233 (setq z marker-end))
234 (setq aux (tildify-tildify a (marker-position z) ask))
235 (if (eq aux 'force)
236 (setq ask nil)
237 (if (eq aux nil)
238 (setq finish t)))))
239 (if (>= (marker-position z) (marker-position marker-end))
240 (setq finish t))
241 (or (>= (point) (marker-position z))
242 (goto-char (marker-position z)))
243 (if (not finish)
244 (if (re-search-forward end-env nil t)
245 (if (> (point) (marker-position marker-end))
246 (setq finish t))
247 (message
248 "End of environment not found: %s" end-env)
249 (setq finish t))))))
250 ;; No ignored environments, tildify directly
251 (tildify-tildify beg end ask)))
252 (message "%d spaces replaced." tildify-count))
253 213
254;;;###autoload 214;;;###autoload
255(defun tildify-buffer (&optional dont-ask) 215(defun tildify-buffer (&optional dont-ask)
@@ -266,42 +226,58 @@ won't be prompted for confirmation of each substitution."
266 226
267;;; *** Auxiliary functions *** 227;;; *** Auxiliary functions ***
268 228
269(defun tildify-build-regexp ()
270 "Build start of environment regexp."
271 (let ((alist (tildify-mode-alist tildify-ignored-environments-alist))
272 regexp)
273 (when alist
274 (setq regexp (caar alist))
275 (setq alist (cdr alist))
276 (while alist
277 (setq regexp (concat regexp "\\|" (caar alist)))
278 (setq alist (cdr alist)))
279 regexp)))
280
281(defun tildify-mode-alist (mode-alist &optional mode) 229(defun tildify-mode-alist (mode-alist &optional mode)
282 "Return alist item for the MODE-ALIST in the current major MODE." 230 "Return alist item for the MODE-ALIST in the current major MODE."
283 (if (null mode) 231 (let ((alist (cdr (or (assoc (or mode major-mode) mode-alist)
284 (setq mode major-mode))
285 (let ((alist (cdr (or (assoc mode mode-alist)
286 (assoc t mode-alist))))) 232 (assoc t mode-alist)))))
287 (if (and alist 233 (if (and alist
288 (symbolp alist)) 234 (symbolp alist))
289 (tildify-mode-alist mode-alist alist) 235 (tildify-mode-alist mode-alist alist)
290 alist))) 236 alist)))
291 237
292(defun tildify-find-env (regexp) 238(defun tildify-foreach-region-outside-env (beg end callback)
239 "Scan region from BEG to END calling CALLBACK on portions out of environments.
240Call CALLBACK on each region outside of environment to ignore.
241CALLBACK will only be called for regions which have intersection
242with [BEG END]. It must be a function that takes two point
243arguments specifying the region to operate on. Stop scanning the
244region as soon as CALLBACK returns nil. Environments to ignore
245are determined from `tildify-ignored-environments-alist'."
246 (declare (indent 2))
247 (let ((pairs (tildify-mode-alist tildify-ignored-environments-alist)))
248 (if (not pairs)
249 (funcall callback beg end)
250 (let ((func (lambda (b e)
251 (let ((b (max b beg)) (e (min e end)))
252 (if (< b e) (funcall callback b e) t))))
253 (beg-re (concat "\\(?:"
254 (mapconcat 'car pairs "\\)\\|\\(?:")
255 "\\)"))
256 p end-re)
257 (save-excursion
258 (save-restriction
259 (widen)
260 (goto-char (point-min))
261 (while (and (< (setq p (point)) end)
262 (if (not (setq end-re
263 (tildify-find-env beg-re pairs)))
264 (progn (funcall func p end) nil)
265 (funcall func p (match-beginning 0))
266 (when (< (point) end)
267 (setq p (point))
268 (re-search-forward end-re nil t)))))))))))
269
270(defun tildify-find-env (regexp pairs)
293 "Find environment using REGEXP. 271 "Find environment using REGEXP.
294Return regexp for the end of the environment or nil if no environment was 272Return regexp for the end of the environment found in PAIRS or nil if
295found." 273no environment was found."
296 ;; Find environment 274 ;; Find environment
297 (when (re-search-forward regexp nil t) 275 (when (re-search-forward regexp nil t)
298 (save-match-data 276 (save-match-data
299 ;; Build end-env regexp 277 (let ((match (match-string 0)))
300 (let ((match (match-string 0)) 278 (while (not (eq (string-match (caar pairs) match) 0))
301 (alist (tildify-mode-alist tildify-ignored-environments-alist))) 279 (setq pairs (cdr pairs)))
302 (while (not (eq (string-match (caar alist) match) 0)) 280 (let ((expression (cdar pairs)))
303 (setq alist (cdr alist)))
304 (let ((expression (cdar alist)))
305 (if (stringp expression) 281 (if (stringp expression)
306 expression 282 expression
307 (mapconcat 283 (mapconcat
@@ -319,8 +295,9 @@ macros.
319 295
320If ASK is nil, perform replace without asking user for confirmation. 296If ASK is nil, perform replace without asking user for confirmation.
321 297
322Returns one of symbols: t (all right), nil (quit), force (replace without 298Returns (count . response) cons where count is number of string
323further questions)." 299replacements done and response is one of symbols: t (all right), nil
300(quit), force (replace without further questions)."
324 (save-excursion 301 (save-excursion
325 (goto-char beg) 302 (goto-char beg)
326 (let* ((alist (tildify-mode-alist tildify-pattern-alist)) 303 (let* ((alist (tildify-mode-alist tildify-pattern-alist))
@@ -332,7 +309,8 @@ further questions)."
332 bad-answer 309 bad-answer
333 replace 310 replace
334 quit 311 quit
335 (message-log-max nil)) 312 (message-log-max nil)
313 (count 0))
336 (while (and (not quit) 314 (while (and (not quit)
337 (re-search-forward regexp (marker-position end-marker) t)) 315 (re-search-forward regexp (marker-position end-marker) t))
338 (when (or (not ask) 316 (when (or (not ask)
@@ -359,12 +337,11 @@ further questions)."
359 (setq bad-answer t))) 337 (setq bad-answer t)))
360 replace)) 338 replace))
361 (replace-match tilde t t nil match-number) 339 (replace-match tilde t t nil match-number)
362 (setq tildify-count (1+ tildify-count)))) 340 (setq count (1+ count))))
363 ;; Return value 341 ;; Return value
364 (cond 342 (cons count (cond (quit nil)
365 (quit nil) 343 ((not ask) 'force)
366 ((not ask) 'force) 344 (t t))))))
367 (t t)))))
368 345
369 346
370;;; *** Announce *** 347;;; *** Announce ***
diff --git a/test/ChangeLog b/test/ChangeLog
index 38a4feb528f..6248d6cb9a6 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,5 +1,11 @@
12014-06-05 Michal Nazarewicz <mina86@mina86.com> 12014-06-05 Michal Nazarewicz <mina86@mina86.com>
2 2
3 * automated/tildify-tests.el (tildify-test-find-env-end-re-bug)
4 (tildify-test-find-env-group-index-bug): Update to support new
5 signature of the `tildify-foreach-region-outside-env' function.
6 Namely, it now takes pairs as an argument instead of looking it up in
7 `tildify-ignored-environments-alist'.
8
3 * automated/tildify-tests.el (tildify-test--example-html): Add support 9 * automated/tildify-tests.el (tildify-test--example-html): Add support
4 for generating XML code, so that… 10 for generating XML code, so that…
5 (tildify-test-xml) …test can be added to check handling of XML 11 (tildify-test-xml) …test can be added to check handling of XML
diff --git a/test/automated/tildify-tests.el b/test/automated/tildify-tests.el
index dd404fcac22..cf18320030d 100644
--- a/test/automated/tildify-tests.el
+++ b/test/automated/tildify-tests.el
@@ -114,23 +114,22 @@ latter is missing, SENTENCE will be used in all placeholder positions."
114(ert-deftest tildify-test-find-env-end-re-bug () 114(ert-deftest tildify-test-find-env-end-re-bug ()
115 "Tests generation of end-regex using mix of indexes and strings" 115 "Tests generation of end-regex using mix of indexes and strings"
116 (with-temp-buffer 116 (with-temp-buffer
117 (let ((tildify-ignored-environments-alist 117 (insert "foo whatever end-foo")
118 `((,major-mode ("foo\\|bar" . ("end-" 0)))))) 118 (goto-char (point-min))
119 (insert "foo whatever end-foo") 119 (should (string-equal "end-foo"
120 (goto-char (point-min)) 120 (tildify-find-env "foo\\|bar"
121 (should (string-equal "end-foo" (tildify-find-env "foo\\|bar")))))) 121 '(("foo\\|bar" . ("end-" 0))))))))
122 122
123 123
124(ert-deftest tildify-test-find-env-group-index-bug () 124(ert-deftest tildify-test-find-env-group-index-bug ()
125 "Tests generation of match-string indexes" 125 "Tests generation of match-string indexes"
126 (with-temp-buffer 126 (with-temp-buffer
127 (let ((tildify-ignored-environments-alist 127 (let ((pairs '(("start-\\(foo\\|bar\\)" . ("end-" 1))
128 `((,major-mode ("start-\\(foo\\|bar\\)" . ("end-" 1)) 128 ("open-\\(foo\\|bar\\)" . ("close-" 1))))
129 ("open-\\(foo\\|bar\\)" . ("close-" 1)))))
130 (beg-re "start-\\(foo\\|bar\\)\\|open-\\(foo\\|bar\\)")) 129 (beg-re "start-\\(foo\\|bar\\)\\|open-\\(foo\\|bar\\)"))
131 (insert "open-foo whatever close-foo") 130 (insert "open-foo whatever close-foo")
132 (goto-char (point-min)) 131 (goto-char (point-min))
133 (should (string-equal "close-foo" (tildify-find-env beg-re)))))) 132 (should (string-equal "close-foo" (tildify-find-env beg-re pairs))))))
134 133
135 134
136(provide 'tildify-tests) 135(provide 'tildify-tests)