emacs-devel
[Top][All Lists]
Advanced

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

Re: Mysterious fontification/C++ context issue - Patch for beginning-of-


From: Chong Yidong
Subject: Re: Mysterious fontification/C++ context issue - Patch for beginning-of-defun-raw.
Date: Sat, 16 Dec 2006 16:26:21 -0500
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.91 (gnu/linux)

Chong Yidong <address@hidden> writes:

>> Anyway, I'm afraid there's nothing we can do here at the moment.  I'm
>> convinced that this bug is responsible for C mode being slow over the
>> past year.  Eventually, Stefan will have to move syntax-ppss in here.
>> So far let's avoid setting `open-paren-in-column-0-is-defun-start' to
>> nil for _any_ mode.  Unless you have an idea ...
>
> It might be possible to construct a "last known defun start position"
> cache variable living in scan_list, so that back_comment can use that
> instead of BOB.  But I don't know how desirable or general such a fix
> is.

This idea seems to work fairly well.  The patch to syntax.c is
attached; it adds an optional DEFUN_START argument to scan_lists which
is a position known to be outside any code structure.  The code in
beginning-of-defun-raw can be altered to use this as follows:

  (let* ((ppss (let (syntax-begin-function
                     font-lock-beginning-of-syntax-function)
                 (syntax-ppss)))
         (defun-start (nth 2 ppss))
         ...)
     ...
    (goto-char (scan-lists (point) (- arg) 0 defun-start))

With this additional change, (progn (goto-char (point-max)) (redisplay))
on xdisp.c takes 0.139s, down from 2.15s.

However M-> is still slow, because, for some reason, (recenter -3) at
the end of the buffer now takes about 2 seconds.  I don't know why.

However, I think all this should be post-22 work; for Emacs 22, let's
just set open-paren-in-column-0-is-defun-start to t, and leave the
existing beginning-of-defun-raw code there should anyone want to set
it to nil.

*** emacs/src/syntax.c.~1.203.~ 2006-12-11 11:37:43.000000000 -0500
--- emacs/src/syntax.c  2006-12-16 15:56:24.000000000 -0500
***************
*** 98,107 ****
  
  static int find_defun_start P_ ((int, int));
  static int back_comment P_ ((EMACS_INT, EMACS_INT, EMACS_INT, int, int,
!                            EMACS_INT *, EMACS_INT *));
  static int char_quoted P_ ((int, int));
  static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object, int));
! static Lisp_Object scan_lists P_ ((EMACS_INT, EMACS_INT, EMACS_INT, int));
  static void scan_sexps_forward P_ ((struct lisp_parse_state *,
                                    int, int, int, int,
                                    int, Lisp_Object, int));
--- 98,107 ----
  
  static int find_defun_start P_ ((int, int));
  static int back_comment P_ ((EMACS_INT, EMACS_INT, EMACS_INT, int, int,
!                            EMACS_INT *, EMACS_INT *, int));
  static int char_quoted P_ ((int, int));
  static Lisp_Object skip_chars P_ ((int, int, Lisp_Object, Lisp_Object, int));
! static Lisp_Object scan_lists P_ ((EMACS_INT, EMACS_INT, EMACS_INT, int, 
int));
  static void scan_sexps_forward P_ ((struct lisp_parse_state *,
                                    int, int, int, int,
                                    int, Lisp_Object, int));
***************
*** 471,480 ****
     the returned value (or at FROM, if the search was not successful).  */
  
  static int
! back_comment (from, from_byte, stop, comnested, comstyle, charpos_ptr, 
bytepos_ptr)
       EMACS_INT from, from_byte, stop;
       int comnested, comstyle;
       EMACS_INT *charpos_ptr, *bytepos_ptr;
  {
    /* Look back, counting the parity of string-quotes,
       and recording the comment-starters seen.
--- 471,482 ----
     the returned value (or at FROM, if the search was not successful).  */
  
  static int
! back_comment (from, from_byte, stop, comnested, comstyle, charpos_ptr, 
bytepos_ptr,
!             defun_start)
       EMACS_INT from, from_byte, stop;
       int comnested, comstyle;
       EMACS_INT *charpos_ptr, *bytepos_ptr;
+      int defun_start;
  {
    /* Look back, counting the parity of string-quotes,
       and recording the comment-starters seen.
***************
*** 497,506 ****
    int comment_end_byte = from_byte;
    int comstart_pos = 0;
    int comstart_byte;
!   /* Place where the containing defun starts,
!      or 0 if we didn't come across it yet.  */
!   int defun_start = 0;
!   int defun_start_byte = 0;
    register enum syntaxcode code;
    int nesting = 1;            /* current comment nesting */
    int c;
--- 499,505 ----
    int comment_end_byte = from_byte;
    int comstart_pos = 0;
    int comstart_byte;
!   int defun_start_byte = defun_start ? CHAR_TO_BYTE (defun_start) : 0;
    register enum syntaxcode code;
    int nesting = 1;            /* current comment nesting */
    int c;
***************
*** 2153,2159 ****
          else if (code == Sendcomment)
            {
              found = back_comment (from, from_byte, stop, comnested, comstyle,
!                                   &out_charpos, &out_bytepos);
              if (found == -1)
                {
                  if (c == '\n')
--- 2152,2158 ----
          else if (code == Sendcomment)
            {
              found = back_comment (from, from_byte, stop, comnested, comstyle,
!                                   &out_charpos, &out_bytepos, 0);
              if (found == -1)
                {
                  if (c == '\n')
***************
*** 2204,2213 ****
     ? SYNTAX (c) : Ssymbol)
  
  static Lisp_Object
! scan_lists (from, count, depth, sexpflag)
       register EMACS_INT from;
       EMACS_INT count, depth;
!      int sexpflag;
  {
    Lisp_Object val;
    register EMACS_INT stop = count > 0 ? ZV : BEGV;
--- 2203,2212 ----
     ? SYNTAX (c) : Ssymbol)
  
  static Lisp_Object
! scan_lists (from, count, depth, sexpflag, defun_start)
       register EMACS_INT from;
       EMACS_INT count, depth;
!      int sexpflag, defun_start;
  {
    Lisp_Object val;
    register EMACS_INT stop = count > 0 ? ZV : BEGV;
***************
*** 2512,2518 ****
              if (!parse_sexp_ignore_comments)
                break;
              found = back_comment (from, from_byte, stop, comnested, comstyle,
!                                   &out_charpos, &out_bytepos);
              /* FIXME:  if found == -1, then it really wasn't a comment-end.
                 For single-char Sendcomment, we can't do much about it apart
                 from skipping the char.
--- 2511,2517 ----
              if (!parse_sexp_ignore_comments)
                break;
              found = back_comment (from, from_byte, stop, comnested, comstyle,
!                                   &out_charpos, &out_bytepos, defun_start);
              /* FIXME:  if found == -1, then it really wasn't a comment-end.
                 For single-char Sendcomment, we can't do much about it apart
                 from skipping the char.
***************
*** 2579,2585 ****
            make_number (last_good), make_number (from));
  }
  
! DEFUN ("scan-lists", Fscan_lists, Sscan_lists, 3, 3, 0,
         doc: /* Scan from character number FROM by COUNT lists.
  Returns the character number of the position thus found.
  
--- 2578,2584 ----
            make_number (last_good), make_number (from));
  }
  
! DEFUN ("scan-lists", Fscan_lists, Sscan_lists, 3, 4, 0,
         doc: /* Scan from character number FROM by COUNT lists.
  Returns the character number of the position thus found.
  
***************
*** 2593,2606 ****
  If the beginning or end of (the accessible part of) the buffer is reached
  and the depth is wrong, an error is signaled.
  If the depth is right but the count is not used up, nil is returned.  */)
!      (from, count, depth)
!      Lisp_Object from, count, depth;
  {
    CHECK_NUMBER (from);
    CHECK_NUMBER (count);
    CHECK_NUMBER (depth);
  
!   return scan_lists (XINT (from), XINT (count), XINT (depth), 0);
  }
  
  DEFUN ("scan-sexps", Fscan_sexps, Sscan_sexps, 2, 2, 0,
--- 2592,2611 ----
  If the beginning or end of (the accessible part of) the buffer is reached
  and the depth is wrong, an error is signaled.
  If the depth is right but the count is not used up, nil is returned.  */)
!      (from, count, depth, defun_start)
! Lisp_Object from, count, depth, defun_start;
  {
    CHECK_NUMBER (from);
    CHECK_NUMBER (count);
    CHECK_NUMBER (depth);
  
!   if (NILP (defun_start))
!     defun_start = make_number (0);
!   else
!     CHECK_NUMBER (defun_start);
! 
!   return scan_lists (XINT (from), XINT (count), XINT (depth), 0,
!                    XINT (defun_start));
  }
  
  DEFUN ("scan-sexps", Fscan_sexps, Sscan_sexps, 2, 2, 0,
***************
*** 2620,2626 ****
    CHECK_NUMBER (from);
    CHECK_NUMBER (count);
  
!   return scan_lists (XINT (from), XINT (count), 0, 1);
  }
  
  DEFUN ("backward-prefix-chars", Fbackward_prefix_chars, 
Sbackward_prefix_chars,
--- 2625,2631 ----
    CHECK_NUMBER (from);
    CHECK_NUMBER (count);
  
!   return scan_lists (XINT (from), XINT (count), 0, 1, 0);
  }
  
  DEFUN ("backward-prefix-chars", Fbackward_prefix_chars, 
Sbackward_prefix_chars,




reply via email to

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