emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Mysterious fontification/C++ context issue


From: Alan Mackenzie
Subject: Re: Mysterious fontification/C++ context issue
Date: 4 Dec 2006 22:17:36 +0100
Date: Mon, 4 Dec 2006 22:17:36 +0100 (CET)

Hi everybody!

On Mon, 4 Dec 2006, martin rudalics wrote:

> I see this too a lot, even in plain C files.  A backtrace when this
> happen looks like this:
>
> Debugger entered--Lisp error: (scan-error "Containing expression ends
> prematurely" 107612 107612)
>   scan-lists(107699 -1 0)
>   forward-list(-1)
>   backward-list(1)
>   beginning-of-defun-raw(nil)
>   beginning-of-defun()
>   c-get-fallback-start-pos(108117)
>   c-parse-state()
>   c-electric-semi&comma(nil)
>   call-interactively(c-electric-semi&comma)
>   call-last-kbd-macro(nil kmacro-loop-setup-function)
>   kmacro-call-macro(nil nil)
>   kmacro-end-and-call-macro(nil)
>   call-interactively(kmacro-end-and-call-macro)
>
> Usually moving the cursor up a few lines, hitting tab to indent that
> line, and then move back to the offending line cures it.

That bit of the CC Mode code is establishing a cache when there isn't already one, so the buggy behaviour won't be readily predictable or easily repeated.

It's a consequence of the recent change to `beginning-of-defun-raw'.
Compare the threads "font-locking and open parens in column 0" and
"emacs hangs in jit-lock".

More precisely, it's a bug in that change. The doc-string of `beginning-of-defun' states that point should just get left at BOB when there's no defun to go back over.

Here's a tentative fix for the bug, not that well tested, but tested a little bit:

2006-12-04  Alan Mackenzie  <address@hidden>

        * emacs-lisp/lisp.el (beginning-of-defun-raw): In the seeking a
        non-nested open-paren case, check there are enough lists to move
        over.  Return the correct value.

Index: lisp.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/emacs-lisp/lisp.el,v
retrieving revision 1.75
diff -c -r1.75 lisp.el
*** lisp.el     8 Nov 2006 19:19:52 -0000       1.75
--- lisp.el     4 Dec 2006 20:59:34 -0000
***************
*** 185,197 ****
  means move forward to Nth following beginning of defun.
  Returns t unless search stops due to beginning or end of buffer.

- Normally a defun starts when there is a char with open-parenthesis
- syntax at the beginning of a line.  If `defun-prompt-regexp' is
- non-nil, then a string which matches that regexp may precede the
- open-parenthesis, and point ends up at the beginning of the line.
-
  If variable `beginning-of-defun-function' is non-nil, its value
! is called as a function to find the defun's beginning."
    (interactive "p")
    (or (not (eq this-command 'beginning-of-defun))
        (eq last-command 'beginning-of-defun)
--- 185,202 ----
  means move forward to Nth following beginning of defun.
  Returns t unless search stops due to beginning or end of buffer.

  If variable `beginning-of-defun-function' is non-nil, its value
! is called as a function to find the defun's beginning.
! ! Normally a defun is assumed to start where there is a char with
! open-parenthesis syntax at the beginning of a line.  If
! `defun-prompt-regexp' is non-nil, then a string which matches
! that regexp may precede the open-parenthesis, and point ends up
! at the beginning of the line.
! ! If `defun-prompt-regexp' and `open-paren-in-column-0-is-defun-start'
! are both nil, the function instead finds an open-paren at the
! outermost level."
    (interactive "p")
    (or (not (eq this-command 'beginning-of-defun))
        (eq last-command 'beginning-of-defun)
***************
*** 208,215 ****

  If variable `beginning-of-defun-function' is non-nil, its value
  is called as a function to find the defun's beginning."
!   (interactive "p") ; change this to "P", maybe, if we ever come to pass ARG
!                   ; to beginning-of-defun-function.
    (unless arg (setq arg 1))           ; The call might not be interactive.
    (cond
     (beginning-of-defun-function
--- 213,220 ----

  If variable `beginning-of-defun-function' is non-nil, its value
  is called as a function to find the defun's beginning."
!   (interactive "p")   ; change this to "P", maybe, if we ever come to pass ARG
!                                       ; to beginning-of-defun-function.
    (unless arg (setq arg 1))           ; The call might not be interactive.
    (cond
     (beginning-of-defun-function
***************
*** 242,271 ****
        (save-restriction
        (widen)
        ;; Get outside of any string or comment.
!       (if (nth 8 pps-state)
            (goto-char (nth 8 pps-state)))

!       (cond
!        ((> arg 0)
!         (when (> nesting-depth 0)
!           (up-list (- nesting-depth))
!           (setq arg (1- arg)))
!         ;; We're now outside of any defun.
!         (backward-list arg)
!         (if (< (point) floor) (goto-char floor)))
! ! ((< arg 0)
!         (cond
!          ((> nesting-depth 0)
!           (up-list nesting-depth)
!           (setq arg (1+ arg)))
!          ((not (looking-at "\\s("))
!           ;; We're between defuns, and not at the start of one.
!           (setq arg (1+ arg))))
!         (forward-list (- arg))
!         (down-list)
!         (backward-char)
!         (if (> (point) ceiling) (goto-char ceiling)))))))))

  (defvar end-of-defun-function nil
    "If non-nil, function for function `end-of-defun' to call.
--- 247,288 ----
        (save-restriction
        (widen)
        ;; Get outside of any string or comment.
!       (if (and (nth 8 pps-state) (/= arg 0))
            (goto-char (nth 8 pps-state)))

!       (condition-case nil ; to catch there being too few defuns to move over.
!           (cond
!            ((> arg 0)
!             (when (> nesting-depth 0)
!               (up-list (- nesting-depth))
!               (setq arg (1- arg)))
!             ;; We're now outside of any defun.
!             (backward-list arg)
!             (if (>= (point) floor)
!                 t
!               (goto-char floor)
!               nil))
! ! ((< arg 0)
!             (cond
!              ((> nesting-depth 0)
!               (up-list nesting-depth)
!               (setq arg (1+ arg)))
!              ((not (looking-at "\\s("))
!               ;; We're between defuns, and not at the start of one.
!               (setq arg (1+ arg))))
!             (forward-list (- arg))
!             (down-list)
!             (backward-char)
!             (if (<= (point) ceiling)
!                 t
!               (goto-char ceiling)
!               nil))
! ! (t))
!         (error (goto-char
!                 (if (> arg 0) floor ceiling))
!                nil)))))))

  (defvar end-of-defun-function nil
    "If non-nil, function for function `end-of-defun' to call.

--
Alan Mackenzie, Ittersbach Germany
"Still having problems sending and receiving Email."




reply via email to

[Prev in Thread] Current Thread [Next in Thread]