Add alternate styling to render window in-buffer using virtual lines
Hi @AckslD,
Really cool plugin 🚀 . I saw the initial announcement and someone suggested this idea which seemed really cool, but didn't raise an issue for it, so I thought I would to see what your thoughts are on it. I think it would be a really nice workflow/UI if rather than a floating window with a border the window overlaid the code block (if possible, could just be beneath if it is not multiline), and using virtual lines it expanded the buffer, so you could edit it as though it were part of the buffer.
I'm not sure if there are complex edge cases to consider here, but thought I'd raise it officially
Hi @akinsho :) Thanks!
I think this would be really cool indeed! I quickly tried some things but would need to investigate a bit more how to do this. If you have ideas feel free to let me know. Here's a quick test of how it would look when the window overlays only the code block:
https://user-images.githubusercontent.com/23341710/189848520-f7994c95-16f4-4cad-b44e-7548eb1f373c.mp4
Two things I'm directly unsure about:
- How to take into account the sign-column to know at which column of the window the floating window should be. Maybe instead of using
relative = 'win'one could dorelative = 'cursor'but subtract the cursor column (to find the start of the buffer) and add the column of the code-block within the buffer. - How to automatically scale the floating window (and then also update the underlying buffer)? Both the width and the height. For width maybe
WinScrolledcould be used somehow? Not sure if there is an event when the text reaches the end of the window. What did you mean with using virtual lines?
@AckslD that looks cool tbh I hadn't even been really thinking of inline ones, but that makes sense and looks quite nice. I was thinking primarily/additionally of multiline code blocks and what I meant re. virtual lines is that you can create extmarks that use the virt_lines options and what that does it insert "virtual" line i.e. fake lines into a buffer so that basically the content of the buffer will be moved down, so the window won't actually obscure buffer content it will just cover the virtual lines.
Check :help nvim_buf_set_extmark and look for virt_lines and try it out.
Regarding window dimensions and detecting changes, maybe it's worth using a decoration_provider these are run every time there is a change for the buffer, depending on certain callbacks worth looking at nvim_set_decoration_provider. From inside one of those callback, you can keep track of changes in the buffer and tweak the window dimensions as needed, I think.
Thanks a lot for the pointers @akinsho! I'll take a look at this, but might take a bit of time :)
Anyway, feel free to try something out if you feel like as well. I think it should be possible without changing any code of the actual plugin since there are the config settings:
-
float_opts: which compute options for the window given the code-block's range, lines, and lang -
prepare_buffer: takes the output fromfloat_optsand prepares a buffer and returns the window number