Closed lacygoill closed 4 years ago
Whether a builtin sid()
or a custom SID()
function, the following still looks awkward (in my opinion):
let &l:includeexpr = sid() .. 'my_includeexpr()'
It would make a lot more sense to allow funcrefs for the above mentioned options, including the input()
function. It seems sid()
is just a dirty workaround since funcrefs are not accepted (yet). In my opinion users shouldn't worry about these internal script IDs.
For timer_start()
I have always wrapped the script-local callback inside a lambda, something like:
call timer_start(1, {-> s:foo()})
Funcrefs are indeed a better solution.
The help already explains how
Whether a builtin sid() or a custom SID() function, the following still looks awkward (in my opinion):
Oh yes, I definitely agree. It's just that in some cases, I don't see any alternative; mainly when I have to invoke a script-local function from a command-line populated by a script. I guess that's an edge case which doesn't warrant a dedicated sid()
function.
It would make a lot more sense to allow funcrefs for the above mentioned options, including the input() function. It seems sid() is just a dirty workaround since funcrefs are not accepted (yet). In my opinion users shouldn't worry about these internal script IDs.
I'll keep an eye on future PRs, regarding the ability of providing a funcref to '*func'
options. When one will be submitted, I'll check input()
is also supported.
In that line of thought, I think it would be OK to make expand('') work.
That would certainly help reduce the amount of code in most cases I mentioned in the OP.
@lacygoill Does this work now? How to expand this? I am trying to set quickfixtextfunc=s:functioname
, what's the best technique for now?
let
seems to work, set
does not for setting quickfixtextfunc
:
let &quickfixtextfunc=expand('<SID>') . 'myQfPrintFunc'
yes and that is expected, because :set
does not expect expressions. See also :help <SID>
where an example is shown.
@chrisbra Thanks!
Is your feature request about something that is currently impossible or hard to do? Please describe the problem.
It is not easy to manually expand the
s:
function scope or the pseudo-key<SID>
.That's an issue – for example – when we need to assign a script-local function name to an option; this doesn't work:
When pressing
gf
on a path which can't be found,E120
is raised:Describe the solution you'd like
A
sid()
function which expands thes:
function scope and the<SID>
pseudo-key into the string<SNR>123_
, where123
is the id of the current script. With it, one could write:Describe alternatives you've considered
The current general workaround is to emulate
sid()
with a custom function:It works, but it makes the code more verbose. It would be easier to read/write if we had a builtin
sid()
function.As an example, that's what
vim-matchup
does:and
vim-Verdin
:and
vim-sandwich
:Sometimes, we can also use
function()
:But it looks awkward, and a builtin
sid()
would still make the code easier to read/write.Besides, we have to make sure that
s:my_includeexpr()
is defined before setting'includeexpr'
. Similarly, withs:SID()
, we have to make sure that the function is defined before we invoke it.With
sid()
, there would be no such requirement.Also, note that
function()
does not always work. For example, it doesn't for'operatorfunc'
:Nor for
'completefunc'
:And more generally, it probably doesn't work for any option which expects a function name, instead of an expression.
Additional context
It's not an issue just when setting an option. It's also an issue when starting a timer:
And when we need to invoke a script-local function from a command-line populated by a script:
And when we pass the name of script-local function as a third optional argument to
input()
:If such a function was provided, I think it should accept an optional boolean argument to additionally make Vim expand the pseudo-key
<SNR>
into a byte sequence (e.g.<80><fd>R
). Most of the time, it's either not needed (e.g. in a timer's callback, or in an option setting), or not desirable (e.g. when invoking a script-local function from a command-line populated by a script). But sometimes, it is needed. See here and there for 2 examples.In the future, we may not need
sid()
to set options, because all the options expecting a function name may accept lambda expressions (and maybe funcrefs/partials?):Source.
Incidentally, this should also allow us to pass arbitrary data to
'opfunc'
, which is awkward/cumbersome right now (we need to use global or script-local variables).But it would still not fix the issue in other contexts (timers,
input()
, command-line, ...).