andreyorst / powerline.kak

Kakoune modeline, but with passion
MIT License
50 stars 8 forks source link

Broken modules with plug.kak 2.x #19

Closed stevengubler closed 3 years ago

stevengubler commented 3 years ago

Problem description

powerline.kak's configuration isn't compatible with the new changes to andreyorst/plug.kak.

Steps to reproduce

  1. Use the current version of andreyorst/plug.kak. (current as of writing)
  2. Declare installation with plug.kak like so:
    plug "andreyorst/powerline.kak" config %{
    powerline-start
    } defer "powerline" %{
    \# NOTE the exact format and theme aren't important. It's the calls that cause issues.
    powerline-format global 'lsp'
    powerline-theme tomorrow-night
    }
  3. kak -e 'b *debug*' to open an new instance of kakoune and show the debug buffer.

What should happen

When configuring a standard installation of powerline.kak in the way the README.md indicates (by using plug.kak and it's defer feature, it should apply configurations correctly and not throw errors.

What happens instead

Powerline is just using the default configuration, and the configurations in the defer block did not apply. The debug buffer shows

powerline.kak: Warning, trying to load non-existing module 'lsp'
error running hook ModuleLoaded(powerline)/: 11:5: 'powerline-theme' 1:2: 'evaluate-commands' no such command: 'powerline-theme-tomorrow-night'

Environment information

Kakoune version: Kakoune v2020.09.01 OS version: MacOS 11.2.2 sh executable version: zsh 5.8


My thoughts

This appears to stem from a new change to plug.kak's defer block:

Note: the ModuleLoaded hook is defined as early as possible - before sourcing any of plugin files.

source: plug.kak's README

This means that the hooks (like this one) that include the modules like lsp, git, etc. run after the hook that plug.kak sets up for the powerline module.

That means that commands like powerline-format will fail and throw errors when in a defer block.

My workaround

To get around this issue, we can manually require all of the modules we need in our defer block:

plug "andreyorst/powerline.kak" config %{
    powerline-start
} defer "powerline" %{
    require-module "powerline_lsp"
    require-module "powerline_tomorrow_night"
    powerline-format global 'lsp'
    powerline-theme tomorrow-night
}

However, this isn't a great user experience; it greatly increases the complexity of configuring powerline. In my particular configuration, it also increased kakoune's startup time by 2x, from ~0.23s to ~0.45s (as measured by time kak -e 'q'). powerline.kak already had a relatively large impact on startup time, so a further doubling makes it significantly worse.

andreyorst commented 3 years ago

This means that the hooks (like this one) that include the modules like lsp, git, etc. run after the hook that plug.kak sets up for the powerline module.

Yes, that's intentional.

plug.kak defer powerline_lsp %{
    echo "powerline lsp hook"
} condig %{
    powerline-start
} defer powerline %{
    echo "powerline hook"
}

Will create ModuleLoaded hooks in this order:

# hooks defined with plug.kak
hook global ModuleLoaded powerline_lsp %{ echo "powerline lsp hook" }
hook global ModuleLoaded powerline     %{ echo "powerline hook" }
# hooks defined by loading .kak scripts in powerline.kak repo in pseudo-random order
hook global ModuleLoaded powerline %{ require-module powerline_lsp }
hook global ModuleLoaded powerline %{ require-module powerline_filetype }
# ... rest hooks

Before loading powerline.kak script or any other files in powerline.kak repo. When powerline_lsp.kak loads, it defines it's own hook for loading powerline module. After all of that when powerline-start is called it creates another hook for BufCreate .* that actually requires the powerline module, and initiates the sequence for loading everything. So first the echo "powerline lsp module" is exectued, then echo "powerline", then everything that was defined during loading files, and after that the internal powerline-enable is called, which constructs the powerline from powerline_format option.

That means that commands like powerline-format will fail and throw errors when in a defer block.

No, that's exactly the opposite :slightly_smiling_face:! Defer block happens after module is loaded, so powerline-format will not fail. But you might need to keep an eye on defer order, this is no magic, and you would have to do the same by defining hooks manually. Luckily, in case of this plugin, this is not necessary.

Now to your config. Plug.kak now supports several defer targets, as I've mentioned above, so you need to put powerline-theme call inside defer:

plug "andreyorst/powerline.kak" defer "powerline" %{
    set-option global powerline_format 'lsp'
    # or powerline-format global 'lsp'
} defer powerline_tomorrow_night %{
    powerline-theme tomorrow-night
} config %{
    powerline-start
}

This works on my end without errors. As for powerline.kak: Warning, trying to load non-existing module 'lsp' This is because the module was not yet loaded (and I'm not sure why, really), but it will be loaded eventually. With the config above I have the following modeline:

image

Although lsp module should declare variables for errors and warnings, as if kak-lsp is not loaded they don't exist and this is a problem.

andreyorst commented 3 years ago

docs are now updated to mention this. Closing