0

TLDR: I want know how to detect from the output of a shell (e.g. zsh, bash) the location of the prompts (e.g. user@machine /etc % ).

Details

I have made a working shell frontend in the browser based on xtermjs. It is now equivalent feature-wise to e.g. the default macOS terminal application with zsh, bash and powershell. In a nutshell, it works by executing a shell process (e.g. zsh) as the child of a parent process that pipes the input/output from/to the browser via web sockets.

I want now to step up and implement a "collapse" functionality that hides the output of the selected commands in the history (like Visual Studio Code does now).

To this end, I need to detect the location of the prompts from the terminal output: the collapse function would then hide the characters between two consecutive prompts.

I know I can use the approaches below:

  1. detect the prompt with a regular expression (I would need to parse the PS1 variable)
  2. inject some special character sequence before and after the prompt (e.g. in variable PS1)

But both do not seem very robust, and may not work with some specific command interpreter. I could not find yet the location where this functionality is implemented in the source code of Visual Studio Code.

My question is: is there a robust way to achieve this functionality for at least zsh, bash and powershell (it is fine if it is specific to xterm.js)

Edit 1

This SO question is related: ANSI escape sequence for collapsing/folding text (maybe hierarchically)

It links to this interesting thread: https://github.com/PerBothner/DomTerm/issues/54

It appears that DomTerm uses escapes sequences at folding points (my solution 2).

Yet I don't see how to inject them into the terminal, besides hacking the PS1 env var.

Edit 2

While parsing iTerm's documentation I found out that it takes advantage of the hooks provided by the shell (e.g. for zsh) in order to print some special escape sequence at various locations, including before showing the prompt.

For example, in zsh, I can print string "" before each prompt be executing precmd() { echo '' }. Then when I execute e.g. ls I get

$> ls
[...]

$> 

There is a more extensive explanation of the various available hooks for various shells here. It looks like PowerShell uses a very different system though.

Antoine Trouve
  • 1,198
  • 10
  • 21
  • 1
    By _the location of the prompt_, do you mean the line in the xterm window, where the most recent prompt has been displayed? How do you handle multi-line prompts? BTW, zsh and bash are not _terminals_, but _shells_. Note also that in most cases, `PS1` is not set as **environment** variable. While it is not forbidden to do so, it is usually not done. – user1934428 Jan 18 '23 at 09:20
  • Thank you, so you confirm hacking around PS1 is a bad idea. My bad for mixing the words. For collapsing I guess the first character of each promp (not only the latest) would be enough, but it won't necessarily be after a new line. – Antoine Trouve Jan 18 '23 at 21:54
  • Honestly, I don't understand what you exactly want to achieve. If you want to **mark** the prompt line in a particular way, so that you can distinguish prompt-output from non-prompt-output, you could for instance put into your PS1 some character which you consider unlikely to be printed by a normal program (for example the character `༗` (U+0F17), and you find a way to grab the content of the terminal window as a text, you could search for this character. However there is no **guarantee** that a program you run won't print something which looks exactly like your prompt. – user1934428 Jan 19 '23 at 08:05
  • 1
    TLDR - thats not possible in a robust way. Long answer: What you are looking for is called terminal shell integration. Problem here - this has to be supported by the terminal to a certain extend, but there is no standard to rely on. DomTerm has alot UX goodies implemented into that direction, xtermjs lit. none. So with DomTerm you'd get a head start, where the terminal already offers a UX pattern to deal with sequence marked prompts (imho also offers folding). With xtermjs you'd have to implement that yourself, prolly in a terminal addon. – jerch Jan 19 '23 at 11:50
  • Thank you for the clarification. I've been reading the source code of iTerm2 and Kitty, and it looks like all the bells and whistles are using extensions based on escape sequences (some are kind off de-facto standard) I'll take a look at DomTerm source code as well. – Antoine Trouve Jan 20 '23 at 06:03
  • 1
    Yes there are some attempts to standardize it with OSC escape sequences, but most terminals still dont know, what to do with those. Furthermore your shell needs to be configurable to send those sequences for the prompt (often done via PS1 overloads or pre/post scripts). The issue goes further, if you also want to decorate prompts of other REPLs, which is de facto not possible atm due to lacking a proper standard + wider terminal support. In summary - you might get something working for your shell on a certain terminal, but a more general approach across different REPLs and terminals wont work. – jerch Jan 24 '23 at 13:30

0 Answers0