From df713b9344e978eff4f0a6aff506932fcdb1a39c Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Fri, 11 Oct 2019 08:27:50 +0200 Subject: [PATCH] Ensure that setq-local take an even number of symbol/value pairs * doc/lispref/variables.texi (Creating Buffer-Local): Document the new syntax for setq-local. * lisp/subr.el (setq-local): Ensure that there's an even number of variable/value pairs, and expand the doc string by taking some text from `setq'. --- doc/lispref/variables.texi | 16 +++++++++++----- etc/NEWS | 3 +++ lisp/subr.el | 35 ++++++++++++++++++++++++----------- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 89dac4f7a4d..76bda7874e3 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -1430,11 +1430,17 @@ needed if you use the @var{local} argument to @code{add-hook} or @code{remove-hook}. @end deffn -@defmac setq-local variable value -This macro creates a buffer-local binding in the current buffer for -@var{variable}, and gives it the buffer-local value @var{value}. It -is equivalent to calling @code{make-local-variable} followed by -@code{setq}. @var{variable} should be an unquoted symbol. +@defmac setq-local &rest pairs +@var{pairs} is a list of variable and value pairs. This macro creates +a buffer-local binding in the current buffer for each of the +variables, and gives them a buffer-local value. It is equivalent to +calling @code{make-local-variable} followed by @code{setq} for each of +the variables. The variables should be unquoted symbols. + +@lisp +(setq-local var1 "value1" + var2 "value2") +@end lisp @end defmac @deffn Command make-variable-buffer-local variable diff --git a/etc/NEWS b/etc/NEWS index b680e180043..4135d47ee18 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2351,6 +2351,9 @@ scrolling. * Lisp Changes in Emacs 27.1 +** 'setq-local' can now set an arbitrary number of variables, which +makes the syntax more like 'setq'. + ** 'reveal-mode' can now also be used for more than to toggle between invisible and visible: It can also toggle 'display' properties in overlays. This is only done on 'display' properties that have the diff --git a/lisp/subr.el b/lisp/subr.el index 2acac3a0518..e50a52e2f53 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -143,22 +143,35 @@ of previous VARs. (push `(set-default ',(pop args) ,(pop args)) exps)) `(progn . ,(nreverse exps)))) -(defmacro setq-local (&rest args) - "Set each SYM to the value of its VAL in the current buffer. +(defmacro setq-local (&rest pairs) + "Make variables in PAIRS buffer-local and assign them the corresponding values. -\(fn [SYM VAL]...)" - ;; Can't use backquote here, it's too early in the bootstrap. - (declare (debug (symbolp form))) - (let ((expr)) - (while args +PAIRS is a list of variable/value pairs. For each variable, make +it buffer-local and assign it the corresponding value. The +variables are literal symbols and should not be quoted. + +The second VALUE is not computed until after the first VARIABLE +is set, and so on; each VALUE can use the new value of variables +set earlier in the ‘setq-local’. The return value of the +‘setq-local’ form is the value of the last VALUE. + +\(fn [VARIABLE VALUE]...)" + (declare (debug setq)) + (unless (zerop (mod (length pairs) 2)) + (error "PAIRS must have an even number of variable/value members")) + (let ((expr nil)) + (while pairs + (unless (symbolp (car pairs)) + (error "Attempting to set a non-symbol: %s" (car pairs))) + ;; Can't use backquote here, it's too early in the bootstrap. (setq expr (cons (list 'set - (list 'make-local-variable (list 'quote (car args))) - (car (cdr args))) + (list 'make-local-variable (list 'quote (car pairs))) + (car (cdr pairs))) expr)) - (setq args (cdr (cdr args)))) - (cons 'progn (nreverse expr)))) + (setq pairs (cdr (cdr pairs)))) + (macroexp-progn (nreverse expr)))) (defmacro defvar-local (var val &optional docstring) "Define VAR as a buffer-local variable with default value VAL. -- 2.39.5