Open jaor opened 3 years ago
This is a bit of an issue I am afraid. All elisp blocks share same indirect buffer for efficiency. So it would be ok if all org blocks use lexical bindings. Is there a way to specify lexical bindings setting for all code blocks? If so then we should inherit that setting. If you could figure out how to retrieve the setting from the org buffer then I will do the rest.
On Wed, May 26 2021, Vitalie Spinu wrote:
This is a bit of an issue I am afraid. All elisp blocks share same indirect buffer for efficiency. So it would be ok if all org blocks use lexical bindings. Is there a way to specify lexical bindings setting for all code blocks? If so then we should inherit that setting. If you could figure out how to retrieve the setting from the org buffer then I will do the rest.
Hmm, sort of. One can use something like
#+PROPERTY: header :lexical t
at a global scope, and then all code blocks inherit the lexical bit. (and ISTR that org mode even has a function to retrieve the global properties of a buffer, but i cannot remember its name). One can still override the setting in a given block, and we would not do the right thing there, but given that lexical mode is not supported at all right now, i think that would be better than the current situation (and the caveat could be documented).
Maybe another option would be to use a new property specific to poly-org, and read that instead?
What do you think?
oh wait, i just tried again and it seems the global :lexical t is working in emacs 28! if i have it at the top level, i see the marker of the mode in a block indicating that it's Elisp/l (i.e. with lexical-binding set to t), and indeed evaluating code inside seems to be using the correct scoping.
i guess i was trying with emacs 27.2 and forgot to check on emacs
personally, that mostly fixes this issue for me, but i guess an emacs 27 user has at least a year before her until the next release :)
EDIT: please ignore what i wrote here, i was just confused again :( After testing a bit more i see:
#+property: header-args :lexical t :shebang ";; -*- lexical-binding: t -*-" :tangle yes
as the first line in the org file seems to do the trick for me.
but if i add something before that line, like, say "#+title: foo", then lexical binding is not activated in the code blocks.
I think we can also honor local block binding. Basically when a user enters into a code block the value of that block is installed, when the user exits the block the global value is restored. I don't imediately see any issues with this, do you?
Would it be difficult for you to figure out how to retrieve the biding value, both local and global? I am not an org user so for me it's a bit of a cost to dig ATM.
it's actually quite easy. org stores in the buffer local variable org-keyword-properties the properties set at a global scope.
for instance, in a file with first line:
#+property: header-args :lexical t :tangle yes
the value of org-keyword-properties is
(("header-args" . ":lexical t :tangle yes"))
and it can be even easier if we defined poly-org's own property. e.g., if one has
#+property: header-args :lexical t :tangle yes
#+property: poly-org-lexical t
the value of org-keyword-properties is:
(("poly-org-lexical" . "t") ("header-args" . ":lexical t :tangle yes"))
Hi. As you know, in elisp blocks one can specify that their evaluation be performed with lexical-binding set to t. But, as far as i can tell, poly-org is oblivious of that setting: when i enter an elisp block, it always shows as set in dynamical binding, and evaluations inside with, say, C-x C-e, are performed with lexical-binding set to nil. Would it be possible to inherit the org block header setting?
Thanks!