andreyorst / plug.kak

Plugin manager for Kakoune
MIT License
197 stars 18 forks source link

Suggestions for plugin authors? #88

Closed mralusw closed 2 years ago

mralusw commented 3 years ago

Perhaps there should be a section for plugin authors in the README.

For example, suppose that, as a plugin author, I recommend that users install my plugin via plug. Normally, my module can be loaded optionally via require-module mymod. This translates to (AFAICT)

plug me/mymod demand mymod

But plug already has a mechanism to noload. Should the module autoload itself (e.g. add a KakBegin hook that require-module's), so that users can just add to their kakrc this and avoid two layers of optional loading?

plug me/mymod
andreyorst commented 3 years ago

But plug already has a mechanism to noload. Should the module autoload itself (e.g. add a KakBegin hook that require-module's), so that users can just add to their kakrc this and avoid two layers of optional loading?

noload is a hack to support plugins that require their kakscript code by themselves somehow. kak-lsp did this, and I needed a way to tell plug.kak about itself without loading it twice, and hardcoding certain names, like plug.kak into the core. It works, but this is still a hack, and should be avoided as much as possible. Besides, by not requiring something immediatelly you would not gain much, as you would need to do it eventually,

By adding a KakBegin hook into your .kak script, you basically force people to delay loading it after KakBegin is executed if they don't want to enable your plugin immediately. This is a bad design IMO. Explicit is always better than implicit.

Plugins support module system, which is a solution to this problem, and plug.kak tries to make it really easy to use and configure modules with defer and demand keywords.

So for example, if you're writing a plugin, that is split up to different modules inside, and you need to provide a single entry point that will require all modules in the needed order, you should use provide-module and require-module commands. Sadly I don't know a best practice to handle this. You can take a look at how powerline.kak or fzf.kak do this, but I think this is not the best architecture. Fzf.kak tries to be lazy, only requiring modes when you invoke a specific keybinding, while powerline.kak loads everything needed.


A comprehensive manual on how to write plugins would be a good thing, but I'm a bit out of the loop, as I'm no longer write new plugins for Kakoune, only maintain the existing ones I already wrote, because they have userbase, so I'm in no position to write one. Paired with the fact that I think that most of my plugins are overengineered in their architecture is really not making me not really an expert in the area :)

Kakoune actually has a bit of its own docs on writing plugins: https://github.com/mawww/kakoune/blob/master/doc/writing_scripts.asciidoc but it's rather an overview of the basic architecture, and doesn't go into great detail of how to use module system for example.

mralusw commented 3 years ago

OK, so you're suggesting that inside the autoload part of the plugin I add

provide-module mod1 %{}
provide-module mod2 %{}
provide-module entry %{}

require-module entry

and have users add plug <URL>://myplugin to their kakrc? I also have some configuration options that users should change before require-module, so I think

plug <URL>://myplugin %{
  set global myplugin_work_dir '/tmp/myplugin'
} demand entry %{}

is more flexible (I noticed the final %{} is required even if empty, not sure if that's intended, but there's #89 for that)

andreyorst commented 3 years ago

OK, so you're suggesting that inside the autoload part of the plugin I add

provide-module mod1 %{}
provide-module mod2 %{}
provide-module entry %{}

require-module entry

By adding require-module entry to your kakscript you've essentially disabled the ability to load this modules lazily. So no, instead I'm suggesting this:

provide-module mod1 %{}
provide-module mod2 %{}
provide-module entry %{
    require-module mod1
    require-module mod2
    ...
}

Then you can suggest users of your plugin to require it by requiring the entry module, which will do all setups it need automatically on demand.

and have users add plug <URL>://myplugin to their kakrc? I also have some configuration options that users should change before require-module, so I think

Then you simply don't put those into modules:

declare-option str option-one ""
provide-module mod1 %{}
provide-module mod2 %{}
provide-module entry %{
    require-module mod1
    require-module mod2
    declare-option str option-two ""
    ...
}

Which can then be set up as follows:

plug <URL>://myplugin %{
  set global option-one "foo"
} demand entry %{
  set global option-one "bar"
}
mralusw commented 3 years ago

OK, I agree, that's what I thought would work best as well (and what I'm currently using for my mru-files.kak plugin).