X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/adf2fc4a01efe77d73cd52bc9173914ed56ff531..5e6d03b2abd37151ae1329c4b98edfa8242d2f0f:/src/buffer.c diff --git a/src/buffer.c b/src/buffer.c index 0bcb608dbd..e4a550fed9 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -20,8 +20,6 @@ along with GNU Emacs. If not, see . */ #include -#define BUFFER_INLINE EXTERN_INLINE - #include #include #include @@ -156,7 +154,8 @@ CHECK_OVERLAY (Lisp_Object x) CHECK_TYPE (OVERLAYP (x), Qoverlayp, x); } -/* These setters are used only in this file, so they can be private. */ +/* These setters are used only in this file, so they can be private. + The public setters are inline functions defined in buffer.h. */ static void bset_abbrev_mode (struct buffer *b, Lisp_Object val) { @@ -203,11 +202,6 @@ bset_buffer_file_coding_system (struct buffer *b, Lisp_Object val) b->INTERNAL_FIELD (buffer_file_coding_system) = val; } static void -bset_cache_long_scans (struct buffer *b, Lisp_Object val) -{ - b->INTERNAL_FIELD (cache_long_scans) = val; -} -static void bset_case_fold_search (struct buffer *b, Lisp_Object val) { b->INTERNAL_FIELD (case_fold_search) = val; @@ -1334,15 +1328,60 @@ No argument or nil as argument means use current buffer as BUFFER. */) return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil; } +DEFUN ("force-mode-line-update", Fforce_mode_line_update, + Sforce_mode_line_update, 0, 1, 0, + doc: /* Force redisplay of the current buffer's mode line and header line. +With optional non-nil ALL, force redisplay of all mode lines and +header lines. This function also forces recomputation of the +menu bar menus and the frame title. */) + (Lisp_Object all) +{ + if (!NILP (all)) + { + update_mode_lines = 10; + /* FIXME: This can't be right. */ + current_buffer->prevent_redisplay_optimizations_p = true; + } + else if (buffer_window_count (current_buffer)) + { + bset_update_mode_line (current_buffer); + current_buffer->prevent_redisplay_optimizations_p = true; + } + return all; +} + DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p, 1, 1, 0, doc: /* Mark current buffer as modified or unmodified according to FLAG. A non-nil FLAG means mark the buffer modified. */) (Lisp_Object flag) { - Lisp_Object fn; + Frestore_buffer_modified_p (flag); + + /* Set update_mode_lines only if buffer is displayed in some window. + Packages like jit-lock or lazy-lock preserve a buffer's modified + state by recording/restoring the state around blocks of code. + Setting update_mode_lines makes redisplay consider all windows + (on all frames). Stealth fontification of buffers not displayed + would incur additional redisplay costs if we'd set + update_modes_lines unconditionally. + Ideally, I think there should be another mechanism for fontifying + buffers without "modifying" buffers, or redisplay should be + smarter about updating the `*' in mode lines. --gerd */ + return Fforce_mode_line_update (Qnil); +} + +DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p, + Srestore_buffer_modified_p, 1, 1, 0, + doc: /* Like `set-buffer-modified-p', with a difference concerning redisplay. +It is not ensured that mode lines will be updated to show the modified +state of the current buffer. Use with care. */) + (Lisp_Object flag) +{ #ifdef CLASH_DETECTION + Lisp_Object fn; + /* If buffer becoming modified, lock the file. If buffer becoming unmodified, unlock the file. */ @@ -1382,52 +1421,6 @@ A non-nil FLAG means mark the buffer modified. */) or increase MODIFF. */ : MODIFF++); - /* Set update_mode_lines only if buffer is displayed in some window. - Packages like jit-lock or lazy-lock preserve a buffer's modified - state by recording/restoring the state around blocks of code. - Setting update_mode_lines makes redisplay consider all windows - (on all frames). Stealth fontification of buffers not displayed - would incur additional redisplay costs if we'd set - update_modes_lines unconditionally. - - Ideally, I think there should be another mechanism for fontifying - buffers without "modifying" buffers, or redisplay should be - smarter about updating the `*' in mode lines. --gerd */ - if (buffer_window_count (current_buffer)) - { - ++update_mode_lines; - current_buffer->prevent_redisplay_optimizations_p = 1; - } - - return flag; -} - -DEFUN ("restore-buffer-modified-p", Frestore_buffer_modified_p, - Srestore_buffer_modified_p, 1, 1, 0, - doc: /* Like `set-buffer-modified-p', with a difference concerning redisplay. -It is not ensured that mode lines will be updated to show the modified -state of the current buffer. Use with care. */) - (Lisp_Object flag) -{ -#ifdef CLASH_DETECTION - Lisp_Object fn; - - /* If buffer becoming modified, lock the file. - If buffer becoming unmodified, unlock the file. */ - - fn = BVAR (current_buffer, file_truename); - /* Test buffer-file-name so that binding it to nil is effective. */ - if (!NILP (fn) && ! NILP (BVAR (current_buffer, filename))) - { - bool already = SAVE_MODIFF < MODIFF; - if (!already && !NILP (flag)) - lock_file (fn); - else if (already && NILP (flag)) - unlock_file (fn); - } -#endif /* CLASH_DETECTION */ - - SAVE_MODIFF = NILP (flag) ? MODIFF : 0; return flag; } @@ -1515,7 +1508,7 @@ This does not change the name of the visited file (if any). */) /* Catch redisplay's attention. Unless we do this, the mode lines for any windows displaying current_buffer will stay unchanged. */ - update_mode_lines++; + update_mode_lines = 11; XSETBUFFER (buf, current_buffer); Fsetcar (Frassq (buf, Vbuffer_alist), newname); @@ -1800,7 +1793,7 @@ cleaning up all windows currently displaying the buffer to be killed. */) /* Run replace_buffer_in_windows before making another buffer current since set-window-buffer-start-and-point will refuse to make another buffer current if the selected window does not show the current - buffer. (Bug#10114) */ + buffer (bug#10114). */ replace_buffer_in_windows (buffer); /* Exit if replacing the buffer in windows has killed our buffer. */ @@ -2076,7 +2069,7 @@ the current buffer's major mode. */) count = SPECPDL_INDEX (); /* To select a nonfundamental mode, - select the buffer temporarily and then call the mode function. */ + select the buffer temporarily and then call the mode function. */ record_unwind_protect (save_excursion_restore, save_excursion_save ()); @@ -2116,7 +2109,7 @@ set_buffer_internal_1 (register struct buffer *b) old_buf = current_buffer; current_buffer = b; - last_known_column_point = -1; /* invalidate indentation cache */ + last_known_column_point = -1; /* Invalidate indentation cache. */ if (old_buf) { @@ -2140,7 +2133,7 @@ set_buffer_internal_1 (register struct buffer *b) fetch_buffer_markers (b); /* Look down buffer's list of local Lisp variables - to find and update any that forward into C variables. */ + to find and update any that forward into C variables. */ do { @@ -2489,6 +2482,8 @@ current buffer is cleared. */) if (narrowed) error ("Changing multibyteness in a narrowed buffer"); + invalidate_buffer_caches (current_buffer, BEGV, ZV); + if (NILP (flag)) { ptrdiff_t pos, stop; @@ -2707,7 +2702,7 @@ current buffer is cleared. */) /* If buffer is shown in a window, let redisplay consider other windows. */ if (buffer_window_count (current_buffer)) - ++windows_or_buffers_changed; + windows_or_buffers_changed = 10; /* Copy this buffer's new multibyte status into all of its indirect buffers. */ @@ -2767,7 +2762,7 @@ the normal hook `change-major-mode-hook'. */) /* Force mode-line redisplay. Useful here because all major mode commands call this function. */ - update_mode_lines++; + update_mode_lines = 12; return Qnil; } @@ -3908,17 +3903,7 @@ modify_overlay (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) BUF_COMPUTE_UNCHANGED (buf, start, end); - /* If BUF is visible, consider updating the display if ... */ - if (buffer_window_count (buf) > 0) - { - /* ... it's visible in other window than selected, */ - if (buf != XBUFFER (XWINDOW (selected_window)->contents)) - windows_or_buffers_changed = 1; - /* ... or if we modify an overlay at the end of the buffer - and so we cannot be sure that window end is still valid. */ - else if (end >= ZV && start <= ZV) - windows_or_buffers_changed = 1; - } + bset_redisplay (buf); ++BUF_OVERLAY_MODIFF (buf); } @@ -5187,7 +5172,7 @@ init_buffer_once (void) bset_buffer_file_coding_system (&buffer_defaults, Qnil); XSETFASTINT (BVAR (&buffer_defaults, fill_column), 70); XSETFASTINT (BVAR (&buffer_defaults, left_margin), 0); - bset_cache_long_scans (&buffer_defaults, Qnil); + bset_cache_long_scans (&buffer_defaults, Qt); bset_file_truename (&buffer_defaults, Qnil); XSETFASTINT (BVAR (&buffer_defaults, display_count), 0); XSETFASTINT (BVAR (&buffer_defaults, left_margin_cols), 0); @@ -5351,13 +5336,10 @@ init_buffer (void) len++; } + /* At this moment, we still don't know how to decode the directory + name. So, we keep the bytes in unibyte form so that file I/O + routines correctly get the original bytes. */ bset_directory (current_buffer, make_unibyte_string (pwd, len)); - if (! NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) - /* At this moment, we still don't know how to decode the - directory name. So, we keep the bytes in multibyte form so - that ENCODE_FILE correctly gets the original bytes. */ - bset_directory - (current_buffer, string_to_multibyte (BVAR (current_buffer, directory))); /* Add /: to the front of the name if it would otherwise be treated as magic. */ @@ -5412,12 +5394,12 @@ defvar_per_buffer (struct Lisp_Buffer_Objfwd *bo_fwd, const char *namestring, if (PER_BUFFER_IDX (offset) == 0) /* Did a DEFVAR_PER_BUFFER without initializing the corresponding - slot of buffer_local_flags */ + slot of buffer_local_flags. */ emacs_abort (); } -/* initialize the buffer routines */ +/* Initialize the buffer routines. */ void syms_of_buffer (void) { @@ -5807,7 +5789,8 @@ its value may not be a list of functions. */); DEFVAR_PER_BUFFER ("buffer-file-name", &BVAR (current_buffer, filename), Qstringp, - doc: /* Name of file visited in current buffer, or nil if not visiting a file. */); + doc: /* Name of file visited in current buffer, or nil if not visiting a file. +This should be an absolute file name. */); DEFVAR_PER_BUFFER ("buffer-file-truename", &BVAR (current_buffer, file_truename), Qstringp, @@ -5900,7 +5883,7 @@ See also the functions `display-table-slot' and `set-display-table-slot'. */); DEFVAR_PER_BUFFER ("left-margin-width", &BVAR (current_buffer, left_margin_cols), Qintegerp, - doc: /* Width of left marginal area for display of a buffer. + doc: /* Width in columns of left marginal area for display of a buffer. A value of nil means no marginal area. Setting this variable does not take effect until a new buffer is displayed @@ -5908,7 +5891,7 @@ in a window. To make the change take effect, call `set-window-buffer'. */); DEFVAR_PER_BUFFER ("right-margin-width", &BVAR (current_buffer, right_margin_cols), Qintegerp, - doc: /* Width of right marginal area for display of a buffer. + doc: /* Width in columns of right marginal area for display of a buffer. A value of nil means no marginal area. Setting this variable does not take effect until a new buffer is displayed @@ -6192,7 +6175,9 @@ If the value is a list, a text character is invisible if its `invisible' property is an element in that list (or is a list with members in common). If an element is a cons cell of the form (PROP . ELLIPSIS), then characters with property value PROP are invisible, -and they have an ellipsis as well if ELLIPSIS is non-nil. */); +and they have an ellipsis as well if ELLIPSIS is non-nil. +Setting this variable is very fast, much faster than scanning all the +text in the buffer looking for properties to change. */); DEFVAR_PER_BUFFER ("buffer-display-count", &BVAR (current_buffer, display_count), Qintegerp, @@ -6305,6 +6290,7 @@ and `bury-buffer-internal'. */); defsubr (&Sbuffer_local_value); defsubr (&Sbuffer_local_variables); defsubr (&Sbuffer_modified_p); + defsubr (&Sforce_mode_line_update); defsubr (&Sset_buffer_modified_p); defsubr (&Sbuffer_modified_tick); defsubr (&Sbuffer_chars_modified_tick);