onivim / oni

Oni: Modern Modal Editing - powered by Neovim
https://www.onivim.io
MIT License
11.35k stars 301 forks source link

Draw underlines and undercurls from NeoVim. #1931

Open Himura2la opened 6 years ago

Himura2la commented 6 years ago

I had a spellchecker configured in my Neovim-Qt, and Oni does not underline the spelling errors in my markdown files. While the ]s works.

image

By the way, it is super impressive how smoothly Oni merged my init.vim with plugins and statusline. I didn't even notice when it started using my init.vim. Amazing work. Thank you.

oni-bot[bot] commented 6 years ago

Hello and welcome to the Oni repository! Thanks for opening your first issue here. To help us out, please make sure to include as much detail as possible - including screenshots and logs, if possible.

akinsho commented 6 years ago

@Himura2la thanks for the kind words its largely thanks to the v. hard work of @bryphe.

Regarding the underline issue unfortunately this relates to the fact that we are currently not drawing the underline highlights that neovim sends us, its an outstanding bit of work we need to look at completing.

I had a look in #1203 but didn't get round to finishing it but I think this issue might be a good place to track this bit of work.

Urooj-786 commented 6 years ago

good

bryphe commented 6 years ago

Good call @Akin909 - we can use this issue to track rendering the underline highlights 👍

CrossR commented 6 years ago

This is pretty odd, but I've just realised that spelling is highlighted fine in onedark but not in nord.

image image

Not sure if that is due to my config, but a friend is using Oni for latex and he gets spelling highlights in onedark too.

bryphe commented 6 years ago

Nice find, @CrossR ! That is weird... I wonder if it is a bug with the theme, or something we're doing wrong on the Oni side?

CrossR commented 6 years ago

To duplicate something I've mentioned over in #2308, as far as I can tell this is due to onedark not using underlines for spelling, which mean its surfaced fine.

nord uses underline which Oni currently does not draw, meaning we get no spelling highlights.

CrossR commented 6 years ago

This isn't a fix, more a work around until we work out how to do the underlines and undercurls in WebGL....but I'm now using this in my init.vim to get around this:

https://github.com/CrossR/dotfiles/blob/229f0db8eb6567abcde5f99ae43efa7d927b0b90/neovim/.config/nvim/init.vim#L509-L524

That is, I clear out the current colour scheme config for spelling mistakes and link them to some I know work with just colouring and bold. I call that function in the activate part of my config.tsx so its run when I start Oni. Less a fix and more a workaround.

It should be colour scheme independant since I picked pretty general things to link to, but I've only tested in gruvbox.

End result:

image

SpellBad in red, and capital/local issues in yellow, orange for rare spellings.

00sapo commented 6 years ago

Underline is also needed to highlight the current word (and the current line too) as in VSCode/Eclipse/IntelliJ etc. We can still use some highlight, but being able to use the underline would be great because most of the vim/nvim plugins for "current word" highlighting also provide options to use the underline instead of the highlight (through a highlight group).

Moreover, I would suggest adding this feature as default in Oni. Should I create a new issue?

Examples: vim-illuminate, vim-quickhl, vim_current_word, autohighlight etc.

CrossR commented 6 years ago

I think this issue is being used to track the adding of underlines and undercurls, so I'll edit the title to reflect that.

When I had a look into this, it looks like the underline information is all there, the undercurl is easily added by just copying a few properties. The hard part is actually drawing those lines/wavy lines.

For the non-WebGL renderer that is assumedly pretty easy? But when I looked into the WebGL side, I couldn't really find anyone talkinga about how it is implemented, outside of over the top looking libraries. Perhaps this is something @Cryza has some more information on/may change with the ligature changes.

manu-unter commented 6 years ago

I think there are many levels of underline support that we can achieve. Something along the lines of these iterations may make sense:

Stuff we can do with the existing information from Neovim

  1. Draw underlines on cells that have the underline flag set. Same color as the character and a simple, straight line, maybe even with a font-independent, fixed position in the cell
  2. Use information from the font file that we read using font-manager and fontkit to position and scale the underline thickness according to the font parameters
  3. Use techniques similar to what http://underlinejs.org/# does to create gaps in the underline around descenders and to align the line with pixel boundaries

Stuff we might need a wider interface to Neovim for

I'm not sure if neovim already publishes all the information we need here and I also don't know where exactly I'd need to look to find out. @CrossR , do you have an idea about that?

General considerations

In general, both our renderer use fillText on canvases for drawing the characters. Unfortunately, fillText does not provide an option for drawing underlined text. That means we need to do it manually using lineTo instead. It also means everything that goes beyond a regular straight line will be as complex as manually defining the points that a squiggly, undercurl etc. should follow and drawing arcs, bezier curves, or whatever makes sense to actually make them happen.

On the good side, I think we can use a similar technique for drawing the underlines in both the WebGL and the Canvas renderer. Both use a software renderer to draw the actual characters, so we "only" need to add the logic for also drawing the underlines there. Then the canvas renderer could use the underline logic for drawing to the buffer canvas while the webgl renderer uses it to create glyph variants containing underlines and renders them to the atlas.

CrossR commented 6 years ago

I'm not sure if neovim already publishes all the information we need here and I also don't know where exactly I'd need to look to find out. @CrossR , do you have an idea about that?

I can check again, but I think for the undercurl, I just copied and pasted a few bits of the underline code and it was fine. I think the information is passed over at the same time as the underline information is, we just throw it away.

As for colours, I'm not actually sure... When I'm looking at plumbing the undercurl in, I'll see if there is any styling colours.

CrossR commented 6 years ago

:help ui-event-highlight_set contained everything, which we are already listening for.

I'm sticking up a PR to do the plumbing through of the undercurl and special, such that the ICell contains them, like the foreground/background colour, as well as the bold/underline etcetc.

manu-unter commented 6 years ago

I'm sticking up a PR to do the plumbing through of the undercurl and special, such that the ICell contains them, like the foreground/background colour, as well as the bold/underline etcetc.

Great! I'll try to get the ligatures thing done and afterwards I'll try to do the underlines and undercurls then. :) Drawing them in special color might require some interesting additional logic though 🤔 , at least for the WebGL renderer.