Extend the previous improvements to efi_console_get_u16_string() by also implementing support for jumping to the previous/next word by holding ctrl when pressing left/right arrow.
This unfortunately can't be handled with only the basic text input protocol, so for now hackily look at the internal state of the efi console to read the modifier keys. Signed-off-by: Casey Connolly <[email protected]> --- lib/efi_loader/efi_console.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 7bfd18233feb..87de38a26569 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -1387,8 +1387,9 @@ efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *c efi_uintn_t len; efi_uintn_t cursor; efi_uintn_t i; struct efi_input_key key; + struct efi_key_state key_state; printf(ANSI_CURSOR_POSITION ANSI_CLEAR_LINE_TO_END ANSI_CURSOR_SHOW, row, col); @@ -1401,10 +1402,18 @@ efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *c printf(ANSI_CURSOR_POSITION "%ls" ANSI_CLEAR_LINE_TO_END ANSI_CURSOR_POSITION, row, col, buf, row, col + (int)cursor); do { + /* + * FIXME: we would ideally just use the proper extension protocol but we + * can't easily get a handle to it... Since this is only called + * internally we can be cheeky and access the internal state. + */ ret = EFI_CALL(cin->read_key_stroke(cin, &key)); - mdelay(10); + if (ret == EFI_SUCCESS) + key_state = next_key.key_state; + else + mdelay(10); } while (ret == EFI_NOT_READY); if (key.unicode_char == u'\b') { if (cursor > 0) { @@ -1429,11 +1438,17 @@ efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *c } 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; + while (key_state.key_shift_state & EFI_LEFT_CONTROL_PRESSED && + cursor < len && buf[cursor] != u' ' && buf[cursor] != u'.') + cursor++; continue; } else if (key.scan_code == 4) { /* Left arrow */ cursor -= (cursor > 0) ? 1 : 0; + while (key_state.key_shift_state & EFI_LEFT_CONTROL_PRESSED && + cursor > 0 && buf[cursor - 1] != u' ' && buf[cursor - 1] != u'.') + cursor--; continue; } else if (key.scan_code == 6) { /* End */ cursor = len; continue; -- 2.51.0

