VimEditingEngine: Operate on real lines rather than wrapped ones

In the normal editing engine keys like Home, End etc work on visual
lines, but vim operates on real ones. Eg if you have a really long line
and wrapping is on then in normal editing Home would take you to the
beginning of the wrapped line, but 'I' would put you insert mode at the
beginning of the real line in vim.
This commit is contained in:
Matthew Hall 2021-07-10 21:48:49 +01:00 committed by Gunnar Beutner
parent 5d1676b05a
commit a7e7f62d08
Notes: sideshowbarker 2024-07-18 08:59:31 +09:00
3 changed files with 34 additions and 24 deletions

View File

@ -241,34 +241,42 @@ void EditingEngine::move_to_next_span(const KeyEvent& event)
}
}
void EditingEngine::move_to_line_beginning()
void EditingEngine::move_to_logical_line_beginning()
{
TextPosition new_cursor;
if (m_editor->is_wrapping_enabled()) {
// FIXME: Replicate the first_nonspace_column behavior in wrapping mode.
auto home_position = m_editor->cursor_content_rect().location().translated(-m_editor->width(), 0);
new_cursor = m_editor->text_position_at_content_position(home_position);
size_t first_nonspace_column = m_editor->current_line().first_non_whitespace_column();
if (m_editor->cursor().column() == first_nonspace_column) {
new_cursor = { m_editor->cursor().line(), 0 };
} else {
size_t first_nonspace_column = m_editor->current_line().first_non_whitespace_column();
if (m_editor->cursor().column() == first_nonspace_column) {
new_cursor = { m_editor->cursor().line(), 0 };
} else {
new_cursor = { m_editor->cursor().line(), first_nonspace_column };
}
new_cursor = { m_editor->cursor().line(), first_nonspace_column };
}
m_editor->set_cursor(new_cursor);
}
void EditingEngine::move_to_line_beginning()
{
if (m_editor->is_wrapping_enabled()) {
// FIXME: Replicate the first_nonspace_column behavior in wrapping mode.
auto home_position = m_editor->cursor_content_rect().location().translated(-m_editor->width(), 0);
m_editor->set_cursor(m_editor->text_position_at_content_position(home_position));
} else {
move_to_logical_line_beginning();
}
}
void EditingEngine::move_to_line_end()
{
TextPosition new_cursor;
if (m_editor->is_wrapping_enabled()) {
auto end_position = m_editor->cursor_content_rect().location().translated(m_editor->width(), 0);
new_cursor = m_editor->text_position_at_content_position(end_position);
m_editor->set_cursor(m_editor->text_position_at_content_position(end_position));
} else {
new_cursor = { m_editor->cursor().line(), m_editor->current_line().length() };
move_to_logical_line_end();
}
m_editor->set_cursor(new_cursor);
}
void EditingEngine::move_to_logical_line_end()
{
m_editor->set_cursor({ m_editor->cursor().line(), m_editor->current_line().length() });
}
void EditingEngine::move_one_up(const KeyEvent& event)

View File

@ -48,6 +48,8 @@ protected:
void move_one_down(const KeyEvent& event);
void move_to_previous_span();
void move_to_next_span(const KeyEvent& event);
void move_to_logical_line_beginning();
void move_to_logical_line_end();
void move_to_line_beginning();
void move_to_line_end();
void move_page_up();

View File

@ -834,10 +834,10 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
delete_line();
if (was_second_last_line || (m_editor->cursor().line() != 0 && m_editor->cursor().line() != m_editor->line_count() - 1)) {
move_one_up(event);
move_to_line_end();
move_to_logical_line_end();
m_editor->add_code_point(0x0A);
} else if (m_editor->cursor().line() == 0) {
move_to_line_beginning();
move_to_logical_line_beginning();
m_editor->add_code_point(0x0A);
move_one_up(event);
} else if (m_editor->cursor().line() == m_editor->line_count() - 1) {
@ -896,15 +896,15 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
if (event.shift() && !event.ctrl() && !event.alt()) {
switch (event.key()) {
case (KeyCode::Key_A):
move_to_line_end();
move_to_logical_line_end();
switch_to_insert_mode();
return true;
case (KeyCode::Key_I):
move_to_line_beginning();
move_to_logical_line_beginning();
switch_to_insert_mode();
return true;
case (KeyCode::Key_O):
move_to_line_beginning();
move_to_logical_line_beginning();
m_editor->add_code_point(0x0A);
move_one_up(event);
switch_to_insert_mode();
@ -958,7 +958,7 @@ bool VimEditingEngine::on_key_in_normal_mode(const KeyEvent& event)
switch_to_insert_mode();
return true;
case (KeyCode::Key_O):
move_to_line_end();
move_to_logical_line_end();
m_editor->add_code_point(0x0A);
switch_to_insert_mode();
return true;
@ -1043,11 +1043,11 @@ bool VimEditingEngine::on_key_in_visual_mode(const KeyEvent& event)
if (event.shift() && !event.ctrl() && !event.alt()) {
switch (event.key()) {
case (KeyCode::Key_A):
move_to_line_end();
move_to_logical_line_end();
switch_to_insert_mode();
return true;
case (KeyCode::Key_I):
move_to_line_beginning();
move_to_logical_line_beginning();
switch_to_insert_mode();
return true;
default:
@ -1230,7 +1230,7 @@ void VimEditingEngine::yank(TextRange range)
void VimEditingEngine::put()
{
if (m_yank_type == YankType::Line) {
move_to_line_end();
move_to_logical_line_end();
StringBuilder sb = StringBuilder(m_yank_buffer.length() + 1);
sb.append_code_point(0x0A);
sb.append(m_yank_buffer);