Add H, M, L commands to move cursor within screen

This commit is contained in:
Josh Holtrop 2018-03-26 10:25:07 -04:00
parent 785801a315
commit 5d4ed598eb
5 changed files with 70 additions and 0 deletions

View File

@ -191,6 +191,15 @@ bool BufferView::cursor_move(CursorMovement which, uint32_t c, bool allow_eol)
case CursorMovement::BACK_ON_TO_CHAR:
moved = m_iterator->go_backward_in_line_on_to_char(c);
break;
case CursorMovement::TOP_OF_SCREEN:
moved = cursor_move_to_screen_position(0, effective_scroll_offset(), allow_eol);
break;
case CursorMovement::MIDDLE_OF_SCREEN:
moved = cursor_move_to_screen_position(0, m_height / 2, allow_eol);
break;
case CursorMovement::BOTTOM_OF_SCREEN:
moved = cursor_move_to_screen_position(0, m_height - effective_scroll_offset() - 1, allow_eol);
break;
}
if (moved)
{
@ -223,6 +232,12 @@ bool BufferView::cursor_move(CursorMovement which, uint32_t c, bool allow_eol)
case CursorMovement::LAST_LINE:
m_cursor_screen_row = m_height - 1;
break;
case CursorMovement::TOP_OF_SCREEN:
case CursorMovement::MIDDLE_OF_SCREEN:
case CursorMovement::BOTTOM_OF_SCREEN:
m_target_virtual_column = 0;
m_target_screen_column = 0;
break;
}
}
@ -266,6 +281,41 @@ bool BufferView::cursor_move_to_line(size_t target_line)
return false;
}
bool BufferView::cursor_move_to_screen_position(int x, int y, bool allow_eol)
{
bool moved = false;
for (const LineDescriptor & screen_line : m_lines)
{
if ((y >= screen_line.row_offset) &&
(y < (screen_line.row_offset + screen_line.n_rows)))
{
Buffer::Iterator scan_iter = *m_iterator;
bool set = false;
int desired_row_offset = y - screen_line.row_offset;
for (auto it = horiz_iter(screen_line.line); it.is_valid(); it++)
{
if (it.row_offset() == desired_row_offset)
{
if ((!set) ||
((it.screen_column() <= x) && (allow_eol || (!it.is_eol()))))
{
scan_iter = *it.iterator();
set = true;
}
}
}
if (scan_iter != *m_iterator)
{
*m_iterator = scan_iter;
moved = true;
determine_new_cursor_screen_row();
}
break;
}
}
return moved;
}
void BufferView::scroll_view_up(int n_lines, bool allow_eol)
{
int orig_cursor_screen_row = m_cursor_screen_row;

View File

@ -32,6 +32,9 @@ public:
FORWARD_ON_TO_CHAR,
BACK_UP_TO_CHAR,
BACK_ON_TO_CHAR,
TOP_OF_SCREEN,
MIDDLE_OF_SCREEN,
BOTTOM_OF_SCREEN,
};
class Iterator
@ -84,6 +87,7 @@ public:
}
bool cursor_move(CursorMovement which, uint32_t c, bool allow_eol);
bool cursor_move_to_line(size_t line);
bool cursor_move_to_screen_position(int x, int y, bool allow_eol);
int cursor_screen_row() const { return m_cursor_screen_row; }
int cursor_screen_column() const { return m_cursor_screen_column; }
int cursor_virtual_column() const { return m_cursor_virtual_column; }
@ -112,6 +116,7 @@ protected:
int m_cursor_screen_row;
int m_cursor_screen_column;
int m_cursor_virtual_column;
/** Holds the screen row offset of the cursor in the current line */
int m_cursor_row_offset;
int m_rows_in_cursor_line;
int m_target_screen_column;

View File

@ -42,6 +42,9 @@ public:
GO_RIGHT,
GO_START_OF_LINE,
GO_END_OF_LINE,
GO_TOP_OF_SCREEN,
GO_MIDDLE_OF_SCREEN,
GO_BOTTOM_OF_SCREEN,
NEXT,
PREV,
SCROLL_WINDOW_UP_ONE_LINE,

View File

@ -47,9 +47,11 @@ static void build_command_mode()
dcm->add("gg", Command::GO_TO_LINE, nullptr, false);
dcm->add("G", Command::GO_TO_LAST_LINE, nullptr, false);
dcm->add("h", Command::GO_LEFT, nullptr, false);
dcm->add("H", Command::GO_TOP_OF_SCREEN, nullptr, false);
dcm->add("j", Command::GO_DOWN, nullptr, false);
dcm->add("k", Command::GO_UP, nullptr, false);
dcm->add("l", Command::GO_RIGHT, nullptr, false);
dcm->add("L", Command::GO_BOTTOM_OF_SCREEN, nullptr, false);
dcm->add(":", Command::ENTER_COMMAND_LINE_PROMPT, nullptr, false);
dcm->add("x", Command::DELETE_CHAR, nullptr, false);
@ -59,6 +61,7 @@ static void build_command_mode()
dcm->add({JES_KEY_MODS_CTRL + 'b'}, Command::SCROLL_WINDOW_UP_WHOLE_SCREEN, nullptr, false);
dcm->add("n", Command::NEXT, nullptr, false);
dcm->add("N", Command::PREV, nullptr, false);
dcm->add("M", Command::GO_MIDDLE_OF_SCREEN, nullptr, false);
dcm->add({JES_KEY_HOME}, Command::GO_START_OF_LINE, nullptr, false);
dcm->add({JES_KEY_MODS_CTRL + JES_KEY_HOME}, Command::GO_START_OF_FILE, nullptr, false);

View File

@ -418,6 +418,15 @@ void Window::execute_command(const Command & command)
case Command::GO_END_OF_LINE:
m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::EOL, 0u);
break;
case Command::GO_TOP_OF_SCREEN:
m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::TOP_OF_SCREEN, 0u);
break;
case Command::GO_MIDDLE_OF_SCREEN:
m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::MIDDLE_OF_SCREEN, 0u);
break;
case Command::GO_BOTTOM_OF_SCREEN:
m_focused_buffer_pane->cursor_move(BufferPane::CursorMovement::BOTTOM_OF_SCREEN, 0u);
break;
case Command::NEXT:
break;
case Command::PREV: