Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Standardization of plugin file-structure layout #2402
Hello. I'm developing a plugin manager for Kakoune (for personal use, but if anyone interested, you're welcome). Since there's no currently de facto standard of Kakoune plugin project layout, I'd like to propose Vim-like one (with some exceptions, because of structure), because it works really well.
Vim's plugin structure
Owerall structure of most plugins can be described like this:
Not all folders are necessary, it is highly dependent on the plugin's task. However, the possibilities that come with abilities off putting different modules of the plugin to the supported methods of loading via different directories are huge.
In Vim plugin we have essential
This sturcture allows easy unified mechanics for all plugins, to be loaded, loaded with specific
One of the most powerful Vim feature is help system, and one of the most powerful feature of vim's help system is that it can be extended easily. As a plugin creator responsible of writing a comprehensive documentation, editor is responsible of making it easy to refer to that documentation.
Plugins tend grow, and it is natural for them to have a documentation. For example, look at the documentation of LanguageClient-Neovim or UltiSnips. It's kinda huge. And it is meaningless to store all that in the README.md, since this file should contain only essential part about a plugin (although some plugin maintainers do that).
The ability to extend Kakoune's doc base with plugin, or user docs will make overall usage and configuration process lot easier already. This can go alongside with already existing ticket #1991
Proposed plugin layout
Currently, most popular plugins have this layout:
There's no separation to documentation, syntax, indentation rules right now.
I'm proposing layout similar to Vim's plugins, but simplified a bit:
I was experimenting with command
I also would like a mechanism of loading colorschemes as arbitrary files, but not enabling them (or a way to distinguish colorscheme from script file in interactive way to store it inside needed folder. This will make possible installation of several colorschemes with single plugin, similar to how base16-vim does it.
I understand that Vim benefits from keeping indent and syntax config separate from general plugins, since it will selectively execute those scripts depending on the active configuration (for example, I believe indent scripts aren't read if you don't have autoindent enabled).
Kakoune doesn't really need to keep those things separate, because it always reads everything anyway, and for the few plugins I use, I'm perfectly happy with adding them as git submodules with no extra ceremony. For colorschemes it's the same deal: Kakoune recursively scans
On the other hand, I'd love it if the
The main point of separation different kind of scripts is to make it easier to automate the process. Right now my plugin manager downloads git repo to certain path, and sources every
I think the idea of @alexherbo2's example is that the documentation could be included inline in the plugin, or read from a file when Kakoune starts up (by shelling out to cat) and stored in memory, presumably in some
referenced this issue
Oct 1, 2018
Actually, naming documentation with the same name as plugin may be enough to deduce that this is documentation, and not a readme (Comparing every file's name to all sort's of ReAdmE is generally a bad idea for me).
Yeah, I think the plugins managers should basically link
@mawww no. The point of plugin manager is not only installation of plugins, which involves downloading and linking, but also loading them, and maintaining them as well. Why should plugin manager use it's own method of loading a plugin instead of relying on symbolic link to plugin's script file? That's easy question that can be answered by a set of simple examples. With my plugin manager, you can download, update, and use any plugin if such entry exists in your configuration:
This interactive command essentially does two main things: It ensures that plugin exists, at installation path, and loads it if it is installed. Given that we could assume that we can use a symbolic link, but actually we can't. Here's why:
Imagine, that we added these two lines to our configuration file:
After resourcing of configuration file, or restarting Kakoune, plug.kak knows about these plugins, and knows that they are not installed, because it tried to load them and failed. We can fix this with
So, user had installed two plugins, and was able to load them without restarting whole session. You can even install plugin's without adding
So user didn't liked that some plugin is loaded for every filetype, or want to disable plugin temporarely. If symbolic link was used, user need to go to
With plug.kak user can do these:
By simply commenting plugin in
Plugin will be loaded only when a markdown file was opened. It will not be loaded for markdown file only though, but this isn't possible to do at all with symbolic link at autoload directory. Because again, plugin may be a general purpose, and not used as a filetype extension, but may be meaningless with certain conditions of user's workflow.
Again, removing plugins is simplified too, because you just need to comment out desired plugin and remove it with
There's one more opportunity to drop usage of symbolic links, and it is interactive plugin loading:
With plug.kak you can specify which branch or tag you want to use in particular plugin:
That is, before loading a plugin, during the startup of the Kakoune, plug.kak will select needed branch, and load a script file from that branch. By using a symbolic link you need to manually go and use
Plugin manager also should be used to create safe configuration file, in first place:
This makes possible to have alias only if plugin is installed, so if you run fresh installation of kakoune, with your configuration file from your dotfiles repo, Kkoune will still be loaded normally even if plugins wasn't installed.
Using symbolic links is easy, but a naive way to maintain plugins, and it was already a known bad experience in vim's world. No need to step on the same rake.
I like the simple solution as well. On the other hand, I've used Vim's pathogen plugin manager and I found it delightful from an end-user perspective.
Setting up pathogen is a matter of putting
After setting up pathogen, installing a plugin is a matter of running
Pathogen is good old tool useful for loading plugins, but it is not plugin manager. It's a runtimepath manager, which is a kind of different thing. With Kakoune you don't even need pathogen, because you can clone plugins to autoload directory and It will work just in the same way, because it loads every .kak file from autoload and from directories inside it recursively.
I think standard plugin structure should resemble structure of
User can basically copy and paste it into
I think it's simple, and consistent with way Kakoune works right now.
@negativedensity I like @tpope’s approach as well. I’ve a similar, at the exception it’s declarative – in the
@andreyorst Symlinking in autoload or just sourcing them is fine by me, regarding doc/ the plugin manager could create a
What I was mostly pointing to is that plugins manager could just source
That said, if it is really preferred, I am not that strongly opposed to an option storing the paths in which to look for docs.
This was referenced
Oct 23, 2018
So I've developed a plugin, called powerline.kak that utilizes the style where sub-modules of the plugin are stored in separate folder. I've did it more or less just to try this paradigm where modules are located separately and turns out that, this really simplifies the code, and makes scripts small and consistent. The very same issue with big and bloated script exists for my another plugin andreyorst/fzf.kak#22, but there were no way how to do it properly back then.
This way of writing plugins also allows other developers to write their modules for my plugin, which are not located directly inside mine plugin, but can use the same interface which plugin provides with variables.
Here's how it is structured:
Full layout looks like so:
I've encountered this caveat (which I've partly solved with plugin manager):
Plugin must be loaded with proper order of script files, since if modules are loaded before the plugin, they complain about variables are not being defined. I can use this thing in each module to workaround the issue:
But this looks ugly (duplicated code) and I'm not sure what will happen if main script will try to declare the same variable.
However, if Kakoune claims that it will never redefine variable, and will always support the syntax where you declare a variable without value, then this is fine to use:
Otherwise it is error prone code.
Therefore I have a question how Kakoune loads files, from
If Kakoune recursively loads
Either plugin file-structure layout should be standardized so such problems can be grouped into easily avoidable situations described by the document of how plugin should be structured to be loaded properly by plugin managers or Kakoune itself, or
Or tweak Kakoune loading mechanics to support loading plugins which store sub-modules in nested folders, or
Or leave this whole task to plugin managers, and not support loading such complex plugins automatically, leaving this task on the user. (and fight those plugins like Vim did a long time, but adopt it after 20 years because it actually good thing to have)