From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Michal Nazarewicz Newsgroups: gmane.emacs.devel Subject: [PATCH 4/5] tildify.el: Rewrite `tildify-region' and co., add foreach function. Date: Sun, 2 Mar 2014 22:55:34 +0100 Message-ID: <1393797335-18125-5-git-send-email-mpn@google.com> References: <1393797335-18125-1-git-send-email-mpn@google.com> NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1393797357 8927 80.91.229.3 (2 Mar 2014 21:55:57 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 2 Mar 2014 21:55:57 +0000 (UTC) To: emacs-devel@gnu.org, Stefan Monnier , =?UTF-8?q?Pavel=20Jan=C3=ADk?= , Milan Zamazal Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Mar 02 22:56:04 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1WKEMd-0001JQ-Db for ged-emacs-devel@m.gmane.org; Sun, 02 Mar 2014 22:56:03 +0100 Original-Received: from localhost ([::1]:36724 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKEMd-0001lL-26 for ged-emacs-devel@m.gmane.org; Sun, 02 Mar 2014 16:56:03 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:39626) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKEMT-0001bz-6n for emacs-devel@gnu.org; Sun, 02 Mar 2014 16:55:58 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WKEMN-0008HK-NP for emacs-devel@gnu.org; Sun, 02 Mar 2014 16:55:53 -0500 Original-Received: from mail-ee0-x229.google.com ([2a00:1450:4013:c00::229]:55957) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WKEMN-0008Gp-C1 for emacs-devel@gnu.org; Sun, 02 Mar 2014 16:55:47 -0500 Original-Received: by mail-ee0-f41.google.com with SMTP id t10so1135712eei.28 for ; Sun, 02 Mar 2014 13:55:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references; bh=1ipOwmZXNZDW58s2K3UvoiT9BXT1SrFu1iAvY7vVXDw=; b=BaTsdZ5YH0sK1+0DacGfx1GfW3UxAnjhzD/xBrM95v31J+lIM2IXKbhRKmuimEMOPW 8lsYEFtDo6308zSmSuOZ6XpF1tpjZVahxFYXQd3idSvqoWclGtjkOLBLeywOMm/CZqRd xgbt4+nhf/6reX5dhmgA53mHXhGuZVCaRrvZY8UbVoGYBOJJCgoH8DE1Fzsu197vxYli 5wd17IaFJls9WaxVIyRJ9PArTIsaJBsD37+VYtUAGC59e2VAFMHXF4VUtfoJp4ahyCCJ 6odEiG+QdGUUAXE27xKP+SU3cD6zvnQOJWQTgtyoaRxMAynXcxskJ4mAlj+Etzq5HDsH 0XeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=1ipOwmZXNZDW58s2K3UvoiT9BXT1SrFu1iAvY7vVXDw=; b=SIcZgScHjiEc54JYVo+yxlzzWf5bL5rDWBi/Tjs3v7qc+VJBg2E/EgP1vstOqY2qWi rIxYsv8jSQF2shWndaYArBa5GdmUXtaHaXUl29plXcjE9mm8aQC2zRTmqXUY01TSWFlb V++pECyQEK0Y+x4rHLXyzaR2RqSqGCVMlp9fvTYS0I8vIiZf12MCB6R5rLnWE7ewk5pg EhP/AivvvPWyp3/flaqz25znWUVWAzpYgxdMgJ4UxauyyD2bpb46AcfSecdo8pLAgrMg MiVxfff/tFHeRAP++Da38gzh8RIrslKZ2xiWrVbC8b37+YwUIsTuz6dMe+GsVqkVccAj NBsg== X-Gm-Message-State: ALoCoQnevCQVo2Td04dUmk7Eb/wRFxl/cgobK1j37ue7svhKs1S2ld0M//YBca9YNahx5zqITsIWC0qYvl8P0b6e3g4IwHu24z1RtRDfynO1TYeTYRTNyN0kKz4tohkenhw3JWYNrJw6jgArPeWoMBeVcstpc/tKL5psxsC0pW4DSbulVCbwCf4/+iNoTc4f5AMub/o3Q7vALlOSRLEr54oU4kPJO5UJ+g== X-Received: by 10.15.23.194 with SMTP id h42mr35167839eeu.32.1393797346337; Sun, 02 Mar 2014 13:55:46 -0800 (PST) Original-Received: from mpn-glaptop.zrh.mina86.com (178-82-34-113.dynamic.hispeed.ch. [178.82.34.113]) by mx.google.com with ESMTPSA id u6sm41551056eep.11.2014.03.02.13.55.44 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 02 Mar 2014 13:55:45 -0800 (PST) X-Mailer: git-send-email 1.9.0 In-Reply-To: <1393797335-18125-1-git-send-email-mpn@google.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c00::229 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:170077 Archived-At: From: Michal Nazarewicz Pull the loop looking for environments to ignore out of `tildify-region' function into a new `tildify-foreach-region-outside-env' function which takes callback argument. With that function, rewrite `tildify-region' to be considerably shorter. This also gets rid of `tildify-build-regexp' function whose functionality is now inlined in the foreach function and thanks to the use of `mapconcat' much shorter then `tildify-build-regexp' has been. Furthermore rewrite `tildify-find-env' so that it takes pairs of regexes as an argument instead of having to look it up in `tildify-ignored-environments-alist' each time. Move to use `mapconcat' also shortened the function a bit. Lastly, rewrite `tildify-tildify' so that it returns number of applied changes along the response. This allows to get rid of the `tildify-count' variable. --- lisp/textmodes/tildify.el | 171 +++++++++++++++++++--------------------------- 1 file changed, 72 insertions(+), 99 deletions(-) diff --git a/lisp/textmodes/tildify.el b/lisp/textmodes/tildify.el index 9accce8..d18721a 100644 --- a/lisp/textmodes/tildify.el +++ b/lisp/textmodes/tildify.el @@ -3,7 +3,8 @@ ;; Copyright (C) 1997-2014 Free Software Foundation, Inc. ;; Author: Milan Zamazal -;; Version: 4.5.3 +;; Michal Nazarewicz +;; Version: 4.5.4 ;; 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 @@ -203,51 +198,16 @@ See variables `tildify-pattern-alist', `tildify-string-alist', and parameters. This function performs no refilling of the changed text." (interactive "*r") - (setq tildify-count 0) - (let (a - z - (marker-end (copy-marker end)) - end-env - finish - (ask t) - (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 t)) + (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 () @@ -262,55 +222,67 @@ This function performs no refilling of the changed text." ;;; *** 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)) + (beg-re (if pairs (mapconcat 'car pairs "\\|") pairs))) + (if (not pairs) + (funcall callback beg end) + (let ((func (lambda (b e) + (let ((b (min b beg)) (e (min e beg))) + (if (< b e) (funcall callback beg end) t)))) + 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)) + (if (re-search-forward end-re nil t) + t + (funcall func p end) + nil))))))))))) + +(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 - (if (re-search-forward regexp nil t) - ;; Build end-env regexp - (let ((match (match-string 0)) - (alist (tildify-mode-alist tildify-ignored-environments-alist)) - expression) - (save-match-data - (while (not (eq (string-match (caar alist) match) 0)) - (setq alist (cdr alist)))) - (if (stringp (setq expression (cdar alist))) - expression - (let ((result "") - aux) - (while expression - (setq result (concat result - (if (stringp (setq aux (car expression))) - expression - (regexp-quote (match-string aux))))) - (setq expression (cdr expression))) - result))) - ;; Return nil if not found - nil)) + (when (re-search-forward regexp nil t) + ;; Find regexp pair that matched + (let ((match (match-string 0))) + (save-match-data + (while (not (eq (string-match (caar pairs) match) 0)) + (setq pairs (cdr pairs))))) + ;; Build end-re regexp + (let ((expression (cdar pairs))) + (if (stringp expression) + expression + (mapconcat (lambda (el) (if (stringp el) el + expression + (regexp-quote (match-string el)))) + expression ""))))) (defun tildify-tildify (beg end ask) "Add tilde characters in the region between BEG and END. @@ -319,8 +291,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 +305,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 +333,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.9.0.279.gdc9e3eb