Skip to content
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

FR: IDE-style marks on scrollbar #1527

Closed
mcpiroman opened this issue Jun 24, 2019 · 20 comments · Fixed by #12948
Closed

FR: IDE-style marks on scrollbar #1527

mcpiroman opened this issue Jun 24, 2019 · 20 comments · Fixed by #12948
Labels
Area-Extensibility A feature that would ideally be fulfilled by us having an extension model. Area-User Interface Issues pertaining to the user interface of the Console or Terminal Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.

Comments

@mcpiroman
Copy link
Contributor

Summary of the new feature/enhancement

Introduce marks and indicators on scrollbar:

1. Command seperators / prompt positions

  • Program runs and you want to see how long the current output is. You can look at scrollbar and see where is the last command marker.
  • You run gcc --help=common that prints ~900 lines of output, and you know the interesting switch is somewhere in the middle. By viewing the command's input line position you can easily navigate to that location.
  • You are running well-known batch script and want to know current state. You can look at scrollbar to count number of commands that has already run or even notice that second command has abnormally big output.
  • Just helps with navigation over previous command.

2. Selection span

  • Not as usefull but nice looking.

3. Colors of text / lines

  • You run some build script that prints errors in red and warnings in yellow. You can leave it running and them just glance at scrollbar to see if there are any issues (and locate them).
  • You run some port scanning script (like this) that prints successful connections in green and unsuccessful in red. Much like above.
  • You run git status that prints everything in green, but then look at scrollbar and see that one, sneeky, unstaged, red line.

Example looks:

Visual Studio IDEA InteliJ
image image

Proposed technical implementation details (optional)

  • This should be controlled by per profile settings
  • When there is one line, say red, surrounded by great number of green lines, that red dot or strip should have some minimum size to ensure it's visible.
  • When only part of the line is colored it should be show the same way as if whole line was colored
  • What if there are two colors on same line?
@mcpiroman mcpiroman added the Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. label Jun 24, 2019
@ghost ghost added Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Jun 24, 2019
@DHowett-MSFT
Copy link
Contributor

Clever feature request, and one we haven't seen before. Thanks!

@DHowett-MSFT DHowett-MSFT added Area-User Interface Issues pertaining to the user interface of the Console or Terminal Product-Terminal The new Windows Terminal. labels Jun 24, 2019
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Jun 24, 2019
@mcpiroman
Copy link
Contributor Author

mcpiroman commented Jun 24, 2019

Technical consideration: Should the scroll bar be implemented as:

  1. ScrollBar as it is now, but with some custom overlay drawings (idk if that's possible)
  2. New control based on uwp primitives (just like the ScrollBar is implemented)
  3. New control based on custom rendering, potentially SwapChainPanel

@DHowett-MSFT
Copy link
Contributor

We've had a "minimap" on our backlog for a while, so this would be a logical extension/step to that. I'm marking this one as backlog. 😄

@DHowett-MSFT DHowett-MSFT added this to the Terminal Backlog milestone Jun 27, 2019
@DHowett-MSFT DHowett-MSFT added Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting and removed Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Jun 27, 2019
@zadjii-msft
Copy link
Member

I'm no XAML expert, but I'd think it'd be possible to put some sort of transparent control over the bounds of the scrollbar, and draw rectangles into that area. We'd have to be careful not to accept any mouse input in that region, but that seems possible to me.

Now here's a question - if we're not doing this "minimap" style, and instead we're just putting little ticks there, how do we determine a tick should be placed? The terminal doesn't know when one command starts or ends, so the shell would have to communicate that to us somehow. Alternatively, we could try a keybinding that the user presses to manually add a tick - though that might not be the best either. Additionally, how would a tick get removed? Could the user click on them to change colors/delete? If so, I'd probably prefer the VS style ticks.

(I'm adding the extensibility tag, since this seems like a good extension case)

@zadjii-msft zadjii-msft added the Area-Extensibility A feature that would ideally be fulfilled by us having an extension model. label Jul 2, 2019
@mcpiroman
Copy link
Contributor Author

I'm no XAML expert, but I'd think it'd be possible to put some sort of transparent control over the bounds of the scrollbar, and draw rectangles into that area.

Yes, but only if it was to draw above the scrollbar. So the marks couldn't go below the thumb or be otherwise integrated into scrollbar. That said, it might be enough.

if we're not doing this "minimap" style

Minimap is another story. This feature just offers quick orientation glance with the benefit that it doesn't require any additional space (assuming that scorllbar is visible). Sublime-style minimap will still be useful.

The terminal doesn't know when one command starts or ends, so the shell would have to communicate that to us somehow.

That's the hard part. It could be done by modifing cmd and powershell to emit some vt sequence or api call at prompt/command start/end, but this wouldn't do for linux shells. Alternatively we can detect the prompt (by emited text, read request, checking if the child-most process is bash or not). This could work for linux shells, but I don't know if wsl would share the process tree information. The problem here is with scripts that use @echo off and potentially with built-in commands like cd.

Alternatively, we could try a keybinding that the user presses to manually add a tick

That seems more like bookmark and yes, I'd like that too.

@lzybkr
Copy link
Member

lzybkr commented Dec 5, 2019

I don't care about the scrollbar UI, but I'd love the ability to easily jump between commands with a key binding and considered adding something to PSReadLine when it was Windows only using the Win32 console apis. That plan quietly died when switching to vt sequences for portability.

It looks like mintty implements a vt sequence for this already: https://github.com/mintty/mintty/wiki/CtrlSeqs#scroll-markers

@jkuebart
Copy link

I would like to strongly support @lzybkr's suggestion and point out that macOS's Terminal.app has a very simple, but effective implementation: When pressing Enter, the current line is automatically »marked«. Visually, this is indicated by little brackets on the side of the line – but that's not the interesting/useful part: subsequently, it's possible to navigate between these lines using Command-↑ and Command-↓, among other things. The marked lines scroll into view, making it very convenient to navigate the terminal's back buffer.

Another really nice feature is Command-Shift-A which selects the text up to the most recently marked line: for example, one can simply type »ls« enter, Command-Shift-A Command-C, which selects the output of the command and copies it to the clipboard.

Proposed technical implementation details (optional)

I have no idea how it could be implemented in practice, but it doesn't feel like a very big feature. I think that the visual feedback is secondary, just marking a line automatically after hitting enter already covers 99% of use cases.

The most important keyboard shortcuts are »up« and »down« to scroll the back buffer between the marks. The second most important shortcut is to select from the current position to the most recent mark, but even that could be implemented as a second step.

Terminal.app has more features such as marking manually, bookmarks &c which I have never used, so seems comparatively unimportant.

@zadjii-msft
Copy link
Member

zadjii-msft commented Jul 6, 2020

From @ralph-snart in #6801:

On macOS, its built-in Terminal app provides a really handy way to navigate up and down through all the prompts and also user-defined locations in the terminal window's visible history, in the form of "Marks" and "Bookmarks", complete with their own keyboard shortcuts and various menu items.

This would be a very convenient feature to port over to and adapt in Windows Terminal as well.

For specifics on macOS Terminal's "Marks" and "Bookmarks" features, please see:

@AltitudeApps
Copy link

Hi, I happened across this issue when looking for something else, but I thought I'd comment.

I would like to suggest that you consider separate vertical gutters, either beside the scrollbar, or as suggested rendered directly on the existing scrollbar.

The minimap is interesting, too. I leave both the scrollbar and minimap enabled when using editors in VSCode, and if I woke up three years from now to see a similar arrangement in Terminal, I would not be surprised.

However, the information presented as little indicators on the scrollbar can get really crowded, sometimes to the point of making it completely useless.

So, I'm going to suggest the same thing I'd like to see in VSCode: the ability to specify n, where n>1, "micro-map" scrollbar annotation columns, which can be either composed side by side, or have a subset configured to contribute annotations to the same column. (In the case where the annotations are expected to be sparse). In other words, they would be semi-transparent and rendered within the same rectangle.

Many times when the annotations are dense, even though the scrollbar indicator control is partly transparent, the blending of the colors makes it so that items are no longer instantly recognizable when that particular annotation moves from the free area of the scrollbar to a position underneath the scroll indicator.

@zadjii-msft
Copy link
Member

xlink: #6232

fhl-scroll-marks-prototype-001

I mean like conceptually, super easy. dev/migrie/fhl/scroll-marks-prototype

Formalizing this is a little tricker of course. I really like the little marks, even though I thought I might hate it. iTerm2 and Terminal.app do these a little differently, so we'd want to make sure we do them in a relatively unified way.

This implementation doesn't at all account for the various prompt markup sequences either. I kinda went ham on just this current approach. I'd want to make sure both will work.

I may also reach out to xterm.js in case @Tyriar has any other ideas for things to add to the marks.

@Tyriar
Copy link
Member

Tyriar commented Mar 22, 2022

@meganrogge and I have been working on the decorations feature in vscode for the last couple of months:

image

We're still polishing and adding to it but the "overview ruler" (same name as monaco) currently includes:

  • Success/skipped/error commands
  • Find matches
  • The focus cursor (when finding or navigating commands)

@Tyriar
Copy link
Member

Tyriar commented Mar 22, 2022

I would like to strongly support @lzybkr's #1527 (comment) and point out that macOS's Terminal.app has a very simple, but effective implementation: When pressing Enter, the current line is automatically »marked«.

Also FWIW this is the baseline behavior in VS Code for identifying commands, but you can enable experimental shell integration which gives more accurate/richer results.

@jkuebart
Copy link

jkuebart commented Mar 23, 2022

This implementation doesn't at all account for the various prompt markup sequences either.

Do you mean the code is interpreting the output or styling to recognise places to be marked and skipped back to?

I think a better approach than trying to second-guess prompts is to use lines on which Enter is pressed. Apart from the fact that most prompts can be customised, people are going to be using all kinds of interactive applications: gdb, lldb, fdisk -e, disklabel and so on and so on. They're also going to be logging into remote systems running who-knows-what OSs. So I don't think there will ever be a way to tell wether any given line of output is a prompt.

Saying that, of course it makes perfect sense for there to be command sequences that allow applications to control the behaviour explicitly.

@zadjii-msft
Copy link
Member

This implementation doesn't at all account for the various prompt markup sequences either.

Do you mean the code is interpreting the output or styling to recognise places to be marked and skipped back to?

Ah, no, I meant the prompt sequences used by Final Term / iTerm2 (et al). There's some docs on the iTerm2 docs, under "Shell Integration/FinalTerm".

My prototype yesterday was just using the iTerm2 OSC 1337 ; SetMark ST sequence in my prompt, so the prompt would explicitly tell the Terminal where the prompt started.

use lines on which Enter is pressed

Added that in 29478a6.


the "overview ruler" (same name as monaco) currently includes....

Ah. So y'all got three different sets of "marks" to display. Okay, that's not a bad idea. That does complicate the design a tad bit, but that can be sorted out in the spec review.

So basically there are

  • marks (either from FinalTerm/VsCode prompt sequences, iTerm2 SetMark, {maybe we want to add our own sequence here?}, or marks added manually via actions)
  • find results
  • where the cursor / current selection is (maybe lower priority?)
    • maybe correct me if I'm wrong, but seems like we don't need to necessarily track which command is being viewed, we could just move the viewport up/down to the prev/next mark, and that's the one that's viewed.

Right now, what I've got is absolutely hackathon quality code. I'm personally also of the shared opinion from before:

the information presented as little indicators on the scrollbar can get really crowded, sometimes to the point of making it completely useless

so maybe there's a design where you can either have all the marks in the scrollbar as little pips (like VS, Monaco), or as whole lines (like JetBrains IDEs), or as separate columns (to the right of the scrollbar?)

@Tyriar
Copy link
Member

Tyriar commented Mar 23, 2022

Ah. So y'all got three different sets of "marks" to display. Okay, that's not a bad idea. That does complicate the design a tad bit, but that can be sorted out in the spec review.

We probably would have gone with something simpler but this is aligning closely to VS Code's editor which shows scm decorations on left, find results/highlights in middle and errors/warnings on the right. So the user is already familiar with the concept. While more complex, it also ends up much less noisy that using "full" horizontal lines (see image below).

marks (either from FinalTerm/VsCode prompt sequences, iTerm2 SetMark, {maybe we want to add our own sequence here?}, or marks added manually via actions)

Be warned if you go this route, it's quite difficult to get this reliably because of conpty doesn't guarantee the marks are in the correct position. Additionally the lack of an alt buffer can lead to odd behavior.

I think passthrough #1173 is what we need to make this simpler? If you could just allow some sequences to be "rendered" at the correct cell this would make our lives so much easier.

where the cursor / current selection is (maybe lower priority?)

  • maybe correct me if I'm wrong, but seems like we don't need to necessarily track which command is being viewed, we could just move the viewport up/down to the prev/next mark, and that's the one that's viewed.

We decided not to show the cursor since it's always at the bottom, instead it's currently used for the current find match and for command navigation:
Recording 2022-03-23 at 07 36 37

so maybe there's a design where you can either have all the marks in the scrollbar as little pips (like VS, Monaco), or as whole lines (like JetBrains IDEs), or as separate columns (to the right of the scrollbar?)

Initially we showed a full line for each command and it was useless imo as it quickly ended up looking like this:

image

The problem is exacerbated by the fact that VS Code's terminal is normally quite short vertically.

@zadjii-msft
Copy link
Member

Be warned if you go this route, it's quite difficult to get this reliably because of conpty doesn't guarantee the marks are in the correct position. Additionally the lack of an alt buffer can lead to odd behavior.

Hah, I have a fairly clever solution for that right now. Whenever we see one of these sequences in conpty, we'll immediately end the current frame and start buffering a new one, and then just adding the sequence directly to the conpty output. That results in the sequence being sent to the terminal with the terminal in the full state you'd expect for when the sequence was emitted. I actually used that to support the alt buffer, which all this work is forked off of 😋

You're right though, passthrough would make this simpler.

Initially we showed a full line for each command and it was useless imo as it quickly ended up looking like this:

{image}

HO BOY yea good point. Maybe we just stick with pips. I'm all for aligning with our other first party partners ☺️

@Tyriar
Copy link
Member

Tyriar commented Mar 23, 2022

Whenever we see one of these sequences in conpty

Are we meant to have this in older versions of conpty? The sequences definitely often print in the wrong spot. Do you just do this for just OSC 7 and 133 because we're using OSC 633 currently. It would happen for all OSC sequences imo.

@zadjii-msft
Copy link
Member

Are we meant to have this in older versions of conpty?

Ah no, that work is still in PR right now (#12561). It's not an amazing solution. I'd have to go through and manually flush the frame on sequences we think that conhost isn't going to handle. I think there's a bit more discussion in #8698.

@Tyriar
Copy link
Member

Tyriar commented Mar 23, 2022

@zadjii-msft cool, well alt buffer support will be great when we eventually get it as well.

@zadjii-msft zadjii-msft modified the milestones: Backlog, Terminal v1.15 Mar 28, 2022
@ghost ghost added the In-PR This issue has a related PR label Apr 20, 2022
@ghost ghost added the Needs-Tag-Fix Doesn't match tag requirements label Jun 9, 2022
zadjii-msft added a commit that referenced this issue Jun 9, 2022
Adds support for marks in the scrollbar. These marks can be added in 3
ways:
* Via the iterm2 `OSC 1337 ; SetMark` sequence
* Via the `addMark` action
* Automatically when the `experimental.autoMarkPrompts` per-profile
  setting is enabled.

#11000 has more tracking for the big-picture for this feature, as well
as additional follow-ups. This set of functionality seemed complete
enough to send a review for now. That issue describes these how I wish
these actions to look in the fullness of time.  This is simply the v0.1
from the hackathon last month.

#### Actions

* `addMark`: add a mark to the buffer. If there's a selection, use
   place the mark covering at the selection. Otherwise, place the mark
   on the cursor row. 
  - `color`: a color for the scrollbar mark. This is optional - defaults
    to the `foreground` color of the current scheme if omitted.
* `scrollToMark`
  - `direction`: `["first", "previous", "next", "last"]`
* `clearMark`: Clears marks at the current postition (either the
  selection if there is one, or the cursor position.
* `clearAllMarks`: Don't think this needs explanation.

#### Per-profile settings

* `experimental.autoMarkPrompts`: `bool`, default `false`.
* `experimental.showMarksOnScrollbar`: `bool` 

## PR Checklist
* [x] Closes #1527
* [x] Closes #6232

## Detailed Description of the Pull Request / Additional comments

This is basically hackathon code. It's experimental! That's okay! We'll
figure the rest of the design in post.

Theoretically, I should make these actions `experimental.` as well, but
it seemed like since the only way to see these guys was via the
`experimental.showMarksOnScrollbar` setting, you've already broken
yourself into experimental jail, and you know what you're doing.

Things that won't work as expected:
* resizing, ESPECIALLY reflowing
* Clearing the buffer with ED sequences / Clear Buffer

I could theoretically add velocity around this in the `TermControl`
layer. Always prevent marks from being visible, ignore all the actions.
Marks could still be set by VT and automark, but they'd be useless.

Next up priorities:
* Making this work with the FinalTerm sequences
* properly speccing
* adding support for `showMarksOnScrollbar: flags(categories)`, so you
  can only display errors on the scrollbar
* adding the `category` flag to the `addMark` action

## Validation Steps Performed

I like using it quite a bit. The marks can get noisy if you have them
emitted on every prompt and the buffer has 9000 lines. But that's the
beautiful thing, the actions work even if the marks aren't visible, so
you can still scroll between prompts. 

<details>
<summary>Settings blob</summary>

```jsonc
// actions
        { "keys": "ctrl+up", "command": { "action": "scrollToMark", "direction": "previous" }, "name": "Previous mark" },
        { "keys": "ctrl+down", "command": { "action": "scrollToMark", "direction": "next" }, "name": "Next mark" },
        { "keys": "ctrl+pgup", "command": { "action": "scrollToMark", "direction": "first" }, "name": "First mark" },
        { "keys": "ctrl+pgdn", "command": { "action": "scrollToMark", "direction": "last" }, "name": "Last mark" },
        { "command": { "action": "addMark" } },
        { "command": { "action": "addMark", "color": "#ff00ff" } },
        { "command": { "action": "addMark", "color": "#0000ff" } },
        { "command": { "action": "clearAllMarks" } },

// profiles.defaults
        "experimental.autoMarkPrompts": true,
        "experimental.showMarksOnScrollbar": true,
```

</details>
@ghost ghost added Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release. and removed In-PR This issue has a related PR labels Jun 9, 2022
@ghost
Copy link

ghost commented Jul 6, 2022

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

Handy links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Extensibility A feature that would ideally be fulfilled by us having an extension model. Area-User Interface Issues pertaining to the user interface of the Console or Terminal Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Needs-Tag-Fix Doesn't match tag requirements Product-Terminal The new Windows Terminal. Resolution-Fix-Committed Fix is checked in, but it might be 3-4 weeks until a release.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants