Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Add conditional control statements to kakscript #2777

Closed
FlyingWombat opened this issue Mar 9, 2019 · 12 comments

Comments

Projects
None yet
5 participants
@FlyingWombat
Copy link

commented Mar 9, 2019

I think some more control statments should be added to kakscript.
In particular, I see a use case for conditionals, such as if; elif; else.
This isn't terribly important, but I think it would be useful.

Rationale

In some pluggins I have seen, there are shell expansions solely for the purpose of a conditional operation, which is a performance drop over a native kakscript if statement.
For operations that are run infrequently (which are most), the performance cost of calling the shell isn't a problem. But for some things, such as RawKey hooks, there is a noticeable performance impact if shell expansions are involved.

Admissions

I'll admit, many things in in kakscript won't need native conditional logic, since they'll be calling the shell anyway for some other purpose. That, and the performance impact is small enough (order of 1ms) that in most situations this is a non-issue. But for situations where conditional logic is all that is needed -- such as settings in plugins -- it seems like a waste to call the shell just for that.

Proposal

Add bash-style conditional statments as kakscript commands: if, then, elif, else, and fi.
Each would accept one argument (except fi accepts no args):
if and elif would accept an expansion that evaluates to true or false.
then and else would accept an expansion of commands to evaluate.

if and elif would do nothing if true (allowing the following then statement to execute), and if false raise a flag that the next then statement would do nothing. This skip_then flag would be set by if/elif, and reset by then.
Another skip_conditional flag would be set by if/elif, and if true would cause any elif, then, or else statment to do nothing. This would be reset by the fi statment.

@Delapouite

This comment has been minimized.

Copy link
Contributor

commented Mar 10, 2019

How noticable in the performance impact of using a shell on RawKey hooks? Is it in ms? tens of ms? or even hundreds?

@alexherbo2

This comment has been minimized.

Copy link
Contributor

commented Mar 10, 2019

When using an expansion the shell is used anyway, no?

@occivink

This comment has been minimized.

Copy link
Contributor

commented Mar 10, 2019

@Delapouite in my (limited) experience, spawning a shell scope with dash has about 1ms of overhead. It's likely several times that with bash. Inside the shell scope, builtins are for the most part free, and process calls have their own overhead, with the unavoidable (but not negligible) process spawn. Even a basic echo "$var" | sed -e ... has noticeable overhead such that you don't want to do it in a loop.

@alexherbo2 only %sh{} expansions, all others do not.

@mawww

This comment has been minimized.

Copy link
Owner

commented Mar 10, 2019

I think this would be acknowledging the failure of Kakoune's extension model, as we could not plausably deny that Kakoune's command language is a scripting language... (Its already ambiguous, the try / catch construct allowing a limited form of flow control already).

It would also be pretty limited, as I can only see two usefull things expanding to true or false:

  • A bool option value, which would be useful to control certain behaviour, but probably not general enough for most cases where we need conditional logic.
  • A shell expansion, but I cannot see what we would gain from not putting the flow control directly inside the shell expansion in that case.

In order to fix that, we would need to extend the command language further to introduce "expressions", as we currently only have statements. This would be a huge change in the extension model.

Out of curiosity, what do you use RawKey for, and in particular, cant the condition be encoded in the RawKey regex filter ?

@alexherbo2

This comment has been minimized.

Copy link
Contributor

commented Mar 11, 2019

@mawww How about the Mustache logic-less templates?

Kakoune could take inspiration from it, for iterations, flow control, etc.

@FlyingWombat

This comment has been minimized.

Copy link
Author

commented Mar 11, 2019

Thanks for the replies.
I'm new to Kakoune, so I'm not that familiar with all the in and outs.

I don't know of a way to measure the performance impact, but from my observations it is in the order of 1ms, as @occivink said.

The application I have noticed this in is the kak-crosshairs plugin pull #11.
The delay is small enough that it is only noticeable when selecting text with the mouse in a wild, sporadic motion -- since mouse selection "rapid fires" the RawKey hook.
Since kak-crosshairs is the only application I have noticed a performance impact in, it doesn't look like this is a feature that Kakoune needs.
I brought this up, however, because I couldn't find any place that this was addressed before.

@mawww For an implementation idea, would it be better to compare the expansion result to the empty string '', or to nop, than trying to use booleans?

@alexherbo2

This comment has been minimized.

Copy link
Contributor

commented Mar 11, 2019

@FlyingWombat RawKey should be avoided in favor of a combination of NormalKey and ModeChange to handle g + next-key – and the various flavors of sub-modes.

@FlyingWombat

This comment has been minimized.

Copy link
Author

commented Mar 12, 2019

So, I understand now that making a new scripting language is one of Kakoune's non-goals. After all, we don't want to just end up with a bad clone of vimscript (which is already bad).
I wasn't around for the initial discussion of the Kakoune's extension model. But now, I think that kakscript should be kept as minimal as possible. And if that's not good enough, then we'll have to look into embedding an existing scripting platform like Lua or Scheme, as mentioned in #1383.

If this interpretation is correct, could it be added to design.asciidoc or faq.asciidoc?

@FlyingWombat

This comment has been minimized.

Copy link
Author

commented Mar 14, 2019

@mawww How about the Mustache logic-less templates?

Kakoune could take inspiration from it, for iterations, flow control, etc.

IDK if it is the intended use, but I've sorta been using options like this: using logic in a shell expansion to determine a command at config time, and store it in an option to be evaluated later.
For example:

declare-option str foo
evaluate-commands %sh{
    if [ "$asdf" ]; then
        echo "set-option global foo 'bar'"
    else
        echo "set-option global foo 'baz'"
    fi
}
define-command run-foo %{ evaluate-commands "%opt(foo)" }
@alexherbo2

This comment has been minimized.

Copy link
Contributor

commented Mar 14, 2019

@FlyingWombat I was thinking to,

for iterating:

with val buflist %{
  execute-keys -buffer %val(value) 'gg'
}

and flow control:

with opt plugin_activated %{
  execute-keys 'gg'
}
@FlyingWombat

This comment has been minimized.

Copy link
Author

commented Mar 17, 2019

I like it: a simple addition. And it would be really helpful for conditional plugin and filetype configuration.
Though I'm not sure how "lists" would work -- space delimited strings?
By the way, does Kakoune have anything like vim's ftplugins?

This still, however, has the question: how far should we develop kakscript as a language vs. supporting an alternative extension model vs. just saying "No, you can't make Kakoune do X"?

@mawww

This comment has been minimized.

Copy link
Owner

commented Mar 17, 2019

@alexherbo2 you can already do evaluate-commands -buffer * %{ ... } to loop on buffers. It is not a general mechanism, but just wanted to point out this is already possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.