nvim-lualine / lualine.nvim

A blazing fast and easy to configure neovim statusline plugin written in pure lua.
MIT License
5.74k stars 455 forks source link

Flickering with "%S" vim statusline component #1129

Open BvngeeCord opened 8 months ago

BvngeeCord commented 8 months ago

This is neither a bug report nor a feature request as far as I can tell, so I've opted to not use one of the two issue templates. Please let me know if the following information is not enough to work with.

My goal is quite simple: To add vim's showcmd statusline component (actions you haven't finished typing yet, eg 3d) to lualine. By default, the showcmd info is shown in the command line in the bottom right corner, but I use cmdheight=0, so that obviously isn't visible. I saw that Lualine supports adding vim's statusline components directly by simply adding the corresponding key inside a string (in this case, "%S"; see :h statusline), so that's exactly what I did.

sections = {
    ...
    lualine_x = {
        '%S', ...
    },
    ...
}

Strangely, this only works when combined with vim.o.showcmdloc = "statusline" and vim.o.showcmd = true, which confuses me as I can't tell if it's neovim writing the component or lualine. I would expect Lualine to handle the component logic internally somehow instead of neovim, but I digress.

With all of that set, the component shows up and works, but theres two issues:

  1. The component renders (with the separator) regardless of whether or not there's any unfinished commands.
  2. It flickers a lot. i.e., the component picks up almost every j/k/w/b etc very briefly, which gives the appearance of flickering. The default neovim showcmd component in the bottom right of the cmdline does not do this whatsoever (I compared with nvim --clean).

I tried to think of alternative ways of querying the showcmd information natively through some api call, but I could not figure anything out.

If you have any idea of what I might be doing wrong with my setup, or what I could do to make it work properly, I would greatly appreciate the help. Thanks so much for your work and the amazing plugin! (p.s. here's the full file' in my dots if it helps.)

shadmansaleh commented 8 months ago

You can try this one, not sure if this still works or not.

https://github.com/nvim-lualine/lualine.nvim/issues/868#issuecomment-1287756771

also folk said noice had a statusline component that did a similar thing.

For vim stl components we pretty much don't do anything to them and let them pass. The statusline renderer renders them when rendering the complete statusline. So anything you can say about it's behavior pretty much falls under how neovim wants to show that behavior. Using %S without lualine should have exact same behavior.

I don't exactly know why %S only works with showcmdloc = statusline. You'll have to ask someone who implemented it or was part of the discussion. Kind of seems weird to add a new option for that. Maybe rendering performance had something to do with that who knows ¯_(ツ)_/¯

BvngeeCord commented 8 months ago

Hi, sorry for the delay!

#868 (comment)

Your comment in that thread shows both (what seems to me like) a hacky-temporary-workaround as well as a potential implementation for exposing showcmd info for use in the statusline. It also linked to a commit with a comment by bfredl who considered doing just that, and since that comment doesn't exist anymore in master, I wanted to find if anyone did.

After a fair bit of searching I found that this neovim commit removed his comment, which also happens to be the commit that added showcommandloc. ( turns out it corresponds with this vim issue which is where they discuss why they wanted a showcmdloc option in the first place, if you're interested in reading :p). That neovim commit added the %S stl component, very similarly to how you proposed it in your original comment. So, assuming I got all that correct, the hacky-workaround shouldn't be necessary anymore, as %S is how it's "officially" supported (and I'd rather try to report if there's a problem with the official solution than use a workaround).

As for why the flickering happens, I do agree that it's likely not lualine. But after trying to confirm what you said ("Using %S without lualine should have exact same behavior"), there's no visible flickering. I suspect somehow one of my plugins is interfering, because:

...but I'm not quite sure yet. It also seems to be more noticeable in certain filetypes, so maybe it has to do with perf? I'll keep looking into it when time allows. Thanks for the help so far <3

trevarj commented 5 months ago

An observation that I made is that when adding { "%S" } as a component to my lualine, I actually see my movement commands (h j k l). They instantly get cleared (flickering). When I do nvim --clean and set the statusline as mentioned above, I don't see these keys at all. Maybe it's happening too fast with the native statusline, small files, and no plugins.

After messing with the nvim code for a bit, I think it's because clear_showcmd() gets called after every normal mode command (see normal_end: in normal.c).

In other words, I don't think the intended behavior is to display the previous command, like how noice.nvim does it, even though I wish this was the case.

showcmd_flicker.webm