From a80024e96d9d09c85422499fe4de5dd59458af75 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 19 May 2026 14:59:38 +0200 Subject: [PATCH] ask-string: support prefilling a string query with an explicit string --- src/basic/terminal-util.c | 14 ++++++++++++-- src/basic/terminal-util.h | 4 ++-- src/firstboot/firstboot.c | 6 ++++++ src/home/homectl-prompts.c | 2 ++ src/home/homectl.c | 1 + src/shared/prompt-util.c | 2 ++ src/shared/prompt-util.h | 1 + src/sysinstall/sysinstall.c | 4 ++++ 8 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c index 5b3fc8990d..0d5b57138b 100644 --- a/src/basic/terminal-util.c +++ b/src/basic/terminal-util.c @@ -283,6 +283,7 @@ static void clear_by_backspace(size_t n) { int ask_string_full( char **ret, + const char *prefill, GetCompletionsCallback get_completions, void *userdata, const char *text, ...) { @@ -296,8 +297,17 @@ int ask_string_full( _cleanup_free_ char *string = NULL; size_t n = 0; - if (get_completions) { - /* Figure out what string to preselect the query with */ + if (prefill) { + /* Prefill query with explicit data if specified */ + + string = strdup(prefill); + if (!string) + return -ENOMEM; + + n = strlen(string); + + } else if (get_completions) { + /* Otherwise, figure out what string to preselect the query with */ _cleanup_strv_free_ char **completions = NULL; r = get_completions("", GET_COMPLETIONS_PRESELECT, &completions, userdata); if (r < 0) diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h index abf999e6d5..f8cd74f410 100644 --- a/src/basic/terminal-util.h +++ b/src/basic/terminal-util.h @@ -95,8 +95,8 @@ typedef enum GetCompletionsFlags { } GetCompletionsFlags; typedef int (*GetCompletionsCallback)(const char *key, GetCompletionsFlags flags, char ***ret_list, void *userdata); -int ask_string_full(char **ret, GetCompletionsCallback get_completions, void *userdata, const char *text, ...) _printf_(4, 5); -#define ask_string(ret, text, ...) ask_string_full(ret, NULL, NULL, text, ##__VA_ARGS__) +int ask_string_full(char **ret, const char *prefill, GetCompletionsCallback get_completions, void *userdata, const char *text, ...) _printf_(5, 6); +#define ask_string(ret, text, ...) ask_string_full(ret, NULL, NULL, NULL, text, ##__VA_ARGS__) bool any_key_to_proceed(void); int show_menu(char **x, size_t n_columns, size_t column_width, unsigned ellipsize_percentage, const char *grey_prefix, bool with_numbers); diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c index 8048ec0e81..ea36b91064 100644 --- a/src/firstboot/firstboot.c +++ b/src/firstboot/firstboot.c @@ -295,6 +295,7 @@ static int prompt_locale(int rfd, sd_varlink **mute_console_link) { r = prompt_loop("Please enter the new system locale name or number", GLYPH_WORLD, + /* prefill= */ NULL, locales, /* accepted= */ NULL, /* ellipsize_percentage= */ 60, @@ -312,6 +313,7 @@ static int prompt_locale(int rfd, sd_varlink **mute_console_link) { r = prompt_loop("Please enter the new system message locale name or number", GLYPH_WORLD, + /* prefill= */ NULL, locales, /* accepted= */ NULL, /* ellipsize_percentage= */ 60, @@ -457,6 +459,7 @@ static int prompt_keymap(int rfd, sd_varlink **mute_console_link) { return prompt_loop( "Please enter the new keymap name or number", GLYPH_KEYBOARD, + /* prefill= */ NULL, kmaps, /* accepted= */ NULL, /* ellipsize_percentage= */ 60, @@ -573,6 +576,7 @@ static int prompt_timezone(int rfd, sd_varlink **mute_console_link) { return prompt_loop( "Please enter the new timezone name or number", GLYPH_CLOCK, + /* prefill= */ NULL, zones, /* accepted= */ NULL, /* ellipsize_percentage= */ 30, @@ -680,6 +684,7 @@ static int prompt_hostname(int rfd, sd_varlink **mute_console_link) { r = prompt_loop("Please enter the new hostname", GLYPH_LABEL, + /* prefill= */ NULL, /* menu= */ NULL, /* accepted= */ NULL, /* ellipsize_percentage= */ 100, @@ -888,6 +893,7 @@ static int prompt_root_shell(int rfd, sd_varlink **mute_console_link) { return prompt_loop( "Please enter the new root shell", GLYPH_SHELL, + /* prefill= */ NULL, /* menu= */ NULL, /* accepted= */ NULL, /* ellipsize_percentage= */ 0, diff --git a/src/home/homectl-prompts.c b/src/home/homectl-prompts.c index 71640377e3..95a6ec3d04 100644 --- a/src/home/homectl-prompts.c +++ b/src/home/homectl-prompts.c @@ -117,6 +117,7 @@ int prompt_groups(const char *username, char ***ret_groups) { _cleanup_free_ char *s = NULL; r = ask_string_full( &s, + /* prefill= */ NULL, group_completion_callback, &available, "%s Please enter an auxiliary group for user %s (empty to continue, \"list\" to list available groups): ", @@ -231,6 +232,7 @@ int prompt_shell(const char *username, char **ret_shell) { return prompt_loop( q, GLYPH_SHELL, + /* prefill= */ NULL, /* menu= */ NULL, /* accepted= */ NULL, /* ellipsize_percentage= */ 0, diff --git a/src/home/homectl.c b/src/home/homectl.c index ab81efbed6..6891475f37 100644 --- a/src/home/homectl.c +++ b/src/home/homectl.c @@ -3009,6 +3009,7 @@ static int create_interactively(void) { r = prompt_loop("Please enter user name to create", GLYPH_IDCARD, + /* prefill= */ NULL, /* menu= */ NULL, /* accepted= */ NULL, /* ellipsize_percentage= */ 60, diff --git a/src/shared/prompt-util.c b/src/shared/prompt-util.c index 2f334f9b52..69728e0cb4 100644 --- a/src/shared/prompt-util.c +++ b/src/shared/prompt-util.c @@ -60,6 +60,7 @@ static int get_completions( int prompt_loop( const char *text, Glyph emoji, + const char *prefill, /* if non-NULL: prefill prompt with this string */ char **menu, /* if non-NULL: choices to suggest */ char **accepted, /* if non-NULL: choices to accept (should be a superset of 'menu') */ unsigned ellipsize_percentage, @@ -116,6 +117,7 @@ int prompt_loop( _cleanup_free_ char *p = NULL; r = ask_string_full( &p, + prefill, get_completions, &(CompletionData) { menu, accepted }, "%s%s%s%s: ", diff --git a/src/shared/prompt-util.h b/src/shared/prompt-util.h index 436127b32c..7afccd1b3d 100644 --- a/src/shared/prompt-util.h +++ b/src/shared/prompt-util.h @@ -14,6 +14,7 @@ typedef enum PromptFlags { int prompt_loop(const char *text, Glyph emoji, + const char *prefill, char **menu, char **accepted, unsigned ellipsize_percentage, diff --git a/src/sysinstall/sysinstall.c b/src/sysinstall/sysinstall.c index 7d08b4866b..23f4472e1c 100644 --- a/src/sysinstall/sysinstall.c +++ b/src/sysinstall/sysinstall.c @@ -384,6 +384,7 @@ static int prompt_block_device(sd_varlink **repart_link, char **ret_node) { r = prompt_loop("Please enter target disk device", GLYPH_COMPUTER_DISK, + /* prefill= */ NULL, menu, accepted, /* ellipsize_percentage= */ 20, @@ -540,6 +541,7 @@ static int prompt_erase( "Please type 'keep' to install the OS in addition to what the disk already contains, or 'erase' to erase all data on the disk" : "Please type 'erase' to confirm that all data on the disk shall be erased", GLYPH_BROOM, + /* prefill= */ NULL, /* menu= */ l, /* accepted= */ l, /* ellipsize_percentage= */ 20, @@ -578,6 +580,7 @@ static int prompt_touch_variables(void) { _cleanup_free_ char *reply = NULL; r = prompt_loop("Type 'yes' to register OS installation in firmware variables of the local system, 'no' otherwise", GLYPH_ROCKET, + /* prefill= */ NULL, /* menu= */ l, /* accepted= */ l, /* ellipsize_percentage= */ 20, @@ -616,6 +619,7 @@ static int prompt_confirm(void) { r = prompt_loop(arg_summary ? "Please type 'yes' to confirm the choices above and begin the installation" : "Please type 'yes' to begin the installation", GLYPH_WARNING_SIGN, + /* prefill= */ NULL, /* menu= */ l, /* accepted= */ l, /* ellipsize_percentage= */ 20,