-
Notifications
You must be signed in to change notification settings - Fork 374
Make whitespace inside selections visible #397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make whitespace inside selections visible #397
Conversation
@microsoft-github-policy-service agree |
Have you seen #188? I described there that we can't really use U+00B7 Middle Dot (·). |
No, sorry, the issue didn't mention any of the usual words I'd expect such as "render" or "whitespace", so a quick search didn't return anything and I just jumped into coding. It's quite a lot thicker for the default Cascadia Mono font of the Windows Terminal, but then again also very visible if we'd only render them inside of the selection: There's another option of U+2E31 that I've seen in https://github.com/microsoft/vscode/blob/c2c80e903fd500914164d1a45a57a52ccf99369f/src/vs/editor/browser/viewParts/whitespace/whitespace.ts#L158 Personally I always have them rendered with the "all" setting in VSCode and never even realized that the default option is "selection". Screen.Recording.2025-06-03.135816.mp4Implementing blending of whitespaces with the selection's bright blue color would require to check chars 1 by 1 inside of the selection logic. For now I have 3 questions then, @lhecker:
|
1123a3a
to
9679e1e
Compare
I've kept playing around with the code and got to something I find usable. In order to not have to keep track of coloring and hiding the text as I for some reason assumed I had to do when I asked my questions (didn't want to let go of my initial code lol), I create a second line with rendered whitespaces in parallel to the line that is rendered by default. This does sound a bit crazy space-wise when I think about it, but I think I ran out of any other ideas. If this seems like something usable, I'm ready for feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While the overall approach is quite alright, I'm not yet happy with the performance and compactness aspects of this PR. For instance, the replace()
call defeats the purpose of the arena allocator.
The char_indices
code is incorrect, because logical coordinates are in grapheme clusters, and not in codepoints.
The way I would do it is by first building the line
as it's currently done. Then, within the selection code, I would build up an entirely separate copy of line
where spaces/tabs are replaced with visualizers. Once that's done, we can replace the original line
with the copy.
Within this logic we'd be searching for spaces/tabs to replace, so we can also use this opportunity to change the foreground color right then and there before writing the text.
Moving the scratch_area
call into the outer loop may help with all that.
I can help with these changes later, if I have time. 🙂
…endered and update color
…other characters with tabs
Instead of making a new This works perfectly and I don't feel like I did any dirty workarounds this time. There are issues with the Word Wrap in conjunction with tabs in the main branch that I've noticed as of 1.0 release, but never got to report though. Now raised in #479 This bug also kills any rendering around the broken lines: 2025-06-14.02-36-14.mp4 |
I've rewritten your PR quite significantly. Your previous approach wasn't necessarily worse than the new one, it's just that this approach is shorter. It also ties into another problem that I needed to solve: #34. I figured by rewriting it like this I can kill two birds with one stone. |
Thanks @pheonick for the first pass at this! |
Thank you guys, sorry I forgot to press the Submit Review button after taking a look and testing the changes a few hours ago. |
I was trying to click into the comment field while I was pushing a commit in the background. This caused the page contents to shift, and I clicked the "Close PR" button... 😅 In any case, thank you for reviewing my changes! I reverted it back to a version you suggested. 🙂 |
src/buffer/mod.rs
Outdated
|
||
// The start of the selection is within this line. We need to update selection_beg. | ||
if selection_beg <= cursor_end.logical_pos | ||
&& selection_beg >= cursor_beg.logical_pos | ||
{ | ||
cursor = self.cursor_move_to_logical_internal( | ||
cursor, | ||
Point { x: selection_beg.x.max(origin.x), y: selection_beg.y }, | ||
Point { x: selection_beg.x, y: selection_beg.y }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this just...
Point { x: selection_beg.x, y: selection_beg.y }, | |
selection_beg, |
src/buffer/mod.rs
Outdated
@@ -1776,18 +1775,18 @@ impl TextBuffer { | |||
{ | |||
cursor = self.cursor_move_to_logical_internal( | |||
cursor, | |||
Point { x: selection_end.x.min(origin.x + text_width), y: selection_end.y }, | |||
Point { x: selection_end.x, y: selection_end.y }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ut supra selection_end
Works perfectly both as is and with suggestions above applied. |
This being my first open source PR I'm not fully equipped with the proper etiqutte in such small review update cases, so I took it upon myself to push the review fixes, sorry if I'm stepping on @lhecker's toes here. |
I think it's a lot ruder for me to push into your PR. You're definitely not stepping on my toes. 😄 |
One day I'll add autofmt on file save, embarrassing... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yall are the best. Thank you :)
FYI: Long-term I think that this code will probably move into |
As a console editor user I often need to see spaces and tabs visually.
Added View->Toggle Render Whitespace checkbox menu option.
Added localizations, borrowed from https://github.com/microsoft/vscode-loc.
All new functionality is only executed if the toggle is enabled.
Any suggestions are welcome.
Closes #34