feature: Statusline caching and custom functions
Did you check the docs?
- [X] I have read the Grapple docs
Is your feature request related to a problem? Please describe.
Hello @cbochs,
Recently, I wrote harpoonline, around the same time grapple incorporated its statusline.
I have been using grapple for a week now and it's a perfect replacement for harpoon. I also like the paradigm and the additional features.
Based on harpoonline, I refactored and wrote grappleline.
The plugin adds the following to grapple's builtin statusline:
- Caching: Only recomputes the last line when needed
- An "on_update" callback, triggering any consumer to refresh
- Additional builtin and custom functions to render the information in various ways.
Would you be interested in a PR? I think that the additional functionality would fit very nicely into grapple.
I would appreciate your opinion!
Describe the solution you'd like
...
Describe alternatives you've considered
...
Additional context
No response
Hey @abeldekat, grappleline looks great! A few questions:
Caching: Only recomputes the last line when needed
Are you experiencing any measurable latency when using the default grapple.nvim statusline? Scope themselves are already cached, which should reduce most of the overhead of recomputing the statusline value.
An "on_update" callback, triggering any consumer to refresh
Grapple already executes a GrappleUpdate autocommand when a change is made. Would this suffice for your usecase?
Additional builtin and custom functions to render the information in various ways.
There are a few methods available to customize your own statusline if you want to. Is there any information that you think a user would need to build their statusline which is not already provided by Grapple?
Thanks for the feedback!
Are you experiencing any measurable latency when using the default grapple.nvim statusline...
Not on my fast laptop. Although scopes are cached, in order to generate the statusline, grapple has to iterate the tags and string.format the output. Potentially, statuslines by nature update on each and every keystroke. When a user edits code or writes prose, those actions are unnecessary. See grappleline format.
Grapple already executes a GrappleUpdate autocommand...
Not completely. I need to know when the user changes the default list. See grappleline decorate
Is there any information that you think a user would need to build their statusline which is not already provided by Grapple?
No, because the grapple api is very complete and well done. The aim of the grappleline genformatter is to allow the user to write a function where the only task is the transformation of the data into the representation. The plugin takes care of the rest: Keeping that data up-to-date and notifying the consumer/statusline. See grappleline data. I think this idea is similar to the hook functions provided in the grapple settings.
For my usecase, the plugin would be redundant when grapple would have:
- A
grapple.statuslineclass caching the line, rebuilding onGrappleUpdateandGrappleChangeScope - A function hook in settings-statusline, to transform data into a custom line representation.
- An on-update hook in settings-statusline, perhaps defaulting to
lualine. The on-update hook is important when using keystrokes that don't affect the buffer. For example, ongrapple.use_scope. I thinklualinehas an autoupdate mechanism. Even then, there could be a slight delay before the name of the scope is updated.
On a side note: I had some problems using the second lualine example:
require("lualine").setup({
sections = {
lualine_b = {
{ require("grapple").name_or_index, cond = require("grapple").exists }
}
}
})
The only way to have the statusline showing tags properly, is to wrap the name_or_index function in a function without any argmuments:
function() return require("grapple").name_or_index() end,
Best regards!
On a side note: I had some problems using the second
lualineexample:require("lualine").setup({ sections = { lualine_b = { { require("grapple").name_or_index, cond = require("grapple").exists } } } })
This appears to have been incorrect. I've updated the README to fix this. Thanks for bringing it up!
For my usecase, the plugin would be redundant when grapple would have:
A
grapple.statuslineclass caching the line, rebuilding onGrappleUpdateandGrappleChangeScopeA function hook in settings-statusline, to transform data into a custom line representation.
An on-update hook in settings-statusline, perhaps defaulting to
lualine. The on-update hook is important when using keystrokes that don't affect the buffer. For example, ongrapple.use_scope. I thinklualinehas an autoupdate mechanism. Even then, there could be a slight delay before the name of the scope is updated.
I added an event called GrappleScopeChanged which will trigger when a user changes their scope. There is now also a global app cache that could be used for caching the statusline in Grapple.statusline.
If you'd still interested, I would be happy to take a look at a PR which would add the last two points you mentioned, just making sure it keeps the current default behaviour 🙂
That's great! I will propose a PR, hopefully this week.
@cbochs, FYI, I started working on the PR. Hope to send a first draft soon.