Kakoune needs a real scripting language

I believe we can’t enforce this, but I guess it will not be a problem, because if such thing to be implemented, Mawww can explicitly state how to use shebangs correctly. Plus currently Kakoune (kinda) allows using different shells, but almost all plugins use POSIX subset of bash, or dash shell. Technically you can use fish or zsh, for your plugin, but it will not work for anyone else, and you’ll quickly get an issue about that. So if /usr/bin/lua will not work for someone, they’ll report it, and the change to /usr/bin/env lua will be made.

The env tool (which, by the way, is not guaranteed to exist in /usr/bin/) is a workaround: the #! system is implemented in the kernel, and the kernel requires an absolute path. If you don’t want to use an absolute path you use the env tool which does the regular $PATH lookup for you.

If Kakoune added #! support on its own, it wouldn’t be restrained by the kernel’s absolute-path-only limitation; it would be reasonable for Kakoune to support something like:

#!lua

…and do the $PATH lookup itself.

or %lua{} and do the lookup, or use KAKOUNE_LUA_COMMAND environment variable, in the same way how it is done for sh. This will bring general mechanism for %guile{} %python{} and %sh{} as well. I guess.

We’ve gone the full circle

I’m currently messing around with implementing some extra control flow options in Kakoune (by patching the source). Thought I might as well post my design notes in case people have suggestions or criticisms. Current scope is very limited as I don’t want to try and build something more complicated than what the existing design has good support for (also I have no clue what I’m doing :upside_down_face:). But I also don’t believe we need that many tools added to kakscript to make it much more ergonomic.

https://gist.githubusercontent.com/Calum-J-I/c02084bb8c4da3d8a41c6a4da50c70fa/raw/78d9b9880ef7c67575fd68d0e9bcfd4a9ce41e39/kakoune-rescripted.notes

Will post on this forum when I eventually get things working as intended…

Hello, have you taken a look at things like luar for simple plugins ?

Due to RSI, I’m trying to completely remap all commands according to the new muscle memory I want to train on on a custom keyboard. I’m optimizing for the fourth time now due to testing and new discoveries like home-row-mod and the efficient use of layers.

I was searching for kakoune config language and this thread showed up as one of the first results. Had kakoune config opted for the possibility of being lua scriptable, I’m confident, I’d have already achieved what I want, rather than writing these lines. Even though I don’t know lua.

If one of the goals is to invest Kakoune plugins as standalone into the Unix ecosystem like Rust parinfer, then increasing the ability to do single file plugins with quotes isn’t likely to reinforce this since it doesn’t solve the problem of carrying standalone dependencies.

kak_source might help to break plugins into their dependent files by enabling plugins to use local directories, but that would require the additional scripts to work with out all of the exposed environment variables. However, that’s also necessary to be standalone.

If the issue is string quoting, does it work to put the whole script into a string option?
declare-option -hidden git_parse_blame %{

This doesn’t get you highlighting, but it might get you out of string quoting issues, and my brief test seemed to work although I didn’t look carefully at the evaluation.

If the issue is performance, which is probably isn’t in a lot of cases, you can design your external tool to be a persistent daemon and do message passing. One thing I want to try is to see if I can get a C FFI interface for kakoune which would let me write a persistent Perl daemon and reduce the overhead of calling Perl.

I’m a 10-year Vim-user and a few-day Kakoune-user. There are already things I can do in Kakoune that I still have no idea how to do in Vimscript. Yesterday I was messing around with mapping a bunch of keys, and all I had to do was write a nice shell-script that prints the commands that I want. I have no idea how I would write that in Vim!

To me Kakoune is a programming language, with two main classes of commands:

  • Editing text
  • Configuring the editor

As long as it can do those two things, what else do you actually need?

2 Likes

I agree that kakoune works great for a lot of small hacks. But when doing complex text editing operation and as the complexity goes up, it can be hard to use shell/kakoune script, even if you have decent scripting skill.

The tradeoff we make in Kakoune regarding complex text editing is that it could be moved to a generic tool with just a thin Kakoune specific glue layer. Granted this is not always easy, anything relying heavily on Kakoune internal state (say something iteracting with the undo tree) cannot really be made generic, yet its still possible to write those tools in any language thats able to process text. kakoune-gdb is a good example of that, with most of the logic written in perl.

2 Likes

I agree that most of the time this work wonderfully well, and this is mostly why I love kakoune.

But in some cases, the interaction with the external tool so much back and forth and/or generate so much “escape character hell” that it’s simpler to write everything in shell/kakscript .

A Solution would be to have an easier way to interact with kakoune from an external script. For example, replacing

echo "evaluate-commands -try-client client0 echo -to-file /tmp/foo %val{selection}" | kak -p 1234
cat /tmp/foo

with something like:

kak -p 1234 --client 0 --api-get val_selection
1 Like

Do you know of connect.kak? Check this.

What you want is

# Connected to session's 1234 client0
# which is the same as
# export IN_KAKOUNE_CONNECT=1
# export KAKOUNE_SESSION=1234, 
# export KAKOUNE_CLIENT=client0

:get %val{selection}

EDIT: Seems I was faster @alexherbo2 :joy:
EDIT2: Anyway add what you were typing

1 Like

Having a script as a single string make it hard to pass arbitrary values. It could be nice if the script could receive the arg-list.

Example – Pass values from the command-line:

kak -p 2525 one two <<'EOF'
  evaluate-commands -client main %{
    echo %arg{@}
  }
EOF

@useredsa For more control you can even do:

:get -quoting [raw|kakoune|shell] %val{selections}

I wish we would have json as quoting, especially as Kakoune has types but all is converted as string or list of strings with the current formats.

2 Likes

Do you know of connect.kak? Check this

Yes, and if I recall well :get from connect.kak is just an wrap around the command

echo "evaluate-commands -try-client client0 echo -to-file /tmp/foo %val{selection}" | kak -p 1234

And I forgot to mention it, but the main problem with the line above and :get is how slow it is. It is slow because it has to write to a temporary file and then read it.

Also IMO using :get is not as versatile and simple as directly calling kak

I don’t see how using a fifo would be much slower than implementing it directly in kakoune. Maybe it’s a problem with connect, whose implementation is a bit slow because it calls many small processes?

@scr The generic command is :send.

If I recall well my OS classes, writting and reading a file is a pretty slow operation, compared to printing to stdout. I might be wrong, it was long time ago :stuck_out_tongue:

This would be great! Is there a GitHub issue for this?

My understanding is that printing to stdout is orders of magnitude slower than writing to a file because in order to print to stdout, you have to write to a file, and that file somehow interacts with I/O. Whenever you start doing things with I/O things start getting significantly slower.

Yep. #3782 #3783