mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-03 11:33:37 +00:00
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'.
This commit is contained in:
parent
df344ab435
commit
03d7d160c3
@ -1,5 +1,22 @@
|
||||
2014-06-05 Michal Nazarewicz <mina86@mina86.com>
|
||||
|
||||
* 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.
|
||||
|
||||
* textmodes/tildify.el (tildify-ignored-environments-alist):
|
||||
Optimise environments regexes
|
||||
|
||||
|
@ -3,7 +3,8 @@
|
||||
;; Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Milan Zamazal <pdm@zamazal.org>
|
||||
;; Version: 4.5.2
|
||||
;; Michal Nazarewicz <mina86@mina86.com>
|
||||
;; Version: 4.5.3
|
||||
;; Keywords: text, TeX, SGML, wp
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
@ -187,12 +188,6 @@ END-REGEX defines end of the corresponding text part and can be either:
|
||||
(symbol :tag "Like other")))))
|
||||
|
||||
|
||||
;;; *** Internal variables ***
|
||||
|
||||
(defvar tildify-count nil
|
||||
"Counter for replacements.")
|
||||
|
||||
|
||||
;;; *** Interactive functions ***
|
||||
|
||||
;;;###autoload
|
||||
@ -205,51 +200,16 @@ This function performs no refilling of the changed text.
|
||||
If DONT-ASK is set, or called interactively with prefix argument, user
|
||||
won't be prompted for confirmation of each substitution."
|
||||
(interactive "*rP")
|
||||
(setq tildify-count 0)
|
||||
(let (a
|
||||
z
|
||||
(marker-end (copy-marker end))
|
||||
end-env
|
||||
finish
|
||||
(ask (not dont-ask))
|
||||
(case-fold-search nil)
|
||||
(regexp (tildify-build-regexp)) ; beginnings of environments
|
||||
aux)
|
||||
(if regexp
|
||||
;; Yes, ignored environments exist for the current major mode,
|
||||
;; tildify just texts outside them
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(while (not finish)
|
||||
(setq a (point))
|
||||
(setq end-env (tildify-find-env regexp))
|
||||
(setq z (copy-marker (if end-env (1- (point)) (point-max))))
|
||||
(if (>= (marker-position z) beg)
|
||||
(progn
|
||||
(or (>= a beg) (setq a beg))
|
||||
(or (<= (marker-position z) (marker-position marker-end))
|
||||
(setq z marker-end))
|
||||
(setq aux (tildify-tildify a (marker-position z) ask))
|
||||
(if (eq aux 'force)
|
||||
(setq ask nil)
|
||||
(if (eq aux nil)
|
||||
(setq finish t)))))
|
||||
(if (>= (marker-position z) (marker-position marker-end))
|
||||
(setq finish t))
|
||||
(or (>= (point) (marker-position z))
|
||||
(goto-char (marker-position z)))
|
||||
(if (not finish)
|
||||
(if (re-search-forward end-env nil t)
|
||||
(if (> (point) (marker-position marker-end))
|
||||
(setq finish t))
|
||||
(message
|
||||
"End of environment not found: %s" end-env)
|
||||
(setq finish t))))))
|
||||
;; No ignored environments, tildify directly
|
||||
(tildify-tildify beg end ask)))
|
||||
(message "%d spaces replaced." tildify-count))
|
||||
(let (case-fold-search (count 0) (ask (not dont-ask)))
|
||||
(tildify-foreach-region-outside-env beg end
|
||||
(lambda (beg end)
|
||||
(let ((aux (tildify-tildify beg end ask)))
|
||||
(setq count (+ count (car aux)))
|
||||
(if (not (eq (cdr aux) 'force))
|
||||
(cdr aux)
|
||||
(setq ask nil)
|
||||
t))))
|
||||
(message "%d spaces replaced." count)))
|
||||
|
||||
;;;###autoload
|
||||
(defun tildify-buffer (&optional dont-ask)
|
||||
@ -266,42 +226,58 @@ won't be prompted for confirmation of each substitution."
|
||||
|
||||
;;; *** Auxiliary functions ***
|
||||
|
||||
(defun tildify-build-regexp ()
|
||||
"Build start of environment regexp."
|
||||
(let ((alist (tildify-mode-alist tildify-ignored-environments-alist))
|
||||
regexp)
|
||||
(when alist
|
||||
(setq regexp (caar alist))
|
||||
(setq alist (cdr alist))
|
||||
(while alist
|
||||
(setq regexp (concat regexp "\\|" (caar alist)))
|
||||
(setq alist (cdr alist)))
|
||||
regexp)))
|
||||
|
||||
(defun tildify-mode-alist (mode-alist &optional mode)
|
||||
"Return alist item for the MODE-ALIST in the current major MODE."
|
||||
(if (null mode)
|
||||
(setq mode major-mode))
|
||||
(let ((alist (cdr (or (assoc mode mode-alist)
|
||||
(let ((alist (cdr (or (assoc (or mode major-mode) mode-alist)
|
||||
(assoc t mode-alist)))))
|
||||
(if (and alist
|
||||
(symbolp alist))
|
||||
(tildify-mode-alist mode-alist alist)
|
||||
alist)))
|
||||
|
||||
(defun tildify-find-env (regexp)
|
||||
(defun tildify-foreach-region-outside-env (beg end callback)
|
||||
"Scan region from BEG to END calling CALLBACK on portions out of environments.
|
||||
Call CALLBACK on each region outside of environment to ignore.
|
||||
CALLBACK will only be called for regions which have intersection
|
||||
with [BEG END]. It must be a function that takes two point
|
||||
arguments specifying the region to operate on. Stop scanning the
|
||||
region as soon as CALLBACK returns nil. Environments to ignore
|
||||
are determined from `tildify-ignored-environments-alist'."
|
||||
(declare (indent 2))
|
||||
(let ((pairs (tildify-mode-alist tildify-ignored-environments-alist)))
|
||||
(if (not pairs)
|
||||
(funcall callback beg end)
|
||||
(let ((func (lambda (b e)
|
||||
(let ((b (max b beg)) (e (min e end)))
|
||||
(if (< b e) (funcall callback b e) t))))
|
||||
(beg-re (concat "\\(?:"
|
||||
(mapconcat 'car pairs "\\)\\|\\(?:")
|
||||
"\\)"))
|
||||
p end-re)
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(while (and (< (setq p (point)) end)
|
||||
(if (not (setq end-re
|
||||
(tildify-find-env beg-re pairs)))
|
||||
(progn (funcall func p end) nil)
|
||||
(funcall func p (match-beginning 0))
|
||||
(when (< (point) end)
|
||||
(setq p (point))
|
||||
(re-search-forward end-re nil t)))))))))))
|
||||
|
||||
(defun tildify-find-env (regexp pairs)
|
||||
"Find environment using REGEXP.
|
||||
Return regexp for the end of the environment or nil if no environment was
|
||||
found."
|
||||
Return regexp for the end of the environment found in PAIRS or nil if
|
||||
no environment was found."
|
||||
;; Find environment
|
||||
(when (re-search-forward regexp nil t)
|
||||
(save-match-data
|
||||
;; Build end-env regexp
|
||||
(let ((match (match-string 0))
|
||||
(alist (tildify-mode-alist tildify-ignored-environments-alist)))
|
||||
(while (not (eq (string-match (caar alist) match) 0))
|
||||
(setq alist (cdr alist)))
|
||||
(let ((expression (cdar alist)))
|
||||
(let ((match (match-string 0)))
|
||||
(while (not (eq (string-match (caar pairs) match) 0))
|
||||
(setq pairs (cdr pairs)))
|
||||
(let ((expression (cdar pairs)))
|
||||
(if (stringp expression)
|
||||
expression
|
||||
(mapconcat
|
||||
@ -319,8 +295,9 @@ macros.
|
||||
|
||||
If ASK is nil, perform replace without asking user for confirmation.
|
||||
|
||||
Returns one of symbols: t (all right), nil (quit), force (replace without
|
||||
further questions)."
|
||||
Returns (count . response) cons where count is number of string
|
||||
replacements done and response is one of symbols: t (all right), nil
|
||||
(quit), force (replace without further questions)."
|
||||
(save-excursion
|
||||
(goto-char beg)
|
||||
(let* ((alist (tildify-mode-alist tildify-pattern-alist))
|
||||
@ -332,7 +309,8 @@ further questions)."
|
||||
bad-answer
|
||||
replace
|
||||
quit
|
||||
(message-log-max nil))
|
||||
(message-log-max nil)
|
||||
(count 0))
|
||||
(while (and (not quit)
|
||||
(re-search-forward regexp (marker-position end-marker) t))
|
||||
(when (or (not ask)
|
||||
@ -359,12 +337,11 @@ further questions)."
|
||||
(setq bad-answer t)))
|
||||
replace))
|
||||
(replace-match tilde t t nil match-number)
|
||||
(setq tildify-count (1+ tildify-count))))
|
||||
(setq count (1+ count))))
|
||||
;; Return value
|
||||
(cond
|
||||
(quit nil)
|
||||
((not ask) 'force)
|
||||
(t t)))))
|
||||
(cons count (cond (quit nil)
|
||||
((not ask) 'force)
|
||||
(t t))))))
|
||||
|
||||
|
||||
;;; *** Announce ***
|
||||
|
@ -1,5 +1,11 @@
|
||||
2014-06-05 Michal Nazarewicz <mina86@mina86.com>
|
||||
|
||||
* 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'.
|
||||
|
||||
* automated/tildify-tests.el (tildify-test--example-html): Add support
|
||||
for generating XML code, so that…
|
||||
(tildify-test-xml) …test can be added to check handling of XML
|
||||
|
@ -114,23 +114,22 @@ latter is missing, SENTENCE will be used in all placeholder positions."
|
||||
(ert-deftest tildify-test-find-env-end-re-bug ()
|
||||
"Tests generation of end-regex using mix of indexes and strings"
|
||||
(with-temp-buffer
|
||||
(let ((tildify-ignored-environments-alist
|
||||
`((,major-mode ("foo\\|bar" . ("end-" 0))))))
|
||||
(insert "foo whatever end-foo")
|
||||
(goto-char (point-min))
|
||||
(should (string-equal "end-foo" (tildify-find-env "foo\\|bar"))))))
|
||||
(insert "foo whatever end-foo")
|
||||
(goto-char (point-min))
|
||||
(should (string-equal "end-foo"
|
||||
(tildify-find-env "foo\\|bar"
|
||||
'(("foo\\|bar" . ("end-" 0))))))))
|
||||
|
||||
|
||||
(ert-deftest tildify-test-find-env-group-index-bug ()
|
||||
"Tests generation of match-string indexes"
|
||||
(with-temp-buffer
|
||||
(let ((tildify-ignored-environments-alist
|
||||
`((,major-mode ("start-\\(foo\\|bar\\)" . ("end-" 1))
|
||||
("open-\\(foo\\|bar\\)" . ("close-" 1)))))
|
||||
(let ((pairs '(("start-\\(foo\\|bar\\)" . ("end-" 1))
|
||||
("open-\\(foo\\|bar\\)" . ("close-" 1))))
|
||||
(beg-re "start-\\(foo\\|bar\\)\\|open-\\(foo\\|bar\\)"))
|
||||
(insert "open-foo whatever close-foo")
|
||||
(goto-char (point-min))
|
||||
(should (string-equal "close-foo" (tildify-find-env beg-re))))))
|
||||
(should (string-equal "close-foo" (tildify-find-env beg-re pairs))))))
|
||||
|
||||
|
||||
(provide 'tildify-tests)
|
||||
|
Loading…
Reference in New Issue
Block a user