diff options
Diffstat (limited to 'src/buffer.c')
-rw-r--r-- | src/buffer.c | 308 |
1 files changed, 93 insertions, 215 deletions
diff --git a/src/buffer.c b/src/buffer.c index 89f4479740a..28cf7024acb 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -25,13 +25,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <sys/param.h> #include <errno.h> #include <stdio.h> +#include <stdlib.h> #include <unistd.h> #include <verify.h> #include "lisp.h" -#include "coding.h" #include "intervals.h" +#include "process.h" #include "systime.h" #include "window.h" #include "commands.h" @@ -48,8 +49,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "w32heap.h" /* for mmap_* */ #endif -struct buffer *current_buffer; /* The current buffer. */ - /* First buffer in chain of all buffers (in reverse order of creation). Threaded through ->header.next.buffer. */ @@ -984,40 +983,54 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too) bset_local_var_alist (b, Qnil); else { - Lisp_Object tmp, prop, last = Qnil; + Lisp_Object tmp, last = Qnil; for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp)) - if (!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)) - bset_local_var_alist (b, XCDR (tmp)); - else - XSETCDR (last, XCDR (tmp)); + { + Lisp_Object local_var = XCAR (XCAR (tmp)); + Lisp_Object prop = Fget (local_var, Qpermanent_local); + + if (!NILP (prop)) + { + /* 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); + } + newlist = Fnreverse (newlist); + if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) + notify_variable_watchers (local_var, newlist, + Qmakunbound, Fcurrent_buffer ()); + XSETCDR (XCAR (tmp), newlist); + continue; /* Don't do variable write trapping twice. */ + } + } + /* Delete this local variable. */ + else if (NILP (last)) + bset_local_var_alist (b, XCDR (tmp)); + else + XSETCDR (last, XCDR (tmp)); + + if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE) + notify_variable_watchers (local_var, Qnil, + Qmakunbound, Fcurrent_buffer ()); + } } for (i = 0; i < last_per_buffer_idx; ++i) @@ -1051,44 +1064,36 @@ it is in the sequence to be tried) even if a buffer with that name exists. If NAME begins with a space (i.e., a buffer that is not normally visible to users), then if buffer NAME already exists a random number is first appended to NAME, to speed up finding a non-existent buffer. */) - (register Lisp_Object name, Lisp_Object ignore) + (Lisp_Object name, Lisp_Object ignore) { - register Lisp_Object gentemp, tem, tem2; - ptrdiff_t count; - char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"]; + Lisp_Object genbase; CHECK_STRING (name); - tem = Fstring_equal (name, ignore); - if (!NILP (tem)) - return name; - tem = Fget_buffer (name); - if (NILP (tem)) + if (!NILP (Fstring_equal (name, ignore)) || NILP (Fget_buffer (name))) return name; - if (!strncmp (SSDATA (name), " ", 1)) /* see bug#1229 */ + if (SREF (name, 0) != ' ') /* See bug#1229. */ + genbase = name; + else { /* Note fileio.c:make_temp_name does random differently. */ - tem2 = concat2 (name, make_formatted_string - (number, "-%"pI"d", - XFASTINT (Frandom (make_number (999999))))); - tem = Fget_buffer (tem2); - if (NILP (tem)) - return tem2; + char number[sizeof "-999999"]; + int i = XFASTINT (Frandom (make_number (999999))); + AUTO_STRING_WITH_LEN (lnumber, number, sprintf (number, "-%d", i)); + genbase = concat2 (name, lnumber); + if (NILP (Fget_buffer (genbase))) + return genbase; } - else - tem2 = name; - count = 1; - while (1) + for (ptrdiff_t count = 2; ; count++) { - gentemp = concat2 (tem2, make_formatted_string - (number, "<%"pD"d>", ++count)); - tem = Fstring_equal (gentemp, ignore); - if (!NILP (tem)) - return gentemp; - tem = Fget_buffer (gentemp); - if (NILP (tem)) + char number[INT_BUFSIZE_BOUND (ptrdiff_t) + sizeof "<>"]; + AUTO_STRING_WITH_LEN (lnumber, number, + sprintf (number, "<%"pD"d>", count)); + Lisp_Object gentemp = concat2 (genbase, lnumber); + if (!NILP (Fstring_equal (gentemp, ignore)) + || NILP (Fget_buffer (gentemp))) return gentemp; } } @@ -1648,6 +1653,9 @@ cleaning up all windows currently displaying the buffer to be killed. */) if (!BUFFER_LIVE_P (b)) return Qnil; + if (thread_check_current_buffer (b)) + return Qnil; + /* Run hooks with the buffer to be killed the current buffer. */ { ptrdiff_t count = SPECPDL_INDEX (); @@ -1993,7 +2001,9 @@ the current buffer's major mode. */) function = BVAR (current_buffer, major_mode); } - if (NILP (function) || EQ (function, Qfundamental_mode)) + if (NILP (function)) /* If function is `fundamental-mode', allow it to run + so that `run-mode-hooks' and thus + `hack-local-variables' get run. */ return Qnil; count = SPECPDL_INDEX (); @@ -2001,7 +2011,7 @@ the current buffer's major mode. */) /* To select a nonfundamental mode, select the buffer temporarily and then call the mode function. */ - record_unwind_protect (save_excursion_restore, save_excursion_save ()); + record_unwind_current_buffer (); Fset_buffer (buffer); call0 (function); @@ -2024,9 +2034,6 @@ DEFUN ("current-buffer", Fcurrent_buffer, Scurrent_buffer, 0, 0, 0, void set_buffer_internal_1 (register struct buffer *b) { - register struct buffer *old_buf; - register Lisp_Object tail; - #ifdef USE_MMAP_FOR_BUFFERS if (b->text->beg == NULL) enlarge_buffer_text (b, 0); @@ -2035,6 +2042,17 @@ set_buffer_internal_1 (register struct buffer *b) if (current_buffer == b) return; + set_buffer_internal_2 (b); +} + +/* Like set_buffer_internal_1, but doesn't check whether B is already + the current buffer. Called upon switch of the current thread, see + post_acquire_global_lock. */ +void set_buffer_internal_2 (register struct buffer *b) +{ + register struct buffer *old_buf; + register Lisp_Object tail; + BUFFER_CHECK_INDIRECTION (b); old_buf = current_buffer; @@ -3562,8 +3580,8 @@ void fix_start_end_in_overlays (register ptrdiff_t start, register ptrdiff_t end) { Lisp_Object overlay; - struct Lisp_Overlay *before_list IF_LINT (= NULL); - struct Lisp_Overlay *after_list IF_LINT (= NULL); + struct Lisp_Overlay *before_list; + struct Lisp_Overlay *after_list; /* These are either nil, indicating that before_list or after_list should be assigned, or the cons cell the cdr of which should be assigned. */ @@ -3710,7 +3728,7 @@ fix_overlays_before (struct buffer *bp, ptrdiff_t prev, ptrdiff_t pos) /* If parent is nil, replace overlays_before; otherwise, parent->next. */ struct Lisp_Overlay *tail = bp->overlays_before, *parent = NULL, *right_pair; Lisp_Object tem; - ptrdiff_t end IF_LINT (= 0); + ptrdiff_t end; /* After the insertion, the several overlays may be in incorrect order. The possibility is that, in the list `overlays_before', @@ -3917,7 +3935,8 @@ buffer. */) struct buffer *b, *ob = 0; Lisp_Object obuffer; ptrdiff_t count = SPECPDL_INDEX (); - ptrdiff_t n_beg, n_end, o_beg IF_LINT (= 0), o_end IF_LINT (= 0); + ptrdiff_t n_beg, n_end; + ptrdiff_t o_beg UNINIT, o_end UNINIT; CHECK_OVERLAY (overlay); if (NILP (buffer)) @@ -5279,7 +5298,7 @@ init_buffer (int initialized) if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) Fset_buffer_multibyte (Qnil); - pwd = get_current_dir_name (); + pwd = emacs_get_current_dir_name (); if (!pwd) { @@ -5418,144 +5437,6 @@ syms_of_buffer (void) Fput (Qprotected_field, Qerror_message, build_pure_c_string ("Attempt to modify a protected field")); - DEFVAR_BUFFER_DEFAULTS ("default-mode-line-format", - mode_line_format, - doc: /* Default value of `mode-line-format' for buffers that don't override it. -This is the same as (default-value \\='mode-line-format). */); - - DEFVAR_BUFFER_DEFAULTS ("default-header-line-format", - header_line_format, - doc: /* Default value of `header-line-format' for buffers that don't override it. -This is the same as (default-value \\='header-line-format). */); - - DEFVAR_BUFFER_DEFAULTS ("default-cursor-type", cursor_type, - doc: /* Default value of `cursor-type' for buffers that don't override it. -This is the same as (default-value \\='cursor-type). */); - - DEFVAR_BUFFER_DEFAULTS ("default-line-spacing", - extra_line_spacing, - doc: /* Default value of `line-spacing' for buffers that don't override it. -This is the same as (default-value \\='line-spacing). */); - - DEFVAR_BUFFER_DEFAULTS ("default-cursor-in-non-selected-windows", - cursor_in_non_selected_windows, - doc: /* Default value of `cursor-in-non-selected-windows'. -This is the same as (default-value \\='cursor-in-non-selected-windows). */); - - DEFVAR_BUFFER_DEFAULTS ("default-abbrev-mode", - abbrev_mode, - doc: /* Default value of `abbrev-mode' for buffers that do not override it. -This is the same as (default-value \\='abbrev-mode). */); - - DEFVAR_BUFFER_DEFAULTS ("default-ctl-arrow", - ctl_arrow, - doc: /* Default value of `ctl-arrow' for buffers that do not override it. -This is the same as (default-value \\='ctl-arrow). */); - - DEFVAR_BUFFER_DEFAULTS ("default-enable-multibyte-characters", - enable_multibyte_characters, - doc: /* Default value of `enable-multibyte-characters' for buffers not overriding it. -This is the same as (default-value \\='enable-multibyte-characters). */); - - DEFVAR_BUFFER_DEFAULTS ("default-buffer-file-coding-system", - buffer_file_coding_system, - doc: /* Default value of `buffer-file-coding-system' for buffers not overriding it. -This is the same as (default-value \\='buffer-file-coding-system). */); - - DEFVAR_BUFFER_DEFAULTS ("default-truncate-lines", - truncate_lines, - doc: /* Default value of `truncate-lines' for buffers that do not override it. -This is the same as (default-value \\='truncate-lines). */); - - DEFVAR_BUFFER_DEFAULTS ("default-fill-column", - fill_column, - doc: /* Default value of `fill-column' for buffers that do not override it. -This is the same as (default-value \\='fill-column). */); - - DEFVAR_BUFFER_DEFAULTS ("default-left-margin", - left_margin, - doc: /* Default value of `left-margin' for buffers that do not override it. -This is the same as (default-value \\='left-margin). */); - - DEFVAR_BUFFER_DEFAULTS ("default-tab-width", - tab_width, - doc: /* Default value of `tab-width' for buffers that do not override it. -NOTE: This controls the display width of a TAB character, and not -the size of an indentation step. -This is the same as (default-value \\='tab-width). */); - - DEFVAR_BUFFER_DEFAULTS ("default-case-fold-search", - case_fold_search, - doc: /* Default value of `case-fold-search' for buffers that don't override it. -This is the same as (default-value \\='case-fold-search). */); - - DEFVAR_BUFFER_DEFAULTS ("default-left-margin-width", - left_margin_cols, - doc: /* Default value of `left-margin-width' for buffers that don't override it. -This is the same as (default-value \\='left-margin-width). */); - - DEFVAR_BUFFER_DEFAULTS ("default-right-margin-width", - right_margin_cols, - doc: /* Default value of `right-margin-width' for buffers that don't override it. -This is the same as (default-value \\='right-margin-width). */); - - DEFVAR_BUFFER_DEFAULTS ("default-left-fringe-width", - left_fringe_width, - doc: /* Default value of `left-fringe-width' for buffers that don't override it. -This is the same as (default-value \\='left-fringe-width). */); - - DEFVAR_BUFFER_DEFAULTS ("default-right-fringe-width", - right_fringe_width, - doc: /* Default value of `right-fringe-width' for buffers that don't override it. -This is the same as (default-value \\='right-fringe-width). */); - - DEFVAR_BUFFER_DEFAULTS ("default-fringes-outside-margins", - fringes_outside_margins, - doc: /* Default value of `fringes-outside-margins' for buffers that don't override it. -This is the same as (default-value \\='fringes-outside-margins). */); - - DEFVAR_BUFFER_DEFAULTS ("default-scroll-bar-width", - scroll_bar_width, - doc: /* Default value of `scroll-bar-width' for buffers that don't override it. -This is the same as (default-value \\='scroll-bar-width). */); - - DEFVAR_BUFFER_DEFAULTS ("default-vertical-scroll-bar", - vertical_scroll_bar_type, - doc: /* Default value of `vertical-scroll-bar' for buffers that don't override it. -This is the same as (default-value \\='vertical-scroll-bar). */); - - DEFVAR_BUFFER_DEFAULTS ("default-indicate-empty-lines", - indicate_empty_lines, - doc: /* Default value of `indicate-empty-lines' for buffers that don't override it. -This is the same as (default-value \\='indicate-empty-lines). */); - - DEFVAR_BUFFER_DEFAULTS ("default-indicate-buffer-boundaries", - indicate_buffer_boundaries, - doc: /* Default value of `indicate-buffer-boundaries' for buffers that don't override it. -This is the same as (default-value \\='indicate-buffer-boundaries). */); - - DEFVAR_BUFFER_DEFAULTS ("default-fringe-indicator-alist", - fringe_indicator_alist, - doc: /* Default value of `fringe-indicator-alist' for buffers that don't override it. -This is the same as (default-value \\='fringe-indicator-alist). */); - - DEFVAR_BUFFER_DEFAULTS ("default-fringe-cursor-alist", - fringe_cursor_alist, - doc: /* Default value of `fringe-cursor-alist' for buffers that don't override it. -This is the same as (default-value \\='fringe-cursor-alist). */); - - DEFVAR_BUFFER_DEFAULTS ("default-scroll-up-aggressively", - scroll_up_aggressively, - doc: /* Default value of `scroll-up-aggressively'. -This value applies in buffers that don't have their own local values. -This is the same as (default-value \\='scroll-up-aggressively). */); - - DEFVAR_BUFFER_DEFAULTS ("default-scroll-down-aggressively", - scroll_down_aggressively, - doc: /* Default value of `scroll-down-aggressively'. -This value applies in buffers that don't have their own local values. -This is the same as (default-value \\='scroll-down-aggressively). */); - DEFVAR_PER_BUFFER ("header-line-format", &BVAR (current_buffer, header_line_format), Qnil, @@ -5626,9 +5507,6 @@ A string is printed verbatim in the mode line except for %-constructs: %% -- print %. %- -- print infinitely many dashes. Decimal digits after the % specify field width to which to pad. */); - DEFVAR_BUFFER_DEFAULTS ("default-major-mode", major_mode, - doc: /* Value of `major-mode' for new buffers. */); - DEFVAR_PER_BUFFER ("major-mode", &BVAR (current_buffer, major_mode), Qsymbolp, doc: /* Symbol for current buffer's major mode. @@ -5687,7 +5565,7 @@ file I/O and the behavior of various editing commands. This variable is buffer-local but you cannot set it directly; use the function `set-buffer-multibyte' to change a buffer's representation. See also Info node `(elisp)Text Representations'. */); - XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1; + make_symbol_constant (intern_c_string ("enable-multibyte-characters")); DEFVAR_PER_BUFFER ("buffer-file-coding-system", &BVAR (current_buffer, buffer_file_coding_system), Qnil, |