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
Clear to end of each line in left prompt #7404
Conversation
Thanks for the initiative and the patch. Writing a character at a time is extremely suboptimal. I'd rather split on new lines and then use |
Line 735 in 45d60f6
Keeping track of which lines we need to clear is unlikely to be worth the increased complexity, so clearing all lines makes sense. I did not realise that writech would be so expensive. I assumed an internal buffer. I think we can easily take "views" into the string by jumping from one |
Okay, updated to write each line at a time. I'm not sure if c_str() causes an allocation, but I think we can live with that even if it does, since this shouldn't be running too frequently (given the if check already in place). |
Thanks for updating the patch. The |
src/screen.cpp
Outdated
if (clr_eol) { | ||
s_write_mbs(scr, clr_eol); | ||
} |
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 would move this to after the last write to minimize flashes of contents/repaints. But first - in what case is it required, given that it would presumably apply to even single-line prompts but we don't have any problems with those now, even without it?
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.
That's a good idea. I will make that change. It might make the logic slightly more complicated, since currently it goes "clr, line+terminator", which will need to be changed into "terminator+line, clr". Just some indexing stuff to take care of :)
I think the fact that it's being printed on a single line prompt is also just an artefact of that, so I can definitely eliminate it. We don't have a problem for single line prompts because rendering the command also clears to the end of the line.
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.
Updated, let me know if you have any suggestions to make the logic clearer.
src/screen.cpp
Outdated
prev_nl = next_nl; | ||
start = prev_nl + 1; | ||
} | ||
s_write_str(scr, left_prompt.substr(prev_nl).c_str()); |
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.
We can avoid allocation in the common case by using left_prompt.c_str() + prev_nl
.
We could also avoid allocations from the substr
above, if we temporarily swap out newlines for null bytes.
while ((next_nl = left_prompt.find('\n', start)) != wcstring::npos) {
left_prompt.at(next_nl) = L'\0';
s_write_str(scr, left_prompt.c_str() + prev_nl);
left_prompt.at(next_nl) = L'\n';
...
}
However, I don't think swapping null bytes is common in the fish code base, so when in doubt I'd leave that part as is. What do others think?
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.
Done for the common case. Agreed that swapping '\n' with '\0' seems dubious. If we're going that far, we might as well make left_prompt a wcstring_list_t instead of a single wcstring. WDYT?
I had to change the logic a little bit because I realised that my first attempt would not handle '\n' inside escape sequences properly. |
Merged as 80aaae5, thank you! |
Happy to help! I think there's still room to add the wcstring_list_t change as well, so I'll probably come back to it later. |
Description
Changes the left prompt rendering to include clr_eol for each rendered line. This prevents issues where if a multiline prompt changes between renderings, the previous prompt shows through.
Fixes #6532
TODOs: