[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: parens matching not matching all matching parens
From: |
Greg Hill |
Subject: |
Re: parens matching not matching all matching parens |
Date: |
Thu, 16 Sep 2004 19:18:45 -0700 |
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
Re: parens matching not matching all matching parens,
Greg Hill <=
Message not available