From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Greg Hill Newsgroups: gmane.emacs.help Subject: Re: parens matching not matching all matching parens Date: Thu, 16 Sep 2004 19:18:45 -0700 Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Message-ID: References: NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============0854001079==" X-Trace: sea.gmane.org 1095387578 8796 80.91.229.6 (17 Sep 2004 02:19:38 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 17 Sep 2004 02:19:38 +0000 (UTC) Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Fri Sep 17 04:19:26 2004 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1C88LN-0005Ic-00 for ; Fri, 17 Sep 2004 04:19:25 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1C88R4-0001xJ-R9 for geh-help-gnu-emacs@m.gmane.org; Thu, 16 Sep 2004 22:25:18 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1C88Qo-0001xD-8v for help-gnu-emacs@gnu.org; Thu, 16 Sep 2004 22:25:02 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1C88Qm-0001x1-OJ for help-gnu-emacs@gnu.org; Thu, 16 Sep 2004 22:25:01 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1C88Qm-0001wy-KI for help-gnu-emacs@gnu.org; Thu, 16 Sep 2004 22:25:00 -0400 Original-Received: from [207.158.54.5] (helo=renfield.synergymicro.com) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.34) id 1C88Ks-0002JT-EW for help-gnu-emacs@gnu.org; Thu, 16 Sep 2004 22:18:55 -0400 Original-Received: from synergy.san.synergymicro.com (synergy.san.synergymicro.com [10.1.2.12]) by renfield.synergymicro.com (8.12.10/8.12.10) with ESMTP id i8H2L89f024225 for ; Thu, 16 Sep 2004 19:21:08 -0700 Original-Received: from [10.1.5.75] ([10.1.5.75]) by synergy.san.synergymicro.com (8.12.10/8.12.10) with ESMTP id i8H2JZkK021825 for ; Thu, 16 Sep 2004 19:19:35 -0700 In-Reply-To: Original-To: help-gnu-emacs@gnu.org X-Virus-Scanned: clamd / ClamAV version 0.70, clamav-milter version 0.70j X-CanItPRO-Stream: default X-Canit-Stats-ID: 265647 - fe5845ceba40 X-Scanned-By: CanIt (www . canit . ca) X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.help:20728 X-Report-Spam: http://spam.gmane.org/gmane.emacs.help:20728 --===============0854001079== Content-Type: multipart/alternative; boundary="============_-1116734969==_ma============" --============_-1116734969==_ma============ Content-Type: text/plain; charset="us-ascii" ; format="flowed" At 9:19 PM +0200 9/16/04, Arjan Bos wrote: >Hi all, > >I'm currently developing yet another rich text format writer. And as >you might know, RTF is using curly braces a lot. Alas, every now and >then, a normal parentheses pops up between a set of matching {}. >Both the parens matching colouring and the forward-sexp / >backward-sexp can't handle this. How can I (help to) solve this? > >An rtf snippet is included here: > >{\rtf1\mac\ansicpg10000\uc1 >{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}} > >This is a complete piece of (non-sensical, but correct) rtf. The >first `{' matches the last `}'. Only C-M-f jumps from the first `{' >to the one-to-last `}'. > >I'm wondering if this is a bug or not. > >TIA, > >Arjan Arjan, Personally, I would call it a bug in the 'scan-sexps built-in function, which is called by 'forward-sexp, which is normally bound to "C-M-f". For some reason 'scan-sexps seems to treat a ")" as matching a "{". You might want to submit a bug report, but there is no guanentee the maintainers of Emacs will not call that odd behavior a "feature." On the other hand, if you just want to get on with life, you can try putting something like the following code in your .emacs file. The 'defun defines a function that scans forward for the first '(', '[', '<' or '{' following point, whatever it see first, then scans for a matching closing character, ignoring any other characters. The '(setq forward-sexp-function... effectively replaces the guts of 'forward-sexp with the new function, so you will not have to rebind your keystroke. It works in the backward direction as well ("C-M-b"). (defun forward-pexp (&optional arg) (interactive "p") (or arg (setq arg 1)) (let (open close next notstrc notstro notstre depth) (catch 'done (cond ((> arg 0) (skip-chars-forward "^([{<") (setq open (char-after)) (cond ((eq open ?\() (setq close ?\))) ((eq open ?\[) (setq close ?\])) ((eq open ?\{) (setq close ?\})) ((eq open ?\<) (setq close ?\>)) (t (throw 'done nil) ) ) (setq notstro (concat "^" (char-to-string open)) notstre (concat notstro (char-to-string close)) ) (while (and (> arg 0) (not (eobp))) (skip-chars-forward notstro) (forward-char 1) (setq depth 1) (while (and (> depth 0) (not (eobp))) (skip-chars-forward notstre) (setq next (char-after)) (cond ((eq next open) (setq depth (1+ depth)) ) ((eq next close) (setq depth (1- depth)) ) (t (throw 'done nil) ) ) (forward-char 1) ) (setq arg (1- arg) ) ) ) ((< arg 0) (skip-chars-backward "^)]}>") (setq close (char-before)) (cond ((eq close ?\)) (setq open ?\()) ((eq close ?\]) (setq open ?\[)) ((eq close ?\}) (setq open ?\{)) ((eq close ?\>) (setq open ?\<)) (t (throw 'done nil) ) ) (setq notstrc (concat "^" (char-to-string close)) notstre (concat notstrc (char-to-string open)) ) (while (and (< arg 0) (not (bobp))) (skip-chars-backward notstrc) (forward-char -1) (setq depth 1) (while (and (> depth 0) (not (bobp))) (skip-chars-backward notstre) (setq next (char-before)) (cond ((eq next close) (setq depth (1+ depth)) ) ((eq next open) (setq depth (1- depth)) ) (t (throw 'done nil) ) ) (forward-char -1) ) (setq arg (1+ arg)) ) ) ) ) )) (setq forward-sexp-function 'forward-pexp) I should warn you, by the way, that I just hacked this code together in a few minutes after work tonight, and have not tested it exhuastively. Let me know if you have any questions or problems. --Greg --============_-1116734969==_ma============ Content-Type: text/html; charset="us-ascii" Re: parens matching not matching all matching parens
At 9:19 PM +0200 9/16/04, Arjan Bos wrote:
Hi all,

I'm currently developing yet another rich text format writer. And as you might know, RTF is using curly braces a lot. Alas, every now and then, a normal parentheses pops up between a set of matching {}. Both the parens matching colouring and the forward-sexp / backward-sexp can't handle this. How can I (help to) solve this?

An rtf snippet is included here:
{\rtf1\mac\ansicpg10000\uc1
{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}}

This is a complete piece of (non-sensical, but correct) rtf. The first `{' matches the last `}'. Only C-M-f jumps from the first `{' to the one-to-last `}'.

I'm wondering if this is a bug or not.

TIA,
Arjan

Arjan,

Personally, I would call it a bug in the 'scan-sexps built-in function, which is called by 'forward-sexp, which is normally bound to "C-M-f".  For some reason 'scan-sexps seems to treat a ")" as matching a "{".  You might want to submit a bug report, but there is no guanentee the maintainers of Emacs will not call that odd behavior a "feature."

On the other hand, if you just want to get on with life, you can try putting something like the following code in your .emacs file.  The 'defun defines a function that scans forward for the first '(', '[', '<' or '{' following point, whatever it see first, then scans for a matching closing character, ignoring any other characters.  The '(setq forward-sexp-function... effectively replaces the guts of 'forward-sexp with the new function, so you will not have to rebind your keystroke.  It works in the backward direction as well ("C-M-b").

(defun forward-pexp (&optional arg)
  (interactive "p")
  (or arg (setq arg 1))
  (let (open close next notstrc notstro notstre depth)
    (catch 'done
      (cond ((> arg 0)
             (skip-chars-forward "^([{<")
             (setq open (char-after))
             (cond ((eq open ?\()
                    (setq close ?\)))
                   ((eq open ?\[)
                    (setq close ?\]))
                   ((eq open ?\{)
                    (setq close ?\}))
                   ((eq open ?\<)
                    (setq close ?\>))
                   (t
                    (throw 'done nil) ) )
             (setq notstro (concat "^" (char-to-string open))
                   notstre (concat notstro (char-to-string close)) )
             (while (and (> arg 0) (not (eobp)))
               (skip-chars-forward notstro)
               (forward-char 1)
               (setq depth 1)
               (while (and (> depth 0) (not (eobp)))
                (skip-chars-forward notstre)
                (setq next (char-after))
                (cond ((eq next open)
                        (setq depth (1+ depth)) )
                       ((eq next close)
                        (setq depth (1- depth)) )
                       (t
                        (throw 'done nil) ) )
                (forward-char 1) )
               (setq arg (1- arg) ) ) )
            ((< arg 0)
             (skip-chars-backward "^)]}>")
             (setq close (char-before))
             (cond ((eq close ?\))
                    (setq open ?\())
                   ((eq close ?\])
                    (setq open ?\[))
                   ((eq close ?\})
                    (setq open ?\{))
                   ((eq close ?\>)
                    (setq open ?\<))
                   (t
                    (throw 'done nil) ) )
             (setq notstrc (concat "^" (char-to-string close))
                   notstre (concat notstrc (char-to-string open)) )
             (while (and (< arg 0) (not (bobp)))
               (skip-chars-backward notstrc)
               (forward-char -1)
               (setq depth 1)
               (while (and (> depth 0) (not (bobp)))
                (skip-chars-backward notstre)
                (setq next (char-before))
                (cond ((eq next close)
                        (setq depth (1+ depth)) )
                       ((eq next open)
                        (setq depth (1- depth)) )
                       (t
                        (throw 'done nil) ) )
                (forward-char -1) )
               (setq arg (1+ arg)) ) )  ) ) ))

(setq forward-sexp-function 'forward-pexp)

I should warn you, by the way, that I just hacked this code together in a few minutes after work tonight, and have not tested it exhuastively.  Let me know if you have any questions or problems.

--Greg
--============_-1116734969==_ma============-- --===============0854001079== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Help-gnu-emacs mailing list Help-gnu-emacs@gnu.org http://lists.gnu.org/mailman/listinfo/help-gnu-emacs --===============0854001079==--