microsoft / terminal

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

Draw a horizontal line / ruler between commands (read: blocks ) #17493

Open inkwadra opened 3 months ago

inkwadra commented 3 months ago

Description of the new feature/enhancement

I recently decided to start developing my dream terminal for Windows. However, since I'm not a professional developer and the development will take quite a long time, I thought: "Why let the concepts go to waste?" Perhaps this will be at least somewhat useful for Windows Terminal developers.

Concepts:

Blocks Dividing results into blocks

History Commands history

Autocomplete Autocomplete

Terminika Default window with entered command

P.S.

If anyone can give me a hint on how to theoretically capture process output and divide it into blocks from the output stream of a Windows pseudoconsole, I would be very grateful.

Thank you for your attention.

o-sdn-o commented 3 months ago

a hint on how to theoretically capture process output

You might be interested in the public API: https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/

Alternatively, you can pass raw pipe endpoints (created by pipe-functions) as stdin/stdout/stderr to the process you start by CreateProcessW with specified HANDLE hStdInput, HANDLE hStdOutput, HANDLE hStdError in STARTUPINFOW structure.

Some important Win32 Console Subsystem details that you need to know and understand (in chronological order):

inkwadra commented 3 months ago

a hint on how to theoretically capture process output

You might be interested in the public API: https://devblogs.microsoft.com/commandline/windows-command-line-introducing-the-windows-pseudo-console-conpty/

Alternatively, you can pass raw pipe endpoints (created by pipe-functions) as stdin/stdout/stderr to the process you start by CreateProcessW with specified HANDLE hStdInput, HANDLE hStdOutput, HANDLE hStdError in STARTUPINFOW structure.

Some important Win32 Console Subsystem details that you need to know and understand (in chronological order):

Thank you, I thought I had already learned everything about working with Pipes, ConPTY, and Escape sequences. I'm disappointed that ConPTY does not provide the flexibility I need. I only receive a stream of bytes without any markers, exit codes, or other signals that would help break the results into blocks. So far, for PowerShell, the best idea I have is to create a module and integrate it into the profile, which places custom markers between commands. However, I'm not sure if this approach is good. As for CMD, I have no ideas at all.

o-sdn-o commented 3 months ago

Perhaps this can be implemented using the so-called Shell Integration: https://devblogs.microsoft.com/commandline/shell-integration-in-the-windows-terminal/

But I do not know. how it works from the 3p terminals side.

inkwadra commented 3 months ago

Perhaps this can be implemented using the so-called Shell Integration: https://devblogs.microsoft.com/commandline/shell-integration-in-the-windows-terminal/

But I do not know. how it works from the 3p terminals side.

Works great! 👍THX

[[ESC[?25l]] [[ESC[2J]] [[ESC[m]] [[ESC[H]] PowerShell[[SP]]7.4.3 [[CR]][[LF]] 
[[ESC]0;]] C:\Program[[SP]]Files\PowerShell\7\pwsh.exe [[BEL]] 
[[ESC[?25h]]

[[ESC]133;A]] [[BEL]]
[[ESC]9;9;]] "C:\Users\Inkwadra" [[BEL]] 
[[ESC]133;B]] [[BEL]]

PWSH[[SP]]C:\Users\Inkwadra>[[SP]][[ESC[93m]]echo[[SP]][[ESC[36m]]'Hello[[SP]]World!' [[CR]][[LF]] [[ESC]133;D;0]] [[BEL]]

[[ESC]133;A]] [[BEL]] 
[[ESC]9;9;]] "C:\Users\Inkwadra" [[BEL]] 
[[ESC]133;B]] [[BEL]]

[[ESC[m]] Hello[[SP]]World! [[CR]][[LF]]

PWSH[[SP]]C:\Users\Inkwadra>[[SP]][[ESC[92m]]exit [[ESC[15X]] [[CR]][[LF]] [[ESC[m]]
plutonium-239 commented 3 months ago

the best idea I have is to create a module and integrate it into the profile, which places custom markers between commands. However, I'm not sure if this approach is good. As for CMD, I have no ideas at all.

Hi, you might want to check out clink, which is an amazing lua-based cmd-overhaul-thing. It has a lot of features like readline command line editing and tons more. It supports lua scripts as plugins which is huge for customization. One of those plugins (specifically, clink-gizmos/divider.lua) does a similar thing to what you describe: place custom markers after start and before end of a (configurable list of) command(s). It can also be customized to make the divider text anything (i.e. output of some command), by default it is timing the program as such:

image

zadjii-msft commented 3 months ago

Alright, lots to unpack here. Looks like there's three main requests, so I'll break those out. A lot of this is stuff we've talked about at length in a variety of threads across the repo, but I'll give you some additional details.

As mentioned, almost all this is powered by some form of Shell Integration. The best docs page we have can be found at Shell Integration. The first two by the aforementioned FTCS marks. The third will be powered by a (still very experimental) protocol for sending suggestions to the Terminal from the shell.


Dividing results into blocks

This one I don't think we actually have tracked anywhere specifically. I'm hunting it down but I think it doesn't have a dedicated thread. I may promote this thread to be the blocks thread. I know we referenced it in #13445

What we do have today is support for navigating by command, and selecting entire command outputs: https://learn.microsoft.com/en-us/windows/terminal/tutorials/shell-integration#automatically-jump-between-commands

The part we're still missing is "a horizontal ruler that separates individual commands when shell integration is enabled". I don't think doing it would be terribly impossible, but there's a lot of weird edge cases for drawing lines in a grid of text[^1].

Commands history

This is something we're actively improving via the suggestions UI. In 1.22, it looks something like: image

Autocomplete

We're tracking this in #3121. What we've got today looks like:

image

That's powered by the same suggestions menu that powers command history, above. https://github.com/microsoft/terminal/wiki/Experimental-Shell-Completion-Menu has some notes on how to enable it.

Other references:

[^1]: hell, just look at the conversation in #17482

j4james commented 3 months ago

Dividing results into blocks

@zadjii-msft It's possible you were thinking of collapsible regions (#13298), which is a similar concept.

inkwadra commented 3 months ago

@zadjii-msft, perhaps you can answer a question I have regarding ConPTY?

From Shell Integration for PowerShell, I took only a small part to see how it would look and if I could use it (it would solve many problems):

function prompt {
  $out += "`e]133;A$([char]07)";
  $out += "`e]9;9;`"$loc`"$([char]07)";
  $out += "PWSH $loc$('>' * ($nestedPromptLevel + 1)) ";
  $out += "`e]133;B$([char]07)";
  return $out
}

Looking at this, I expected to get the prompt from ConPTY in this form:

<ESC]133;A><BEL>
<ESC]9;9;>"C:\Users\Inkwadra"<BEL>
PWSH C:\Users\Inkwadra>
<ESC]133;B><BEL>

But in my result, PWSH C:\Users\Inkwadra> appears outside the <ESC]133;B><BEL> block:

<ESC]133;A><BEL>
<ESC]9;9;>"C:\Users\Inkwadra"<BEL>
<ESC]133;B><BEL>
PWSH C:\Users\Inkwadra>

Is this the correct behavior, or did I miss something?

zadjii-msft commented 3 months ago

@inkwadra I bet that's right, if you're using the in-the-OS version of the ConPTY APIs. Certain VT sequences can arrive out of order with older versions of ConPTY[^1]. The Terminal actually packages a version of the latest conpty directly into our package. It's not impossible to do, but it's certainly not as easy as we'd like to make it. That work is tracked over in #15065, but it's definitely possible to do today. I believe wezterm is already doing something similar.


Thanks @j4james for finding that issue. I honestly have no memory of writing that issue up two years ago 😅 The debate I'm mulling over is if we should use this just for "draw a horizontal rule between commands", and leave #13298 for "make the space between rules collapsible". In my head there's some space between those two, so I'm leaning towards leaving this open

[^1]: See #17314, #8698, #1173