Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to separate real prompts from unfinished output #20

Open
hanslub42 opened this issue Oct 1, 2014 · 5 comments
Open

Option to separate real prompts from unfinished output #20

hanslub42 opened this issue Oct 1, 2014 · 5 comments
Milestone

Comments

@hanslub42
Copy link
Owner

Eric Pruitt wrote:

I was wondering if there was a way to make rlwrap either A: stop the wrapped command from writing to stdout when the user is type or B: make rlwrap clear the prompt before allowing the subprocess to write to stdout. I am using rlwrap with an IRC client, and if someone sends a message while I'm typing, my prompt gets mangled, so I was wondering if there was an option that would help with that problem. I read the man page section "DIRECT MODE AND READLINE MODE," but unless I'm overlooking something, I don't believe that addresses this situation

At present, rlwrap considers any output that doesn't end in a newline a prompt. If such a 'prompt' arrives while you are typing it will be appended to the current prompt before the cursor, which is messy.

This is the most general solution, but for many commands a prompt can be recognised as such because it fits a certain pattern (e.g. it ends in a '>' or a '$'). Specifying e.g --only-cook '>\s?$' prevents rlwrap from cooking (e.g. colouring) anything else.

I could extend the effect of this option (or add a new option), making rlwrap reprint the original prompt (on a new line) below any output that doesn't fit the given regexp, even if this output doesn't end in a newlne.

If more output arrives, rlwrap should go back to the line above the prompt, append the new output, and reprint the prompt (except when this fits the regexp, in which case rlwrap should behave as it does now)

This (Eric's solution 'B') is a bit tricky, but probably doable.

An alternative (or additional) solution would be to extend the filter mechanism (which already can send back messages _THIS_IS_NOT_A_PROMPT_)

Solution 'A' -don't print any of the slave command's output between starting the line editor and accepting the resulting input - is less attractive to me: the user would miss out on important information, like error messages.

@hanslub42
Copy link
Owner Author

rlwrap wants to be completely transparent, i.e. rlwrap <command> should behave exactly like <command>, except that the input is handled by readline. If you never use arrow keys, you should not be able to notice the difference.

There exists another rlwrap-like line editor: src (https://bitbucket.org/emg/srw/src) that always prompts for user input on a separate line; any command output (even command's own prompt) is displayed above this line. This is immediately noticeable, hence non-transparent, but it avoids the messiness that rlwrap suffers when the slave command outputs something while you're typing.

What I propose is that rlwrap behaves like src (hence non-transparently) as long as there is no recognisable prompt, using the last seen and recognised prompt as (temporary) src-like prompt

As this breaks transparency, it certainly should not be default behaviour. The --only-cook <regexp> option seems like a good candidate option, as it automatically specifies a way to distinguish prompts from unfinished output.

@hanslub42 hanslub42 reopened this Oct 2, 2014
@hanslub42 hanslub42 added this to the 0.43 milestone Oct 2, 2014
@gsf
Copy link

gsf commented Oct 2, 2014

I was about to say something along the lines of your last comment. I think of rlwrap as an input-handling tool. The less it manipulates output the better -- that's what you call "transparency" above. Any assumptions made about an underlying command's output complicate things. As long as output mangling isn't the default that complexity can be avoided. To further separate this feature from rlwrap's core functionality could it be written as a filter plugin?

@hanslub42
Copy link
Owner Author

In theory a filter could mangle output by inserting cursor movement commands, but this would be a very messy solution.
In essence, rlwrap is a state machine (or rather the cartesian product of a few state machines) with states like "editing input", "received output that could be a prompt", and transitions like "user keypress", "child has died".
When rlwrap was young it made sense to implement this machine with a few if(){..}else{..} constructs. Now that the number of states has grown (filtering adds quite a few) this gets a bit unwieldy
The current proposal adds yet another state ("received output which is certainly not a prompt") There is a point at which a complete re-write is less trouble than adding a lot of extra if() {} else{} lines to accomodate just one extra state. rlwrap has almost arrived at that point

@gsf
Copy link

gsf commented Oct 2, 2014

Interesting. Are you thinking the full state machine rewrite could be a target for the 0.43 release?

@hanslub42
Copy link
Owner Author

Are you thinking the full state machine rewrite could be a target for the 0.43 release

No, this would be a very major rewrite. A lot of code is currently devoted to rare corner cases (like receiving slave command's output after the slave has died, or ,indeed, receiving output during a line edit, the original motivation for this thread), this re-write could lead to a different (hopefully smaller, but still significant) set of obscure corner cases

I'm not exactly looking forward to it....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants