From 7833dc0f5a4d3cad4edba1a9bdbba940ce36182a Mon Sep 17 00:00:00 2001 From: ronak69 Date: Mon, 29 Jan 2024 15:38:58 +0000 Subject: [PATCH] LibLine: Add internal functions to search character forwards & backwards --- Userland/Libraries/LibLine/Editor.cpp | 2 + Userland/Libraries/LibLine/Editor.h | 2 + .../Libraries/LibLine/InternalFunctions.cpp | 63 +++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/Userland/Libraries/LibLine/Editor.cpp b/Userland/Libraries/LibLine/Editor.cpp index b84a5217ac..1c3e22332a 100644 --- a/Userland/Libraries/LibLine/Editor.cpp +++ b/Userland/Libraries/LibLine/Editor.cpp @@ -156,6 +156,8 @@ void Editor::set_default_keybinds() register_key_input_callback(ctrl('K'), EDITOR_INTERNAL_FUNCTION(erase_to_end)); register_key_input_callback(ctrl('L'), EDITOR_INTERNAL_FUNCTION(clear_screen)); register_key_input_callback(ctrl('R'), EDITOR_INTERNAL_FUNCTION(enter_search)); + register_key_input_callback(ctrl(']'), EDITOR_INTERNAL_FUNCTION(search_character_forwards)); + register_key_input_callback(Key { ctrl(']'), Key::Alt }, EDITOR_INTERNAL_FUNCTION(search_character_backwards)); register_key_input_callback(ctrl('T'), EDITOR_INTERNAL_FUNCTION(transpose_characters)); register_key_input_callback('\n', EDITOR_INTERNAL_FUNCTION(finish)); diff --git a/Userland/Libraries/LibLine/Editor.h b/Userland/Libraries/LibLine/Editor.h index ab5bb82f3e..0c9ce9a054 100644 --- a/Userland/Libraries/LibLine/Editor.h +++ b/Userland/Libraries/LibLine/Editor.h @@ -110,6 +110,8 @@ struct Configuration { M(cursor_right_word) \ M(cursor_right_nonspace_word) \ M(enter_search) \ + M(search_character_backwards) \ + M(search_character_forwards) \ M(erase_character_backwards) \ M(erase_character_forwards) \ M(erase_to_beginning) \ diff --git a/Userland/Libraries/LibLine/InternalFunctions.cpp b/Userland/Libraries/LibLine/InternalFunctions.cpp index cea4662968..c86403a576 100644 --- a/Userland/Libraries/LibLine/InternalFunctions.cpp +++ b/Userland/Libraries/LibLine/InternalFunctions.cpp @@ -449,6 +449,69 @@ void Editor::enter_search() } } +namespace { +Optional read_unicode_char() +{ + // FIXME: It would be ideal to somehow communicate that the line editor is + // not operating in a normal mode and expects a character during the unicode + // read (cursor mode? change current cell? change prompt? Something else?) + StringBuilder builder; + + for (int i = 0; i < 4; ++i) { + char c = 0; + auto nread = read(0, &c, 1); + + if (nread <= 0) + return {}; + + builder.append(c); + + Utf8View search_char_utf8_view { builder.string_view() }; + + if (search_char_utf8_view.validate()) + return *search_char_utf8_view.begin(); + } + + return {}; +} +} + +void Editor::search_character_forwards() +{ + auto optional_search_char = read_unicode_char(); + if (not optional_search_char.has_value()) + return; + u32 search_char = optional_search_char.value(); + + for (auto index = m_cursor + 1; index < m_buffer.size(); ++index) { + if (m_buffer[index] == search_char) { + m_cursor = index; + return; + } + } + + fputc('\a', stderr); + fflush(stderr); +} + +void Editor::search_character_backwards() +{ + auto optional_search_char = read_unicode_char(); + if (not optional_search_char.has_value()) + return; + u32 search_char = optional_search_char.value(); + + for (auto index = m_cursor; index > 0; --index) { + if (m_buffer[index - 1] == search_char) { + m_cursor = index - 1; + return; + } + } + + fputc('\a', stderr); + fflush(stderr); +} + void Editor::transpose_words() { // A word here is contiguous alnums. `foo=bar baz` is three words.