Detect prompt with xterm.js

647 Views Asked by At

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.

0

There are 0 best solutions below