From 3f86407481135d8ef61b2f174a1df092d0f4dddf Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 3 Jun 2015 21:29:31 +0100 Subject: [PATCH] elm_code: consistently use 0 based text index This means it's more familiar as regular string work when using the elm_code_line APIs. It's also more distinct from the elm_code_widget layout which is still 1 based columns. To support unicode we must convert correctly. Now FIXED! --- elm_code/src/bin/elm_code_test_main.c | 4 +- elm_code/src/lib/elm_code_line.c | 2 +- elm_code/src/lib/elm_code_text.c | 77 +------------------ elm_code/src/lib/elm_code_text.h | 6 -- elm_code/src/lib/widget/elm_code_widget.c | 76 ++++++++---------- elm_code/src/lib/widget/elm_code_widget.eo | 23 +++++- .../lib/widget/elm_code_widget_selection.c | 70 ++++++++--------- .../src/lib/widget/elm_code_widget_text.c | 70 +++++++++++++++++ elm_code/src/tests/elm_code_test_text.c | 2 +- .../src/tests/widget/elm_code_test_widget.c | 4 +- src/bin/editor/edi_editor.c | 2 +- src/bin/editor/edi_editor_search.c | 20 ++--- 12 files changed, 169 insertions(+), 187 deletions(-) diff --git a/elm_code/src/bin/elm_code_test_main.c b/elm_code/src/bin/elm_code_test_main.c index a7ec071..8e2c9a0 100644 --- a/elm_code/src/bin/elm_code_test_main.c +++ b/elm_code/src/bin/elm_code_test_main.c @@ -54,7 +54,7 @@ _elm_code_test_line_done_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED, line = (Elm_Code_Line *)event_info; if (line->number == 1) - elm_code_line_token_add(line, 18, 25, 1, ELM_CODE_TOKEN_TYPE_COMMENT); + elm_code_line_token_add(line, 17, 24, 1, ELM_CODE_TOKEN_TYPE_COMMENT); else if (line->number == 4) line->status = ELM_CODE_STATUS_TYPE_ERROR; @@ -112,7 +112,7 @@ _elm_code_test_editor_setup(Evas_Object *parent) _append_line(code->file, "...Please?"); line = elm_code_file_line_get(code->file, 1); - elm_code_line_token_add(line, 6, 7, 1, ELM_CODE_TOKEN_TYPE_COMMENT); + elm_code_line_token_add(line, 5, 6, 1, ELM_CODE_TOKEN_TYPE_COMMENT); elm_code_callback_fire(code, &ELM_CODE_EVENT_LINE_LOAD_DONE, line); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); diff --git a/elm_code/src/lib/elm_code_line.c b/elm_code/src/lib/elm_code_line.c index f9d3b08..e0de0d5 100644 --- a/elm_code/src/lib/elm_code_line.c +++ b/elm_code/src/lib/elm_code_line.c @@ -83,7 +83,7 @@ EAPI void elm_code_line_token_add(Elm_Code_Line *line, int start, int end, int l if (end_line > line->number) { next_line = elm_code_file_line_get(line->file, line->number + 1); - elm_code_line_token_add(next_line, 1, end, lines - 1, type); + elm_code_line_token_add(next_line, 0, end, lines - 1, type); } } diff --git a/elm_code/src/lib/elm_code_text.c b/elm_code/src/lib/elm_code_text.c index e789942..9d42e4e 100644 --- a/elm_code/src/lib/elm_code_text.c +++ b/elm_code/src/lib/elm_code_text.c @@ -145,12 +145,10 @@ elm_code_line_text_insert(Elm_Code_Line *line, unsigned int position, const char return; inserted = malloc(sizeof(char) * line->length + length); - if (position > 0) - position--; if (position > line->length) position = line->length; - _elm_code_line_tokens_move_right(line, position + 1, length); + _elm_code_line_tokens_move_right(line, position, length); if (line->modified) { @@ -184,12 +182,10 @@ elm_code_line_text_remove(Elm_Code_Line *line, unsigned int position, int length return; removed = malloc(sizeof(char) * line->length - length); - if (position > 0) - position--; if (position > line->length) position = line->length; - _elm_code_line_tokens_move_left(line, position + 1, length); + _elm_code_line_tokens_move_left(line, position, length); if (line->modified) { @@ -248,72 +244,3 @@ elm_code_text_newlinenpos(const char *text, unsigned int length, short *nllen) return crpos; } -EAPI unsigned int -elm_code_line_text_column_width_to_position(Elm_Code_Line *line, unsigned int position, unsigned int tabstop) -{ - Eina_Unicode unicode; - unsigned int count = 0; - int index = 0; - const char *chars; - - if (line->length == 0) - return 0; - - if (line->modified) - chars = line->modified; - else - chars = line->content; - if (position > line->length) - position = line->length; - - while ((unsigned int) index < position) - { - unicode = eina_unicode_utf8_next_get(chars, &index); - if (unicode == 0) - break; - - if (unicode == '\t') - count += elm_code_text_tabwidth_at_position(count, tabstop); - else - count++; - } - - return count; -} - -EAPI unsigned int -elm_code_line_text_column_width(Elm_Code_Line *line, unsigned int tabstop) -{ - return elm_code_line_text_column_width_to_position(line, line->length, tabstop); -} - -EAPI unsigned int -elm_code_line_text_position_for_column_get(Elm_Code_Line *line, unsigned int column, unsigned int tabstop) -{ - Eina_Unicode unicode; - unsigned int count = 0; - int index = 0; - const char *chars; - - if (line->length == 0) - return 0; - - if (line->modified) - chars = line->modified; - else - chars = line->content; - - while ((unsigned int) count < column && index < (int) line->length) - { - unicode = eina_unicode_utf8_next_get(chars, &index); - - if (unicode == 0) - return line->length; - else if (unicode == '\t') - count += elm_code_text_tabwidth_at_position(count, tabstop); - else - count++; - } - - return (unsigned int) index; -} diff --git a/elm_code/src/lib/elm_code_text.h b/elm_code/src/lib/elm_code_text.h index 07eced9..f547891 100644 --- a/elm_code/src/lib/elm_code_text.h +++ b/elm_code/src/lib/elm_code_text.h @@ -54,12 +54,6 @@ EAPI int elm_code_text_strnpos(const char *text, unsigned int length, const char EAPI int elm_code_text_newlinenpos(const char *text, unsigned int length, short *nllen); -EAPI unsigned int elm_code_line_text_column_width_to_position(Elm_Code_Line *line, unsigned int length, unsigned int tabstop); - -EAPI unsigned int elm_code_line_text_column_width(Elm_Code_Line *line, unsigned int tabstop); - -EAPI unsigned int elm_code_line_text_position_for_column_get(Elm_Code_Line *line, unsigned int column, unsigned int tabstop); - /** * @} */ diff --git a/elm_code/src/lib/widget/elm_code_widget.c b/elm_code/src/lib/widget/elm_code_widget.c index c231d44..22ba56b 100644 --- a/elm_code/src/lib/widget/elm_code_widget.c +++ b/elm_code/src/lib/widget/elm_code_widget.c @@ -126,7 +126,7 @@ _elm_code_widget_resize(Elm_Code_Widget *widget) h = elm_code_file_lines_get(pd->code->file); EINA_LIST_FOREACH(pd->code->file->lines, item, line) { - line_width = elm_code_line_text_column_width(line, pd->tabstop); + line_width = elm_code_widget_line_text_column_width_get(widget, line); if ((int) line_width + gutter + 1 > w) w = (int) line_width + gutter + 1; } @@ -152,7 +152,7 @@ _elm_code_widget_fill_line_token(Evas_Textgrid_Cell *cells, int count, int start for (x = start; x <= end && x < count; x++) { - cells[x].fg = type; + cells[x - 1].fg = type; } } @@ -176,21 +176,19 @@ static void _elm_code_widget_fill_line_tokens(Elm_Code_Widget *widget, Evas_Textgrid_Cell *cells, unsigned int count, Elm_Code_Line *line) { - Elm_Code_Widget_Data *pd; Eina_List *item; Elm_Code_Token *token; unsigned int start, end, length, offset; unsigned int token_start_col, token_end_col; - pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); eo_do(widget, offset = elm_obj_code_widget_text_left_gutter_width_get()); start = offset; - length = elm_code_line_text_column_width(line, pd->tabstop) + offset; + length = elm_code_widget_line_text_column_width_get(widget, line) + offset; EINA_LIST_FOREACH(line->tokens, item, token) { - token_start_col = elm_code_line_text_column_width_to_position(line, token->start - 1, pd->tabstop) + offset; - token_end_col = elm_code_line_text_column_width_to_position(line, token->end - 1, pd->tabstop) + offset; + token_start_col = elm_code_widget_line_text_column_width_to_position(widget, line, token->start) + offset; + token_end_col = elm_code_widget_line_text_column_width_to_position(widget, line, token->end) + offset; if (token_start_col > start) _elm_code_widget_fill_line_token(cells, count, start, token_start_col, ELM_CODE_TOKEN_TYPE_DEFAULT); @@ -339,7 +337,7 @@ _elm_code_widget_fill_line(Elm_Code_Widget *widget, Elm_Code_Line *line) _elm_code_widget_fill_gutter(widget, cells, line->status, line->number); _elm_code_widget_fill_line_tokens(widget, cells, w, line); - length = elm_code_line_text_column_width(line, pd->tabstop); + length = elm_code_widget_line_text_column_width_get(widget, line); chrpos = 0; chr = (char *)elm_code_line_text_get(line, NULL); @@ -499,7 +497,7 @@ _elm_code_widget_cursor_key_will_move(Elm_Code_Widget *widget, const char *key) else if (!strcmp(key, "Left")) return pd->cursor_col > 1 || pd->cursor_line > 1; else if (!strcmp(key, "Right")) - return pd->cursor_col < elm_code_line_text_column_width(line, pd->tabstop) + 1 || + return pd->cursor_col < elm_code_widget_line_text_column_width_get(widget, line) + 1 || pd->cursor_line < elm_code_file_lines_get(pd->code->file); else return EINA_FALSE; @@ -637,7 +635,7 @@ _elm_code_widget_clicked_editable_cb(Elm_Code_Widget *widget, unsigned int row, line = elm_code_file_line_get(pd->code->file, row); if (!line) return; - column_width = elm_code_line_text_column_width(line, pd->tabstop); + column_width = elm_code_widget_line_text_column_width_get(widget, line); if (col > column_width + 1) col = column_width + 1; @@ -777,7 +775,7 @@ _elm_code_widget_cursor_move_end(Elm_Code_Widget *widget) pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); line = elm_code_file_line_get(pd->code->file, pd->cursor_line); - lastcol = elm_code_line_text_column_width(line, pd->tabstop); + lastcol = elm_code_widget_line_text_column_width_get(widget, line); if (pd->cursor_col > lastcol + 1) return; @@ -800,7 +798,7 @@ _elm_code_widget_cursor_move_up(Elm_Code_Widget *widget) row--; line = elm_code_file_line_get(pd->code->file, row); - column_width = elm_code_line_text_column_width(line, pd->tabstop); + column_width = elm_code_widget_line_text_column_width_get(widget, line); if (col > column_width + 1) col = column_width + 1; @@ -823,7 +821,7 @@ _elm_code_widget_cursor_move_down(Elm_Code_Widget *widget) row++; line = elm_code_file_line_get(pd->code->file, row); - column_width = elm_code_line_text_column_width(line, pd->tabstop); + column_width = elm_code_widget_line_text_column_width_get(widget, line); if (col > column_width + 1) col = column_width + 1; @@ -859,7 +857,7 @@ _elm_code_widget_cursor_move_right(Elm_Code_Widget *widget) pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); line = elm_code_file_line_get(pd->code->file, pd->cursor_line); - if (pd->cursor_col > elm_code_line_text_column_width(line, pd->tabstop)) + if (pd->cursor_col > elm_code_widget_line_text_column_width_get(widget, line)) { if (pd->cursor_line < elm_code_file_lines_get(pd->code->file)) { @@ -901,7 +899,7 @@ _elm_code_widget_cursor_move_pageup(Elm_Code_Widget *widget) row = 1; line = elm_code_file_line_get(pd->code->file, row); - column_width = elm_code_line_text_column_width(line, pd->tabstop); + column_width = elm_code_widget_line_text_column_width_get(widget, line); if (col > column_width + 1) col = column_width + 1; @@ -927,7 +925,7 @@ _elm_code_widget_cursor_move_pagedown(Elm_Code_Widget *widget) row = elm_code_file_lines_get(pd->code->file); line = elm_code_file_line_get(pd->code->file, row); - column_width = elm_code_line_text_column_width(line, pd->tabstop); + column_width = elm_code_widget_line_text_column_width_get(widget, line); if (col > column_width + 1) col = column_width + 1; @@ -953,21 +951,18 @@ _elm_code_widget_text_at_cursor_insert(Elm_Code_Widget *widget, const char *text { Elm_Code *code; Elm_Code_Line *line; - Elm_Code_Widget_Data *pd; unsigned int row, col, position, col_width; - pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); - _elm_code_widget_delete_selection(widget); eo_do(widget, code = elm_obj_code_widget_code_get(), elm_obj_code_widget_cursor_position_get(&col, &row)); line = elm_code_file_line_get(code->file, row); - position = elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); - elm_code_line_text_insert(line, position + 1, text, length); - col_width = elm_code_line_text_column_width_to_position(line, position + length, pd->tabstop) - - elm_code_line_text_column_width_to_position(line, position, pd->tabstop); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col); + elm_code_line_text_insert(line, position, text, length); + col_width = elm_code_widget_line_text_column_width_to_position(widget, line, position + length) - + elm_code_widget_line_text_column_width_to_position(widget, line, position); eo_do(widget, elm_obj_code_widget_cursor_position_set(col + col_width, row), @@ -980,17 +975,15 @@ _elm_code_widget_newline(Elm_Code_Widget *widget) { Elm_Code *code; Elm_Code_Line *line; - Elm_Code_Widget_Data *pd; unsigned int row, col, position; - pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); _elm_code_widget_delete_selection(widget); eo_do(widget, code = elm_obj_code_widget_code_get(), elm_obj_code_widget_cursor_position_get(&col, &row)); line = elm_code_file_line_get(code->file, row); - position = elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col); elm_code_line_split_at(line, position); eo_do(widget, @@ -1004,7 +997,6 @@ _elm_code_widget_backspaceline(Elm_Code_Widget *widget, Eina_Bool nextline) { Elm_Code *code; Elm_Code_Line *line, *otherline; - Elm_Code_Widget_Data *pd; unsigned int row, col, position; const char *text1, *text2; @@ -1040,11 +1032,10 @@ _elm_code_widget_backspaceline(Elm_Code_Widget *widget, Eina_Bool nextline) free(newtext); if (!nextline) { - pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); - position = elm_code_line_text_column_width_to_position(line, length1, pd->tabstop); + position = elm_code_widget_line_text_column_width_to_position(widget, line, length1); eo_do(widget, - elm_obj_code_widget_cursor_position_set(position + 1, row - 1)); + elm_obj_code_widget_cursor_position_set(position, row - 1)); } // TODO construct and pass a change object eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL)); @@ -1055,7 +1046,6 @@ _elm_code_widget_backspace(Elm_Code_Widget *widget) { Elm_Code *code; Elm_Code_Line *line; - Elm_Code_Widget_Data *pd; unsigned int row, col, position, start_col, char_width; if (_elm_code_widget_delete_selection(widget)) @@ -1064,7 +1054,6 @@ _elm_code_widget_backspace(Elm_Code_Widget *widget) eo_do(widget, code = elm_obj_code_widget_code_get(), elm_obj_code_widget_cursor_position_get(&col, &row)); - pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); if (col <= 1) { @@ -1077,14 +1066,13 @@ _elm_code_widget_backspace(Elm_Code_Widget *widget) line = elm_code_file_line_get(code->file, row); - position = elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); - char_width = elm_code_line_text_position_for_column_get(line, col, pd->tabstop) - - elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); - start_col = elm_code_line_text_column_width_to_position(line, position - 1, pd->tabstop); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col - 1); + char_width = elm_code_widget_line_text_position_for_column_get(widget, line, col) - position; + start_col = elm_code_widget_line_text_column_width_to_position(widget, line, position); elm_code_line_text_remove(line, position, char_width?char_width:1); eo_do(widget, - elm_obj_code_widget_cursor_position_set(start_col + 1, row)); + elm_obj_code_widget_cursor_position_set(start_col, row)); // TODO construct and pass a change object eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL)); @@ -1096,9 +1084,6 @@ _elm_code_widget_delete(Elm_Code_Widget *widget) Elm_Code *code; Elm_Code_Line *line; unsigned int row, col, position, char_width, start_col; - Elm_Code_Widget_Data *pd; - - pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); if (_elm_code_widget_delete_selection(widget)) return; @@ -1107,7 +1092,7 @@ _elm_code_widget_delete(Elm_Code_Widget *widget) code = elm_obj_code_widget_code_get(), elm_obj_code_widget_cursor_position_get(&col, &row)); line = elm_code_file_line_get(code->file, row); - if (col > elm_code_line_text_column_width(line, pd->tabstop)) + if (col > elm_code_widget_line_text_column_width_get(widget, line)) { if (row == elm_code_file_lines_get(code->file)) return; @@ -1116,14 +1101,13 @@ _elm_code_widget_delete(Elm_Code_Widget *widget) return; } - position = elm_code_line_text_position_for_column_get(line, col, pd->tabstop); - char_width = elm_code_line_text_position_for_column_get(line, col, pd->tabstop) - - elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); - start_col = elm_code_line_text_column_width_to_position(line, position - 1, pd->tabstop); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col); + char_width = elm_code_widget_line_text_position_for_column_get(widget, line, col + 1) - position; + start_col = elm_code_widget_line_text_column_width_to_position(widget, line, position); elm_code_line_text_remove(line, position, char_width?char_width:1); eo_do(widget, - elm_obj_code_widget_cursor_position_set(start_col + 1, row), + elm_obj_code_widget_cursor_position_set(start_col, row), // TODO construct and pass a change object eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL)); } diff --git a/elm_code/src/lib/widget/elm_code_widget.eo b/elm_code/src/lib/widget/elm_code_widget.eo index cd8be42..fde1902 100644 --- a/elm_code/src/lib/widget/elm_code_widget.eo +++ b/elm_code/src/lib/widget/elm_code_widget.eo @@ -199,7 +199,7 @@ class Elm.Code_Widget (Elm.Layout, Elm_Interface_Atspi_Text) } values { col: uint; /*@ The horizontal position of the cursor, starting from column 1 */ - line: uint; /*@ The vertical position of the cursor - the top row is 1 an */ + line: uint; /*@ The vertical position of the cursor - the top row is 1 */ } } line_refresh { @@ -224,6 +224,27 @@ class Elm.Code_Widget (Elm.Layout, Elm_Interface_Atspi_Text) text_line_number_width_get { return: int; /*@ the column width required to represent the number of lines in the widget. */ } + + line_text_column_width_to_position { + params { + line: Elm_Code_Line *; + position: uint; + } + return: uint; + } + line_text_column_width_get { + params { + line: Elm_Code_Line *; + } + return: uint; + } + line_text_position_for_column_get { + params { + line: Elm_Code_Line *; + column: uint; + } + return: uint; + } } implements { class.constructor; diff --git a/elm_code/src/lib/widget/elm_code_widget_selection.c b/elm_code/src/lib/widget/elm_code_widget_selection.c index a410e27..9774526 100644 --- a/elm_code/src/lib/widget/elm_code_widget_selection.c +++ b/elm_code/src/lib/widget/elm_code_widget_selection.c @@ -30,7 +30,7 @@ _elm_code_widget_selection_limit(Evas_Object *widget EINA_UNUSED, Elm_Code_Widge *row = elm_code_file_lines_get(file); line = elm_code_file_line_get(file, *row); - width = elm_code_line_text_column_width(line, pd->tabstop); + width = elm_code_widget_line_text_column_width_get(widget, line); if (*col > width + 1) *col = width + 1; @@ -105,7 +105,7 @@ elm_code_widget_selection_clear(Evas_Object *widget) } static void -_elm_code_widget_selection_delete_single(Elm_Code_Widget_Data *pd) +_elm_code_widget_selection_delete_single(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd) { Elm_Code_Line *line; const char *old; @@ -117,10 +117,8 @@ _elm_code_widget_selection_delete_single(Elm_Code_Widget_Data *pd) line = elm_code_file_line_get(pd->code->file, pd->selection->start_line); old = elm_code_line_text_get(line, &old_length); - start = elm_code_line_text_position_for_column_get(line, pd->selection->start_col, - pd->tabstop) - 1; - end = elm_code_line_text_position_for_column_get(line, pd->selection->end_col, - pd->tabstop) - 1; + start = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->start_col); + end = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->end_col); length = line->length - (end - start + 1); content = malloc(sizeof(char) * length); @@ -132,7 +130,7 @@ _elm_code_widget_selection_delete_single(Elm_Code_Widget_Data *pd) } static void -_elm_code_widget_selection_delete_multi(Elm_Code_Widget_Data *pd) +_elm_code_widget_selection_delete_multi(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd) { Elm_Code_Line *line; const char *first, *last; @@ -144,13 +142,11 @@ _elm_code_widget_selection_delete_multi(Elm_Code_Widget_Data *pd) line = elm_code_file_line_get(pd->code->file, pd->selection->start_line); first = elm_code_line_text_get(line, NULL); - start = elm_code_line_text_position_for_column_get(line, pd->selection->start_col, - pd->tabstop) - 1; + start = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->start_col); line = elm_code_file_line_get(pd->code->file, pd->selection->end_line); last = elm_code_line_text_get(line, &last_length); - end = elm_code_line_text_position_for_column_get(line, pd->selection->end_col, - pd->tabstop) - 1; + end = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->end_col); length = start + last_length - (end + 1); content = malloc(sizeof(char) * length); @@ -177,9 +173,9 @@ elm_code_widget_selection_delete(Evas_Object *widget) return; if (pd->selection->start_line == pd->selection->end_line) - _elm_code_widget_selection_delete_single(pd); + _elm_code_widget_selection_delete_single(widget, pd); else - _elm_code_widget_selection_delete_multi(pd); + _elm_code_widget_selection_delete_multi(widget, pd); free(pd->selection); pd->selection = NULL; @@ -187,34 +183,37 @@ elm_code_widget_selection_delete(Evas_Object *widget) } static char * -_elm_code_widget_selection_text_single_get(Elm_Code_Widget_Data *pd) +_elm_code_widget_selection_text_single_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd) { Elm_Code_Line *line; + unsigned int start, end; line = elm_code_file_line_get(pd->code->file, pd->selection->start_line); + start = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->start_col); + end = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->end_col + 1); - return elm_code_line_text_substr(line, pd->selection->start_col - 1, - pd->selection->end_col - pd->selection->start_col + 1); + return elm_code_line_text_substr(line, start, end - start); } static char * -_elm_code_widget_selection_text_multi_get(Elm_Code_Widget_Data *pd) +_elm_code_widget_selection_text_multi_get(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd) { Elm_Code_Line *line; char *first, *last, *ret, *ptr; const char *newline; short newline_len; int ret_len; - unsigned int row; + unsigned int row, start, end; newline = elm_code_file_line_ending_chars_get(pd->code->file, &newline_len); line = elm_code_file_line_get(pd->code->file, pd->selection->start_line); - first = elm_code_line_text_substr(line, pd->selection->start_col - 1, - line->length - pd->selection->start_col + 1); + start = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->start_col); + first = elm_code_line_text_substr(line, start, line->length - start + 1); line = elm_code_file_line_get(pd->code->file, pd->selection->end_line); - last = elm_code_line_text_substr(line, 0, pd->selection->end_col); + end = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->end_col + 1); + last = elm_code_line_text_substr(line, 0, end); ret_len = strlen(first) + strlen(last) + newline_len; @@ -259,9 +258,9 @@ elm_code_widget_selection_text_get(Evas_Object *widget) return strdup(""); if (pd->selection->start_line == pd->selection->end_line) - return _elm_code_widget_selection_text_single_get(pd); + return _elm_code_widget_selection_text_single_get(widget, pd); else - return _elm_code_widget_selection_text_multi_get(pd); + return _elm_code_widget_selection_text_multi_get(widget, pd); } static void @@ -299,23 +298,23 @@ elm_code_widget_selection_copy(Evas_Object *widget) } static void -_selection_paste_single(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd, Elm_Code *code, +_selection_paste_single(Elm_Code_Widget *widget, Elm_Code *code, unsigned int col, unsigned int row, const char *text, unsigned int len) { Elm_Code_Line *line; unsigned int position, newcol; line = elm_code_file_line_get(code->file, row); - position = elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); - elm_code_line_text_insert(line, position + 1, text, len); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col); + elm_code_line_text_insert(line, position, text, len); - newcol = elm_code_line_text_column_width_to_position(line, position + len, pd->tabstop); + newcol = elm_code_widget_line_text_column_width_to_position(widget, line, position + len); eo_do(widget, - elm_obj_code_widget_cursor_position_set(newcol + 1, row)); + elm_obj_code_widget_cursor_position_set(newcol, row)); } static void -_selection_paste_multi(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd, Elm_Code *code, +_selection_paste_multi(Elm_Code_Widget *widget, Elm_Code *code, unsigned int col, unsigned int row, const char *text, unsigned int len) { Elm_Code_Line *line; @@ -325,7 +324,7 @@ _selection_paste_multi(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd, Elm_Co char *ptr; line = elm_code_file_line_get(code->file, row); - position = elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); + position = elm_code_widget_line_text_position_for_column_get(widget, line, col); elm_code_line_split_at(line, position); newrow = row; @@ -334,7 +333,7 @@ _selection_paste_multi(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd, Elm_Co while ((nlpos = elm_code_text_newlinenpos(ptr, remain, &nllen)) != ELM_CODE_TEXT_NOT_FOUND) { if (newrow == row) - _selection_paste_single(widget, pd, code, col, row, text, nlpos); + _selection_paste_single(widget, code, col, row, text, nlpos); else elm_code_file_line_insert(code->file, newrow, ptr, nlpos, NULL); @@ -343,7 +342,7 @@ _selection_paste_multi(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd, Elm_Co newrow++; } - _selection_paste_single(widget, pd, code, 1, newrow, ptr, len - (ptr - text)); + _selection_paste_single(widget, code, 1, newrow, ptr, len - (ptr - text)); } static Eina_Bool @@ -351,15 +350,12 @@ _selection_paste_cb(void *data, Evas_Object *obj EINA_UNUSED, Elm_Selection_Data { Elm_Code *code; Elm_Code_Widget *widget; - Elm_Code_Widget_Data *pd; unsigned int row, col; widget = (Elm_Code_Widget *)data; - pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); if (ev->format != ELM_SEL_FORMAT_TEXT) return EINA_TRUE; - if (ev->len <= 0) return EINA_TRUE; @@ -368,9 +364,9 @@ _selection_paste_cb(void *data, Evas_Object *obj EINA_UNUSED, Elm_Selection_Data elm_obj_code_widget_cursor_position_get(&col, &row)); if (elm_code_text_newlinenpos(ev->data, ev->len, NULL) == ELM_CODE_TEXT_NOT_FOUND) - _selection_paste_single(widget, pd, code, col, row, ev->data, ev->len - 1); + _selection_paste_single(widget, code, col, row, ev->data, ev->len - 1); else - _selection_paste_multi(widget, pd, code, col, row, ev->data, ev->len - 1); + _selection_paste_multi(widget, code, col, row, ev->data, ev->len - 1); return EINA_TRUE; } diff --git a/elm_code/src/lib/widget/elm_code_widget_text.c b/elm_code/src/lib/widget/elm_code_widget_text.c index 696fc30..b3be117 100644 --- a/elm_code/src/lib/widget/elm_code_widget_text.c +++ b/elm_code/src/lib/widget/elm_code_widget_text.c @@ -33,3 +33,73 @@ _elm_code_widget_text_left_gutter_width_get(Eo *obj, Elm_Code_Widget_Data *pd) return width; } + +static unsigned int +_elm_code_widget_line_text_column_width_to_position(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd, Elm_Code_Line *line, unsigned int position) +{ + Eina_Unicode unicode; + unsigned int count = 1; + int index = 0; + const char *chars; + + if (line->length == 0) + return 1; + + if (line->modified) + chars = line->modified; + else + chars = line->content; + if (position > line->length) + position = line->length; + + while ((unsigned int) index < position) + { + unicode = eina_unicode_utf8_next_get(chars, &index); + if (unicode == 0) + break; + + if (unicode == '\t') + count += elm_code_text_tabwidth_at_position(count, pd->tabstop); + else + count++; + } + + return count; +} + +static unsigned int +_elm_code_widget_line_text_column_width_get(Eo *obj, Elm_Code_Widget_Data *pd, Elm_Code_Line *line) +{ + return _elm_code_widget_line_text_column_width_to_position(obj, pd, line, line->length) - 1; +} + +static unsigned int +_elm_code_widget_line_text_position_for_column_get(Eo *obj EINA_UNUSED, Elm_Code_Widget_Data *pd, Elm_Code_Line *line, unsigned int column) +{ + Eina_Unicode unicode; + unsigned int count = 1; + int index = 0; + const char *chars; + + if (line->length == 0 || column == 1) + return 0; + + if (line->modified) + chars = line->modified; + else + chars = line->content; + + while ((unsigned int) count < column && index < (int) line->length) + { + unicode = eina_unicode_utf8_next_get(chars, &index); + + if (unicode == 0) + return line->length; + else if (unicode == '\t') + count += elm_code_text_tabwidth_at_position(count, pd->tabstop); + else + count++; + } + + return (unsigned int) index; +} diff --git a/elm_code/src/tests/elm_code_test_text.c b/elm_code/src/tests/elm_code_test_text.c index c291569..85784a4 100644 --- a/elm_code/src/tests/elm_code_test_text.c +++ b/elm_code/src/tests/elm_code_test_text.c @@ -32,7 +32,7 @@ START_TEST (elm_code_text_insert_test) elm_code_file_line_append(file, "test", 4, NULL); line = elm_code_file_line_get(file, 1); - elm_code_line_text_insert(line, 5, "ing", 3); + elm_code_line_text_insert(line, 4, "ing", 3); ck_assert_str_eq("testing", elm_code_line_text_get(line, NULL)); } END_TEST diff --git a/elm_code/src/tests/widget/elm_code_test_widget.c b/elm_code/src/tests/widget/elm_code_test_widget.c index cd10319..a30e6ea 100644 --- a/elm_code/src/tests/widget/elm_code_test_widget.c +++ b/elm_code/src/tests/widget/elm_code_test_widget.c @@ -35,8 +35,8 @@ START_TEST (elm_code_widget_token_render_simple_test) line = elm_code_file_line_get(file, 1); length = line->length; - elm_code_line_token_add(line, 6+1, 17+1, 1, ELM_CODE_TOKEN_TYPE_COMMENT); - elm_code_line_token_add(line, 21+1, 22+1, 1, ELM_CODE_TOKEN_TYPE_COMMENT); + elm_code_line_token_add(line, 6, 17, 1, ELM_CODE_TOKEN_TYPE_COMMENT); + elm_code_line_token_add(line, 21, 22, 1, ELM_CODE_TOKEN_TYPE_COMMENT); _elm_code_widget_fill_line_tokens(widget, cells, length+1, line); _assert_cell_type(cells[1], ELM_CODE_TOKEN_TYPE_DEFAULT, 1); diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index f787c2e..bd1ea23 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -257,7 +257,7 @@ _edi_range_color_set(Edi_Editor *editor, Edi_Range range, Elm_Code_Token_Type ty ecore_thread_main_loop_begin(); - elm_code_line_token_add(line, range.start.col, range.end.col - 1, + elm_code_line_token_add(line, range.start.col - 1, range.end.col - 2, range.end.line - range.start.line + 1, type); elm_code_widget_line_refresh(editor->entry, line); diff --git a/src/bin/editor/edi_editor_search.c b/src/bin/editor/edi_editor_search.c index 6bb858a..6f180dc 100644 --- a/src/bin/editor/edi_editor_search.c +++ b/src/bin/editor/edi_editor_search.c @@ -56,7 +56,7 @@ _edi_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search) code = elm_code_widget_code_get(entry); elm_code_widget_cursor_position_get(entry, &pos_col, &pos_line); - if (search->current_search_line == pos_line || + if (search->current_search_line == pos_line && search->current_search_col == pos_col) { try_next = EINA_TRUE; @@ -70,15 +70,15 @@ _edi_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search) offset = 0; if (line->number == pos_line) - offset = pos_col - 1 + (try_next ? 1 : 0); + offset = elm_code_widget_line_text_position_for_column_get(entry, line, pos_col) + (try_next ? 1 : 0); found = elm_code_line_text_strpos(line, text, offset); if (found == ELM_CODE_TEXT_NOT_FOUND) continue; search->current_search_line = line->number; -// TODO make this unicode - search->current_search_col = found + 1; + search->current_search_col = + elm_code_widget_line_text_column_width_to_position(entry, line, found); break; } @@ -87,20 +87,10 @@ _edi_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search) if (!search->term_found) return EINA_FALSE; -/* - size_t pos = 0; - int idx = 0; - while ((utf8 + idx) < found) - { - pos++; - eina_unicode_utf8_next_get(utf8, &idx); - } -*/ elm_code_widget_selection_start(entry, search->current_search_line, search->current_search_col); -// TODO make that strlen unicode strlen elm_code_widget_selection_end(entry, search->current_search_line, - search->current_search_col + strlen(text) - 1); + elm_code_widget_line_text_column_width_to_position(entry, line, found + strlen(text)) - 1); return EINA_TRUE; }