/* Buffer manipulation primitives for GNU Emacs.
- Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1997
+ Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1997, 1998
Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* For debugging; temporary. See set_buffer_internal. */
/* Lisp_Object Qlisp_mode, Vcheck_symbol; */
+void
nsberror (spec)
Lisp_Object spec;
{
BUF_BEGV (b) = 1;
BUF_ZV (b) = 1;
BUF_Z (b) = 1;
+ BUF_PT_BYTE (b) = 1;
+ BUF_GPT_BYTE (b) = 1;
+ BUF_BEGV_BYTE (b) = 1;
+ BUF_ZV_BYTE (b) = 1;
+ BUF_Z_BYTE (b) = 1;
BUF_MODIFF (b) = 1;
BUF_OVERLAY_MODIFF (b) = 1;
BUF_SAVE_MODIFF (b) = 1;
BUF_BEGV (b) = BUF_BEGV (b->base_buffer);
BUF_ZV (b) = BUF_ZV (b->base_buffer);
BUF_PT (b) = BUF_PT (b->base_buffer);
+ BUF_BEGV_BYTE (b) = BUF_BEGV_BYTE (b->base_buffer);
+ BUF_ZV_BYTE (b) = BUF_ZV_BYTE (b->base_buffer);
+ BUF_PT_BYTE (b) = BUF_PT_BYTE (b->base_buffer);
b->newline_cache = 0;
b->width_run_cache = 0;
if (NILP (b->base_buffer->pt_marker))
{
b->base_buffer->pt_marker = Fmake_marker ();
- Fset_marker (b->base_buffer->pt_marker,
- make_number (BUF_PT (b->base_buffer)), base_buffer);
+ set_marker_both (b->base_buffer->pt_marker, base_buffer,
+ BUF_PT (b->base_buffer),
+ BUF_PT_BYTE (b->base_buffer));
}
if (NILP (b->base_buffer->begv_marker))
{
b->base_buffer->begv_marker = Fmake_marker ();
- Fset_marker (b->base_buffer->begv_marker,
- make_number (BUF_BEGV (b->base_buffer)), base_buffer);
+ set_marker_both (b->base_buffer->begv_marker, base_buffer,
+ BUF_BEGV (b->base_buffer),
+ BUF_BEGV_BYTE (b->base_buffer));
}
if (NILP (b->base_buffer->zv_marker))
{
b->base_buffer->zv_marker = Fmake_marker ();
- Fset_marker (b->base_buffer->zv_marker,
- make_number (BUF_ZV (b->base_buffer)), base_buffer);
+ set_marker_both (b->base_buffer->zv_marker, base_buffer,
+ BUF_ZV (b->base_buffer),
+ BUF_ZV_BYTE (b->base_buffer));
XMARKER (b->base_buffer->zv_marker)->insertion_type = 1;
}
/* Give the indirect buffer markers for its narrowing. */
b->pt_marker = Fmake_marker ();
- Fset_marker (b->pt_marker, make_number (BUF_PT (b)), buf);
+ set_marker_both (b->pt_marker, buf, BUF_PT (b), BUF_PT_BYTE (b));
b->begv_marker = Fmake_marker ();
- Fset_marker (b->begv_marker, make_number (BUF_BEGV (b)), buf);
+ set_marker_both (b->begv_marker, buf, BUF_BEGV (b), BUF_BEGV_BYTE (b));
b->zv_marker = Fmake_marker ();
- Fset_marker (b->zv_marker, make_number (BUF_ZV (b)), buf);
-
+ set_marker_both (b->zv_marker, buf, BUF_ZV (b), BUF_ZV_BYTE (b));
XMARKER (b->zv_marker)->insertion_type = 1;
return buf;
/* 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;
{
Fset_buffer (buf);
if (NILP (norecord))
record_buffer (buf);
- Fselect_window (Fdisplay_buffer (buf, other_window));
+ Fselect_window (Fdisplay_buffer (buf, other_window, Qnil));
return buf;
}
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->pt_marker, make_number (BUF_PT (old_buf)),
- obuf);
+ set_marker_both (old_buf->pt_marker, obuf,
+ BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
}
if (! NILP (old_buf->begv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->begv_marker, make_number (BUF_BEGV (old_buf)),
- obuf);
+ set_marker_both (old_buf->begv_marker, obuf,
+ BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
}
if (! NILP (old_buf->zv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->zv_marker, make_number (BUF_ZV (old_buf)),
- obuf);
+ set_marker_both (old_buf->zv_marker, obuf,
+ BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
}
}
/* If the new current buffer has markers to record PT, BEGV and ZV
when it is not current, fetch them now. */
if (! NILP (b->pt_marker))
- BUF_PT (b) = marker_position (b->pt_marker);
+ {
+ BUF_PT (b) = marker_position (b->pt_marker);
+ BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
+ }
if (! NILP (b->begv_marker))
- BUF_BEGV (b) = marker_position (b->begv_marker);
+ {
+ BUF_BEGV (b) = marker_position (b->begv_marker);
+ BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
+ }
if (! NILP (b->zv_marker))
- BUF_ZV (b) = marker_position (b->zv_marker);
+ {
+ BUF_ZV (b) = marker_position (b->zv_marker);
+ BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
+ }
/* Look down buffer's list of local Lisp variables
to find and update any that forward into C variables. */
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->pt_marker, make_number (BUF_PT (old_buf)),
- obuf);
+ set_marker_both (old_buf->pt_marker, obuf,
+ BUF_PT (old_buf), BUF_PT_BYTE (old_buf));
}
if (! NILP (old_buf->begv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->begv_marker, make_number (BUF_BEGV (old_buf)),
- obuf);
+ set_marker_both (old_buf->begv_marker, obuf,
+ BUF_BEGV (old_buf), BUF_BEGV_BYTE (old_buf));
}
if (! NILP (old_buf->zv_marker))
{
Lisp_Object obuf;
XSETBUFFER (obuf, old_buf);
- Fset_marker (old_buf->zv_marker, make_number (BUF_ZV (old_buf)),
- obuf);
+ set_marker_both (old_buf->zv_marker, obuf,
+ BUF_ZV (old_buf), BUF_ZV_BYTE (old_buf));
}
}
/* If the new current buffer has markers to record PT, BEGV and ZV
when it is not current, fetch them now. */
if (! NILP (b->pt_marker))
- BUF_PT (b) = marker_position (b->pt_marker);
+ {
+ BUF_PT (b) = marker_position (b->pt_marker);
+ BUF_PT_BYTE (b) = marker_byte_position (b->pt_marker);
+ }
if (! NILP (b->begv_marker))
- BUF_BEGV (b) = marker_position (b->begv_marker);
+ {
+ BUF_BEGV (b) = marker_position (b->begv_marker);
+ BUF_BEGV_BYTE (b) = marker_byte_position (b->begv_marker);
+ }
if (! NILP (b->zv_marker))
- BUF_ZV (b) = marker_position (b->zv_marker);
+ {
+ BUF_ZV (b) = marker_position (b->zv_marker);
+ BUF_ZV_BYTE (b) = marker_byte_position (b->zv_marker);
+ }
}
DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0,
set_buffer_internal (XBUFFER (buf));
return buf;
}
+
+/* Set the current buffer to BUFFER provided it is alive. */
+
+Lisp_Object
+set_buffer_if_live (buffer)
+ Lisp_Object buffer;
+{
+ if (! NILP (XBUFFER (buffer)->name))
+ Fset_buffer (buffer);
+ return Qnil;
+}
\f
DEFUN ("barf-if-buffer-read-only", Fbarf_if_buffer_read_only,
Sbarf_if_buffer_read_only, 0, 0, 0,
return Qnil;
}
+void
validate_region (b, e)
register Lisp_Object *b, *e;
{
args_out_of_range (*b, *e);
}
\f
+/* Advance BYTE_POS up to a character boundary
+ and return the adjusted position. */
+
+static int
+advance_to_char_boundary (byte_pos)
+ int byte_pos;
+{
+ int c = FETCH_BYTE (byte_pos);
+
+ while (! CHAR_HEAD_P (c))
+ {
+ byte_pos++;
+ c = FETCH_BYTE (byte_pos);
+ }
+
+ return byte_pos;
+}
+
+DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte,
+ 1, 1, 0,
+ "Set the multibyte flag of the current buffer to FLAG.\n\
+If FLAG is t, this makes the buffer a multibyte buffer.\n\
+If FLAG is nil, this makes the buffer a single-byte buffer.\n\
+The buffer contents remain unchanged as a sequence of bytes\n\
+but the contents viewed as characters do change.")
+ (flag)
+ Lisp_Object flag;
+{
+ Lisp_Object tail, markers;
+
+ /* It would be better to update the list,
+ but this is good enough for now. */
+ if (! EQ (current_buffer->undo_list, Qt))
+ current_buffer->undo_list = Qnil;
+
+ /* If the cached position is for this buffer, clear it out. */
+ clear_charpos_cache (current_buffer);
+
+ if (NILP (flag))
+ {
+ /* Do this first, so it can use CHAR_TO_BYTE
+ to calculate the old correspondences. */
+ set_intervals_multibyte (0);
+
+ current_buffer->enable_multibyte_characters = Qnil;
+
+ Z = Z_BYTE;
+ BEGV = BEGV_BYTE;
+ ZV = ZV_BYTE;
+ GPT = GPT_BYTE;
+ TEMP_SET_PT_BOTH (PT_BYTE, PT_BYTE);
+
+ tail = BUF_MARKERS (current_buffer);
+ while (XSYMBOL (tail) != XSYMBOL (Qnil))
+ {
+ XMARKER (tail)->charpos = XMARKER (tail)->bytepos;
+ tail = XMARKER (tail)->chain;
+ }
+ }
+ else
+ {
+ /* Do this first, so that chars_in_text asks the right question.
+ set_intervals_multibyte needs it too. */
+ current_buffer->enable_multibyte_characters = Qt;
+
+ GPT_BYTE = advance_to_char_boundary (GPT_BYTE);
+ GPT = chars_in_text (BEG_ADDR, GPT_BYTE - BEG_BYTE) + BEG;
+
+ Z = chars_in_text (GPT_ADDR, Z_BYTE - GPT_BYTE) + GPT;
+
+ BEGV_BYTE = advance_to_char_boundary (BEGV_BYTE);
+ if (BEGV_BYTE > GPT_BYTE)
+ BEGV = chars_in_text (GPT_ADDR, BEGV_BYTE - GPT_BYTE) + GPT;
+ else
+ BEGV = chars_in_text (BEG_ADDR, BEGV_BYTE - BEG_BYTE) + BEG;
+
+ ZV_BYTE = advance_to_char_boundary (ZV_BYTE);
+ if (ZV_BYTE > GPT_BYTE)
+ ZV = chars_in_text (GPT_ADDR, ZV_BYTE - GPT_BYTE) + GPT;
+ else
+ ZV = chars_in_text (BEG_ADDR, ZV_BYTE - BEG_BYTE) + BEG;
+
+ {
+ int pt_byte = advance_to_char_boundary (PT_BYTE);
+ int pt;
+
+ if (pt_byte > GPT_BYTE)
+ pt = chars_in_text (GPT_ADDR, pt_byte - GPT_BYTE) + GPT;
+ else
+ pt = chars_in_text (BEG_ADDR, pt_byte - BEG_BYTE) + BEG;
+ TEMP_SET_PT_BOTH (pt, pt_byte);
+ }
+
+ tail = markers = BUF_MARKERS (current_buffer);
+ BUF_MARKERS (current_buffer) = Qnil;
+
+ while (XSYMBOL (tail) != XSYMBOL (Qnil))
+ {
+ XMARKER (tail)->bytepos
+ = advance_to_char_boundary (XMARKER (tail)->bytepos);
+ XMARKER (tail)->charpos = BYTE_TO_CHAR (XMARKER (tail)->bytepos);
+
+ tail = XMARKER (tail)->chain;
+ }
+ BUF_MARKERS (current_buffer) = markers;
+
+ /* Do this last, so it can calculate the new correspondences
+ between chars and bytes. */
+ set_intervals_multibyte (1);
+ }
+
+ return flag;
+}
+\f
DEFUN ("kill-all-local-variables", Fkill_all_local_variables, Skill_all_local_variables,
0, 0, 0,
"Switch to Fundamental mode by killing current buffer's local variables.\n\
Lisp_Object str, str2, pri;
int size;
{
+ int nbytes;
+
if (ssl->used == ssl->size)
{
if (ssl->buf)
ssl->buf[ssl->used].size = size;
ssl->buf[ssl->used].priority = (INTEGERP (pri) ? XINT (pri) : 0);
ssl->used++;
- ssl->bytes += XSTRING (str)->size;
+
+ if (NILP (current_buffer->enable_multibyte_characters))
+ nbytes = XSTRING (str)->size;
+ else if (! STRING_MULTIBYTE (str))
+ nbytes = count_size_as_multibyte (XSTRING (str)->data,
+ XSTRING (str)->size_byte);
+ else
+ nbytes = XSTRING (str)->size_byte;
+
+ ssl->bytes += nbytes;
+
if (STRINGP (str2))
- ssl->bytes += XSTRING (str2)->size;
+ {
+ if (NILP (current_buffer->enable_multibyte_characters))
+ nbytes = XSTRING (str2)->size;
+ else if (! STRING_MULTIBYTE (str2))
+ nbytes = count_size_as_multibyte (XSTRING (str2)->data,
+ XSTRING (str2)->size_byte);
+ else
+ nbytes = XSTRING (str2)->size_byte;
+
+ ssl->bytes += nbytes;
+ }
}
/* Return the concatenation of the strings associated with overlays that
{
Lisp_Object ov, overlay, window, str;
int startpos, endpos;
+ int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
overlay_heads.used = overlay_heads.bytes = 0;
overlay_tails.used = overlay_tails.bytes = 0;
p = overlay_str_buf;
for (i = overlay_tails.used; --i >= 0;)
{
+ int nbytes;
tem = overlay_tails.buf[i].string;
- bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
- p += XSTRING (tem)->size;
+ nbytes = copy_text (XSTRING (tem)->data, p, XSTRING (tem)->size_byte,
+ STRING_MULTIBYTE (tem), multibyte);
+ p += nbytes;
}
for (i = 0; i < overlay_heads.used; ++i)
{
+ int nbytes;
tem = overlay_heads.buf[i].string;
- bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
- p += XSTRING (tem)->size;
+ nbytes = copy_text (XSTRING (tem)->data, p, XSTRING (tem)->size_byte,
+ STRING_MULTIBYTE (tem), multibyte);
+ p += nbytes;
tem = overlay_heads.buf[i].string2;
if (STRINGP (tem))
{
- bcopy (XSTRING (tem)->data, p, XSTRING (tem)->size);
- p += XSTRING (tem)->size;
+ nbytes = copy_text (XSTRING (tem)->data, p,
+ XSTRING (tem)->size_byte,
+ STRING_MULTIBYTE (tem), multibyte);
+ p += nbytes;
}
}
if (p != overlay_str_buf + total)
`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;
defsubr (&Sbuffer_disable_undo);
defsubr (&Sbuffer_enable_undo);
defsubr (&Skill_buffer);
- defsubr (&Serase_buffer);
defsubr (&Sset_buffer_major_mode);
defsubr (&Sswitch_to_buffer);
defsubr (&Spop_to_buffer);
defsubr (&Sset_buffer);
defsubr (&Sbarf_if_buffer_read_only);
defsubr (&Sbury_buffer);
+ defsubr (&Serase_buffer);
+ defsubr (&Sset_buffer_multibyte);
defsubr (&Skill_all_local_variables);
defsubr (&Soverlayp);