X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/43aac990c339c0fc3304aa476ebc8ea8467f107e..8b55eeeb70be4b4ff3dd4694013bdb1a9f668bc6:/src/buffer.c
diff --git a/src/buffer.c b/src/buffer.c
index 7bc98a8b1d..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;
@@ -888,8 +882,8 @@ drop_overlay (struct buffer *b, struct Lisp_Overlay *ov)
eassert (b == XBUFFER (Fmarker_buffer (ov->start)));
modify_overlay (b, marker_position (ov->start),
marker_position (ov->end));
- Fset_marker (ov->start, Qnil, Qnil);
- Fset_marker (ov->end, Qnil, Qnil);
+ unchain_marker (XMARKER (ov->start));
+ unchain_marker (XMARKER (ov->end));
}
@@ -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;
}
@@ -3834,7 +3829,8 @@ for the front of the overlay advance when text is inserted there
The fifth arg REAR-ADVANCE, if non-nil, makes the marker
for the rear of the overlay advance when text is inserted there
\(which means the text *is* included in the overlay). */)
- (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer, Lisp_Object front_advance, Lisp_Object rear_advance)
+ (Lisp_Object beg, Lisp_Object end, Lisp_Object buffer,
+ Lisp_Object front_advance, Lisp_Object rear_advance)
{
Lisp_Object overlay;
struct buffer *b;
@@ -3843,12 +3839,11 @@ for the rear of the overlay advance when text is inserted there
XSETBUFFER (buffer, current_buffer);
else
CHECK_BUFFER (buffer);
- if (MARKERP (beg)
- && ! EQ (Fmarker_buffer (beg), buffer))
- error ("Marker points into wrong buffer");
- if (MARKERP (end)
- && ! EQ (Fmarker_buffer (end), buffer))
- error ("Marker points into wrong buffer");
+
+ if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer))
+ signal_error ("Marker points into wrong buffer", beg);
+ if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
+ signal_error ("Marker points into wrong buffer", end);
CHECK_NUMBER_COERCE_MARKER (beg);
CHECK_NUMBER_COERCE_MARKER (end);
@@ -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);
}
@@ -3974,12 +3959,10 @@ buffer. */)
if (NILP (Fbuffer_live_p (buffer)))
error ("Attempt to move overlay to a dead buffer");
- if (MARKERP (beg)
- && ! EQ (Fmarker_buffer (beg), buffer))
- error ("Marker points into wrong buffer");
- if (MARKERP (end)
- && ! EQ (Fmarker_buffer (end), buffer))
- error ("Marker points into wrong buffer");
+ if (MARKERP (beg) && !EQ (Fmarker_buffer (beg), buffer))
+ signal_error ("Marker points into wrong buffer", beg);
+ if (MARKERP (end) && !EQ (Fmarker_buffer (end), buffer))
+ signal_error ("Marker points into wrong buffer", end);
CHECK_NUMBER_COERCE_MARKER (beg);
CHECK_NUMBER_COERCE_MARKER (end);
@@ -4161,6 +4144,9 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
CHECK_NUMBER_COERCE_MARKER (pos);
+ if (!buffer_has_overlays ())
+ return Qnil;
+
len = 10;
/* We can't use alloca here because overlays_at can call xrealloc. */
overlay_vec = xmalloc (len * sizeof *overlay_vec);
@@ -4193,6 +4179,9 @@ end of the buffer. */)
CHECK_NUMBER_COERCE_MARKER (beg);
CHECK_NUMBER_COERCE_MARKER (end);
+ if (!buffer_has_overlays ())
+ return Qnil;
+
len = 10;
overlay_vec = xmalloc (len * sizeof *overlay_vec);
@@ -4221,6 +4210,9 @@ the value is (point-max). */)
CHECK_NUMBER_COERCE_MARKER (pos);
+ if (!buffer_has_overlays ())
+ return make_number (ZV);
+
len = 10;
overlay_vec = xmalloc (len * sizeof *overlay_vec);
@@ -4260,6 +4252,9 @@ the value is (point-min). */)
CHECK_NUMBER_COERCE_MARKER (pos);
+ if (!buffer_has_overlays ())
+ return make_number (BEGV);
+
/* At beginning of buffer, we know the answer;
avoid bug subtracting 1 below. */
if (XINT (pos) == BEGV)
@@ -5177,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);
@@ -5341,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. */
@@ -5402,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)
{
@@ -5797,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,
@@ -5890,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
@@ -5898,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
@@ -6182,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,
@@ -6295,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);