mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:37:35 +00:00
VimEditingEngine: Allow repeats for dd, yy and x
This commit is contained in:
parent
c1e2710a0d
commit
7b7548ce9d
2 changed files with 65 additions and 10 deletions
|
@ -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 } } };
|
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)
|
void VimMotion::calculate_document_range(TextEditor& editor)
|
||||||
{
|
{
|
||||||
if (m_amount >= 0) {
|
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 (m_previous_key == KeyCode::Key_D) {
|
||||||
if (event.key() == KeyCode::Key_D && !m_motion.should_consume_next_character()) {
|
if (event.key() == KeyCode::Key_D && !m_motion.should_consume_next_character()) {
|
||||||
yank(Line);
|
if (m_motion.amount()) {
|
||||||
delete_line();
|
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_motion.reset();
|
||||||
m_previous_key = {};
|
m_previous_key = {};
|
||||||
} else {
|
} else {
|
||||||
|
@ -804,7 +844,13 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
|
||||||
}
|
}
|
||||||
} else if (m_previous_key == KeyCode::Key_Y) {
|
} else if (m_previous_key == KeyCode::Key_Y) {
|
||||||
if (event.key() == KeyCode::Key_Y && !m_motion.should_consume_next_character()) {
|
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_motion.reset();
|
||||||
m_previous_key = {};
|
m_previous_key = {};
|
||||||
} else {
|
} else {
|
||||||
|
@ -977,10 +1023,18 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
|
||||||
case (KeyCode::Key_U):
|
case (KeyCode::Key_U):
|
||||||
m_editor->undo();
|
m_editor->undo();
|
||||||
return true;
|
return true;
|
||||||
case (KeyCode::Key_X):
|
case (KeyCode::Key_X): {
|
||||||
yank({ m_editor->cursor(), { m_editor->cursor().line(), m_editor->cursor().column() + 1 } });
|
TextRange range = { m_editor->cursor(), { m_editor->cursor().line(), m_editor->cursor().column() + 1 } };
|
||||||
delete_char();
|
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;
|
return true;
|
||||||
|
}
|
||||||
case (KeyCode::Key_V):
|
case (KeyCode::Key_V):
|
||||||
switch_to_visual_mode();
|
switch_to_visual_mode();
|
||||||
return true;
|
return true;
|
||||||
|
@ -1233,10 +1287,10 @@ void VimEditingEngine::yank(YankType type)
|
||||||
m_yank_buffer = m_yank_buffer.trim_whitespace(TrimMode::Left);
|
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_type = yank_type;
|
||||||
m_yank_buffer = m_editor->document().text_in_range(range);
|
m_yank_buffer = m_editor->document().text_in_range(range).trim_whitespace(AK::TrimMode::Right);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VimEditingEngine::put_before()
|
void VimEditingEngine::put_before()
|
||||||
|
|
|
@ -101,6 +101,7 @@ public:
|
||||||
|
|
||||||
void add_key_code(KeyCode key, bool ctrl, bool shift, bool alt);
|
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_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);
|
Optional<TextPosition> get_position(VimEditingEngine& engine, bool in_visual_mode = false);
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
@ -165,7 +166,7 @@ private:
|
||||||
YankType m_yank_type {};
|
YankType m_yank_type {};
|
||||||
String m_yank_buffer {};
|
String m_yank_buffer {};
|
||||||
void yank(YankType);
|
void yank(YankType);
|
||||||
void yank(TextRange);
|
void yank(TextRange, YankType yank_type);
|
||||||
void put_before();
|
void put_before();
|
||||||
void put_after();
|
void put_after();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue