Now on revision 106729. ------------------------------------------------------------ revno: 106729 committer: Alan Mackenzie branch nick: trunk timestamp: Sat 2011-12-24 19:32:31 +0000 message: Introduce a mechanism to widen the region used in context font locking. Use this to protect declarations from losing their contexts. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-12-24 19:16:53 +0000 +++ lisp/ChangeLog 2011-12-24 19:32:31 +0000 @@ -1,3 +1,26 @@ +2011-12-24 Alan Mackenzie + + Introduce a mechanism to widen the region used in context font + locking. Use this to protect declarations from losing their + contexts. + + * progmodes/cc-langs.el (c-before-font-lock-functions): replace + c-set-fl-decl-start with c-change-set-fl-decl-start (Renaming). + (c-before-context-fontification-functions): new defvar, a list of + functions to be run just before context (etc.) font locking. + + * progmodes/cc-mode.el (c-extend-font-lock-region-for-macros): + new, functionality extracted from + c-neutralize-syntax-in-and-mark-CPP. + (c-in-after-change-fontification): new variable. + (c-after-change): Set c-in-after-change-fontification. + (c-set-fl-decl-start): Rejig its interface, so it can be called + from both after-change and context fontifying. + (c-change-set-fl-decl-start, c-context-set-fl-decl-start): new + functions. + (c-standard-font-lock-fontify-region-function): new variable. + (c-font-lock-fontify-region): new function. + 2011-12-24 Juri Linkov * window.el (window--state-get-1): Set `FORCE' arg of `mark' to t. === modified file 'lisp/progmodes/cc-langs.el' --- lisp/progmodes/cc-langs.el 2011-12-23 11:48:54 +0000 +++ lisp/progmodes/cc-langs.el 2011-12-24 19:32:31 +0000 @@ -488,8 +488,9 @@ (c-lang-defconst c-before-font-lock-functions ;; For documentation see the following c-lang-defvar of the same name. ;; The value here may be a list of functions or a single function. - t 'c-set-fl-decl-start - (c c++ objc) '(c-neutralize-syntax-in-and-mark-CPP c-set-fl-decl-start) + t 'c-change-set-fl-decl-start + (c c++ objc) '(c-neutralize-syntax-in-and-mark-CPP + c-change-set-fl-decl-start) awk 'c-awk-extend-and-syntax-tablify-region) (c-lang-defvar c-before-font-lock-functions (let ((fs (c-lang-const c-before-font-lock-functions))) @@ -514,6 +515,27 @@ When the mode is initialized, these functions are called with parameters \(point-min), \(point-max) and .") +(c-lang-defconst c-before-context-fontification-functions + awk nil + t 'c-context-set-fl-decl-start) + ;; For documentation see the following c-lang-defvar of the same name. + ;; The value here may be a list of functions or a single function. +(c-lang-defvar c-before-context-fontification-functions + (let ((fs (c-lang-const c-before-context-fontification-functions))) + (if (listp fs) + fs + (list fs))) + "If non-nil, a list of functions called just before context (or +other non-change) fontification is done. Typically they will +extend the region. + +These functions will be run in the order given. Each of them +takes 2 parameters, the BEG and END of the region to be +fontified. Point is undefined on both entry and exit. On entry, +the buffer will have been widened and match-data will have been +saved; the return value is a cons of the adjusted +region, (NEW-BEG . NEW-END).") + ;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK). (c-lang-defconst c-at-vsemi-p-fn === modified file 'lisp/progmodes/cc-mode.el' --- lisp/progmodes/cc-mode.el 2011-12-23 11:48:54 +0000 +++ lisp/progmodes/cc-mode.el 2011-12-24 19:32:31 +0000 @@ -599,8 +599,8 @@ ;; Buffer local variables defining the region to be fontified by a font lock ;; after-change function. They are set in c-after-change to -;; after-change-function's BEG and END, and may be modified by a -;; `c-before-font-lock-function'. +;; after-change-functions' BEG and END, and may be modified by functions in +;; `c-before-font-lock-functions'. (defvar c-new-BEG 0) (make-variable-buffer-local 'c-new-BEG) (defvar c-new-END 0) @@ -830,6 +830,35 @@ ; with a c-cpp-delimiter category property (setq c-old-EOM (point))) +(defun c-extend-font-lock-region-for-macros (begg endd &optional old-len) + ;; Extend the region (BEGG ENDD) to cover all (possibly changed) + ;; preprocessor macros; return the cons (new-BEG . new-END). OLD-LEN should + ;; be either the old length parameter when called from an + ;; after-change-function, or nil otherwise. This defun uses the variables + ;; c-old-BOM, c-new-BOM. + ;; + ;; Point is undefined on both entry and exit to this function. The buffer + ;; will have been widened on entry. + (let (limits new-beg new-end) + (goto-char c-old-BOM) ; already set to old start of macro or begg. + (setq new-beg + (min begg + (if (setq limits (c-state-literal-at (point))) + (cdr limits) ; go forward out of any string or comment. + (point)))) + + (goto-char endd) + (if (setq limits (c-state-literal-at (point))) + (goto-char (car limits))) ; go backward out of any string or comment. + (if (c-beginning-of-macro) + (c-end-of-macro)) + (setq new-end (max endd + (if old-len + (+ (- c-old-EOM old-len) (- endd begg)) + c-old-EOM) + (point))) + (cons new-beg new-end))) + (defun c-neutralize-CPP-line (beg end) ;; BEG and END bound a region, typically a preprocessor line. Put a ;; "punctuation" syntax-table property on syntactically obtrusive @@ -886,26 +915,14 @@ ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!! ;; ;; This function might make hidden buffer changes. - (c-save-buffer-state (limits) + (c-save-buffer-state (new-bounds) ;; First determine the region, (c-new-BEG c-new-END), which will get font ;; locked. It might need "neutralizing". This region may not start ;; inside a string, comment, or macro. - (goto-char c-old-BOM) ; already set to old start of macro or begg. - (setq c-new-BEG - (min c-new-BEG - (if (setq limits (c-state-literal-at (point))) - (cdr limits) ; go forward out of any string or comment. - (point)))) - - (goto-char endd) - (if (setq limits (c-state-literal-at (point))) - (goto-char (car limits))) ; go backward out of any string or comment. - (if (c-beginning-of-macro) - (c-end-of-macro)) - (setq c-new-END (max c-new-END - (+ (- c-old-EOM old-len) (- endd begg)) - (point))) - + (setq new-bounds (c-extend-font-lock-region-for-macros + c-new-BEG c-new-END old-len)) + (setq c-new-BEG (car new-bounds) + c-new-END (cdr new-bounds)) ;; Clear all old relevant properties. (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1)) (c-clear-char-property-with-value c-new-BEG c-new-END 'category 'c-cpp-delimiter) @@ -1015,6 +1032,11 @@ c-get-state-before-change-functions)) )))) +(defvar c-in-after-change-fontification nil) +(make-variable-buffer-local 'c-in-after-change-fontification) +;; A flag to prevent region expanding stuff being done twice for after-change +;; fontification. + (defun c-after-change (beg end old-len) ;; Function put on `after-change-functions' to adjust various caches ;; etc. Prefer speed to finesse here, since there will be an order @@ -1066,63 +1088,113 @@ ;; larger than (beg end). (setq c-new-BEG beg c-new-END end) + (setq c-in-after-change-fontification t) (save-excursion (mapc (lambda (fn) (funcall fn beg end old-len)) c-before-font-lock-functions)))))) -(defun c-set-fl-decl-start (beg end old-len) - ;; If the beginning of line containing c-new-BEG is in the middle of a - ;; "local" declaration (i.e. one which does not start outside of braces - ;; enclosing this pos, such as a struct), set c-new-BEG to (at most) the - ;; beginning of that declaration. Note that declarations, in this sense, - ;; can be nested. c-new-BEG will be used later by c-font-lock-declarations. - ;; - ;; This function is an element of c-before-font-lock-functions, being called - ;; (indirectly) from an after-change function. The after-change-functions' - ;; parameters BEG, OLD and OLD-LEN are ignored here. - (when font-lock-mode - (goto-char (c-point 'bol c-new-BEG)) - (let ((lit-limits (c-literal-limits)) - bod-lim bo-decl) - - (when lit-limits ; Comment or string. - (goto-char (car lit-limits))) - (setq bod-lim (max (- (point) 500) (point-min))) - - (while - ;; Go to a less nested declaration each time round this loop. - (and - (eq (car (c-beginning-of-decl-1 bod-lim)) 'same) - (progn (setq bo-decl (point)) - ;; Are we looking at a keyword such as "template" or - ;; "typedef" which can decorate a type, or the type itself? - (when (or (looking-at c-prefix-spec-kwds-re) - (c-forward-type t)) - ;; We've found another candidate position. - (setq c-new-BEG (min c-new-BEG bo-decl)) - (goto-char bo-decl)) - t) - ;; Try and go out a level to search again. - (progn - (c-backward-syntactic-ws bod-lim) - (or (memq (char-before) '(?\( ?\[)) - (and (eq (char-before) ?\<) - (eq (c-get-char-property - (1- (point)) 'syntax-table) - c-<-as-paren-syntax)))) - (not (bobp))) - (backward-char))))) ; back over (, [, <. - +(defun c-set-fl-decl-start (pos) + ;; If the beginning of the line containing POS is in the middle of a "local" + ;; declaration (i.e. one which does not start outside of braces enclosing + ;; POS, such as a struct), return the beginning of that declaration. + ;; Otherwise return POS. Note that declarations, in this sense, can be + ;; nested. + ;; + ;; This function is called indirectly from font locking stuff - either from + ;; c-after-change (to prepare for after-change font-lockng) or from font + ;; lock context (etc.) fontification. + (let ((lit-limits (c-literal-limits)) + (new-pos pos) + bod-lim bo-decl) + (goto-char (c-point 'bol new-pos)) + (when lit-limits ; Comment or string. + (goto-char (car lit-limits))) + (setq bod-lim (max (- (point) 500) (point-min))) + + (while + ;; Go to a less nested declaration each time round this loop. + (and + (eq (car (c-beginning-of-decl-1 bod-lim)) 'same) + (progn (setq bo-decl (point)) + ;; Are we looking at a keyword such as "template" or + ;; "typedef" which can decorate a type, or the type itself? + (when (or (looking-at c-prefix-spec-kwds-re) + (c-forward-type t)) + ;; We've found another candidate position. + (setq new-pos (min new-pos bo-decl)) + (goto-char bo-decl)) + t) + ;; Try and go out a level to search again. + (progn + (c-backward-syntactic-ws bod-lim) + (or (memq (char-before) '(?\( ?\[)) + (and (eq (char-before) ?\<) + (eq (c-get-char-property + (1- (point)) 'syntax-table) + c-<-as-paren-syntax)))) + (not (bobp))) + (backward-char)) + new-pos)) ; back over (, [, <. + +(defun c-change-set-fl-decl-start (beg end old-len) + ;; Set c-new-BEG to the beginning of a "local" declaration if it('s BOL) is + ;; inside one. This is called from an after-change-function, but the + ;; parameters BEG END and OLD-LEN are ignored. See `c-set-fl-decl-start' + ;; for the detailed functionality. + (if font-lock-mode + (setq c-new-BEG (c-set-fl-decl-start c-new-BEG)))) + +(defun c-context-set-fl-decl-start (beg end) + ;; Return a cons (NEW-BEG . END), where NEW-BEG is the beginning of a + ;; "local" declaration (BOL at) NEW is inside or BEG. See + ;; `c-set-fl-decl-start' for the detailed functionality. + (cons (c-set-fl-decl-start beg) end)) + +(defvar c-standard-font-lock-fontify-region-function nil + "Standard value of `font-lock-fontify-region-function'") + +(defun c-font-lock-fontify-region (beg end &optional verbose) + ;; Effectively advice around `font-lock-fontify-region' which extends the + ;; region (BEG END), for example, to avoid context fontification chopping + ;; off the start of the context. Do not do anything if it's already been + ;; done (i.e. from and after-change fontification. An example (C++) where + ;; this used to happen is this: + ;; + ;; template + ;; + ;; + ;; void myfunc(T* p) {} + ;; + ;; Type a space in the first blank line, and the fontification of the next + ;; line was fouled up by context fontification. + (let ((new-beg beg) (new-end end) new-region) + (if c-in-after-change-fontification + (setq c-in-after-change-fontification nil) + (save-restriction + (widen) + (save-excursion + (mapc (lambda (fn) + (setq new-region (funcall fn new-beg new-end)) + (setq new-beg (car new-region) new-end (cdr new-region))) + c-before-context-fontification-functions)))) + (funcall c-standard-font-lock-fontify-region-function + new-beg new-end verbose))) + (defun c-after-font-lock-init () - ;; Put on `font-lock-mode-hook'. + ;; Put on `font-lock-mode-hook'. This function ensures our after-change + ;; function will get excuted before the font-lock one. Amongst other + ;; things. (remove-hook 'after-change-functions 'c-after-change t) - (add-hook 'after-change-functions 'c-after-change nil t)) + (add-hook 'after-change-functions 'c-after-change nil t) + (setq c-standard-font-lock-fontify-region-function + (default-value 'font-lock-fontify-region-function))) (defun c-font-lock-init () "Set up the font-lock variables for using the font-lock support in CC Mode. This does not load the font-lock package. Use after -`c-basic-common-init' and after cc-fonts has been loaded." +`c-basic-common-init' and after cc-fonts has been loaded. +This function is called from `c-common-init', once per mode initialization." (set (make-local-variable 'font-lock-defaults) `(,(if (c-major-mode-is 'awk-mode) @@ -1136,6 +1208,10 @@ c-beginning-of-syntax (font-lock-mark-block-function . c-mark-function))) + + (make-local-variable 'font-lock-fontify-region-function) + (setq font-lock-fontify-region-function 'c-font-lock-fontify-region) + (if (featurep 'xemacs) (make-local-hook 'font-lock-mode-hook)) (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t)) ------------------------------------------------------------ revno: 106728 fixes bug(s): http://debbugs.gnu.org/10360 committer: Eli Zaretskii branch nick: trunk timestamp: Sat 2011-12-24 21:24:10 +0200 message: Add the bug number #10360 to the entry for revision 106726. The real fix for bug 10360 is in revision 106726. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-12-23 14:51:51 +0000 +++ src/ChangeLog 2011-12-24 19:24:10 +0000 @@ -2,7 +2,7 @@ * xdisp.c (handle_invisible_prop): Handle correctly an invisible property that ends at ZV, so that the bidi iteration could be - resumed from there (after widening). + resumed from there (after widening). (Bug#10360) 2011-12-22 Jan Djärv ------------------------------------------------------------ revno: 106727 fixes bug(s): http://debbugs.gnu.org/10348 committer: Juri Linkov branch nick: trunk timestamp: Sat 2011-12-24 21:16:53 +0200 message: * lisp/window.el (window--state-get-1): Set `FORCE' arg of `mark' to t. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2011-12-23 14:31:35 +0000 +++ lisp/ChangeLog 2011-12-24 19:16:53 +0000 @@ -1,3 +1,8 @@ +2011-12-24 Juri Linkov + + * window.el (window--state-get-1): Set `FORCE' arg of `mark' to t. + (Bug#10348) + 2011-12-23 Michael Albinus * net/ange-ftp.el (ange-ftp-copy-file-internal): Check for === modified file 'lisp/window.el' --- lisp/window.el 2011-12-20 07:45:20 +0000 +++ lisp/window.el 2011-12-24 19:16:53 +0000 @@ -3604,7 +3604,7 @@ (with-current-buffer (window-buffer window) (let ((point (window-point-1 window)) (start (window-start window)) - (mark (mark))) + (mark (mark t))) `((buffer ,(buffer-name buffer) (selected . ,selected) ------------------------------------------------------------ revno: 106726 committer: Eli Zaretskii branch nick: trunk timestamp: Fri 2011-12-23 16:51:51 +0200 message: Fix assertion violation in pop_it when org-indent-mode is used. src/xdisp.c (handle_invisible_prop): Handle correctly an invisible property that ends at ZV, so that the bidi iteration could be resumed from there (after widening). diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2011-12-22 13:58:40 +0000 +++ src/ChangeLog 2011-12-23 14:51:51 +0000 @@ -1,3 +1,9 @@ +2011-12-23 Eli Zaretskii + + * xdisp.c (handle_invisible_prop): Handle correctly an invisible + property that ends at ZV, so that the bidi iteration could be + resumed from there (after widening). + 2011-12-22 Jan Djärv * nsfont.m (ns_spec_to_descriptor): Do not autorelease fdesc. === modified file 'src/xdisp.c' --- src/xdisp.c 2011-12-10 19:54:45 +0000 +++ src/xdisp.c 2011-12-23 14:51:51 +0000 @@ -4090,10 +4090,11 @@ while (invis_p); /* The position newpos is now either ZV or on visible text. */ - if (it->bidi_p && newpos < ZV) + if (it->bidi_p) { EMACS_INT bpos = CHAR_TO_BYTE (newpos); - int on_newline = FETCH_BYTE (bpos) == '\n'; + int on_newline = + bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n'; int after_newline = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n'; @@ -4111,16 +4112,16 @@ SET_TEXT_POS (tpos, newpos, bpos); reseat_1 (it, tpos, 0); - /* If we reseat on a newline, we need to prep the + /* If we reseat on a newline/ZV, we need to prep the bidi iterator for advancing to the next character - after the newline, keeping the current paragraph + after the newline/EOB, keeping the current paragraph direction (so that PRODUCE_GLYPHS does TRT wrt prepending/appending glyphs to a glyph row). */ if (on_newline) { it->bidi_it.first_elt = 0; it->bidi_it.paragraph_dir = pdir; - it->bidi_it.ch = '\n'; + it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n'; it->bidi_it.nchars = 1; it->bidi_it.ch_len = 1; }