-
Notifications
You must be signed in to change notification settings - Fork 279
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
added a command line flag and associated code to support dumb terminals #99
base: master
Are you sure you want to change the base?
Conversation
Thanks, Adler!
I was hoping for textinput to only print that new character. That's what I expected it to do - instead of re-writing the whole line. Can you find out / remind us why it prints everything again and again when adding a single character? If we manage to fix that (i.e. only add that new character) then we don't need a flag at all - everything will work, magically :-) |
I'll take a look! However, I do think it's still a better user experience if the input is not echoed at all on these dumb terminals because the input will already be there and would be duplicated if there is any printing on user input. |
Let's step back for a second: when I run
What do you have? |
Yes, unfortunately, term is not the subshell that the other emacs tools are built on (comint, for example). I believe that the tools are built on eshell which is why the interactive cling mode that I am working on for emacs has the noisy echo.
|
Ah that's great! textinput already checks for |
Yes, that makes sense! I'll look into that. |
Any news? I really like your patch, and changing this to be |
I've been swamped, but I will work on it very soon |
…l type and respond appropriately when type is dumb
Sorry for the delay. I pushed an update to my fork that removes the flag and detects when terminal type is "dumb". However, since I had to make the change to TerminalDisplay, this may affect Windows as well (which I didn't test). Since TerminalDisplay has a fTerm field that holds the terminal type as a string, I set it to "win" in the subclass TerminalDisplayWin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice, thanks a lot! That's much better! I'd still move some of the interfaces around, to make this even more transparent / simple. Could you address the comments?
@@ -145,9 +145,11 @@ void CompilerOptions::Parse(int argc, const char* const argv[], | |||
} | |||
|
|||
InvocationOptions::InvocationOptions(int argc, const char* const* argv) : | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the changes in this file from this PR?
@@ -98,6 +98,9 @@ namespace cling { | |||
UITabCompletion* Completion = | |||
new UITabCompletion(m_MetaProcessor->getInterpreter()); | |||
TI.SetCompletion(Completion); | |||
if (D->GetTERM() && strstr(D->GetTERM(), "dumb")) { | |||
TI.SetIsDumbTerm(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't this be done inside textinput itself? See below...
@@ -40,6 +40,8 @@ namespace textinput { | |||
void Detach(); | |||
void DisplayInfo(const std::vector<std::string>& Options); | |||
bool IsTTY() const { return fIsTTY; } | |||
void SetTERM(const char* TERM) { fTERM = TERM; }; | |||
const char* GetTERM() { return fTERM; }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These interfaces (nor the data member) should not be needed, see below. Instead we'd need an IsDumb()
.
@@ -31,6 +31,7 @@ | |||
namespace textinput { | |||
TextInput::TextInput(Reader& reader, Display& display, | |||
const char* HistFile /* = 0 */): | |||
fIsDumbTerm(false), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't that a property of the TerminalDisplay
? I'd prefer to have the interface there.
@@ -119,6 +119,7 @@ namespace textinput { | |||
TerminalConfigUnix::Get().TIOS()->c_lflag |= ECHOCTL|ECHOKE|ECHOE; | |||
#endif | |||
const char* TERM = getenv("TERM"); | |||
SetTERM(TERM); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If TERM
is "dumb"
, the dumb flag on the TerminalDisplay
base should be set.
if (!fIsDumbTerm) { | ||
// Signal displays that the input got taken. | ||
std::for_each(fContext->GetDisplays().begin(), fContext->GetDisplays().end(), | ||
std::mem_fun(&Display::NotifyResetInput)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if
should test the display of the current iteration: if it's dumb, don't call NotifyResetInput..
@@ -124,7 +127,9 @@ namespace textinput { | |||
|| (*iR)->HaveBufferedInput()) { | |||
if ((*iR)->ReadInput(nRead, in)) { | |||
ProcessNewInput(in, R); | |||
DisplayNewInput(R, OldCursorPos); | |||
if (!IsDumbTerm()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd move that if
into DisplayNewInput
, testing the dumbness of the display.
void SetIsDumbTerm(bool isDumbTerm) { fIsDumbTerm = isDumbTerm; } | ||
|
||
protected: | ||
bool fIsDumbTerm; // whether this is a dumb terminal or not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should all be moved to TerminalDisplay
.
I will take a look, thanks for the comments. |
@Axel-Naumann Hello, I'd love this to get merged. C++ is definitely not my thing but I'm learning it, would you be open to accept the requested changes and possibly give me some advice on the way? |
Hi, apologies, but I had to stop working on this pull request because of other responsibilities. I would also love to see this completed if @rilerez or @lazywithclass has some time to work on the refactoring and new conflicts. |
Has there been any progress? If not, I'm happy to give it a go, but I might need some pointers to get started. |
I think this repo is just a mirror, consider moving your PR here instead: https://github.com/root-project/root/pulls (subdirectory interpreter/cling). Thanks! |
Emacs and other subshells that manage their own input result in noisy output at the cling interpreter. More specifically, entering "int x = 5;" at the prompt will result in the interpreter recursively printing the input adding one character each time - "iinintint int xint x int x =int x = int x = 5int x = 5;int x = 5;". This seems to be because cling cannot control the cursor location in dumb terminals and therefore cannot update the text at the prompt with each new character. It instead prints each update.
Subshells such as those in emacs, manage user input until a newline and then send the input to the underlying process. The output of the underlying process is echoed in the subshell. Because this shell is managed and cling does not have as much control, this results in noisy output.
This pull request adds a command line flag to indicate whether this is a dumb terminal. If so, it does not update the content of the terminal on each input character and does not add a newline (since the dumb terminal would add its own). This is implemented as a member variable of the TextInput class.