On Thu, 23 Oct 2025 at 17:26, Casey Connolly <[email protected]> wrote: > > When editing eficonfig "optional data" (typically cmdline arguments) > it's useful to be able to edit the string rather than having to re-type > the entire thing. Implement support for editing buffers to make this a > whole lot nicer. Specifically, add support for moving the cursor with > the arrow keys and End key as well as deleting backwards with the delete > key. > > Signed-off-by: Casey Connolly <[email protected]> > --- > cmd/eficonfig.c | 2 ++ > lib/efi_loader/efi_console.c | 52 > ++++++++++++++++++++++++++++++++++++-------- > 2 files changed, 45 insertions(+), 9 deletions(-) > > diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c > index 8ac0fb98e02e..d8d946c87ac8 100644 > --- a/cmd/eficonfig.c > +++ b/cmd/eficonfig.c > @@ -973,8 +973,10 @@ static efi_status_t handle_user_input(u16 *buf, int > buf_size, > tmp = calloc(1, buf_size * sizeof(u16)); > if (!tmp) > return EFI_OUT_OF_RESOURCES; > > + /* Populate tmp so user can edit existing string */ > + u16_strcpy(tmp, buf); > ret = efi_console_get_u16_string(cin, tmp, buf_size, NULL, 4, > cursor_col); > if (ret == EFI_SUCCESS) > u16_strcpy(buf, tmp); > > diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c > index 953f6831466e..7bfd18233feb 100644 > --- a/lib/efi_loader/efi_console.c > +++ b/lib/efi_loader/efi_console.c > @@ -1383,36 +1383,61 @@ efi_status_t efi_console_get_u16_string(struct > efi_simple_text_input_protocol *c > efi_console_filter_func filter_func, > int row, int col) > { > efi_status_t ret; > - efi_uintn_t len = 0; > + efi_uintn_t len; > + efi_uintn_t cursor; > + efi_uintn_t i; > struct efi_input_key key; > > printf(ANSI_CURSOR_POSITION > ANSI_CLEAR_LINE_TO_END > ANSI_CURSOR_SHOW, row, col); > > efi_cin_empty_buffer(); > > + len = u16_strlen(buf); > + cursor = len; > for (;;) { > + printf(ANSI_CURSOR_POSITION "%ls" > + ANSI_CLEAR_LINE_TO_END ANSI_CURSOR_POSITION, > + row, col, buf, row, col + (int)cursor); > do { > ret = EFI_CALL(cin->read_key_stroke(cin, &key)); > mdelay(10); > } while (ret == EFI_NOT_READY); > > if (key.unicode_char == u'\b') { > - if (len > 0) > - buf[--len] = u'\0'; > - > - printf(ANSI_CURSOR_POSITION > - "%ls" > - ANSI_CLEAR_LINE_TO_END, row, col, buf); > + if (cursor > 0) { > + if (cursor == len) { > + buf[--cursor] = u'\0'; > + } else { > + for (i = cursor - 1; i < len; i++) > + buf[i] = buf[i + 1]; > + cursor--; > + } > + len--; > + } > + continue; > + } else if (key.scan_code == 8) { /* delete */ > + for (i = cursor; i <= len; i++) > + buf[i] = buf[i + 1]; > + len--; > continue; > } else if (key.unicode_char == u'\r') { > buf[len] = u'\0'; > return EFI_SUCCESS; > } else if (key.unicode_char == 0x3 || key.scan_code == 23) { > return EFI_ABORTED; > + } else if (key.scan_code == 3) { /* Right arrow */ > + cursor += (cursor < len) ? 1 : 0; > + continue; > + } else if (key.scan_code == 4) { /* Left arrow */ > + cursor -= (cursor > 0) ? 1 : 0; > + continue; > + } else if (key.scan_code == 6) { /* End */ > + cursor = len; > + continue; > } else if (key.unicode_char < 0x20) { > /* ignore control codes other than Ctrl+C, '\r' and > '\b' */ > continue; > } else if (key.scan_code != 0) { > @@ -1427,9 +1452,18 @@ efi_status_t efi_console_get_u16_string(struct > efi_simple_text_input_protocol *c > > if (len >= (count - 1)) > continue; > > - buf[len] = key.unicode_char; > + /* > + * Insert the character into the middle of the buffer, shift > the > + * characters after the cursor along. The check above ensures > we > + * will never overflow the buffer. > + * If the cursor is at the end of the string then this will > + * do nothing. > + */ > + for (i = len + 1; i > cursor; i--) > + buf[i] = buf[i - 1]; > + buf[cursor] = key.unicode_char; > + cursor++; > len++; > - printf(ANSI_CURSOR_POSITION "%ls", row, col, buf); > } > } > > -- > 2.51.0 >
Acked-by: Ilias Apalodimas <[email protected]> Tested-by: Ilias Apalodimas <[email protected]>

