5

I'm in buffer A and I want to set a buffer-local variable in buffer B. I'm currently doing:

(with-current-buffer B
  (setq-local some-var 'some-val))

but is there a way to do this without changing the current buffer, i.e. can I explicitly specify the buffer whose value I want to change?

ivan
  • 1,928
  • 10
  • 20
  • Good idea. I just submitted an enhancement request for this: bug #[26923](https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26923). – Drew May 14 '17 at 14:17

2 Answers2

9

is there a way to do this without changing the current buffer

No, but buffer-local-value is a Generalized Variable, so you can use setf to take care of the buffer switching for you:

(setf (buffer-local-value 'some-var B) 'some-val)

This macroexpands to essentially the same code as what your wrote above:

(let* ((#1=#:v B))
  (with-current-buffer #1#
    (set (make-local-variable 'some-var) 'some-val)))
npostavs
  • 9,033
  • 1
  • 21
  • 53
  • Cool. Now that I know there are two ways to do this, the inevitable question is "which is faster?" I guess I can try it out both ways and compare. – ivan May 15 '17 at 16:57
  • 5
    @ivan The `setf` just macroexpands to pretty much the same code you wrote, there's no point in worrying about performance for something like this. – npostavs May 15 '17 at 17:12
5

What you're doing is correct.

is there a way to do this without changing the current buffer, i.e. can I explicitly specify the buffer whose value I want to change?

While there is nothing built in, you can trivially write a macro which takes all three arguments, and then does exactly what you were doing.

phils
  • 48,657
  • 3
  • 76
  • 115
  • 6
    `(setf (buffer-local-value 'some-var B) 'some-val)` might qualify as a builtin macro for this. – npostavs May 14 '17 at 15:56
  • 1
    Ah, the magic of setf places. Thanks npostavs. You should post that as a separate answer. – phils May 15 '17 at 00:35