X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/b2529d56b5126319a1659dc1530d6fc102cc21d6..5371d722ecd94db9d5b3b21f4b91d073a38bd73b:/src/buffer.c?ds=sidebyside diff --git a/src/buffer.c b/src/buffer.c index 740f9fe53d..021867c0ef 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -1,7 +1,8 @@ /* Buffer manipulation primitives for GNU Emacs. Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -42,7 +43,7 @@ extern int errno; #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" @@ -99,17 +100,6 @@ DECL_ALIGN (struct buffer, buffer_local_symbols); /* A Lisp_Object pointer to the above, used for staticpro */ static Lisp_Object Vbuffer_local_symbols; -/* This structure holds the required types for the values in the - buffer-local slots. If a slot contains Qnil, then the - corresponding buffer slot may contain a value of any type. If a - slot contains an integer, then prospective values' tags must be - equal to that integer (except nil is always allowed). - When a tag does not match, the function - buffer_slot_type_mismatch will signal an error. - - If a slot here contains -1, the corresponding variable is read-only. */ -struct buffer buffer_local_types; - /* Flags indicating which built-in buffer-local variables are permanent locals. */ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; @@ -118,12 +108,14 @@ static char buffer_permanent_local_flags[MAX_PER_BUFFER_VARS]; int last_per_buffer_idx; -Lisp_Object Fset_buffer (); -void set_buffer_internal (); -void set_buffer_internal_1 (); -static void call_overlay_mod_hooks (); -static void swap_out_buffer_local_variables (); -static void reset_buffer_local_variables (); +EXFUN (Fset_buffer, 1); +void set_buffer_internal P_ ((struct buffer *b)); +void set_buffer_internal_1 P_ ((struct buffer *b)); +static void call_overlay_mod_hooks P_ ((Lisp_Object list, Lisp_Object overlay, + int after, Lisp_Object arg1, + Lisp_Object arg2, Lisp_Object arg3)); +static void swap_out_buffer_local_variables P_ ((struct buffer *b)); +static void reset_buffer_local_variables P_ ((struct buffer *b, int permanent_too)); /* Alist of all buffer names vs the buffers. */ /* This used to be a variable, but is no longer, @@ -161,6 +153,7 @@ Lisp_Object Qucs_set_table_for_input; int inhibit_modification_hooks; Lisp_Object Qfundamental_mode, Qmode_class, Qpermanent_local; +Lisp_Object Qpermanent_local_hook; Lisp_Object Qprotected_field; @@ -184,6 +177,7 @@ static struct Lisp_Overlay * copy_overlays P_ ((struct buffer *, struct Lisp_Ove 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; */ @@ -359,9 +353,7 @@ The value is never nil. */) if (SCHARS (name) == 0) error ("Empty string for buffer name is not allowed"); - b = (struct buffer *) allocate_buffer (); - - b->size = sizeof (struct buffer) / sizeof (EMACS_INT); + b = allocate_buffer (); /* An ordinary buffer uses its own struct buffer_text. */ b->text = &b->own_text; @@ -416,10 +408,7 @@ The value is never nil. */) STRING_SET_INTERVALS (name, NULL_INTERVAL); b->name = name; - if (SREF (name, 0) != ' ') - b->undo_list = Qnil; - else - b->undo_list = Qt; + b->undo_list = (SREF (name, 0) != ' ') ? Qnil : Qt; reset_buffer (b); reset_buffer_local_variables (b, 1); @@ -429,7 +418,6 @@ The value is never nil. */) b->name = name; /* Put this in the alist of all live buffers. */ - XSETPVECTYPE (b, PVEC_BUFFER); XSETBUFFER (buf, b); Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil)); @@ -508,7 +496,9 @@ clone_per_buffer_values (from, to) 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)) { @@ -566,14 +556,11 @@ CLONE nil means the indirect buffer's state is reset to default values. */) if (SCHARS (name) == 0) error ("Empty string for buffer name is not allowed"); - b = (struct buffer *) allocate_buffer (); - b->size = sizeof (struct buffer) / sizeof (EMACS_INT); - XSETPVECTYPE (b, PVEC_BUFFER); + b = allocate_buffer (); - if (XBUFFER (base_buffer)->base_buffer) - b->base_buffer = XBUFFER (base_buffer)->base_buffer; - else - b->base_buffer = XBUFFER (base_buffer); + b->base_buffer = (XBUFFER (base_buffer)->base_buffer + ? XBUFFER (base_buffer)->base_buffer + : XBUFFER (base_buffer)); /* Use the base buffer's text object. */ b->text = b->base_buffer->text; @@ -736,7 +723,7 @@ reset_buffer (b) it does not treat permanent locals consistently. Instead, use Fkill_all_local_variables. - If PERMANENT_TOO is 1, then we reset permanent built-in + If PERMANENT_TOO is 1, then we reset permanent buffer-local variables. If PERMANENT_TOO is 0, we preserve those. */ @@ -774,7 +761,48 @@ reset_buffer_local_variables (b, permanent_too) #endif /* Reset all (or most) per-buffer variables to their defaults. */ - b->local_var_alist = Qnil; + if (permanent_too) + b->local_var_alist = Qnil; + else + { + Lisp_Object tmp, prop, last = Qnil; + for (tmp = b->local_var_alist; CONSP (tmp); tmp = XCDR (tmp)) + if (CONSP (XCAR (tmp)) + && SYMBOLP (XCAR (XCAR (tmp))) + && !NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) + { + /* If permanent-local, keep it. */ + last = tmp; + if (EQ (prop, Qpermanent_local_hook)) + { + /* This is a partially permanent hook variable. + Preserve only the elements that want to be preserved. */ + Lisp_Object list, newlist; + list = XCDR (XCAR (tmp)); + if (!CONSP (list)) + newlist = list; + else + for (newlist = Qnil; CONSP (list); list = XCDR (list)) + { + Lisp_Object elt = XCAR (list); + /* Preserve element ELT if it's t, + if it is a function with a `permanent-local-hook' property, + or if it's not a symbol. */ + if (! SYMBOLP (elt) + || EQ (elt, Qt) + || !NILP (Fget (elt, Qpermanent_local_hook))) + newlist = Fcons (elt, newlist); + } + XSETCDR (XCAR (tmp), Fnreverse (newlist)); + } + } + /* Delete this local variable. */ + else if (NILP (last)) + b->local_var_alist = XCDR (tmp); + else + XSETCDR (last, XCDR (tmp)); + } + for (i = 0; i < last_per_buffer_idx; ++i) if (permanent_too || buffer_permanent_local_flags[i] == 0) SET_PER_BUFFER_VALUE_P (b, i, 0); @@ -782,7 +810,9 @@ reset_buffer_local_variables (b, permanent_too) /* 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)) { @@ -904,8 +934,7 @@ is the default binding of the variable. */) CHECK_BUFFER (buffer); buf = XBUFFER (buffer); - if (SYMBOLP (variable)) - variable = indirect_variable (variable); + variable = indirect_variable (variable); /* Look in local_var_list */ result = Fassoc (variable, buf->local_var_alist); @@ -915,7 +944,9 @@ is the default binding of the variable. */) 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))) @@ -1026,7 +1057,9 @@ No argument or nil as argument means use current buffer as BUFFER. */) { 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))) @@ -1190,7 +1223,9 @@ buffer as BUFFER. */) } DEFUN ("rename-buffer", Frename_buffer, Srename_buffer, 1, 2, - "sRename buffer (to new name): \nP", + "(list (read-string \"Rename buffer (to new name): \" \ + nil 'buffer-name-history (buffer-name (current-buffer))) \ + current-prefix-arg)", doc: /* Change current buffer's name to NEWNAME (a string). If second arg UNIQUE is nil or omitted, it is an error if a buffer named NEWNAME already exists. @@ -1599,7 +1634,7 @@ record_buffer (buf) 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)) @@ -1767,7 +1802,10 @@ the window-buffer correspondences. */) } 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); } @@ -1918,8 +1956,7 @@ set_buffer_internal_1 (b) for (tail = b->local_var_alist; CONSP (tail); tail = XCDR (tail)) { valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))); - if ((BUFFER_LOCAL_VALUEP (valcontents) - || SOME_BUFFER_LOCAL_VALUEP (valcontents)) + if ((BUFFER_LOCAL_VALUEP (valcontents)) && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) /* Just reference the variable @@ -1933,8 +1970,7 @@ set_buffer_internal_1 (b) for (tail = old_buf->local_var_alist; CONSP (tail); tail = XCDR (tail)) { valcontents = SYMBOL_VALUE (XCAR (XCAR (tail))); - if ((BUFFER_LOCAL_VALUEP (valcontents) - || SOME_BUFFER_LOCAL_VALUEP (valcontents)) + if ((BUFFER_LOCAL_VALUEP (valcontents)) && (tem = XBUFFER_LOCAL_VALUE (valcontents)->realvalue, (BOOLFWDP (tem) || INTFWDP (tem) || OBJFWDP (tem)))) /* Just reference the variable @@ -2179,13 +2215,110 @@ advance_to_char_boundary (byte_pos) 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) @@ -2259,11 +2392,11 @@ current buffer is cleared. */) 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. */ @@ -2278,6 +2411,11 @@ current buffer is cleared. */) 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)); @@ -2286,13 +2424,14 @@ current buffer is cleared. */) { 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; @@ -2311,6 +2450,7 @@ current buffer is cleared. */) pos = BEG; stop = GPT; p = BEG_ADDR; + pend = GPT_ADDR; while (1) { int bytes; @@ -2320,16 +2460,21 @@ current buffer is cleared. */) 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--; @@ -2343,6 +2488,7 @@ current buffer is cleared. */) zv += bytes; if (pos <= pt) pt += bytes; + pend = Z_ADDR; stop = Z; } } @@ -2474,14 +2620,10 @@ The first thing this function does is run the normal hook `change-major-mode-hook'. */) () { - register Lisp_Object alist, sym, tem; - Lisp_Object oalist; - if (!NILP (Vrun_hooks)) call1 (Vrun_hooks, Qchange_major_mode_hook); - oalist = current_buffer->local_var_alist; - /* Make sure none of the bindings in oalist + /* Make sure none of the bindings in local_var_alist remain swapped in, in their symbols. */ swap_out_buffer_local_variables (current_buffer); @@ -2490,20 +2632,6 @@ the normal hook `change-major-mode-hook'. */) reset_buffer_local_variables (current_buffer, 0); - /* Any which are supposed to be permanent, - make local again, with the same values they had. */ - - for (alist = oalist; !NILP (alist); alist = XCDR (alist)) - { - sym = XCAR (XCAR (alist)); - tem = Fget (sym, Qpermanent_local); - if (! NILP (tem)) - { - Fmake_local_variable (sym); - Fset (sym, XCDR (XCAR (alist))); - } - } - /* Force mode-line redisplay. Useful here because all major mode commands call this function. */ update_mode_lines++; @@ -2523,32 +2651,17 @@ swap_out_buffer_local_variables (b) XSETBUFFER (buffer, b); oalist = b->local_var_alist; - for (alist = oalist; !NILP (alist); alist = XCDR (alist)) + for (alist = oalist; CONSP (alist); alist = XCDR (alist)) { sym = XCAR (XCAR (alist)); /* Need not do anything if some other buffer's binding is now encached. */ tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer; - if (BUFFERP (tem) && XBUFFER (tem) == current_buffer) + if (EQ (tem, buffer)) { - /* Symbol is set up for this buffer's old local value. - Set it up for the current buffer with the default value. */ - - tem = XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->cdr; - /* Store the symbol's current value into the alist entry - it is currently set up for. This is so that, if the - local is marked permanent, and we make it local again - later in Fkill_all_local_variables, we don't lose the value. */ - XSETCDR (XCAR (tem), - do_symval_forwarding (XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue)); - /* Switch to the symbol's default-value alist entry. */ - XSETCAR (tem, tem); - /* Mark it as current for buffer B. */ - XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->buffer = buffer; - /* Store the current value into any forwarding in the symbol. */ - store_symval_forwarding (sym, - XBUFFER_LOCAL_VALUE (SYMBOL_VALUE (sym))->realvalue, - XCDR (tem), NULL); + /* Symbol is set up for this buffer's old local value: + swap it out! */ + swap_in_global_binding (sym); } } } @@ -2581,8 +2694,8 @@ overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req) 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; @@ -2700,8 +2813,9 @@ overlays_at (pos, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, change_req) return idx; } -/* 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. @@ -2736,6 +2850,7 @@ overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr) 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) { @@ -2753,10 +2868,12 @@ overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr) 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) { @@ -2801,10 +2918,12 @@ overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr) 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) { @@ -2883,7 +3002,7 @@ overlay_touches_p (pos) int endpos; XSETMISC (overlay ,tail); - if (!GC_OVERLAYP (overlay)) + if (!OVERLAYP (overlay)) abort (); endpos = OVERLAY_POSITION (OVERLAY_END (overlay)); @@ -2898,7 +3017,7 @@ overlay_touches_p (pos) int startpos; XSETMISC (overlay, tail); - if (!GC_OVERLAYP (overlay)) + if (!OVERLAYP (overlay)) abort (); startpos = OVERLAY_POSITION (OVERLAY_START (overlay)); @@ -3987,7 +4106,7 @@ DEFUN ("overlays-at", Foverlays_at, Soverlays_at, 1, 1, 0, /* 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); @@ -4000,8 +4119,9 @@ DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0, 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; { @@ -4037,7 +4157,7 @@ the value is (point-max). */) Lisp_Object pos; { int noverlays; - int endpos; + EMACS_INT endpos; Lisp_Object *overlay_vec; int len; int i; @@ -4051,14 +4171,14 @@ the value is (point-max). */) 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); @@ -4079,7 +4199,7 @@ the value is (point-min). */) Lisp_Object pos; { int noverlays; - int prevpos; + EMACS_INT prevpos; Lisp_Object *overlay_vec; int len; @@ -4097,7 +4217,7 @@ the value is (point-min). */) 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); @@ -4220,8 +4340,10 @@ add_overlay_mod_hooklist (functionlist, overlay) 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++; } /* Run the modification-hooks of overlays that include @@ -4429,13 +4551,13 @@ evaporate_overlays (pos) in the slot with offset OFFSET. */ void -buffer_slot_type_mismatch (offset) - int offset; +buffer_slot_type_mismatch (sym, type) + Lisp_Object sym; + int type; { - Lisp_Object sym; char *type_name; - switch (XINT (PER_BUFFER_TYPE (offset))) + switch (type) { case Lisp_Int: type_name = "integers"; @@ -4453,7 +4575,6 @@ buffer_slot_type_mismatch (offset) abort (); } - sym = PER_BUFFER_SYMBOL (offset); error ("Only %s should be stored in the buffer-local variable %s", type_name, SDATA (SYMBOL_NAME (sym))); } @@ -4960,9 +5081,7 @@ alloc_buffer_text (b, nbytes) 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 @@ -5301,9 +5420,9 @@ defvar_per_buffer (namestring, address, type, doc) XMISCTYPE (val) = Lisp_Misc_Buffer_Objfwd; XBUFFER_OBJFWD (val)->offset = offset; + XBUFFER_OBJFWD (val)->slottype = type; SET_SYMBOL_VALUE (sym, val); PER_BUFFER_SYMBOL (offset) = sym; - PER_BUFFER_TYPE (offset) = type; if (PER_BUFFER_IDX (offset) == 0) /* Did a DEFVAR_PER_BUFFER without initializing the corresponding @@ -5328,6 +5447,8 @@ syms_of_buffer () staticpro (&Vbuffer_alist); staticpro (&Qprotected_field); staticpro (&Qpermanent_local); + Qpermanent_local_hook = intern ("permanent-local-hook"); + staticpro (&Qpermanent_local_hook); staticpro (&Qkill_buffer_hook); Qoverlayp = intern ("overlayp"); staticpro (&Qoverlayp); @@ -5355,6 +5476,7 @@ syms_of_buffer () staticpro (&Qbefore_change_functions); Qafter_change_functions = intern ("after-change-functions"); staticpro (&Qafter_change_functions); + /* The next one is initialized in init_buffer_once. */ staticpro (&Qucs_set_table_for_input); Qkill_buffer_query_functions = intern ("kill-buffer-query-functions"); @@ -5595,7 +5717,9 @@ its hooks should not expect certain variables such as DEFVAR_PER_BUFFER ("mode-name", ¤t_buffer->mode_name, Qnil, - doc: /* Pretty name of current buffer's major mode (a string). */); + doc: /* Pretty name of current buffer's major mode. +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. */); @@ -6168,6 +6292,7 @@ The function `kill-all-local-variables' runs this before doing anything else. * 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);