Handle movement between editor lines with tabs.

This commit is contained in:
Jonas 'Sortie' Termansen 2014-08-01 10:47:10 +02:00
parent 8cf873e6d3
commit 18539b2240
3 changed files with 72 additions and 14 deletions

View File

@ -339,7 +339,7 @@ void editor_type_control_right(struct editor* editor)
{
struct line* line = &editor->lines[editor->cursor_row];
wchar_t wc = editor->cursor_column != line->used ?
line->data[editor->cursor_column] : ' ';
line->data[editor->cursor_column] : L' ';
if ( (state == 0 && !iswspace(wc)) || (state == 1 && iswspace(wc)) )
{
if ( ++state == 2 )
@ -357,7 +357,7 @@ void editor_type_control_select_right(struct editor* editor)
{
struct line* line = &editor->lines[editor->select_row];
wchar_t wc = editor->select_column != line->used ?
line->data[editor->select_column] : ' ';
line->data[editor->select_column] : L' ';
if ( (state == 0 && !iswspace(wc)) || (state == 1 && iswspace(wc)) )
{
if ( ++state == 2 )
@ -375,9 +375,11 @@ void editor_type_up(struct editor* editor)
editor_cursor_column_set(editor, 0);
return;
}
size_t new_line_len = editor->lines[editor_cursor_row_dec(editor)].used;
if ( new_line_len < editor->cursor_column )
editor_cursor_column_set(editor, new_line_len);
struct line* old_line = &editor->lines[editor->cursor_row];
struct line* new_line = &editor->lines[editor_cursor_row_dec(editor)];
size_t old_column = editor_display_column_of_line_offset(editor, old_line, editor->cursor_column);
size_t new_offset = editor_line_offset_of_display_column(editor, new_line, old_column);
editor_cursor_column_set(editor, new_offset);
}
void editor_type_select_up(struct editor* editor)
@ -387,9 +389,11 @@ void editor_type_select_up(struct editor* editor)
editor_select_column_set(editor, 0);
return;
}
size_t new_line_len = editor->lines[editor_select_row_dec(editor)].used;
if ( new_line_len < editor->select_column )
editor_select_column_set(editor, new_line_len);
struct line* old_line = &editor->lines[editor->select_row];
struct line* new_line = &editor->lines[editor_select_row_dec(editor)];
size_t old_column = editor_display_column_of_line_offset(editor, old_line, editor->select_column);
size_t new_offset = editor_line_offset_of_display_column(editor, new_line, old_column);
editor_select_column_set(editor, new_offset);
}
void editor_type_control_up(struct editor* editor)
@ -415,9 +419,11 @@ void editor_type_down(struct editor* editor)
editor_cursor_column_set(editor, editor->lines[editor->cursor_row].used);
return;
}
size_t new_line_len = editor->lines[editor_cursor_row_inc(editor)].used;
if ( new_line_len < editor->cursor_column )
editor_cursor_column_set(editor, new_line_len);
struct line* old_line = &editor->lines[editor->cursor_row];
struct line* new_line = &editor->lines[editor_cursor_row_inc(editor)];
size_t old_column = editor_display_column_of_line_offset(editor, old_line, editor->cursor_column);
size_t new_offset = editor_line_offset_of_display_column(editor, new_line, old_column);
editor_cursor_column_set(editor, new_offset);
}
void editor_type_select_down(struct editor* editor)
@ -427,9 +433,11 @@ void editor_type_select_down(struct editor* editor)
editor_select_column_set(editor, editor->lines[editor->select_row].used);
return;
}
size_t new_line_len = editor->lines[editor_select_row_inc(editor)].used;
if ( new_line_len < editor->select_column )
editor_select_column_set(editor, new_line_len);
struct line* old_line = &editor->lines[editor->select_row];
struct line* new_line = &editor->lines[editor_select_row_inc(editor)];
size_t old_column = editor_display_column_of_line_offset(editor, old_line, editor->select_column);
size_t new_offset = editor_line_offset_of_display_column(editor, new_line, old_column);
editor_select_column_set(editor, new_offset);
}
void editor_type_control_down(struct editor* editor)

View File

@ -33,6 +33,48 @@
#include "multibyte.h++"
#include "terminal.h++"
size_t editor_display_column_of_line_offset(struct editor* editor,
const struct line* line,
size_t offset)
{
if ( line->used < offset )
offset = line->used;
return displayed_string_length(line->data, offset, editor->tabsize);
}
size_t editor_line_offset_of_display_column(struct editor* editor,
const struct line* line,
size_t column)
{
size_t current_column = 0;
for ( size_t offset = 0; offset < line->used; offset++ )
{
if ( column <= current_column )
return offset;
wchar_t wc = line->data[offset];
if ( wc == L'\t' )
{
size_t old_column = current_column;
do current_column++;
while ( current_column % editor->tabsize != 0 );
if ( column <= current_column )
{
size_t dist_to_old = column - old_column;
size_t dist_to_cur = current_column - column;
if ( dist_to_old < dist_to_cur )
return offset;
return offset + 1;
}
continue;
}
current_column++;
}
return line->used;
}
size_t displayed_string_length(const wchar_t* str, size_t len, size_t tabsize)
{
size_t ret_len = 0;

View File

@ -27,6 +27,7 @@
#include <stdint.h>
struct editor;
struct line;
struct terminal_state;
struct display_char
@ -35,6 +36,13 @@ struct display_char
uint8_t color;
};
size_t editor_display_column_of_line_offset(struct editor* editor,
const struct line* line,
size_t offset);
size_t editor_line_offset_of_display_column(struct editor* editor,
const struct line* line,
size_t column);
size_t displayed_string_length(const wchar_t* str, size_t len, size_t tabsize);
struct display_char* expand_tabs(const wchar_t* str, size_t len, uint8_t* colors,
size_t colors_len, size_t* ret_len_ptr,