#include "window.h"
#include "commands.h"
#include "buffer.h"
-#include "charset.h"
+#include "character.h"
#include "region-cache.h"
#include "indent.h"
#include "blockinput.h"
static void modify_overlay P_ ((struct buffer *, EMACS_INT, EMACS_INT));
static Lisp_Object buffer_lisp_local_variables P_ ((struct buffer *));
+extern char * emacs_strerror P_ ((int));
/* For debugging; temporary. See set_buffer_internal. */
/* Lisp_Object Qlisp_mode, Vcheck_symbol; */
XSETBUFFER (to_buffer, to);
- for (offset = PER_BUFFER_VAR_OFFSET (name) + sizeof (Lisp_Object);
+ /* buffer-local Lisp variables start at `undo_list',
+ tho only the ones from `name' on are GC'd normally. */
+ for (offset = PER_BUFFER_VAR_OFFSET (undo_list) + sizeof (Lisp_Object);
offset < sizeof *to;
offset += sizeof (Lisp_Object))
{
/* For each slot that has a default value,
copy that into the slot. */
- for (offset = PER_BUFFER_VAR_OFFSET (name);
+ /* buffer-local Lisp variables start at `undo_list',
+ tho only the ones from `name' on are GC'd normally. */
+ for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
offset < sizeof *b;
offset += sizeof (Lisp_Object))
{
int found = 0;
/* Look in special slots */
- for (offset = PER_BUFFER_VAR_OFFSET (name);
+ /* buffer-local Lisp variables start at `undo_list',
+ tho only the ones from `name' on are GC'd normally. */
+ for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
offset < sizeof (struct buffer);
/* sizeof EMACS_INT == sizeof Lisp_Object */
offset += (sizeof (EMACS_INT)))
{
int offset, idx;
- for (offset = PER_BUFFER_VAR_OFFSET (name);
+ /* buffer-local Lisp variables start at `undo_list',
+ tho only the ones from `name' on are GC'd normally. */
+ for (offset = PER_BUFFER_VAR_OFFSET (undo_list);
offset < sizeof (struct buffer);
/* sizeof EMACS_INT == sizeof Lisp_Object */
offset += (sizeof (EMACS_INT)))
Vbuffer_alist = link;
/* Effectively do a delq on buried_buffer_list. */
-
+
prev = Qnil;
for (link = XFRAME (frame)->buried_buffer_list; CONSP (link);
link = XCDR (link))
}
err = no_switch_window (selected_window);
- if (err) error (err);
+ if (err)
+ /* If can't display in current window, let pop-to-buffer
+ try some other window. */
+ return call3 (intern ("pop-to-buffer"), buffer, Qnil, norecord);
return switch_to_buffer_1 (buffer, norecord);
}
return byte_pos;
}
+DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
+ 1, 1, 0,
+ doc: /* Swap the text between current buffer and BUFFER. */)
+ (buffer)
+ Lisp_Object buffer;
+{
+ struct buffer *other_buffer;
+ CHECK_BUFFER (buffer);
+ other_buffer = XBUFFER (buffer);
+
+ /* Actually, it probably works just fine.
+ * if (other_buffer == current_buffer)
+ * error ("Cannot swap a buffer's text with itself"); */
+
+ /* Actually, this may be workable as well, tho probably only if they're
+ *both* indirect. */
+ if (other_buffer->base_buffer
+ || current_buffer->base_buffer)
+ error ("Cannot swap indirect buffers's text");
+
+ { /* This is probably harder to make work. */
+ struct buffer *other;
+ for (other = all_buffers; other; other = other->next)
+ if (other->base_buffer == other_buffer
+ || other->base_buffer == current_buffer)
+ error ("One of the buffers to swap has indirect buffers");
+ }
+
+#define swapfield(field, type) \
+ do { \
+ type tmp##field = other_buffer->field; \
+ other_buffer->field = current_buffer->field; \
+ current_buffer->field = tmp##field; \
+ } while (0)
+
+ swapfield (own_text, struct buffer_text);
+ eassert (current_buffer->text == ¤t_buffer->own_text);
+ eassert (other_buffer->text == &other_buffer->own_text);
+ swapfield (pt, EMACS_INT);
+ swapfield (pt_byte, EMACS_INT);
+ swapfield (begv, EMACS_INT);
+ swapfield (begv_byte, EMACS_INT);
+ swapfield (zv, EMACS_INT);
+ swapfield (zv_byte, EMACS_INT);
+ eassert (!current_buffer->base_buffer);
+ eassert (!other_buffer->base_buffer);
+ current_buffer->clip_changed = 1; other_buffer->clip_changed = 1;
+ swapfield (newline_cache, struct region_cache *);
+ swapfield (width_run_cache, struct region_cache *);
+ current_buffer->prevent_redisplay_optimizations_p = 1;
+ other_buffer->prevent_redisplay_optimizations_p = 1;
+ swapfield (overlays_before, struct Lisp_Overlay *);
+ swapfield (overlays_after, struct Lisp_Overlay *);
+ swapfield (overlay_center, EMACS_INT);
+ swapfield (undo_list, Lisp_Object);
+ swapfield (mark, Lisp_Object);
+ if (MARKERP (current_buffer->mark) && XMARKER (current_buffer->mark)->buffer)
+ XMARKER (current_buffer->mark)->buffer = current_buffer;
+ if (MARKERP (other_buffer->mark) && XMARKER (other_buffer->mark)->buffer)
+ XMARKER (other_buffer->mark)->buffer = other_buffer;
+ swapfield (enable_multibyte_characters, Lisp_Object);
+ /* FIXME: Not sure what we should do with these *_marker fields.
+ Hopefully they're just nil anyway. */
+ swapfield (pt_marker, Lisp_Object);
+ swapfield (begv_marker, Lisp_Object);
+ swapfield (zv_marker, Lisp_Object);
+ current_buffer->point_before_scroll = Qnil;
+ other_buffer->point_before_scroll = Qnil;
+
+ current_buffer->text->modiff++; other_buffer->text->modiff++;
+ current_buffer->text->chars_modiff++; other_buffer->text->chars_modiff++;
+ current_buffer->text->overlay_modiff++; other_buffer->text->overlay_modiff++;
+ current_buffer->text->beg_unchanged = current_buffer->text->gpt;
+ current_buffer->text->end_unchanged = current_buffer->text->gpt;
+ other_buffer->text->beg_unchanged = current_buffer->text->gpt;
+ other_buffer->text->end_unchanged = current_buffer->text->gpt;
+ {
+ struct Lisp_Marker *m;
+ for (m = BUF_MARKERS (current_buffer); m; m = m->next)
+ if (m->buffer == other_buffer)
+ m->buffer = current_buffer;
+ for (m = BUF_MARKERS (other_buffer); m; m = m->next)
+ if (m->buffer == current_buffer)
+ m->buffer = other_buffer;
+ }
+ if (current_buffer->text->intervals)
+ (eassert (EQ (current_buffer->text->intervals->up.obj, buffer)),
+ XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer));
+ if (other_buffer->text->intervals)
+ (eassert (EQ (other_buffer->text->intervals->up.obj, Fcurrent_buffer ())),
+ XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer));
+
+ return Qnil;
+}
+
DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte,
1, 1, 0,
doc: /* Set the multibyte flag of the current buffer to FLAG.
If FLAG is t, this makes the buffer a multibyte buffer.
If FLAG is nil, this makes the buffer a single-byte buffer.
-The buffer contents remain unchanged as a sequence of bytes
-but the contents viewed as characters do change.
+In these cases, the buffer contents remain unchanged as a sequence of
+bytes but the contents viewed as characters do change.
+If FLAG is `to', this makes the buffer a multibyte buffer by changing
+all eight-bit bytes to eight-bit characters.
If the multibyte flag was really changed, undo information of the
current buffer is cleared. */)
(flag)
p = GAP_END_ADDR;
stop = Z;
}
- if (MULTIBYTE_STR_AS_UNIBYTE_P (p, bytes))
- p += bytes, pos += bytes;
- else
+ if (ASCII_BYTE_P (*p))
+ p++, pos++;
+ else if (CHAR_BYTE8_HEAD_P (*p))
{
- c = STRING_CHAR (p, stop - pos);
+ c = STRING_CHAR_AND_LENGTH (p, stop - pos, bytes);
/* Delete all bytes for this 8-bit character but the
last one, and change the last one to the charcter
code. */
zv -= bytes;
stop = Z;
}
+ else
+ {
+ bytes = BYTES_BY_CHAR_HEAD (*p);
+ p += bytes, pos += bytes;
+ }
}
if (narrowed)
Fnarrow_to_region (make_number (begv), make_number (zv));
{
int pt = PT;
int pos, stop;
- unsigned char *p;
+ unsigned char *p, *pend;
/* Be sure not to have a multibyte sequence striding over the GAP.
- Ex: We change this: "...abc\201 _GAP_ \241def..."
- to: "...abc _GAP_ \201\241def..." */
+ Ex: We change this: "...abc\302 _GAP_ \241def..."
+ to: "...abc _GAP_ \302\241def..." */
- if (GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
+ if (EQ (flag, Qt)
+ && GPT_BYTE > 1 && GPT_BYTE < Z_BYTE
&& ! CHAR_HEAD_P (*(GAP_END_ADDR)))
{
unsigned char *p = GPT_ADDR - 1;
pos = BEG;
stop = GPT;
p = BEG_ADDR;
+ pend = GPT_ADDR;
while (1)
{
int bytes;
if (pos == Z)
break;
p = GAP_END_ADDR;
+ pend = Z_ADDR;
stop = Z;
}
- if (UNIBYTE_STR_AS_MULTIBYTE_P (p, stop - pos, bytes))
+ if (ASCII_BYTE_P (*p))
+ p++, pos++;
+ else if (EQ (flag, Qt) && (bytes = MULTIBYTE_LENGTH (p, pend)) > 0)
p += bytes, pos += bytes;
else
{
unsigned char tmp[MAX_MULTIBYTE_LENGTH];
+ int c;
- bytes = CHAR_STRING (*p, tmp);
+ c = BYTE8_TO_CHAR (*p);
+ bytes = CHAR_STRING (c, tmp);
*p = tmp[0];
TEMP_SET_PT_BOTH (pos + 1, pos + 1);
bytes--;
zv += bytes;
if (pos <= pt)
pt += bytes;
+ pend = Z_ADDR;
stop = Z;
}
}
int extend;
Lisp_Object **vec_ptr;
int *len_ptr;
- int *next_ptr;
- int *prev_ptr;
+ EMACS_INT *next_ptr;
+ EMACS_INT *prev_ptr;
int change_req;
{
Lisp_Object overlay, start, end;
return idx;
}
\f
-/* Find all the overlays in the current buffer that overlap the range BEG-END
- or are empty at BEG.
+/* Find all the overlays in the current buffer that overlap the range
+ BEG-END, or are empty at BEG, or are empty at END provided END
+ denotes the position at the end of the current buffer.
Return the number found, and store them in a vector in *VEC_PTR.
Store in *LEN_PTR the size allocated for the vector.
int next = ZV;
int prev = BEGV;
int inhibit_storing = 0;
+ int end_is_Z = end == Z;
for (tail = current_buffer->overlays_before; tail; tail = tail->next)
{
break;
}
startpos = OVERLAY_POSITION (ostart);
- /* Count an interval if it either overlaps the range
- or is empty at the start of the range. */
+ /* Count an interval if it overlaps the range, is empty at the
+ start of the range, or is empty at END provided END denotes the
+ end of the buffer. */
if ((beg < endpos && startpos < end)
- || (startpos == endpos && beg == endpos))
+ || (startpos == endpos
+ && (beg == endpos || (end_is_Z && endpos == end))))
{
if (idx == len)
{
break;
}
endpos = OVERLAY_POSITION (oend);
- /* Count an interval if it either overlaps the range
- or is empty at the start of the range. */
+ /* Count an interval if it overlaps the range, is empty at the
+ start of the range, or is empty at END provided END denotes the
+ end of the buffer. */
if ((beg < endpos && startpos < end)
- || (startpos == endpos && beg == endpos))
+ || (startpos == endpos
+ && (beg == endpos || (end_is_Z && endpos == end))))
{
if (idx == len)
{
int endpos;
XSETMISC (overlay ,tail);
- if (!GC_OVERLAYP (overlay))
+ if (!OVERLAYP (overlay))
abort ();
endpos = OVERLAY_POSITION (OVERLAY_END (overlay));
int startpos;
XSETMISC (overlay, tail);
- if (!GC_OVERLAYP (overlay))
+ if (!OVERLAYP (overlay))
abort ();
startpos = OVERLAY_POSITION (OVERLAY_START (overlay));
/* Put all the overlays we want in a vector in overlay_vec.
Store the length in len. */
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
- (int *) 0, (int *) 0, 0);
+ (EMACS_INT *) 0, (EMACS_INT *) 0, 0);
/* Make a list of them all. */
result = Flist (noverlays, overlay_vec);
doc: /* Return a list of the overlays that overlap the region BEG ... END.
Overlap means that at least one character is contained within the overlay
and also contained within the specified region.
-Empty overlays are included in the result if they are located at BEG
-or between BEG and END. */)
+Empty overlays are included in the result if they are located at BEG,
+between BEG and END, or at END provided END denotes the position at the
+end of the buffer. */)
(beg, end)
Lisp_Object beg, end;
{
Lisp_Object pos;
{
int noverlays;
- int endpos;
+ EMACS_INT endpos;
Lisp_Object *overlay_vec;
int len;
int i;
Store the length in len.
endpos gets the position where the next overlay starts. */
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
- &endpos, (int *) 0, 1);
+ &endpos, (EMACS_INT *) 0, 1);
/* If any of these overlays ends before endpos,
use its ending point instead. */
for (i = 0; i < noverlays; i++)
{
Lisp_Object oend;
- int oendpos;
+ EMACS_INT oendpos;
oend = OVERLAY_END (overlay_vec[i]);
oendpos = OVERLAY_POSITION (oend);
Lisp_Object pos;
{
int noverlays;
- int prevpos;
+ EMACS_INT prevpos;
Lisp_Object *overlay_vec;
int len;
Store the length in len.
prevpos gets the position of the previous change. */
noverlays = overlays_at (XINT (pos), 1, &overlay_vec, &len,
- (int *) 0, &prevpos, 1);
+ (EMACS_INT *) 0, &prevpos, 1);
xfree (overlay_vec);
return make_number (prevpos);
if (last_overlay_modification_hooks_used == oldsize)
last_overlay_modification_hooks = larger_vector
(last_overlay_modification_hooks, oldsize * 2, Qnil);
- AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = functionlist;
- AREF (last_overlay_modification_hooks, last_overlay_modification_hooks_used++) = overlay;
+ ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
+ functionlist); last_overlay_modification_hooks_used++;
+ ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
+ overlay); last_overlay_modification_hooks_used++;
}
\f
/* Run the modification-hooks of overlays that include
shrink it. */
void
-enlarge_buffer_text (b, delta)
- struct buffer *b;
- int delta;
+enlarge_buffer_text (struct buffer *b, EMACS_INT delta)
{
POINTER_TYPE *p;
size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
DEFVAR_PER_BUFFER ("mode-name", ¤t_buffer->mode_name,
Qnil,
doc: /* Pretty name of current buffer's major mode.
-Usually a string. See `mode-line-format' for other possible forms. */);
+Usually a string. See `mode-line-format' for other possible forms.
+Use the function `format-mode-line' to get the value as a string. */);
DEFVAR_PER_BUFFER ("local-abbrev-table", ¤t_buffer->abbrev_table, Qnil,
doc: /* Local (mode-specific) abbrev table of current buffer. */);
defsubr (&Sbarf_if_buffer_read_only);
defsubr (&Sbury_buffer);
defsubr (&Serase_buffer);
+ defsubr (&Sbuffer_swap_text);
defsubr (&Sset_buffer_multibyte);
defsubr (&Skill_all_local_variables);