microsoft / terminal

The new Windows Terminal and the original Windows console host, all in the same place!
MIT License
94.88k stars 8.22k forks source link

Feature Request: Show character under cursor when cursorShape is set to filledBox #1203

Closed cheuk-fung closed 4 years ago

cheuk-fung commented 5 years ago

Summary of the new feature/enhancement

When cursorShape is set to filledBox, it hides the character under it: image (The command is cat /etc/os-release)

This is a bit annoying. It will be helpful if the character can still be visible when the cursor is moved to its position.

DHowett-MSFT commented 5 years ago

It's a good idea. Naively doing this will break up ligatures under the cursor, but perhaps that is desirable!

johnmcdowall commented 4 years ago

As a big Vim user this one is annoying me enough that I've had to switch to Hyper. Raised an issue in #3241 but closed it in favour of this one. Otherwise everything worked pretty great!

zadjii-msft commented 4 years ago

Adding to this discussion from #3322, since we should probably include all these scenarios:

Also relevant: #1356, which tracks a similar request in conhost (not the terminal).

Jkoutsoumpas commented 4 years ago

Configuration of this will be great, but the most important and easy fix for now would be to just display the underlying character negative. That will make it at the very least usable, until the added configuration is implemented.

skuridin commented 4 years ago

Maybe allowing to change the cursor opacity can be a solution for now?

krage commented 4 years ago

I'd like something along the lines of cursorForegroundColor, defined in colorschemes/profiles, describing the color of the character under the cursor as a complement to the existing cursorColor.

cairijun commented 4 years ago

For those frustrated vim users, changing OPACITY_OPAQUE to 0x7F000000 should somewhat mitigate this issue. Drawing the character on top of the cursor might be a better solution but it doesn't seems trivial. https://github.com/microsoft/terminal/blob/64ac0d25e04834391598775f3aced6856cb59257/src/renderer/dx/DxRenderer.cpp#L1454

hanxi commented 4 years ago

For those frustrated vim users, changing OPACITY_OPAQUE to 0x7F000000 should somewhat mitigate this issue. Drawing the character on top of the cursor might be a better solution but it doesn't seems trivial. https://github.com/microsoft/terminal/blob/64ac0d25e04834391598775f3aced6856cb59257/src/renderer/dx/DxRenderer.cpp#L1454

image

DHowett-MSFT commented 4 years ago

Notes from @nj-ms:

Description of the new feature/enhancement

Unless I'm mistaken, Windows Terminal configuration supports just the cursorColor setting, which functions as if I've set both the foreground and background colors to the same color. Other terminal programs (Alacritty, ..., ?) support configuration of the cursor foreground color and the cursor background color, and/or they respect the foreground color setting and the character shows through the cursor. For example, I'd like to set the background to black (#000000), foreground to white (#ffffff), the cursor background to magenta (#990099) and the cursor foreground to white (#ffffff). This way, I can still see the character under the cursor. This is especially annoying, for example, if I'm in a Linux WSL and vim'ing a file. This modification is also important in relation to #1379.

Proposed technical implementation details

  • Make the current cursorColor setting continue to set both foreground and background colors.
  • Add a cursorBackground setting to set just the background color; should use cursorColor by default.
  • Add a cursorForeground setting to set just the foreground color; should use foreground and/or cursorColor by default. It might also work to just use the foreground color and make the character show through the cursor, with the drawback that it's slightly less configurable.
yzlnew commented 4 years ago

Can we just reverse the foreground and the background color of the text under cursor like what gVim does? image image

johnmcdowall commented 4 years ago

@DHowett-MSFT Is there any chance we can get the simple case fix that multiple people have suggest above?

Yes, it would be great if this could be configured and what not, but I think there's a large group of Terminal users who would just be thankful for a basic fix as outlined above https://github.com/microsoft/terminal/issues/1203#issuecomment-598002624.

DHowett-MSFT commented 4 years ago

If it were trivially possible with our renderer set up the way it is, I'd say yes. This close to our signoff date, though, I'm a bit concerned about that. ☹️

johnmcdowall commented 4 years ago

@DHowett-MSFT I'm not sure I understand.

In the comment I linked to a solution is presented that requires changing one flag in an existing call from OPACITY_OPAQUE to 0x7F000000: https://github.com/microsoft/terminal/blob/64ac0d25e04834391598775f3aced6856cb59257/src/renderer/dx/DxRenderer.cpp#L1454

While not perfect, the change seems to involve changing 14 characters, and it seems to at least let the character be seen in most cases. Others have confirmed this above.

Maybe I'm completely misunderstanding, but this seems like the literal definition of a trivial change that has useful impact today? If you want someone to PR it I'm happy to do so.

johnmcdowall commented 4 years ago

@DHowett-MSFT Just to clarify - I understand and appreciate what you're saying about being close to 1.0, and I really appreciate all of the work you and the team are doing for Terminal. If it wasn't for you folks and this project I'd still be stuck in the Apple ecosystem.

hanxi commented 4 years ago

I think this is a bug, not a feature for console/tty/terminal. Need Make it usable before optimizing. image image image

mwyvr commented 4 years ago

An illegible filled box is not a feature it's a bug. It's about the one thing I have found problematic with Windows Terminal; in general Terminal has been well behaved and the configuration capability was a delight to discover.

A number of color terminals allow end-applications to set colors independently - vim is an example, when paired with the right terminal. That's probably a feature set too much to ask for, so being able to tune the FG/BG colors would be enough. Some of us can't live without our filled boxes - they make spotting location much easier in a big page of text. Granted the opaque ones fill that need but seeing the character underneath is a must-half. Cheers.

cmcpasserby commented 4 years ago

I consider this a bug, all characters on screen should be legible. Also this is not even a problem in the basic cmd terminal. The behavior Windows terminal currently shows for this does not exist in any other Windows, Linux or Mac terminals i have seen.

AundreL commented 4 years ago

I would like to start by saying that the overall experience of the terminal from installing in the Microsoft Store to the tabs all are wonderful but this is a serious issue that ruins the entire WSL experience. There is no way for someone to practically use the terminal with editor like vim/neovim/gvim. I am disappointed that this has been open for almost a year now, I do not feel this is getting the response from the maintainers. With great regret, I am going to have to switch to another open-source terminal, hopefully, this will get resolved quickly so I can return to this wonderful terminal.

zadjii-msft commented 4 years ago

I am disappointed that this has been open for almost a year now, I do not feel this is getting the response from the maintainers

https://github.com/microsoft/terminal/issues/1203#issuecomment-622045617 DHowett-MSFT 21 days ago

We're pretty actively looking into it. It's unfortunately not trivial to just implement, because the right solution isn't just "paint the cursor at half opacity". I'd rather not stick in the wrong behavior temporarily while we're working on the right behavior.

The real problem here is that the cursor is drawn in our renderer after the text is, so it's always painted on top. @DHowett and I discussed a bunch of options here, but none of them were trivial changes to sneak in right before a major release.

Now that we're past 1.0, we'll be coming back to see which of the options we discussed is the best. Hence why it's on our "v1.x" milestone, the generic "we want to get to this ASAP after 1.0" milestone.

johnmcdowall commented 4 years ago

@zadjii-msft Appreciate the thought and effort you and @DHowett and the rest of the team are putting towards this issue.

That said and by way of explanation of why we're being so annoying about this issue, I don't think anyone in this thread proposed the 0x7f hack as the right behaviour, simply that it would be implementing a working fix today over something that is completely broken.

Maybe you don't encounter this frustration because y'all are using VSCode as your daily drivers - but for the large contingent of terminal based editor users out there this bug is frustrating on a daily basis, and that's why we'd push for a working but temporary fix today over a perfect and right fix however many more months away.

To add some personal context, now that Apple have fixed their atrocious keyboards this year, I'm considering moving back to OSX because it would remove this daily and constant source of frustration as I try to work everyday. That's how annoying I find this issue.

EDIT: And I am particularly galled by this whole thing when I think about the fact I can turn on retro-style CRT effects, which literally no one asked for, but I can't reliably edit text in Vim.

hanxi commented 4 years ago

I use filledBox in vim/bash/tmux every day, So I use 0x7f hack build it for myself now. But I don't want build every time when update. I support merge this hack before right solution come.

zadjii-msft commented 4 years ago

Okay I'm putting together a more formal spec now, but here's the important bits:

We could try drawing the cursor first.

We're going to draw the cursor in two phases - a pre-paint and a post-paint. All the other renderers will just return S_FALSE from the cursor pre-paint phase automatically - we absolutely don't need to implement it for them.

We'll introduce cursorTextColor as a setting that accepts the following values:

null is effectively the behavior we have now. I'm proposing we move the default for all profiles to textForeground.

So, for this new setting, we get the following scenarios:

cursorShape cursorTextColor cursorColor Break Ligatures? Pre-draw cursor character color post-draw cursor Result Notes
FilledBox #rrggbb
FilledBox null #rrggbb FALSE N/A cell FG #rrggbb Solid box of #rrggbb Current behavior
FilledBox #r2g2b2 #rrggbb TRUE #rrggbb #r2g2b2 N/A Box of #rrggbb with character in #r2g2b2 on top
FilledBox textForeground #rrggbb FALSE #rrggbb cell FG N/A Box of #rrggbb with character in (text FG) on top Proposed Default
FilledBox textBackground #rrggbb TRUE #rrggbb cell BG N/A Box of #rrggbb with character in (text BG) on top
Vintage
Vintage null #rrggbb FALSE N/A cell FG #rrggbb ▃ of #rrggbb on top of char in (text FG) Current behavior
Vintage #r2g2b2 #rrggbb TRUE #rrggbb #r2g2b2 N/A ▃ of #rrggbb with character in #r2g2b2 on top of ▃
Vintage textForeground #rrggbb FALSE #rrggbb cell FG N/A ▃ of #rrggbb with character in (text FG) on top of ▃ Proposed Default
Vintage textBackground #rrggbb TRUE #rrggbb cell BG N/A ▃ of #rrggbb with character in (text BG) on top of ▃
Vertical Bar
Vertical Bar null #rrggbb FALSE N/A cell FG #rrggbb ┃ of #rrggbb on top of char in (text FG) Current behavior
Vertical Bar #r2g2b2 #rrggbb TRUE #rrggbb #r2g2b2 N/A ┃ of #rrggbb with character in #r2g2b2 on top of ┃
Vertical Bar textForeground #rrggbb FALSE #rrggbb cell FG N/A ┃ of #rrggbb with character in (text FG) on top of ┃ Proposed Default
Vertical Bar textBackground #rrggbb TRUE #rrggbb cell BG N/A ┃ of #rrggbb with character in (text BG) on top of ┃

I omitted underscore, emptyBox because they're just the same as Vertical Bar

I think I can break this into 3 PRs:

  1. The first would simply move the Terminal to use "cursorTextColor": "textForeground" by default. This won't introduce the setting or anything - merely change the default behavior silently so the character appears on top of the cursor.
  2. The second would actually introduce the cursorTextColor setting, accepting only null or textForeground. This will let users opt-in to the old behavior.
  3. the third would introduce the #rrggbb and textBackground settings to the cursorTextColor property. This is left as a separate PR because these involve manually breaking runs of characters on the cell where the cursor is, which will require some extra plumbing.

I'd want to get both 1&2 done in the course of a single release. Ideally all 3 would be done in the course of a single release, but if only the first two are done, then at least users can opt-out of the new behavior.

I'm cleaning this up for a formal review. The code for 1 is trivial, and already written. The biggest delay now is there's a long weekend before the team will be in the office to review 😄

johnmcdowall commented 4 years ago

@zadjii-msft Looks awesome, thanks for getting this together and moving us all closer to a rockin' terminal!

rohitkrishna094 commented 4 years ago

For anyone who want a quick fix right away, use this until this feature gets deployed.

"cursorShape": "emptyBox"

When I go into insert mode, my cursor goes to bar. While in normal mode, I just let it be emptyBox for now.

cmcpasserby commented 4 years ago

@rohitkrishna094 yeah that's a odd one, for regular vim, that works but neovim seems to have some way to change the cursor. Though find it makes it confusing for me doing empty box, since on my other machine with iterm2 it uses the empty box for when its not in focus

j4james commented 4 years ago

@zadjii-msft FYI, I had a look at how other terminals handled cursor colors a while back, and I think your proposed solution might not cover some of the common approaches I've seen used.

  1. When no color has been specified, one of the most common defaults is to render a box cursor with the text foreground color, and the character on top of it using the text background color. For an underline cursor (any non-box cursor really), both the cursor and character would be rendered with the same text foreground color, These defaults are essentially the equivalent of the reverse video attribute and the underline attribute, which is actually how the early terminals rendered a cursor.

  2. When a cursorColor has been set, there's a fair bit of variation in what is used for the character color of the box cursor. Personally I think the text background color makes the most sense, but as long as we have all the options I think we're good. My only concern is that the cursorTextColor should only apply to the box cursor - the underline cursor never changes the character color as far as I've seen (the one exception to this would be a per-pixel color inversion cursor, but that's an entirely different concept).

So what I think we might be missing from this proposal is a way to set the cursorColor to textForeground rather than a specific rgb value. And also the ability to set the cursorTextColor, but only have it apply for the box cursor (possibly also the vintage cursor depending on the size, but that's a more complicated issue).

pianocomposer321 commented 4 years ago

@zadjii-msft so I gather that this will (hopefully) be part of the v1.1 release. What is the release date for v1.1, or when can I expect this feature/bug fix/whatever it's being called now to be released?

zadjii-msft commented 4 years ago

As much as I'd love to, I can't really commit on an official date for 1.1, or if this fix will be able to make it for 1.1. We're tracking the work in this thread, in the spec over in #6151, and also in #6224, which I think we'll need in addition to what I've outlined above. When this issue is closed, you'll know that the fix will be available in the next release.

behlakhil commented 4 years ago

Thanks guys for looking into this. I'm in the same boat as the other vim-users. I've tried both emptyBox and vintage but it still happens that I lose the cursor. In any case, maybe this helps someone too: https://vim.fandom.com/wiki/Highlight_current_word_to_find_cursor

zadjii-msft commented 4 years ago

Okay, some progress here:

textAboveCursor

Or for more contrast:

textAboveCursor002

As Dustin called out in the spec over in #6151, I had forgotten that that text background is drawn in the same step as the text foregrounds. So I think this needs to be 4 PRS now:

  1. Separate FG and BG rendering, so they happen in separate steps.
  2. Default the dx renderer to "cursorTextColor": "textForeground" (step 1 above)
  3. Introduce the cursorTextColor setting, accepting only null or textForeground (step 2 above)
  4. Introduce the #rrggbb and textBackground settings to the cursorTextColor property (step 3 above)

1 is a tricky PR, because I want to make sure I don't do double the work. 2 is trivial, 3 is basically trivial, and 4 is a pain to say the least. Fortunately, I think getting to 3 will solve the 99% use case here.


re:

So what I think we might be missing from this proposal is a way to set the cursorColor to textForeground rather than a specific rgb value.

We could probably make cursorColor: null mean this. That seems like a sensible default.

ghost commented 4 years ago

:tada:This issue was addressed in #6337, which has now been successfully released as Windows Terminal Preview v1.1.1671.0.:tada:

Handy links:

ghost commented 4 years ago

:tada:This issue was addressed in #6337, which has now been successfully released as Windows Terminal v1.0.1811.0.:tada:

Handy links:

habamax commented 4 years ago

Thank you! I have just run vim and suddenly I can see under the cursor:

image

DHowett commented 4 years ago

There’s still a couple limitations; we’re just drawing the character on top of the cursor in whatever color it would have otherwise been rendered in. We’re tracking a spec and eventual implementation of “better cursors” in #6151

pianocomposer321 commented 4 years ago

@DHowett yeah, I probably won't be using Microsoft Terminal until this feature is fully implemented in the way you are describing.

nickjj commented 3 years ago

Text is still very hard to read with a lot of Vim themes.

For example here's a screenshot using Gruvbox:

image

And another using Vim One:

image

I left the text size as my normal editing size because if I zoom it by 500% then it's easier to read but that's not how most folks will work in practice.

But for comparison, here is what wsltty looks like (another WSL terminal):

image

I didn't have to set anything special to make this work. It just auto-calculates the contrast and flips the foreground text under the cursor to be something that's always very readable.

I know work is being done towards supporting this in the MS terminal, but so far there hasn't been much discussion around what a high contrast solution could look like. When you compare these 2, I don't think it's really safe to say you can use the block cursor with the MS Terminal yet despite this issue being closed.

pianocomposer321 commented 3 years ago

@nickjj Here's a screenshot of what mine looks like with Gruvbox: image For me, it was a matter of setting the right color. The one I'm using now is #7C6F64.

But I totally agree that more work still needs to be done on this. I much prefer the way that wsltty does it (draw the cursor the same color as the foreground and the character under the cursor the same color as the background).

psxvoid commented 3 years ago

The cursor in bash with vim-mode enabled looks even worse without any theming:

image

Can you even guess what is hidden under the cursor?

P.S.: the screenshot is taken on the latest Windows 10, Terminal Build: 1.4.3243.0, Ubuntu 18.04.5 LTS When I'm working in a terminal, I'm looking at the cursor 90% of the time. And this thing drives me crazy.

Just in case anyone thinks that I deleted "o" under the cursor, here is the animation, feel the pain: record

ElSamhaa commented 3 years ago

Why is this closed? I think we've missed the essential solution to all this hassle, which is implementing cursorTextColor.

n1ghtmare commented 3 years ago

I've been using WSL for a while and it's been great, but using nvim with this issue still pending is at times unusable. Other terminals are not having this issue (see ConEmu or Hyper for example). I hope this issue gets re-opened.

zadjii-msft commented 3 years ago

This is closed because #6337 fixed the general issue of "draw the filled box underneath the character". That solved the 99% use case where the text color and the cursor color aren't an exact match. You've got a point, it doesn't address "what to do when the cursor and text are the exact same color".

6337 ended up being dramatically simpler than what I had started in https://github.com/microsoft/terminal/issues/1203#issuecomment-638226208. That path ended up with doubling the amount of work to render each row, and weird logic to try and break runs on the cell where the cursor was.

6151 also never got updated to reflect the solution that we started with, and the issues that spec had never got resolved. Since this was largely fixed by changing either the foreground or cursorColor, there hasn't been much impetus to sort out the remaining issues.

I know @DHowett at one point was working on a multipass renderer that did backgrounds then foregrounds and it wasn't insane, but again, that's moved way lower in the backlog. Did we have another issue open tracking that line of work? We should probably open a new thread for the remaining cursorTextColor ideas I had, as well as fixing "what to do when the cursor and text are the exact same color"

nickjj commented 3 years ago

I'm with @n1ghtmare on this one. Most syntax highlighting colors in Vim have a wide array of colors that very much clash with the cursor color when the cursor color isn't able to be swapped to a contrasted color dynamically. This has been demonstrated in the few screenshots I uploaded before. It affects everyone using terminal Vim or another terminal based text editor.

I know @pianocomposer321 said to pick a better color for the cursor but this doesn't make a difference in the end. If he adjusted his screenshot to be over a comment instead of the self keyword then the comment's character under the cursor would be invisible. Also in his current screenshot the contrast is very low, it would certainly not be good enough for a video recording or giving a talk.

As good as the MS terminal is, I still tend to use wsltty (which dynamically sets its cursor color based on contrast calculations) in my day to day because having a block cursor in terminal Vim is much better than the vintage cursor in the MS terminal. Not just from a legibility POV, but it allows you to configure Vim so that your cursor shape changes from the block cursor to a line cursor depending on if you're in normal or insert mode.

DHowett commented 3 years ago

Yeah- I do think that we should reactivate this or track the followups somewhere. Sorry we lost it in all the shuffling around.

n1ghtmare commented 3 years ago

Further to what @nickjj setting the cursor to vintage (or any other style for that matter) doesn't work with neovim, not sure why, but once you start nvim it sets its own cursor style, I've tried it from 2 different machines.

If someone finds a temporary solution to this problem, please do share!

krage commented 3 years ago

@n1ghtmare If you clear the default guicursor value during init then neovim won't touch cursor shape, eg. nvim -c "set guicursor=". More details in :h guicursor.

DHowett commented 3 years ago

Followup: #9610 I've migrated a couple of your comments over. Sorry for the delay, it's been busy here.

weibeld commented 1 year ago

Is this still not fixed? I think there should be a cursorTextColor attrribute in the colour scheme that allows setting a cursor text colour matching well with the cursorColor. That's for example how it is solved in iTerm2:

unnamed

A consideration is that cursorTextColor should only be applied for Filled box cursors, for all other cursor types, the text colour shouldn't change. So, maybe the attribute could also be named cursorFilledBoxTextColour or something to make this clear.

DHowett commented 1 year ago

Is this still not fixed?

This is fixed in the new rendering engine shipped as part of 1.18. The parts of the text occluded by the cursor automatically display in a contrasting color. It's been a few years, and I need to page back in why this was kept separate from #9610...

zadjii-msft commented 1 year ago

I need to page back in why this was kept separate

I too have not paged this back in yet, but IIRC there was a collection of related issues:

again, long since paged this out 😕

notes:

DavidTelenko commented 7 months ago

It could be implemented similar to how alacritty does it, just by inverting the foreground and background colors. Just suggesting) image