/* Buffer manipulation primitives for GNU Emacs.
- Copyright (C) 1985, 1986, 1987, 1988, 1989, 1992, 1993
+ Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993
Free Software Foundation, Inc.
This file is part of GNU Emacs.
Lisp_Object Fset_buffer ();
void set_buffer_internal ();
+static void call_overlay_mod_hooks ();
/* Alist of all buffer names vs the buffers. */
/* This used to be a variable, but is no longer,
Lisp_Object Vtransient_mark_mode;
+/* t means ignore all read-only text properties.
+ A list means ignore such a property if its value is a member of the list.
+ Any non-nil value means ignore buffer-read-only. */
+Lisp_Object Vinhibit_read_only;
+
/* List of functions to call before changing an unmodified buffer. */
Lisp_Object Vfirst_change_hook;
Lisp_Object Qfirst_change_hook;
b->overlays_before = Qnil;
b->overlays_after = Qnil;
XFASTINT (b->overlay_center) = 1;
+ b->mark_active = Qnil;
/* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
INITIALIZE_INTERVAL (b, NULL_INTERVAL);
b->upcase_table = Vascii_upcase_table;
b->case_canon_table = Vascii_downcase_table;
b->case_eqv_table = Vascii_upcase_table;
- b->mark_active = Qnil;
#if 0
b->sort_table = XSTRING (Vascii_sort_table);
b->folding_sort_table = XSTRING (Vascii_folding_sort_table);
rename the buffer properly. */
DEFUN ("generate-new-buffer-name", Fgenerate_new_buffer_name, Sgenerate_new_buffer_name,
- 1, 1, 0,
+ 1, 2, 0,
"Return a string that is the name of no existing buffer based on NAME.\n\
If there is no live buffer named NAME, then return NAME.\n\
Otherwise modify name by appending `<NUMBER>', incrementing NUMBER\n\
-until an unused name is found, and then return that name.")
- (name)
- register Lisp_Object name;
+until an unused name is found, and then return that name.\n\
+Optional second argument IGNORE specifies a name that is okay to use\n\
+\(if it is in the sequence to be tried)\n\
+even if a buffer with that name exists.")
+ (name, ignore)
+ register Lisp_Object name, ignore;
{
register Lisp_Object gentemp, tem;
int count;
{
sprintf (number, "<%d>", ++count);
gentemp = concat2 (name, build_string (number));
+ tem = Fstring_equal (gentemp, ignore);
+ if (!NILP (tem))
+ return gentemp;
tem = Fget_buffer (gentemp);
if (NILP (tem))
return gentemp;
if (!NILP (tem))
{
if (!NILP (unique))
- name = Fgenerate_new_buffer_name (name);
+ name = Fgenerate_new_buffer_name (name, current_buffer->name);
else
error ("Buffer name \"%s\" is in use", XSTRING (name)->data);
}
if (XSTRING (XBUFFER (buf)->name)->data[0] == ' ')
continue;
if (NILP (visible_ok))
- tem = Fget_buffer_window (buf, Qnil);
+ tem = Fget_buffer_window (buf, Qt);
else
tem = Qnil;
if (NILP (tem))
: selected_window,
buf);
- return Qnil;
+ return buf;
}
DEFUN ("pop-to-buffer", Fpop_to_buffer, Spop_to_buffer, 1, 2, 0,
Fset_buffer (buf);
record_buffer (buf);
Fselect_window (Fdisplay_buffer (buf, other));
- return Qnil;
+ return buf;
}
DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0,
"Signal a `buffer-read-only' error if the current buffer is read-only.")
()
{
- while (!NILP (current_buffer->read_only))
+ if (!NILP (current_buffer->read_only)
+ && NILP (Vinhibit_read_only))
Fsignal (Qbuffer_read_only, (Fcons (Fcurrent_buffer (), Qnil)));
return Qnil;
}
register Lisp_Object tail, tem, buf;
Lisp_Object col1, col2, col3, minspace;
register struct buffer *old = current_buffer, *b;
- int desired_point = 0;
+ Lisp_Object desired_point;
Lisp_Object other_file_symbol;
+ desired_point = Qnil;
other_file_symbol = intern ("list-buffers-directory");
XFASTINT (col1) = 19;
continue;
/* Identify the current buffer. */
if (b == old)
- desired_point = point;
+ XFASTINT (desired_point) = point;
write_string (b == old ? "." : " ", -1);
/* Identify modified buffers */
write_string (BUF_MODIFF (b) > b->save_modified ? "*" : " ", -1);
current_buffer->read_only = Qt;
set_buffer_internal (old);
-/* Foo. This doesn't work since temp_output_buffer_show sets point to 1
- if (desired_point)
- XBUFFER (Vstandard_output)->text.pointloc = desired_point;
- */
- return Qnil;
+ return desired_point;
}
DEFUN ("list-buffers", Flist_buffers, Slist_buffers, 0, 1, "P",
(files)
Lisp_Object files;
{
- internal_with_output_to_temp_buffer ("*Buffer List*",
- list_buffers_1, files);
- return Qnil;
+ Lisp_Object desired_point;
+
+ desired_point =
+ internal_with_output_to_temp_buffer ("*Buffer List*",
+ list_buffers_1, files);
+
+ if (NUMBERP (desired_point))
+ {
+ int count = specpdl_ptr - specpdl;
+ record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
+ Fset_buffer (build_string ("*Buffer List*"));
+ SET_PT (XINT (desired_point));
+ return unbind_to (count, Qnil);
+ }
}
DEFUN ("kill-all-local-variables", Fkill_all_local_variables, Skill_all_local_variables,
or ZV if there are no more overlays.
*VEC_PTR and *LEN_PTR should contain a valid vector and size
- when this function is called. */
+ when this function is called.
+
+ If EXTEND is non-zero, we make the vector bigger if necessary.
+ If EXTEND is zero, we never extend the vector,
+ and we store only as many overlays as will fit.
+ But we still return the total number of overlays. */
int
-overlays_at (pos, vec_ptr, len_ptr, next_ptr)
+overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr)
int pos;
+ int extend;
Lisp_Object **vec_ptr;
int *len_ptr;
int *next_ptr;
int len = *len_ptr;
Lisp_Object *vec = *vec_ptr;
int next = ZV;
+ int inhibit_storing = 0;
+
for (tail = current_buffer->overlays_before;
CONSP (tail);
tail = XCONS (tail)->cdr)
{
if (idx == len)
{
- *len_ptr = len *= 2;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
- *vec_ptr = vec;
+ /* The supplied vector is full.
+ Either make it bigger, or don't store any more in it. */
+ if (extend)
+ {
+ *len_ptr = len *= 2;
+ vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ *vec_ptr = vec;
+ }
+ else
+ inhibit_storing = 1;
}
- vec[idx++] = overlay;
+
+ if (!inhibit_storing)
+ vec[idx] = overlay;
+ /* Keep counting overlays even if we can't return them all. */
+ idx++;
}
else if (startpos < next)
next = startpos;
{
if (idx == len)
{
- *len_ptr = len *= 2;
- vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
- *vec_ptr = vec;
+ if (extend)
+ {
+ *len_ptr = len *= 2;
+ vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+ *vec_ptr = vec;
+ }
+ else
+ inhibit_storing = 1;
}
- vec[idx++] = overlay;
+
+ if (!inhibit_storing)
+ vec[idx] = overlay;
+ idx++;
}
}
if (NILP (buffer))
XSET (buffer, Lisp_Buffer, current_buffer);
- CHECK_BUFFER (buffer, 2);
+ else
+ CHECK_BUFFER (buffer, 2);
+ 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");
- b = XBUFFER (buffer);
+ CHECK_NUMBER_COERCE_MARKER (beg, 1);
+ CHECK_NUMBER_COERCE_MARKER (end, 1);
- if (MARKERP (beg))
- {
- if (! EQ (Fmarker_buffer (beg), buffer))
- error ("Marker points into wrong buffer");
- else
- beg = Fcopy_marker (beg);
- }
- else
- beg = Fset_marker (Fmake_marker (), beg, buffer);
- if (MARKERP (end))
+ if (XINT (beg) > XINT (end))
{
- if (! EQ (Fmarker_buffer (end), buffer))
- error ("Marker points into wrong buffer");
- else
- end = Fcopy_marker (end);
+ Lisp_Object temp = beg;
+ beg = end; end = temp;
}
- else
- end = Fset_marker (Fmake_marker (), end, buffer);
+
+ b = XBUFFER (buffer);
+
+ beg = Fset_marker (Fmake_marker (), beg, buffer);
+ end = Fset_marker (Fmake_marker (), end, buffer);
overlay = Fcons (Fcons (beg, end), Qnil);
XSETTYPE (overlay, Lisp_Overlay);
DEFUN ("move-overlay", Fmove_overlay, Smove_overlay, 3, 4, 0,
"Set the endpoints of OVERLAY to BEG and END in BUFFER.\n\
-If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.")
+If BUFFER is omitted, leave OVERLAY in the same buffer it inhabits now.\n\
+If BUFFER is omitted, and OVERLAY is in no buffer, put it in the current\n\
+buffer.")
(overlay, beg, end, buffer)
Lisp_Object overlay, beg, end, buffer;
{
- struct buffer *b;
+ struct buffer *b, *ob;
+ Lisp_Object obuffer;
+ int count = specpdl_ptr - specpdl;
CHECK_OVERLAY (overlay, 0);
if (NILP (buffer))
buffer = Fmarker_buffer (OVERLAY_START (overlay));
+ if (NILP (buffer))
+ XSET (buffer, Lisp_Buffer, current_buffer);
CHECK_BUFFER (buffer, 3);
+
+ 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");
+
CHECK_NUMBER_COERCE_MARKER (beg, 1);
CHECK_NUMBER_COERCE_MARKER (end, 1);
+ specbind (Qinhibit_quit, Qt);
+
if (XINT (beg) > XINT (end))
{
Lisp_Object temp = beg;
beg = end; end = temp;
}
+ obuffer = Fmarker_buffer (OVERLAY_START (overlay));
b = XBUFFER (buffer);
+ ob = XBUFFER (obuffer);
- /* Redisplay the area the overlay has just left, or just enclosed. */
- {
- Lisp_Object o_beg = OVERLAY_START (overlay);
- Lisp_Object o_end = OVERLAY_END (overlay);
- int change_beg, change_end;
-
- o_beg = OVERLAY_POSITION (o_beg);
- o_end = OVERLAY_POSITION (o_end);
-
- if (XINT (o_beg) == XINT (beg))
- redisplay_region (b, XINT (o_end), XINT (end));
- else if (XINT (o_end) == XINT (end))
- redisplay_region (b, XINT (o_beg), XINT (beg));
- else
- {
- if (XINT (beg) < XINT (o_beg)) o_beg = beg;
- if (XINT (end) > XINT (o_end)) o_end = end;
- redisplay_region (b, XINT (o_beg), XINT (o_end));
- }
- }
+ /* If the overlay has changed buffers, do a thorough redisplay. */
+ if (!EQ (buffer, obuffer))
+ windows_or_buffers_changed = 1;
+ else
+ /* Redisplay the area the overlay has just left, or just enclosed. */
+ {
+ Lisp_Object o_beg = OVERLAY_START (overlay);
+ Lisp_Object o_end = OVERLAY_END (overlay);
+ int change_beg, change_end;
- b->overlays_before = Fdelq (overlay, b->overlays_before);
- b->overlays_after = Fdelq (overlay, b->overlays_after);
+ o_beg = OVERLAY_POSITION (o_beg);
+ o_end = OVERLAY_POSITION (o_end);
+
+ if (XINT (o_beg) == XINT (beg))
+ redisplay_region (b, XINT (o_end), XINT (end));
+ else if (XINT (o_end) == XINT (end))
+ redisplay_region (b, XINT (o_beg), XINT (beg));
+ else
+ {
+ if (XINT (beg) < XINT (o_beg)) o_beg = beg;
+ if (XINT (end) > XINT (o_end)) o_end = end;
+ redisplay_region (b, XINT (o_beg), XINT (o_end));
+ }
+ }
+
+ if (!NILP (obuffer))
+ {
+ ob->overlays_before = Fdelq (overlay, ob->overlays_before);
+ ob->overlays_after = Fdelq (overlay, ob->overlays_after);
+ }
Fset_marker (OVERLAY_START (overlay), beg, buffer);
Fset_marker (OVERLAY_END (overlay), end, buffer);
/* This puts it in the right list, and in the right order. */
recenter_overlay_lists (b, XINT (b->overlay_center));
- return overlay;
+ return unbind_to (count, overlay);
}
DEFUN ("delete-overlay", Fdelete_overlay, Sdelete_overlay, 1, 1, 0,
(overlay)
Lisp_Object overlay;
{
+ Lisp_Object buffer;
struct buffer *b;
+ int count = specpdl_ptr - specpdl;
CHECK_OVERLAY (overlay, 0);
- b = XBUFFER (Fmarker_buffer (OVERLAY_START (overlay)));
+ buffer = Fmarker_buffer (OVERLAY_START (overlay));
+ if (NILP (buffer))
+ return Qnil;
+
+ b = XBUFFER (buffer);
+
+ specbind (Qinhibit_quit, Qt);
b->overlays_before = Fdelq (overlay, b->overlays_before);
b->overlays_after = Fdelq (overlay, b->overlays_after);
- Fset_marker (OVERLAY_START (overlay), 1, Qnil);
- Fset_marker (OVERLAY_END (overlay), 1, Qnil);
-
redisplay_region (b,
OVERLAY_POSITION (OVERLAY_START (overlay)),
OVERLAY_POSITION (OVERLAY_END (overlay)));
- return Qnil;
+ Fset_marker (OVERLAY_START (overlay), Qnil, Qnil);
+ Fset_marker (OVERLAY_END (overlay), Qnil, Qnil);
+
+ return unbind_to (count, Qnil);
}
\f
/* Overlay dissection functions. */
\f
DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0,
- "Return a list of the overays that contain position POS.")
+ "Return a list of the overlays that contain position POS.")
(pos)
Lisp_Object pos;
{
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
- noverlays = overlays_at (XINT (pos), &overlay_vec, &len, &endpos);
+ noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &endpos);
/* Make a list of them all. */
result = Flist (noverlays, overlay_vec);
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len.
endpos gets the position where the next overlay starts. */
- noverlays = overlays_at (XINT (pos), &overlay_vec, &len, &endpos);
+ noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len, &endpos);
/* If any of these overlays ends before endpos,
use its ending point instead. */
return value;
}
\f
+/* Run the modification-hooks of overlays that include
+ any part of the text in START to END.
+ Run the insert-before-hooks of overlay starting at END,
+ and the insert-after-hooks of overlay ending at START. */
+
+void
+verify_overlay_modification (start, end)
+ Lisp_Object start, end;
+{
+ Lisp_Object prop, overlay, tail;
+ int insertion = EQ (start, end);
+
+ for (tail = current_buffer->overlays_before;
+ CONSP (tail);
+ tail = XCONS (tail)->cdr)
+ {
+ int startpos, endpos;
+ int ostart, oend;
+
+ overlay = XCONS (tail)->car;
+
+ ostart = OVERLAY_START (overlay);
+ oend = OVERLAY_END (overlay);
+ endpos = OVERLAY_POSITION (oend);
+ if (XFASTINT (start) > endpos)
+ break;
+ startpos = OVERLAY_POSITION (ostart);
+ if (XFASTINT (end) == startpos && insertion)
+ {
+ prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
+ call_overlay_mod_hooks (prop, overlay, start, end);
+ }
+ if (XFASTINT (start) == endpos && insertion)
+ {
+ prop = Foverlay_get (overlay, Qinsert_behind_hooks);
+ call_overlay_mod_hooks (prop, overlay, start, end);
+ }
+ if (insertion
+ ? (XFASTINT (start) > startpos && XFASTINT (end) < endpos)
+ : (XFASTINT (start) >= startpos && XFASTINT (end) <= endpos))
+ {
+ prop = Foverlay_get (overlay, Qmodification_hooks);
+ call_overlay_mod_hooks (prop, overlay, start, end);
+ }
+ }
+
+ for (tail = current_buffer->overlays_after;
+ CONSP (tail);
+ tail = XCONS (tail)->cdr)
+ {
+ int startpos, endpos;
+ int ostart, oend;
+
+ overlay = XCONS (tail)->car;
+
+ ostart = OVERLAY_START (overlay);
+ oend = OVERLAY_END (overlay);
+ startpos = OVERLAY_POSITION (ostart);
+ if (XFASTINT (end) < startpos)
+ break;
+ if (XFASTINT (end) == startpos && insertion)
+ {
+ prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
+ call_overlay_mod_hooks (prop, overlay, start, end);
+ }
+ if (XFASTINT (start) == endpos && insertion)
+ {
+ prop = Foverlay_get (overlay, Qinsert_behind_hooks);
+ call_overlay_mod_hooks (prop, overlay, start, end);
+ }
+ if (insertion
+ ? (XFASTINT (start) > startpos && XFASTINT (end) < endpos)
+ : (XFASTINT (start) >= startpos && XFASTINT (end) <= endpos))
+ {
+ prop = Foverlay_get (overlay, Qmodification_hooks);
+ call_overlay_mod_hooks (prop, overlay, start, end);
+ }
+ }
+}
+
+static void
+call_overlay_mod_hooks (list, overlay, start, end)
+ Lisp_Object list, overlay, start, end;
+{
+ struct gcpro gcpro1;
+ GCPRO1 (list);
+ while (!NILP (list))
+ {
+ call3 (Fcar (list), overlay, start, end);
+ list = Fcdr (list);
+ }
+ UNGCPRO;
+}
+\f
/* Somebody has tried to store NEWVAL into the buffer-local slot with
offset XUINT (valcontents), and NEWVAL has an unacceptable type. */
void
char buf[MAXPATHLEN+1];
char *pwd;
struct stat dotstat, pwdstat;
+ Lisp_Object temp;
Fset_buffer (Fget_buffer_create (build_string ("*scratch*")));
strcat (buf, "/");
#endif /* not VMS */
current_buffer->directory = build_string (buf);
+
+ temp = get_minibuffer (0);
+ XBUFFER (temp)->directory = current_buffer->directory;
}
/* initialize the buffer routines */
"*Non-nil means deactivate the mark when the buffer contents change.");
Vtransient_mark_mode = Qnil;
+ DEFVAR_LISP ("inhibit-read-only", &Vinhibit_read_only,
+ "*Non-nil means disregard read-only status of buffers or characters.\n\
+If the value is t, disregard `buffer-read-only' and all `read-only'\n\
+text properties. If the value is a list, disregard `buffer-read-only'\n\
+and disregard a `read-only' text property if the property value\n\
+is a member of the list.");
+ Vinhibit_read_only = Qnil;
+
defsubr (&Sbuffer_list);
defsubr (&Sget_buffer);
defsubr (&Sget_file_buffer);