/* Buffer manipulation primitives for GNU Emacs.
- Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995
+ Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1997
Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
+#include <errno.h>
+
+extern int errno;
#ifndef MAXPATHLEN
/* in 4.1, param.h fails to define this. */
#include "region-cache.h"
#include "indent.h"
#include "blockinput.h"
+#include "frame.h"
struct buffer *current_buffer; /* the current buffer */
/* For debugging; temporary. See set_buffer_internal. */
/* Lisp_Object Qlisp_mode, Vcheck_symbol; */
+void
nsberror (spec)
Lisp_Object spec;
{
? Qt : Qnil);
}
-DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 0, 0,
- "Return a list of all existing live buffers.")
- ()
+DEFUN ("buffer-list", Fbuffer_list, Sbuffer_list, 0, 1, 0,
+ "Return a list of all existing live buffers.\n\
+If the optional arg FRAME is a frame, we return that frame's buffer list.")
+ (frame)
+ Lisp_Object frame;
{
- return Fmapcar (Qcdr, Vbuffer_alist);
+ Lisp_Object framelist, general;
+ general = Fmapcar (Qcdr, Vbuffer_alist);
+
+ if (FRAMEP (frame))
+ {
+ Lisp_Object tail;
+
+ CHECK_FRAME (frame, 1);
+
+ framelist = Fcopy_sequence (XFRAME (frame)->buffer_list);
+
+ /* Remove from GENERAL any buffer that duplicates one in FRAMELIST. */
+ tail = framelist;
+ while (! NILP (tail))
+ {
+ general = Fdelq (XCONS (tail)->car, general);
+ tail = XCONS (tail)->cdr;
+ }
+ return nconc2 (framelist, general);
+ }
+
+ return general;
}
/* Like Fassoc, but use Fstring_equal to compare
b->modtime = 0;
XSETFASTINT (b->save_length, 0);
b->last_window_start = 1;
+ /* It is more conservative to start out "changed" than "unchanged". */
+ b->clip_changed = 1;
b->backed_up = Qnil;
b->auto_save_modified = 0;
b->auto_save_failure_time = -1;
b->point_before_scroll = Qnil;
b->file_format = Qnil;
b->last_selected_window = Qnil;
+ XSETINT (b->display_count, 0);
b->extra2 = Qnil;
b->extra3 = Qnil;
}
register Lisp_Object buffer, visible_ok;
{
Lisp_Object Fset_buffer_major_mode ();
- register Lisp_Object tail, buf, notsogood, tem;
+ register Lisp_Object tail, buf, notsogood, tem, pred, add_ons;
notsogood = Qnil;
- for (tail = Vbuffer_alist; !NILP (tail); tail = Fcdr (tail))
+ tail = Vbuffer_alist;
+ pred = frame_buffer_predicate ();
+
+ /* Consider buffers that have been seen in the selected frame
+ before other buffers. */
+
+ tem = frame_buffer_list ();
+ add_ons = Qnil;
+ while (CONSP (tem))
+ {
+ if (BUFFERP (XCONS (tem)->car))
+ add_ons = Fcons (Fcons (Qnil, XCONS (tem)->car), add_ons);
+ tem = XCONS (tem)->cdr;
+ }
+ tail = nconc2 (Fnreverse (add_ons), tail);
+
+ for (; !NILP (tail); tail = Fcdr (tail))
{
buf = Fcdr (Fcar (tail));
if (EQ (buf, buffer))
continue;
/* If the selected frame has a buffer_predicate,
disregard buffers that don't fit the predicate. */
- tem = frame_buffer_predicate ();
- if (!NILP (tem))
+ if (!NILP (pred))
{
- tem = call1 (tem, buf);
+ tem = call1 (pred, buf);
if (NILP (tem))
continue;
}
Vinhibit_quit = Qt;
replace_buffer_in_all_windows (buf);
Vbuffer_alist = Fdelq (Frassq (buf, Vbuffer_alist), Vbuffer_alist);
+ frames_discard_buffer (buf);
Vinhibit_quit = tem;
/* Delete any auto-save file, if we saved it in this session. */
if (STRINGP (b->auto_save_file_name)
&& b->auto_save_modified != 0
- && SAVE_MODIFF < b->auto_save_modified)
+ && BUF_SAVE_MODIFF (b) < b->auto_save_modified)
{
Lisp_Object tem;
tem = Fsymbol_value (intern ("delete-auto-save-files"));
selected buffers are always closer to the front of the list. This
means that other_buffer is more likely to choose a relevant buffer. */
+void
record_buffer (buf)
Lisp_Object buf;
{
else
XCONS (prev)->cdr = XCONS (XCONS (prev)->cdr)->cdr;
- XCONS(link)->cdr = Vbuffer_alist;
+ XCONS (link)->cdr = Vbuffer_alist;
Vbuffer_alist = link;
+
+ /* Now move this buffer to the front of frame_buffer_list also. */
+
+ prev = Qnil;
+ for (link = frame_buffer_list (); CONSP (link); link = XCONS (link)->cdr)
+ {
+ if (EQ (XCONS (link)->car, buf))
+ break;
+ prev = link;
+ }
+
+ /* Effectively do delq. */
+
+ if (CONSP (link))
+ {
+ if (NILP (prev))
+ set_frame_buffer_list (XCONS (frame_buffer_list ())->cdr);
+ else
+ XCONS (prev)->cdr = XCONS (XCONS (prev)->cdr)->cdr;
+
+ XCONS (link)->cdr = frame_buffer_list ();
+ set_frame_buffer_list (link);
+ }
+ else
+ set_frame_buffer_list (Fcons (buf, frame_buffer_list ()));
}
DEFUN ("set-buffer-major-mode", Fset_buffer_major_mode, Sset_buffer_major_mode, 1, 1, 0,
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf);
+ Fset_marker (old_buf->pt_marker, make_number (BUF_PT (old_buf)),
+ obuf);
}
if (! NILP (old_buf->begv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf);
+ Fset_marker (old_buf->begv_marker, make_number (BUF_BEGV (old_buf)),
+ obuf);
}
if (! NILP (old_buf->zv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf);
+ Fset_marker (old_buf->zv_marker, make_number (BUF_ZV (old_buf)),
+ obuf);
}
}
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf);
+ Fset_marker (old_buf->pt_marker, make_number (BUF_PT (old_buf)),
+ obuf);
}
if (! NILP (old_buf->begv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf);
+ Fset_marker (old_buf->begv_marker, make_number (BUF_BEGV (old_buf)),
+ obuf);
}
if (! NILP (old_buf->zv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf);
+ Fset_marker (old_buf->zv_marker, make_number (BUF_ZV (old_buf)),
+ obuf);
}
}
Vbuffer_alist = nconc2 (Vbuffer_alist, link);
}
+ frames_bury_buffer (buffer);
+
return Qnil;
}
\f
return Qnil;
}
+void
validate_region (b, e)
register Lisp_Object *b, *e;
{
it's more efficient to hold onto the memory instead of repeatedly
allocating and freeing it. */
static struct sortstrlist overlay_heads, overlay_tails;
-static char *overlay_str_buf;
+static unsigned char *overlay_str_buf;
/* Allocated length of overlay_str_buf. */
static int overlay_str_len;
{
Lisp_Object tem;
int i;
- char *p;
+ unsigned char *p;
int total = overlay_heads.bytes + overlay_tails.bytes;
if (total > overlay_str_len)
- overlay_str_buf = (char *)xrealloc (overlay_str_buf,
- overlay_str_len = total);
+ {
+ overlay_str_len = total;
+ overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
+ total);
+ }
p = overlay_str_buf;
for (i = overlay_tails.used; --i >= 0;)
{
if (startpos > endpos)
{
int tem;
- Fset_marker (OVERLAY_START (overlay), endpos, Qnil);
- Fset_marker (OVERLAY_END (overlay), startpos, Qnil);
+ Fset_marker (OVERLAY_START (overlay), make_number (endpos),
+ Qnil);
+ Fset_marker (OVERLAY_END (overlay), make_number (startpos),
+ Qnil);
tem = startpos; startpos = endpos; endpos = tem;
}
/* Add it to the end of the wrong list. Later on,
if (startpos > endpos)
{
int tem;
- Fset_marker (OVERLAY_START (overlay), endpos, Qnil);
- Fset_marker (OVERLAY_END (overlay), startpos, Qnil);
+ Fset_marker (OVERLAY_START (overlay), make_number (endpos),
+ Qnil);
+ Fset_marker (OVERLAY_END (overlay), make_number (startpos),
+ Qnil);
tem = startpos; startpos = endpos; endpos = tem;
}
if (endpos < XINT (current_buffer->overlay_center))
`overlays_before' of the buffer *BP. Before the insertion, `point'
was at PREV, and now is at POS. */
+void
fix_overlays_before (bp, prev, pos)
struct buffer *bp;
int prev, pos;
}
}
- ++OVERLAY_MODIFF;
+ ++BUF_OVERLAY_MODIFF (buf);
}
\f\f
+Lisp_Object Fdelete_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.\n\
/* Redisplay where the overlay was. */
if (!NILP (obuffer))
{
- Lisp_Object o_beg;
- Lisp_Object o_end;
+ int o_beg;
+ int o_end;
- o_beg = OVERLAY_START (overlay);
- o_end = OVERLAY_END (overlay);
- o_beg = OVERLAY_POSITION (o_beg);
- o_end = OVERLAY_POSITION (o_end);
+ o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
+ o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
- modify_overlay (ob, XINT (o_beg), XINT (o_end));
+ modify_overlay (ob, o_beg, o_end);
}
/* Redisplay where the overlay is going to be. */
else
/* Redisplay the area the overlay has just left, or just enclosed. */
{
- Lisp_Object o_beg;
- Lisp_Object o_end;
+ int o_beg, o_end;
int change_beg, change_end;
- o_beg = OVERLAY_START (overlay);
- o_end = OVERLAY_END (overlay);
- o_beg = OVERLAY_POSITION (o_beg);
- o_end = OVERLAY_POSITION (o_end);
+ o_beg = OVERLAY_POSITION (OVERLAY_START (overlay));
+ o_end = OVERLAY_POSITION (OVERLAY_END (overlay));
- if (XINT (o_beg) == XINT (beg))
- modify_overlay (b, XINT (o_end), XINT (end));
- else if (XINT (o_end) == XINT (end))
- modify_overlay (b, XINT (o_beg), XINT (beg));
+ if (o_beg == XINT (beg))
+ modify_overlay (b, o_end, XINT (end));
+ else if (o_end == XINT (end))
+ modify_overlay (b, o_beg, XINT (beg));
else
{
- if (XINT (beg) < XINT (o_beg)) o_beg = beg;
- if (XINT (end) > XINT (o_end)) o_end = end;
- modify_overlay (b, XINT (o_beg), XINT (o_end));
+ if (XINT (beg) < o_beg) o_beg = XINT (beg);
+ if (XINT (end) > o_end) o_end = XINT (end);
+ modify_overlay (b, o_beg, o_end);
}
}
buffer_defaults.buffer_file_type = Qnil; /* TEXT */
#endif
buffer_defaults.enable_multibyte_characters = Qt;
+ buffer_defaults.buffer_file_coding_system = Qnil;
XSETFASTINT (buffer_defaults.fill_column, 70);
XSETFASTINT (buffer_defaults.left_margin, 0);
buffer_defaults.cache_long_line_scans = Qnil;
buffer_defaults.file_truename = Qnil;
+ XSETFASTINT (buffer_defaults.display_count, 0);
/* Assign the local-flags to the slots that have default values.
The local flag is a bit that is used in the buffer
XSETINT (buffer_local_flags.file_truename, -1);
XSETINT (buffer_local_flags.invisibility_spec, -1);
XSETINT (buffer_local_flags.file_format, -1);
+ XSETINT (buffer_local_flags.display_count, -1);
XSETFASTINT (buffer_local_flags.mode_line_format, 1);
XSETFASTINT (buffer_local_flags.abbrev_mode, 2);
XSETFASTINT (buffer_local_flags.enable_multibyte_characters, 0x80000);
/* Make this one a permanent local. */
buffer_permanent_local_flags |= 0x80000;
-
+ XSETFASTINT (buffer_local_flags.buffer_file_coding_system, 0x100000);
+ /* Make this one a permanent local. */
+ buffer_permanent_local_flags |= 0x100000;
+
Vbuffer_alist = Qnil;
current_buffer = 0;
all_buffers = 0;
&& dotstat.st_dev == pwdstat.st_dev
&& strlen (pwd) < MAXPATHLEN)
strcpy (buf, pwd);
+#ifdef HAVE_GETCWD
+ else if (getcwd (buf, MAXPATHLEN+1) == 0)
+ fatal ("`getcwd' failed: %s\n", strerror (errno));
+#else
else if (getwd (buf) == 0)
fatal ("`getwd' failed: %s\n", buf);
+#endif
#ifndef VMS
/* Maybe this should really use some standard subroutine
/* Add /: to the front of the name
if it would otherwise be treated as magic. */
temp = Ffind_file_name_handler (current_buffer->directory, Qt);
- if (! NILP (temp))
+ if (! NILP (temp)
+ /* If the default dir is just /, TEMP is non-nil
+ because of the ange-ftp completion handler.
+ However, it is not necessary to turn / into /:/.
+ So avoid doing that. */
+ && strcmp ("/", XSTRING (current_buffer->directory)->data))
current_buffer->directory
= concat2 (build_string ("/:"), current_buffer->directory);
"Default value of `enable-multibyte-characters' for buffers not overriding it.\n\
This is the same as (default-value 'enable-multibyte-characters).");
+ DEFVAR_LISP_NOPRO ("default-buffer-file-coding-system",
+ &buffer_defaults.buffer_file_coding_system,
+ "Default value of `buffer-file-coding-system' for buffers not overriding it.\n\
+ This is the same as (default-value 'buffer-file-coding-system).");
+
DEFVAR_LISP_NOPRO ("default-truncate-lines",
&buffer_defaults.truncate_lines,
"Default value of `truncate-lines' for buffers that do not override it.\n\
(%-constructs are allowed when the string is the entire mode-line-format\n\
or when it is found in a cons-cell or a list)\n\
%b -- print buffer name. %f -- print visited file name.\n\
+ %F -- print frame name.\n\
%* -- print %, * or hyphen. %+ -- print *, % or hyphen.\n\
% means buffer is read-only and * means it is modified.\n\
For a modified read-only buffer, %* gives % and %+ gives *.\n\
%s -- print process status. %l -- print the current line number.\n\
%c -- print the current column number (this makes editing slower).\n\
+ To make the column number update correctly in all cases,\n\
+ `column-number-mode' must be non-nil.\n\
%p -- print percent of buffer above top of window, or Top, Bot or All.\n\
%P -- print percent of buffer above bottom of window, perhaps plus Top,\n\
or print Bottom or All.\n\
DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow, Qnil,
"*Non-nil means display control chars with uparrow.\n\
-Nil means use backslash and octal digits.\n\
+A value of nil means use backslash and octal digits.\n\
Automatically becomes buffer-local when set in any fashion.\n\
This variable does not apply to characters whose display is specified\n\
in the current display table (if there is one).");
DEFVAR_PER_BUFFER ("enable-multibyte-characters",
¤t_buffer->enable_multibyte_characters, Qnil,
- "Non-nil means the buffer contents are regarded as multi-byte form\n\
+ "*Non-nil means the buffer contents are regarded as multi-byte form\n\
of characters, not a binary code. This affects the display, file I/O,\n\
and behaviors of various editing commands.");
+ DEFVAR_PER_BUFFER ("buffer-file-coding-system",
+ ¤t_buffer->buffer_file_coding_system, Qnil,
+ "Coding system to be used for encoding the buffer contents on saving.\n\
+If it is nil, the buffer is saved without any code conversion unless\n\
+some coding system is specified in file-coding-system-alist\n\
+for the buffer file.\n\
+\n\
+This variable is never applied to a way of decoding\n\
+a file while reading it.");
+
DEFVAR_PER_BUFFER ("direction-reversed", ¤t_buffer->direction_reversed,
Qnil,
"*Non-nil means lines in the buffer are displayed right to left.");
the beginning and end of the range of changed text,\n\
and the length of the pre-change text replaced by that range.\n\
\(For an insertion, the pre-change length is zero;\n\
-for a deletion, that length is the number of characters deleted,\n\
+for a deletion, that length is the number of bytes deleted,\n\
and the post-change beginning and end are at the same place.)\n\
\n\
Buffer changes made while executing the `after-change-function'\n\
"List of function to call after each text change.\n\
Three arguments are passed to each function: the positions of\n\
the beginning and end of the range of changed text,\n\
-and the length of the pre-change text replaced by that range.\n\
+and the length in bytes of the pre-change text replaced by that range.\n\
\(For an insertion, the pre-change length is zero;\n\
-for a deletion, that length is the number of characters deleted,\n\
+for a deletion, that length is the number of bytes deleted,\n\
and the post-change beginning and end are at the same place.)\n\
\n\
Buffer changes made while executing the `after-change-functions'\n\
then characters with property value PROP are invisible,\n\
and they have an ellipsis as well if ELLIPSIS is non-nil.");
+ DEFVAR_PER_BUFFER ("buffer-display-count",
+ ¤t_buffer->display_count, Qnil,
+ "A number incremented each time the buffer is displayed in a window.");
+
DEFVAR_LISP ("transient-mark-mode", &Vtransient_mark_mode,
"*Non-nil means deactivate the mark when the buffer contents change.\n\
Non-nil also enables highlighting of the region whenever the mark is active.\n\