jcubic / jquery.terminal

jQuery Terminal Emulator - JavaScript library for creating web-based terminals with custom commands
https://terminal.jcubic.pl
MIT License
3.11k stars 572 forks source link

Question: Multiple prompt lines #645

Open hoodmane opened 3 years ago

hoodmane commented 3 years ago

In a native repl, there is support for multiline input with different prompts on the first line and later lines:

image

Is there a way to handle this with jquery terminal? I was unable to get it to work. Same input in jquery terminal:

image

jcubic commented 3 years ago

You have two options for multiline commands I think that the one in Python REPL is not ideal. Because when you press up arrow to get the item from history you don't have whole function (like in your example) but each line in the function is different history item. If you want that you can check my

trypython (it also have python syntax highlighting)

and code is in https://trypython.jcubic.pl/main.py

There are no auto indentation though, you will need to write it yourself as everything else. If you save the code in variable you can parse the python code (I think this would be best solution, but python colon is pretty regular then you can try to parse the code with regex) and search how many colons there are in the code.

But I think better solution is to highjack the enter key and don't process the line if it's not finished. With this you will be able to have whole function in history so it's easier to invoke it again.

jcubic commented 3 years ago

This need better documentation, both solution should be documented.

hoodmane commented 3 years ago

I implemented a solution for this by setting the prompt to be empty and using my own margin area to include the prompts. I use a MutationObserver to update my prompts when the length of the input region changes, and set different values for the margin-left of the input / output depending on whether one of my custom prompts is present.

This has the effect that multiline input works correctly with the history / reverse search and also with multiple lines of prompt. Also, if you copy the input it won't include the prompts, which I personally think is preferable (for instance for the common use case where you are copying the input code into a source file it's annoying to delete them).

https://spectralsequences.com/worker-pyodide-console/ https://github.com/hoodmane/worker-pyodide-console/

jcubic commented 3 years ago

This is way overengineered also this is not good idea because in real python prompt the person can delete the indent. PS: you demo show black page and no output.

hoodmane commented 3 years ago

Well it may be over engineered, but I am imitating existing repls. All input lines are forced to be indented equally, output lines are not indented. This is to allow distinguishing between input and output.

Compare:

>>> x = 7
... print(x*x+1)
50
>>> def f(x):
...    x -= 1
...    return x*x - 1
... print(f(7))
35

A native repl:

image

My repl:

image

jcubic commented 3 years ago

Of course you can use whatever you think it's good for you, but with my code I prefer to add spaces and use real prompt from the terminal. I can create example for my trypython, since it don't have indentation. But this how python REPL works, I'm not sure what type of native REPL you're using, but native python REPL don't have indentation (like my trypython) and don't have multiple because that is limitation of readline library. Python REPL also don't have colors maybe you're using something else than native python REPL (which on GNU/Linux is when you execute python).

jcubic commented 3 years ago

I've notcied one thing, if you use --background: transparent you break text selection.