+2014-07-16 Dmitry Antipov <dmantipov@yandex.ru>
+
+ More precise control over values of some buffer-local variables.
+ * keyboard.c (Qvertical_scroll_bar):
+ * frame.c (Qleft, Qright): Move to ...
+ * buffer.c (Qleft, Qright, Qvertical_scroll_bar): ... here.
+ * buffer.c (Qchoice, Qrange, Qoverwrite_mode, Qfraction): New symbols.
+ (syms_of_buffer): DEFSYM all of the above, attach special properties.
+ Use special symbols to DEFVAR_PER_BUFFER overwrite-mode,
+ vertical-scroll-bar, scroll-up-aggressively
+ and scroll-down-aggressively.
+ * buffer.h (Qchoice, Qrange, Qleft, Qright, Qvertical_scroll_bar):
+ Add declarations.
+ * nsfns.m, frame.h (Qleft, Qright):
+ * nsterm.m (Qleft): Remove declarations.
+ * gtkutil.c (toplevel): Include buffer.h.
+ * data.c (wrong_choice, wrong_range): New functions.
+ (store_symval_forwarding): Handle special properties of buffer-local
+ variables and use functions from the above to signal error, if any.
+
2014-07-15 Daiki Ueno <ueno@gnu.org>
* nsgui.h (XCHAR2B_BYTE1): Add missing parentheses around
Lisp_Object Qinsert_in_front_hooks;
Lisp_Object Qinsert_behind_hooks;
+Lisp_Object Qchoice, Qrange, Qleft, Qright, Qvertical_scroll_bar;
+static Lisp_Object Qoverwrite_mode, Qfraction;
+
static void alloc_buffer_text (struct buffer *, ptrdiff_t);
static void free_buffer_text (struct buffer *b);
static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
staticpro (&Qpermanent_local);
staticpro (&Qkill_buffer_hook);
+ DEFSYM (Qleft, "left");
+ DEFSYM (Qright, "right");
+ DEFSYM (Qrange, "range");
+
DEFSYM (Qpermanent_local_hook, "permanent-local-hook");
DEFSYM (Qoverlayp, "overlayp");
DEFSYM (Qevaporate, "evaporate");
DEFSYM (Qafter_change_functions, "after-change-functions");
DEFSYM (Qkill_buffer_query_functions, "kill-buffer-query-functions");
+ DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
+ Fput (Qvertical_scroll_bar, Qchoice, list4 (Qnil, Qt, Qleft, Qright));
+
+ DEFSYM (Qfraction, "fraction");
+ Fput (Qfraction, Qrange, Fcons (make_float (0.0), make_float (1.0)));
+
+ DEFSYM (Qoverwrite_mode, "overwrite-mode");
+ Fput (Qoverwrite_mode, Qchoice,
+ list3 (Qnil, intern ("overwrite-mode-textual"),
+ intern ("overwrite-mode-binary")));
+
Fput (Qprotected_field, Qerror_conditions,
listn (CONSTYPE_PURE, 2, Qprotected_field, Qerror));
Fput (Qprotected_field, Qerror_message,
Qnil,
doc: /* Non-nil means display ... on previous line when a line is invisible. */);
- DEFVAR_PER_BUFFER ("overwrite-mode", &BVAR (current_buffer, overwrite_mode), Qnil,
+ DEFVAR_PER_BUFFER ("overwrite-mode", &BVAR (current_buffer, overwrite_mode),
+ Qoverwrite_mode,
doc: /* Non-nil if self-insertion should replace existing text.
The value should be one of `overwrite-mode-textual',
`overwrite-mode-binary', or nil.
A value of nil means to use the scroll bar width from the window's frame. */);
DEFVAR_PER_BUFFER ("vertical-scroll-bar", &BVAR (current_buffer, vertical_scroll_bar_type),
- Qnil,
+ Qvertical_scroll_bar,
doc: /* Position of this buffer's vertical scroll bar.
The value takes effect whenever you tell a window to display this buffer;
for instance, with `set-window-buffer' or when `display-buffer' displays it.
cursor type. */);
DEFVAR_PER_BUFFER ("scroll-up-aggressively",
- &BVAR (current_buffer, scroll_up_aggressively), Qfloatp,
+ &BVAR (current_buffer, scroll_up_aggressively), Qfraction,
doc: /* How far to scroll windows upward.
If you move point off the bottom, the window scrolls automatically.
This variable controls how far it scrolls. The value nil, the default,
between 0.0 and 1.0, inclusive. */);
DEFVAR_PER_BUFFER ("scroll-down-aggressively",
- &BVAR (current_buffer, scroll_down_aggressively), Qfloatp,
+ &BVAR (current_buffer, scroll_down_aggressively), Qfraction,
doc: /* How far to scroll windows downward.
If you move point off the top, the window scrolls automatically.
This variable controls how far it scrolls. The value nil, the default,
extern Lisp_Object Qafter_change_functions;
extern Lisp_Object Qfirst_change_hook;
extern Lisp_Object Qpriority, Qbefore_string, Qafter_string;
+extern Lisp_Object Qchoice, Qrange, Qleft, Qright, Qvertical_scroll_bar;
/* FOR_EACH_LIVE_BUFFER (LIST_VAR, BUF_VAR) followed by a statement is
a `for' loop which iterates over the buffers from Vbuffer_alist. */
}
}
+/* Used to signal a user-friendly error when symbol WRONG is
+ not a member of CHOICE, which should be a list of symbols. */
+
+static void
+wrong_choice (Lisp_Object choice, Lisp_Object wrong)
+{
+ ptrdiff_t i = 0, len = XINT (Flength (choice));
+ Lisp_Object obj, *args;
+
+ USE_SAFE_ALLOCA;
+ SAFE_ALLOCA_LISP (args, len * 2 + 1);
+
+ args[i++] = build_string ("One of ");
+
+ for (obj = choice; !NILP (obj); obj = XCDR (obj))
+ {
+ args[i++] = SYMBOL_NAME (XCAR (obj));
+ args[i++] = build_string (NILP (XCDR (obj)) ? " should be specified"
+ : (NILP (XCDR (XCDR (obj))) ? " or " : ", "));
+ }
+
+ obj = Fconcat (i, args);
+ SAFE_FREE ();
+ xsignal2 (Qerror, obj, wrong);
+}
+
+/* Used to signal a user-friendly error if WRONG is not a number or
+ integer/floating-point number outsize of inclusive MIN..MAX range. */
+
+static void
+wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong)
+{
+ Lisp_Object args[4];
+
+ args[0] = build_string ("Value should be from ");
+ args[1] = Fnumber_to_string (min);
+ args[2] = build_string (" to ");
+ args[3] = Fnumber_to_string (max);
+
+ xsignal2 (Qerror, Fconcat (4, args), wrong);
+}
+
/* Store NEWVAL into SYMBOL, where VALCONTENTS is found in the value cell
of SYMBOL. If SYMBOL is buffer-local, VALCONTENTS should be the
buffer-independent contents of the value cell: forwarded just one
int offset = XBUFFER_OBJFWD (valcontents)->offset;
Lisp_Object predicate = XBUFFER_OBJFWD (valcontents)->predicate;
- if (!NILP (predicate) && !NILP (newval)
- && NILP (call1 (predicate, newval)))
- wrong_type_argument (predicate, newval);
+ if (!NILP (newval))
+ {
+ if (SYMBOLP (predicate))
+ {
+ Lisp_Object prop;
+
+ if ((prop = Fget (predicate, Qchoice), !NILP (prop)))
+ {
+ if (NILP (Fmemq (newval, prop)))
+ wrong_choice (prop, newval);
+ }
+ else if ((prop = Fget (predicate, Qrange), !NILP (prop)))
+ {
+ Lisp_Object min = XCAR (prop), max = XCDR (prop);
+ if (!NUMBERP (newval)
+ || !NILP (arithcompare (newval, min, ARITH_LESS))
+ || !NILP (arithcompare (newval, max, ARITH_GRTR)))
+ wrong_range (min, max, newval);
+ }
+ else if (FUNCTIONP (predicate))
+ {
+ if (NILP (call1 (predicate, newval)))
+ wrong_type_argument (predicate, newval);
+ }
+ }
+ }
if (buf == NULL)
buf = current_buffer;
set_per_buffer_value (buf, offset, newval);
Lisp_Object Qborder_color, Qborder_width;
Lisp_Object Qcursor_color, Qcursor_type;
Lisp_Object Qheight, Qwidth;
-Lisp_Object Qleft, Qright;
Lisp_Object Qicon_left, Qicon_top, Qicon_type, Qicon_name;
Lisp_Object Qtooltip;
Lisp_Object Qinternal_border_width;
DEFSYM (Qicon_left, "icon-left");
DEFSYM (Qicon_top, "icon-top");
DEFSYM (Qtooltip, "tooltip");
- DEFSYM (Qleft, "left");
- DEFSYM (Qright, "right");
DEFSYM (Quser_position, "user-position");
DEFSYM (Quser_size, "user-size");
DEFSYM (Qwindow_id, "window-id");
extern Lisp_Object Qx_resource_name;
-extern Lisp_Object Qleft, Qright, Qtop, Qbox, Qbottom;
+extern Lisp_Object Qtop, Qbox, Qbottom;
extern Lisp_Object Qdisplay;
extern Lisp_Object Qrun_hook_with_args;
#include "blockinput.h"
#include "syssignal.h"
#include "window.h"
+#include "buffer.h"
#include "gtkutil.h"
#include "termhooks.h"
#include "keyboard.h"
Lisp_Object Qmode_line;
Lisp_Object Qvertical_line;
Lisp_Object Qright_divider, Qbottom_divider;
-static Lisp_Object Qvertical_scroll_bar;
Lisp_Object Qmenu_bar;
static Lisp_Object Qecho_keystrokes;
DEFSYM (Qmode_line, "mode-line");
DEFSYM (Qvertical_line, "vertical-line");
- DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
DEFSYM (Qmenu_bar, "menu-bar");
DEFSYM (Qright_divider, "right-divider");
DEFSYM (Qbottom_divider, "bottom-divider");
extern Lisp_Object Qicon_name;
extern Lisp_Object Qicon_left;
extern Lisp_Object Qicon_top;
-extern Lisp_Object Qleft;
-extern Lisp_Object Qright;
extern Lisp_Object Qtop;
extern Lisp_Object Qdisplay;
extern Lisp_Object Qvertical_scroll_bars;
static Lisp_Object Qmodifier_value;
Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper;
-extern Lisp_Object Qcursor_color, Qcursor_type, Qns, Qleft;
+extern Lisp_Object Qcursor_color, Qcursor_type, Qns;
static Lisp_Object QUTF8_STRING;
static Lisp_Object Qcocoa, Qgnustep;