-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
cli: multi-line history replay produces terminal output with padded spaces instead of newlines #31843
Comments
I went ahead and made a tiny C reproduction, so this probably can be closed in favor of an upstream bug report... but leaving open anyway at least to track the issue. Compile with
To produce this, I typed And lo and behold, the padding issue exists there too.
|
Much simpler repro (just feed a newline string into add_history):
|
Fun fact: the problem faced by libedit, and in turn one of the major reasons why the terminfo database is so much more complex than termcap (and why ncurses exist -- hint, the terminfo db (in the shape of ncurses initially) has primarily been brought into existence to implement GNU readline), is exactly the problem of how to draw multiple lines of text from the current cursor position on the terminal and subsequently bring the cursor back where it was, without waisting the terminal bandwidth by filling with space characters. I fear this is one of the things that can't be solved unless libedit was grown to expand into the shape of GNU readline and mandate the complexity of terminfo with it, by which time we'd have grown the The alternative, of course, is to pretend to solve this problem for just one or two terminals, perhaps biased by what the current cockroachdb developers happen to use on macOS, and annoy the majority of sysadmins out there who are unlucky to use various levels of terminal emulators with odd semantics. |
@knz note that this still happens on Debian Linux... unless you're saying that it's biased by the shell I'm accessing the machine from |
I started a mailing list thread about it http://mail-index.netbsd.org/netbsd-bugs/2018/10/25/msg059467.html |
Thanks for launching that thread. Meanwhile I went ahead and dug into the netbsd changes since the version we're using. I haven't seen anything of note. |
Just for the record - this is factually wrong. You can perfectly well do this with termcap if termcap can describe your terminal (and for most terminals you don't need the advanced terminfo terminal description language features). |
@nbuwe my understanding is that termcap entries are not rich enough to allow clients to reliably determine the cursor position after emitting output when the cursor is positioned at the last column of a line, especially on the last line, on several common terminal types. If you think that's misinformed I would love you to point me to documentation on how to best achieve this using termcaps only. |
I don't think terminfo has a capability to express that for the lower-right corner either. GNU termcap had an For the lower-right corner you can avoid the problem by using insert mode or insert character(s) caps. Since ~all terminals that are not completely dumb provide some insertion command, you should be ok for all practical purposes. Worst case, you just avoid writing anything into the corner... The GNU termcap |
My understanding is that the complexity of GNU readline comes partly from the fact that this problem exists, and GNU readline as a result instead manually uses other terminfo caps to scroll the terminal when handling multi-line input a the bottom of the terminal. These caps in turn are terminfo-specific. Because these facilities are not available in termcap, libedit limits itself to not do this and is thus affected by the bug filed here. |
Your understanding is wrong. Again, termcap has two (or rather one and a half) limitations compared to terminfo. One (half) is that two-character capability names are awkward to work with. That made sense back in 16-bit days, but now it's an annoyance. That's not, really, a limitation (unless you need a lot of caps, just letters and numbers give you 36 ** 2 = 1296). The other is that that the terminfo language allows you to express more complex capabilities, but I don't remember (it's been 25+ years) which terminals actually needed that. So in theory there may be a terminal that has some command sequence that you can express with terminfo and cannot express in termcap. I'm pretty sure none of the common terminal types actually falls into that category. As i said, to work correctly with the lower-right corner you only need some form of character insertion (or, worst case, you just avoid it) and there's definitely nothing terminfo specific about that. That kind of logic is usually handled by curses and nothing prevents libedit from doing the same. As I said, the format of the capabilities database has nothing to do with it. It's just nobody really bothered. |
This was fixed by http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/terminal.c.diff?r1=1.33&r2=1.34&only_with_tag=MAIN&f=h, now we just need to find a way to vendor that library unconditionally, and not just on linux. |
…ries This is a fix for cockroachdb/cockroach#31843. Contributed upstream to NetBSD [0]. 0: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/terminal.c?rev=1.34&content-type=text/x-cvsweb-markup&f=h&only_with_tag=MAIN
…ries This is a fix for cockroachdb/cockroach#31843. Contributed upstream to NetBSD [0]. 0: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/terminal.c?rev=1.34&content-type=text/x-cvsweb-markup&f=h&only_with_tag=MAIN
…ries This is a fix for cockroachdb/cockroach#31843. Contributed upstream to NetBSD [0]. 0: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/terminal.c?rev=1.34&content-type=text/x-cvsweb-markup&f=h&only_with_tag=MAIN
…ries This is a fix for cockroachdb/cockroach#31843. Contributed upstream to NetBSD [0]. 0: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/terminal.c?rev=1.34&content-type=text/x-cvsweb-markup&f=h&only_with_tag=MAIN
…ries This is a fix for cockroachdb/cockroach#31843. Contributed upstream to NetBSD [0]. 0: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/terminal.c?rev=1.34&content-type=text/x-cvsweb-markup&f=h&only_with_tag=MAIN
…ries This is a fix for cockroachdb/cockroach#31843. Contributed upstream to NetBSD [0]. 0: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libedit/terminal.c?rev=1.34&content-type=text/x-cvsweb-markup&f=h&only_with_tag=MAIN
Teach our Makefile to orchestrate the configuration and building of our line editing library, libedit. This allows us to incorporate an upstream patch for cockroachdb#31843, which was causing incorrect spacing when recalling multi-line history entries. Previously, we were attempting to link against potentially outdated system libedits, which are likely to exhibit the bug for years to come. Release note (build change): a recent libedit is now bundled with CockroachDB, which fixes some line editing bugs in the CockroachDB console. On platforms that include libedit as part of the base system, like macOS and FreeBSD, CockroachDB no longer links against the system libedit.
Teach our Makefile to orchestrate the configuration and building of our line editing library, libedit. This allows us to incorporate an upstream patch for cockroachdb#31843, which was causing incorrect spacing when recalling multi-line history entries. Previously, we were attempting to link against potentially outdated system libedits, which are likely to exhibit the bug for years to come. Release note (build change): a recent libedit is now bundled with CockroachDB, which fixes some line editing bugs in the CockroachDB console. On platforms that include libedit as part of the base system, like macOS and FreeBSD, CockroachDB no longer links against the system libedit.
Teach our Makefile to orchestrate the configuration and building of our line editing library, libedit. This allows us to incorporate an upstream patch for cockroachdb#31843, which was causing incorrect spacing when recalling multi-line history entries. Previously, we were attempting to link against potentially outdated system libedits, which are likely to exhibit the bug for years to come. Release note (build change): a recent libedit is now bundled with CockroachDB, which fixes some line editing bugs in the CockroachDB console. On platforms that include libedit as part of the base system, like macOS and FreeBSD, CockroachDB no longer links against the system libedit.
32623: deps: configure and build patched libedit r=knz a=benesch ~There is more work to do here to appease the linter, but wanted to get this proof-of-concept out. @knz what copyright header would you like me to put on the files in cli/editline?~ --- ~Absorb our line-editing library, github.com/knz/go-libedit. The C library, libedit, is extracted into a c-deps submodule, where its build can be properly orchestrated by our Makefile to use the upstream autotools build system. The Go code is extracted into pkg/cli/editline, where it can more easily be modified to meet our needs.~ ~Fix #31843.~ ~Release note: None~ --- Teach our Makefile to orchestrate the configuration and building of our line editing library, libedit. This allows us to incorporate an upstream patch for #31843, which was causing incorrect spacing when recalling multi-line history entries. Previously, we were attempting to link against potentially outdated system libedits, which are likely to exhibit the bug for years to come. Release note (build change): a recent libedit is now bundled with CockroachDB, which fixes some line editing bugs in the CockroachDB console. On platforms that include libedit as part of the base system, like macOS and FreeBSD, CockroachDB no longer links against the system libedit. Co-authored-by: Nikhil Benesch <nikhil.benesch@gmail.com>
@benesch thank you so much for your determination on this! |
💪🏽
…On Fri, Jun 21, 2019 at 6:07 PM Jordan Lewis ***@***.***> wrote:
@benesch <https://github.com/benesch> thank you so much for your
determination on this!
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#31843?email_source=notifications&email_token=AAGXSIAXHGRVQEBJNSN2GPDP3VGI3A5CNFSM4F7E7NH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYJWLDQ#issuecomment-504587662>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAGXSIG45ZHGKWRMHHGMRHDP3VGI3ANCNFSM4F7E7NHQ>
.
|
This usability issue is very irritating - it causes pastes from terminal sessions to appear mangled. This happens all the time with customers.
Here's how to reproduce:
Now, press up and enter. That will produce the following output (changes depending on your terminal size):
As you can see, the problem is that the readline renderer produces a single, long string output for the line with an embedded newline, padding the continued lines with spaces up to the edge of the terminal.
I looked into this a bit and unfortunately the problem is not easy to solve. I confirmed that we're passing the correct (unpadded) input into readline. The problem occurs when readline retrieves that input from its history and renders it to the screen. The code is very confusing, but look at
refresh.c
, specifically the routines that callre__copy_and_pad()
- that's the function that pads a line with spaces. Naively messing with that function to stop doing that completely breaks libedit.The text was updated successfully, but these errors were encountered: