浏览代码

LibLine: Add internal functions to search character forwards & backwards

ronak69 1 年之前
父节点
当前提交
7833dc0f5a

+ 2 - 0
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('K'), EDITOR_INTERNAL_FUNCTION(erase_to_end));
     register_key_input_callback(ctrl('L'), EDITOR_INTERNAL_FUNCTION(clear_screen));
     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('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(ctrl('T'), EDITOR_INTERNAL_FUNCTION(transpose_characters));
     register_key_input_callback('\n', EDITOR_INTERNAL_FUNCTION(finish));
     register_key_input_callback('\n', EDITOR_INTERNAL_FUNCTION(finish));
 
 

+ 2 - 0
Userland/Libraries/LibLine/Editor.h

@@ -110,6 +110,8 @@ struct Configuration {
     M(cursor_right_word)                       \
     M(cursor_right_word)                       \
     M(cursor_right_nonspace_word)              \
     M(cursor_right_nonspace_word)              \
     M(enter_search)                            \
     M(enter_search)                            \
+    M(search_character_backwards)              \
+    M(search_character_forwards)               \
     M(erase_character_backwards)               \
     M(erase_character_backwards)               \
     M(erase_character_forwards)                \
     M(erase_character_forwards)                \
     M(erase_to_beginning)                      \
     M(erase_to_beginning)                      \

+ 63 - 0
Userland/Libraries/LibLine/InternalFunctions.cpp

@@ -449,6 +449,69 @@ void Editor::enter_search()
     }
     }
 }
 }
 
 
+namespace {
+Optional<u32> 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()
 void Editor::transpose_words()
 {
 {
     // A word here is contiguous alnums. `foo=bar baz` is three words.
     // A word here is contiguous alnums. `foo=bar baz` is three words.