summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGUI
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Libraries/LibGUI')
-rw-r--r--Userland/Libraries/LibGUI/VimEditingEngine.cpp72
-rw-r--r--Userland/Libraries/LibGUI/VimEditingEngine.h3
2 files changed, 65 insertions, 10 deletions
diff --git a/Userland/Libraries/LibGUI/VimEditingEngine.cpp b/Userland/Libraries/LibGUI/VimEditingEngine.cpp
index 6e2b478787..34de80c697 100644
--- a/Userland/Libraries/LibGUI/VimEditingEngine.cpp
+++ b/Userland/Libraries/LibGUI/VimEditingEngine.cpp
@@ -415,6 +415,39 @@ Optional<TextRange> VimMotion::get_range(VimEditingEngine& engine, bool normaliz
return { TextRange { { m_start_line, m_start_column }, { m_end_line, m_end_column } } };
}
+Optional<TextRange> VimMotion::get_repeat_range(VimEditingEngine& engine, VimMotion::Unit unit, bool normalize_for_position)
+{
+ TextEditor& editor = engine.editor();
+
+ if (m_amount > 0) {
+ m_amount--;
+ } else if (m_amount < 0) {
+ m_amount++;
+ }
+ auto position = editor.cursor();
+ int amount = abs(m_amount);
+ bool forwards = m_amount >= 0;
+ VimCursor cursor { editor, position, forwards };
+
+ m_start_line = m_end_line = position.line();
+ m_start_column = m_end_column = position.column();
+
+ switch (unit) {
+ case Unit::Line: {
+ calculate_line_range(editor, normalize_for_position);
+ break;
+ }
+ case Unit::Character: {
+ calculate_character_range(cursor, amount, normalize_for_position);
+ break;
+ }
+ default:
+ return {};
+ }
+
+ return { TextRange { { m_start_line, m_start_column }, { m_end_line, m_end_column } } };
+}
+
void VimMotion::calculate_document_range(TextEditor& editor)
{
if (m_amount >= 0) {
@@ -782,8 +815,15 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
if (m_previous_key == KeyCode::Key_D) {
if (event.key() == KeyCode::Key_D && !m_motion.should_consume_next_character()) {
- yank(Line);
- delete_line();
+ if (m_motion.amount()) {
+ auto range = m_motion.get_repeat_range(*this, VimMotion::Unit::Line);
+ VERIFY(range.has_value());
+ yank(*range, Line);
+ m_editor->delete_text_range(*range);
+ } else {
+ yank(Line);
+ delete_line();
+ }
m_motion.reset();
m_previous_key = {};
} else {
@@ -804,7 +844,13 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
}
} else if (m_previous_key == KeyCode::Key_Y) {
if (event.key() == KeyCode::Key_Y && !m_motion.should_consume_next_character()) {
- yank(Line);
+ if (m_motion.amount()) {
+ auto range = m_motion.get_repeat_range(*this, VimMotion::Unit::Line);
+ VERIFY(range.has_value());
+ yank(*range, Line);
+ } else {
+ yank(Line);
+ }
m_motion.reset();
m_previous_key = {};
} else {
@@ -977,10 +1023,18 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
case (KeyCode::Key_U):
m_editor->undo();
return true;
- case (KeyCode::Key_X):
- yank({ m_editor->cursor(), { m_editor->cursor().line(), m_editor->cursor().column() + 1 } });
- delete_char();
+ case (KeyCode::Key_X): {
+ TextRange range = { m_editor->cursor(), { m_editor->cursor().line(), m_editor->cursor().column() + 1 } };
+ if (m_motion.amount()) {
+ auto opt = m_motion.get_repeat_range(*this, VimMotion::Unit::Character);
+ VERIFY(opt.has_value());
+ range = *opt;
+ m_motion.reset();
+ }
+ yank(range, Selection);
+ m_editor->delete_text_range(range);
return true;
+ }
case (KeyCode::Key_V):
switch_to_visual_mode();
return true;
@@ -1233,10 +1287,10 @@ void VimEditingEngine::yank(YankType type)
m_yank_buffer = m_yank_buffer.trim_whitespace(TrimMode::Left);
}
-void VimEditingEngine::yank(TextRange range)
+void VimEditingEngine::yank(TextRange range, YankType yank_type)
{
- m_yank_type = YankType::Selection;
- m_yank_buffer = m_editor->document().text_in_range(range);
+ m_yank_type = yank_type;
+ m_yank_buffer = m_editor->document().text_in_range(range).trim_whitespace(AK::TrimMode::Right);
}
void VimEditingEngine::put_before()
diff --git a/Userland/Libraries/LibGUI/VimEditingEngine.h b/Userland/Libraries/LibGUI/VimEditingEngine.h
index 19c1e388c0..02652f8967 100644
--- a/Userland/Libraries/LibGUI/VimEditingEngine.h
+++ b/Userland/Libraries/LibGUI/VimEditingEngine.h
@@ -101,6 +101,7 @@ public:
void add_key_code(KeyCode key, bool ctrl, bool shift, bool alt);
Optional<TextRange> get_range(class VimEditingEngine& engine, bool normalize_for_position = false);
+ Optional<TextRange> get_repeat_range(class VimEditingEngine& engine, Unit, bool normalize_for_position = false);
Optional<TextPosition> get_position(VimEditingEngine& engine, bool in_visual_mode = false);
void reset();
@@ -165,7 +166,7 @@ private:
YankType m_yank_type {};
String m_yank_buffer {};
void yank(YankType);
- void yank(TextRange);
+ void yank(TextRange, YankType yank_type);
void put_before();
void put_after();