Open asmeurer opened 7 years ago
This is correct, and this feature request makes sense. In ptpython, this is possible because it uses a more low-level API (which is not guaranteed to remain stable).
I take this as a feature request.
I didn't know it was possible in ptpython. I'll take a look at how it works there.
Actually, what I really want is no continuation prompt for soft-wrapped text. Ideally, the text wouldn't even soft wrap, so that if I select it and copy it, there are no newlines. Is this possible? It works this way in readline shells.
For a single-line input, it is already the case that there is no continuation prompt.
About having one for hard line wraps, but no for soft wraps: this is not possible right now. I'm not sure what it would take to get this to work, but I'll keep it in mind.
For a single-line input, it is already the case that there is no continuation prompt.
Can you clarify what you mean here? I have a continuation prompt set up and it always shows when a single line of input fills the terminal width. If I could disable it for this case, even with hard wrapping, that would be a good start.
I can get roughly the behavior I want by setting wrap_lines
to False, with the following diff
diff --git a/prompt_toolkit/renderer.py b/prompt_toolkit/renderer.py
index 7a8fde5..a2d0d57 100644
--- a/prompt_toolkit/renderer.py
+++ b/prompt_toolkit/renderer.py
@@ -118,7 +118,8 @@ def _output_screen_diff(output, screen, current_pos, previous_screen=None, last_
# background threads, and it's hard for debugging if their output is not
# wrapped.)
if not previous_screen or not use_alternate_screen:
- output.disable_autowrap()
+ pass
+ # output.disable_autowrap()
# When the previous screen has a different size, redraw everything anyway.
# Also when we are done. (We meight take up less rows, so clearing is important.)
diff --git a/prompt_toolkit/terminal/vt100_output.py b/prompt_toolkit/terminal/vt100_output.py
index b800aaa..17dc558 100644
--- a/prompt_toolkit/terminal/vt100_output.py
+++ b/prompt_toolkit/terminal/vt100_output.py
@@ -426,7 +426,7 @@ class Vt100_Output(Output):
rows, columns = _get_size(stdout.fileno())
# If terminal (incorrectly) reports its size as 0, pick a reasonable default.
# See https://github.com/ipython/ipython/issues/10071
- return Size(rows=(rows or 24), columns=(columns or 80))
+ return Size(rows=(rows or 24), columns=1000)
return cls(stdout, get_size, true_color=true_color,
ansi_colors_only=ansi_colors_only, term=term)
Hacking the terminal size is not good, obviously, but I couldn't figure out where the columns
actually gets used (everything I've tried just keeps writing over the last visible character, instead of wrapping).
Ok, I think I understand the issue. You don't want the \n
to be rendered in the terminal, so that copy/pasting works.
Unfortunately this is still not possible, and very hard to implement right now, taking into account how the rendering engine works. We first render to an in-memory 2d canvas, then we diff that against the 2d canvas from the previous rendering, and we output the diff by doing both horizontal and vertical cursor movements. We never rely on the terminal to do line wrapping.
Not showing a continuation prompt for a soft wrap is possible by using the is_soft_wrap
argument of get_continuation_prompt
. But this will still render a \n
.
Also, see this example: https://github.com/jonathanslenders/python-prompt-toolkit/blob/master/examples/prompts/get-multiline-input.py
Are there terminals that don't do soft-wrapping that would need to be handled in the code?
It sounds like the code would need to be abstracted a bit to differentiate between visual rows and physical rows, where there may be more visual rows because of wrapping. Calculations involving the terminal size should use visual rows but calculations involving cursor movements should use physical rows.
This sounds somewhat related to another feature that I would like to see, which is that when I execute a a prompt that is larger than the screen (sometimes I paste in large blocks of code), it would be nice if the terminal scrollback history showed the full input, not just what was visible onscreen when I pressed Enter. But I have no idea how hard that would be to implement.
This is actually really complex to get multiline rendering reliable on all terminals. The current algorithm has been battle tested for a couple of years now and seems to work fine. Changing that possibly also means changing how mouse events correspond to positions and how the CPR response needs to be handled. And further, and lot of effort has been put into making the rendering performance as efficient as possible.
Feel free to experiment with this, but unfortunately, I probably have other priorities with prompt_toolkit first.
OK, I might at some point. It helps to know how it works. Also, I don't think this sort of thing needs to be supported when mouse reporting is enabled. To me, that turns it into a real full-screen terminal application (even if it doesn't do a clear
), and I have never seen a full screen application that doesn't do line wrapping (is it even possible?).
One other thing to keep into account I'm just thinking about is double width characters (+ maybe decomposed double width characters). I'm not sure all terminals handle it the same way during the line break. I remember certain inconsistencies. Further terminals like tmux do some tricks for getting auto reflow of to work. These are all things to keep in mind.
It would be nice if
get_continuation_prompt
had enough information passed to it to have a different continuation prompt depending on if the line is hard wrapped or soft wrapped. As far as I can tell this is currently impossible (from the logic here, theget_continuation_prompt
has no distinction between the different calls. Even if it were just passedn
(for then
-th continuation prompt) I think this would be possible.