From: Tom de Vries <tdevries@suse.de>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: Re: [PATCH v2] [gdb/tui] Fix superfluous newline for long prompt
Date: Fri, 21 Jul 2023 09:37:25 +0200 [thread overview]
Message-ID: <3c2b0584-591d-8f2d-dd3c-cc478d319bea@suse.de> (raw)
In-Reply-To: <fadf580d-e28c-c3c8-0e34-be58cd6c20f7@suse.de>
On 7/14/23 14:18, Tom de Vries wrote:
> On 6/22/23 21:14, Tom de Vries via Gdb-patches wrote:
>> In test-case gdb.tui/long-prompt.exp, with a prompt of 40 chars, the
>> same size
>> as the terminal width, we get a superfluous newline at line 19:
>> ...
>> 16 (gdb) set prompt 123456789A123456789B123
>> 17 456789C123456789>
>> 18 123456789A123456789B123456789C123456789>
>> 19
>> 20 123456789A123456789B123456789C123456789>
>> 21 set prompt (gdb)
>> 22 (gdb)
>> ...
>> as well as a superfluous repetition of the prompt at line 20 once we
>> type the
>> 's' starting "set prompt".
>>
>> I traced the superfluous newline back to readline's
>> readline_internal_setup,
>> that does:
>> ...
>> /* If we're not echoing, we still want to at least print a prompt,
>> because
>> rl_redisplay will not do it for us. If the calling application
>> has a
>> custom redisplay function, though, let that function handle it. */
>> if (_rl_echoing_p == 0 && rl_redisplay_function == rl_redisplay)
>> ...
>> else
>> {
>> if (rl_prompt && rl_already_prompted)
>> rl_on_new_line_with_prompt ();
>> else
>> rl_on_new_line ();
>> (*rl_redisplay_function) ();
>> ...
>> and then we hit the case that calls rl_on_new_line_with_prompt, which
>> does:
>> ...
>> /* If the prompt length is a multiple of real_screenwidth, we don't
>> know
>> whether the cursor is at the end of the last line, or already at
>> the
>> beginning of the next line. Output a newline just to be safe. */
>> if (l > 0 && (l % real_screenwidth) == 0)
>> _rl_output_some_chars ("\n", 1);
>> ...
>>
>> This doesn't look like a readline bug, because the behaviour matches the
>> comment.
>>
>> [ And the fact that the output of the newline doesn't happen in the
>> scope of
>> tui_redisplay_readline means it doesn't get the prompt wrap detection
>> treatment, causing start_line to be incorrect, which causes the
>> superfluous
>> repetition of the prompt. ]
>>
>> I looked at ways to work around this, and managed by switching off
>> rl_already_prompted, which we set to 1 in tui_rl_startup_hook:
>> ...
>> /* Readline hook to redisplay ourself the gdb prompt.
>> In the SingleKey mode, the prompt is not printed so that
>> the command window is cleaner. It will be displayed if
>> we temporarily leave the SingleKey mode. */
>> static int
>> tui_rl_startup_hook (void)
>> {
>> rl_already_prompted = 1;
>> if (tui_current_key_mode != TUI_COMMAND_MODE
>> && !gdb_in_secondary_prompt_p (current_ui))
>> tui_set_key_mode (TUI_SINGLE_KEY_MODE);
>> tui_redisplay_readline ();
>> return 0;
>> }
>> ...
>>
>> Then I started looking at why rl_already_prompted is set to 1.
>>
>> The use case for rl_already_prompted seems to be:
>> - app (application, the readline user) outputs prompt,
>> - app sets rl_already_prompted to 1, and
>> - app calls readline, which calls rl_on_new_line_with_prompt, which
>> figures
>> out how long the prompt is, and sets a few readline variables
>> accordingly,
>> which can be used in the following call to rl_redisplay_function.
>>
>> AFAICT, TUI does not fit this pattern. It does not output an initial
>> prompt,
>> rather it writes the prompt in every rl_redisplay_function. It
>> doesn't use
>> the variables set by rl_on_new_line_with_prompt, instead it figures
>> stuff out
>> by itself.
>>
>> Fix this by removing the rl_already_prompted setting.
>>
>> Also remove the call to tui_redisplay_readline, it's not necessary, the
>> function is called anyway.
>>
>
> I'll commit this end of next week, unless there are comments.
>
Pushed.
Thanks,
- Tom
>> Tested on x86_64-linux, no regressions.
>> ---
>> gdb/testsuite/gdb.tui/long-prompt.exp | 18 +-----------------
>> gdb/tui/tui.c | 2 --
>> 2 files changed, 1 insertion(+), 19 deletions(-)
>>
>> diff --git a/gdb/testsuite/gdb.tui/long-prompt.exp
>> b/gdb/testsuite/gdb.tui/long-prompt.exp
>> index e4e8b75ede0..a08c08a884a 100644
>> --- a/gdb/testsuite/gdb.tui/long-prompt.exp
>> +++ b/gdb/testsuite/gdb.tui/long-prompt.exp
>> @@ -101,29 +101,13 @@ with_test_prefix "prompt size == width" {
>> # 16 (gdb) set prompt 123456789A123456789B123
>> # 17 456789C123456789>
>> # 18 123456789A123456789B123456789C123456789>
>> - # 19
>> - # 20 123456789A123456789B123456789C123456789>
>> - # 21 set prompt (gdb)
>> - # 22 (gdb)
>> - #
>> - # Note that it would be nice to get instead:
>> - #
>> - # 16 (gdb) set prompt 123456789A123456789B123
>> - # 17 456789C123456789>
>> - # 18 123456789A123456789B123456789C123456789>
>> # 19 set prompt (gdb)
>> # 20 (gdb)
>> - #
>> - # The extra newline is added by rl_on_new_line_with_prompt, which
>> decides
>> - # this as follows:
>> - # /* If the prompt length is a multiple of real_screenwidth, we
>> don't know
>> - # whether the cursor is at the end of the last line, or
>> already at the
>> - # beginning of the next line. Output a newline just to be
>> safe. */
>> gdb_assert { [Term::wait_for "^set prompt $gdb_prompt "] } \
>> "got prompt back"
>> - gdb_assert { $Term::_cur_row == 22 }
>> + gdb_assert { $Term::_cur_row == 20 }
>> }
>> with_test_prefix "prompt size == width - 1" {
>> diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c
>> index 43be8161e4c..941c65c970f 100644
>> --- a/gdb/tui/tui.c
>> +++ b/gdb/tui/tui.c
>> @@ -271,11 +271,9 @@ tui_rl_next_keymap (int notused1, int notused2)
>> static int
>> tui_rl_startup_hook (void)
>> {
>> - rl_already_prompted = 1;
>> if (tui_current_key_mode != TUI_COMMAND_MODE
>> && !gdb_in_secondary_prompt_p (current_ui))
>> tui_set_key_mode (TUI_SINGLE_KEY_MODE);
>> - tui_redisplay_readline ();
>> return 0;
>> }
>>
>> base-commit: d4d5b571954a2bde2a14772d9b18027a9048eb2d
>
prev parent reply other threads:[~2023-07-21 7:37 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-22 19:14 Tom de Vries
2023-07-14 12:18 ` Tom de Vries
2023-07-21 7:37 ` Tom de Vries [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3c2b0584-591d-8f2d-dd3c-cc478d319bea@suse.de \
--to=tdevries@suse.de \
--cc=gdb-patches@sourceware.org \
--cc=tom@tromey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).