1

Does Emacs have a way to set buffer-local properties on symbols?

It's well-known that there are buffer-local variables. But a property belongs to a symbol, not to a variable. Hence, if I have understood correctly, making a variable foo buffer-local has no effect on on properties set on the symbol foo.

(Note: In Emacs Lisp, the term property can refer to anything having to do with property lists (plists), including their uses for text properties, symbol properties, and other things. This question is about symbol properties specifically.)

  • 3
    "Properties" does not necessarily mean symbol properties. "Symbol properties" means symbol properties. Out of any specific context, "properties" would refer only to property lists (plists) in general, which could include their uses for text properties, symbol properties, and anything else. – phils Apr 5 at 7:46
  • 2
    I wonder whether this might be an X-Y problem. What is the use case, i.e., why do you think you want to have symbol property-values that are different depending on the buffer? – Drew Apr 5 at 16:00
  • 1
    A symbol property-value can be any Lisp object, including a sexp (list, symbol,...) that you evaluate - e.g., within a given buffer. E.g., it can be a symbol whose value you evaluate as a variable in a given buffer. But it's not clear to me what you really want to do, i.e., why you think you want buffer-local symbol property values. – Drew Apr 5 at 16:03
  • @Drew It is indeed an X-Y problem (like every other problem in life :) My use case would be having different lisp-indent-function and scheme-indent-function property values in different buffers. That particular problem is probably more easily solved using a custom lisp-indent-function that doesn't use symbol properties. But I asked the present question anyway out of curiosity. – Lassi Apr 6 at 8:18
  • 1
    function-get and put are not really separate from symbol properties. All they do is check the symbol property, and if nil then they check the symbol-function and follow an autoload trail to get to the ultimate symbol. IOW, they look for the symbol that represents the function, and then use get on that symbol. – Drew Apr 6 at 16:07
4

I am certain that the answer is no, and that variables are the only kind of buffer-local bindings provided by elisp. (I'm sure one of the elisp language maintainers will correct me if I'm wrong about this.)

There are a handful of other kinds of "local" values (such as frame parameters, and terminal-local variables), and other things may also be associated with buffers (such as processes), but the feature you're asking for isn't provided.

However, FWIW, (get SYM PROP) is a PLACE form (or "generalised variable"), such that you can provide a dynamic binding for it. E.g.:

(require 'cl-lib)

(put 'foo 'bar 'normal)

(list (cl-letf (((get 'foo 'bar) 'overridden))
        (get 'foo 'bar))
      (get 'foo 'bar))

=> (overridden normal)

As such, if you have control over the elisp for which you felt you needed this feature, then you may be able to adapt it to this approach (although without knowing your actual goal, it's impossible to say for sure).

| improve this answer | |
  • 1
    One way to emulate buffer-local symbols is by interning them in a new obarray that is stored buffer-locally. – Basil Apr 5 at 9:20
  • 1
    If you mean making C-h v obarray itself buffer-local, I can imagine that doing the trick, but at the same time being a catastrophically bad idea :) An interesting idea, though. If you just mean passing the obarray argument to intern, that's clearly safer, but likely requires more of the code to be aware of the requirement, and in practice I would think that using uninterned symbols would be a better option in those cases. – phils Apr 5 at 10:43
  • 1
    I was thinking of the latter :) You're right that uninterned symbols would be simpler and more idiomatic, but each of those symbols would have to be stored somewhere (which could be consolidated in a new obarray), and the question is about something inherently non-idiomatic. – Basil Apr 5 at 11:00
  • I am humbled by the level of elisp wizardry elicited by this question. Your discussion makes for very interesting reading. Thank you for having it. – Lassi Apr 6 at 8:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.