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!
This commit is contained in:
Andy Williams 2015-06-03 21:29:31 +01:00
parent e3ed8806c3
commit 3f86407481
12 changed files with 169 additions and 187 deletions

View File

@ -54,7 +54,7 @@ _elm_code_test_line_done_cb(void *data EINA_UNUSED, Eo *obj EINA_UNUSED,
line = (Elm_Code_Line *)event_info; line = (Elm_Code_Line *)event_info;
if (line->number == 1) 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) else if (line->number == 4)
line->status = ELM_CODE_STATUS_TYPE_ERROR; line->status = ELM_CODE_STATUS_TYPE_ERROR;
@ -112,7 +112,7 @@ _elm_code_test_editor_setup(Evas_Object *parent)
_append_line(code->file, "...Please?"); _append_line(code->file, "...Please?");
line = elm_code_file_line_get(code->file, 1); 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); 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); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);

View File

@ -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) if (end_line > line->number)
{ {
next_line = elm_code_file_line_get(line->file, line->number + 1); 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);
} }
} }

View File

@ -145,12 +145,10 @@ elm_code_line_text_insert(Elm_Code_Line *line, unsigned int position, const char
return; return;
inserted = malloc(sizeof(char) * line->length + length); inserted = malloc(sizeof(char) * line->length + length);
if (position > 0)
position--;
if (position > line->length) if (position > line->length)
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) if (line->modified)
{ {
@ -184,12 +182,10 @@ elm_code_line_text_remove(Elm_Code_Line *line, unsigned int position, int length
return; return;
removed = malloc(sizeof(char) * line->length - length); removed = malloc(sizeof(char) * line->length - length);
if (position > 0)
position--;
if (position > line->length) if (position > line->length)
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) if (line->modified)
{ {
@ -248,72 +244,3 @@ elm_code_text_newlinenpos(const char *text, unsigned int length, short *nllen)
return crpos; 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;
}

View File

@ -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 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);
/** /**
* @} * @}
*/ */

View File

@ -126,7 +126,7 @@ _elm_code_widget_resize(Elm_Code_Widget *widget)
h = elm_code_file_lines_get(pd->code->file); h = elm_code_file_lines_get(pd->code->file);
EINA_LIST_FOREACH(pd->code->file->lines, item, line) 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) if ((int) line_width + gutter + 1 > w)
w = (int) line_width + gutter + 1; 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++) 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, _elm_code_widget_fill_line_tokens(Elm_Code_Widget *widget, Evas_Textgrid_Cell *cells,
unsigned int count, Elm_Code_Line *line) unsigned int count, Elm_Code_Line *line)
{ {
Elm_Code_Widget_Data *pd;
Eina_List *item; Eina_List *item;
Elm_Code_Token *token; Elm_Code_Token *token;
unsigned int start, end, length, offset; unsigned int start, end, length, offset;
unsigned int token_start_col, token_end_col; 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()); eo_do(widget, offset = elm_obj_code_widget_text_left_gutter_width_get());
start = offset; 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) 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_start_col = elm_code_widget_line_text_column_width_to_position(widget, line, token->start) + offset;
token_end_col = elm_code_line_text_column_width_to_position(line, token->end - 1, pd->tabstop) + offset; token_end_col = elm_code_widget_line_text_column_width_to_position(widget, line, token->end) + offset;
if (token_start_col > start) if (token_start_col > start)
_elm_code_widget_fill_line_token(cells, count, start, token_start_col, ELM_CODE_TOKEN_TYPE_DEFAULT); _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_gutter(widget, cells, line->status, line->number);
_elm_code_widget_fill_line_tokens(widget, cells, w, line); _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; chrpos = 0;
chr = (char *)elm_code_line_text_get(line, NULL); 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")) else if (!strcmp(key, "Left"))
return pd->cursor_col > 1 || pd->cursor_line > 1; return pd->cursor_col > 1 || pd->cursor_line > 1;
else if (!strcmp(key, "Right")) 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); pd->cursor_line < elm_code_file_lines_get(pd->code->file);
else else
return EINA_FALSE; 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); line = elm_code_file_line_get(pd->code->file, row);
if (!line) if (!line)
return; 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) if (col > column_width + 1)
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); pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
line = elm_code_file_line_get(pd->code->file, pd->cursor_line); 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) if (pd->cursor_col > lastcol + 1)
return; return;
@ -800,7 +798,7 @@ _elm_code_widget_cursor_move_up(Elm_Code_Widget *widget)
row--; row--;
line = elm_code_file_line_get(pd->code->file, 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) if (col > column_width + 1)
col = column_width + 1; col = column_width + 1;
@ -823,7 +821,7 @@ _elm_code_widget_cursor_move_down(Elm_Code_Widget *widget)
row++; row++;
line = elm_code_file_line_get(pd->code->file, 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) if (col > column_width + 1)
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); pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
line = elm_code_file_line_get(pd->code->file, pd->cursor_line); 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)) 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; row = 1;
line = elm_code_file_line_get(pd->code->file, 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) if (col > column_width + 1)
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); row = elm_code_file_lines_get(pd->code->file);
line = elm_code_file_line_get(pd->code->file, 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) if (col > column_width + 1)
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 *code;
Elm_Code_Line *line; Elm_Code_Line *line;
Elm_Code_Widget_Data *pd;
unsigned int row, col, position, col_width; unsigned int row, col, position, col_width;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
_elm_code_widget_delete_selection(widget); _elm_code_widget_delete_selection(widget);
eo_do(widget, eo_do(widget,
code = elm_obj_code_widget_code_get(), code = elm_obj_code_widget_code_get(),
elm_obj_code_widget_cursor_position_get(&col, &row)); elm_obj_code_widget_cursor_position_get(&col, &row));
line = elm_code_file_line_get(code->file, 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_text_insert(line, position + 1, text, length); elm_code_line_text_insert(line, position, text, length);
col_width = elm_code_line_text_column_width_to_position(line, position + length, pd->tabstop) - col_width = elm_code_widget_line_text_column_width_to_position(widget, line, position + length) -
elm_code_line_text_column_width_to_position(line, position, pd->tabstop); elm_code_widget_line_text_column_width_to_position(widget, line, position);
eo_do(widget, eo_do(widget,
elm_obj_code_widget_cursor_position_set(col + col_width, row), 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 *code;
Elm_Code_Line *line; Elm_Code_Line *line;
Elm_Code_Widget_Data *pd;
unsigned int row, col, position; unsigned int row, col, position;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
_elm_code_widget_delete_selection(widget); _elm_code_widget_delete_selection(widget);
eo_do(widget, eo_do(widget,
code = elm_obj_code_widget_code_get(), code = elm_obj_code_widget_code_get(),
elm_obj_code_widget_cursor_position_get(&col, &row)); elm_obj_code_widget_cursor_position_get(&col, &row));
line = elm_code_file_line_get(code->file, 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); elm_code_line_split_at(line, position);
eo_do(widget, eo_do(widget,
@ -1004,7 +997,6 @@ _elm_code_widget_backspaceline(Elm_Code_Widget *widget, Eina_Bool nextline)
{ {
Elm_Code *code; Elm_Code *code;
Elm_Code_Line *line, *otherline; Elm_Code_Line *line, *otherline;
Elm_Code_Widget_Data *pd;
unsigned int row, col, position; unsigned int row, col, position;
const char *text1, *text2; const char *text1, *text2;
@ -1040,11 +1032,10 @@ _elm_code_widget_backspaceline(Elm_Code_Widget *widget, Eina_Bool nextline)
free(newtext); free(newtext);
if (!nextline) if (!nextline)
{ {
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS); position = elm_code_widget_line_text_column_width_to_position(widget, line, length1);
position = elm_code_line_text_column_width_to_position(line, length1, pd->tabstop);
eo_do(widget, 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 // TODO construct and pass a change object
eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL)); 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 *code;
Elm_Code_Line *line; Elm_Code_Line *line;
Elm_Code_Widget_Data *pd;
unsigned int row, col, position, start_col, char_width; unsigned int row, col, position, start_col, char_width;
if (_elm_code_widget_delete_selection(widget)) if (_elm_code_widget_delete_selection(widget))
@ -1064,7 +1054,6 @@ _elm_code_widget_backspace(Elm_Code_Widget *widget)
eo_do(widget, eo_do(widget,
code = elm_obj_code_widget_code_get(), code = elm_obj_code_widget_code_get(),
elm_obj_code_widget_cursor_position_get(&col, &row)); elm_obj_code_widget_cursor_position_get(&col, &row));
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (col <= 1) if (col <= 1)
{ {
@ -1077,14 +1066,13 @@ _elm_code_widget_backspace(Elm_Code_Widget *widget)
line = elm_code_file_line_get(code->file, 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 - 1);
char_width = elm_code_line_text_position_for_column_get(line, col, pd->tabstop) - char_width = elm_code_widget_line_text_position_for_column_get(widget, line, col) - position;
elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); start_col = elm_code_widget_line_text_column_width_to_position(widget, line, position);
start_col = elm_code_line_text_column_width_to_position(line, position - 1, pd->tabstop);
elm_code_line_text_remove(line, position, char_width?char_width:1); elm_code_line_text_remove(line, position, char_width?char_width:1);
eo_do(widget, 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 // TODO construct and pass a change object
eo_do(widget, eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL)); 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 *code;
Elm_Code_Line *line; Elm_Code_Line *line;
unsigned int row, col, position, char_width, start_col; 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)) if (_elm_code_widget_delete_selection(widget))
return; return;
@ -1107,7 +1092,7 @@ _elm_code_widget_delete(Elm_Code_Widget *widget)
code = elm_obj_code_widget_code_get(), code = elm_obj_code_widget_code_get(),
elm_obj_code_widget_cursor_position_get(&col, &row)); elm_obj_code_widget_cursor_position_get(&col, &row));
line = elm_code_file_line_get(code->file, 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)) if (row == elm_code_file_lines_get(code->file))
return; return;
@ -1116,14 +1101,13 @@ _elm_code_widget_delete(Elm_Code_Widget *widget)
return; return;
} }
position = elm_code_line_text_position_for_column_get(line, col, pd->tabstop); position = elm_code_widget_line_text_position_for_column_get(widget, line, col);
char_width = elm_code_line_text_position_for_column_get(line, col, pd->tabstop) - char_width = elm_code_widget_line_text_position_for_column_get(widget, line, col + 1) - position;
elm_code_line_text_position_for_column_get(line, col - 1, pd->tabstop); start_col = elm_code_widget_line_text_column_width_to_position(widget, line, position);
start_col = elm_code_line_text_column_width_to_position(line, position - 1, pd->tabstop);
elm_code_line_text_remove(line, position, char_width?char_width:1); elm_code_line_text_remove(line, position, char_width?char_width:1);
eo_do(widget, 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 // TODO construct and pass a change object
eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL)); eo_event_callback_call(ELM_CODE_WIDGET_EVENT_CHANGED_USER, NULL));
} }

View File

@ -199,7 +199,7 @@ class Elm.Code_Widget (Elm.Layout, Elm_Interface_Atspi_Text)
} }
values { values {
col: uint; /*@ The horizontal position of the cursor, starting from column 1 */ 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 { line_refresh {
@ -224,6 +224,27 @@ class Elm.Code_Widget (Elm.Layout, Elm_Interface_Atspi_Text)
text_line_number_width_get { text_line_number_width_get {
return: int; /*@ the column width required to represent the number of lines in the widget. */ 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 { implements {
class.constructor; class.constructor;

View File

@ -30,7 +30,7 @@ _elm_code_widget_selection_limit(Evas_Object *widget EINA_UNUSED, Elm_Code_Widge
*row = elm_code_file_lines_get(file); *row = elm_code_file_lines_get(file);
line = elm_code_file_line_get(file, *row); 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) if (*col > width + 1)
*col = width + 1; *col = width + 1;
@ -105,7 +105,7 @@ elm_code_widget_selection_clear(Evas_Object *widget)
} }
static void 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; Elm_Code_Line *line;
const char *old; 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); line = elm_code_file_line_get(pd->code->file, pd->selection->start_line);
old = elm_code_line_text_get(line, &old_length); old = elm_code_line_text_get(line, &old_length);
start = elm_code_line_text_position_for_column_get(line, pd->selection->start_col, start = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->start_col);
pd->tabstop) - 1; end = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->end_col);
end = elm_code_line_text_position_for_column_get(line, pd->selection->end_col,
pd->tabstop) - 1;
length = line->length - (end - start + 1); length = line->length - (end - start + 1);
content = malloc(sizeof(char) * length); content = malloc(sizeof(char) * length);
@ -132,7 +130,7 @@ _elm_code_widget_selection_delete_single(Elm_Code_Widget_Data *pd)
} }
static void 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; Elm_Code_Line *line;
const char *first, *last; 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); line = elm_code_file_line_get(pd->code->file, pd->selection->start_line);
first = elm_code_line_text_get(line, NULL); first = elm_code_line_text_get(line, NULL);
start = elm_code_line_text_position_for_column_get(line, pd->selection->start_col, start = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->start_col);
pd->tabstop) - 1;
line = elm_code_file_line_get(pd->code->file, pd->selection->end_line); line = elm_code_file_line_get(pd->code->file, pd->selection->end_line);
last = elm_code_line_text_get(line, &last_length); last = elm_code_line_text_get(line, &last_length);
end = elm_code_line_text_position_for_column_get(line, pd->selection->end_col, end = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->end_col);
pd->tabstop) - 1;
length = start + last_length - (end + 1); length = start + last_length - (end + 1);
content = malloc(sizeof(char) * length); content = malloc(sizeof(char) * length);
@ -177,9 +173,9 @@ elm_code_widget_selection_delete(Evas_Object *widget)
return; return;
if (pd->selection->start_line == pd->selection->end_line) 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 else
_elm_code_widget_selection_delete_multi(pd); _elm_code_widget_selection_delete_multi(widget, pd);
free(pd->selection); free(pd->selection);
pd->selection = NULL; pd->selection = NULL;
@ -187,34 +183,37 @@ elm_code_widget_selection_delete(Evas_Object *widget)
} }
static char * 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; Elm_Code_Line *line;
unsigned int start, end;
line = elm_code_file_line_get(pd->code->file, pd->selection->start_line); 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, return elm_code_line_text_substr(line, start, end - start);
pd->selection->end_col - pd->selection->start_col + 1);
} }
static char * 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; Elm_Code_Line *line;
char *first, *last, *ret, *ptr; char *first, *last, *ret, *ptr;
const char *newline; const char *newline;
short newline_len; short newline_len;
int ret_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); 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); 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, start = elm_code_widget_line_text_position_for_column_get(widget, line, pd->selection->start_col);
line->length - pd->selection->start_col + 1); 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); 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; ret_len = strlen(first) + strlen(last) + newline_len;
@ -259,9 +258,9 @@ elm_code_widget_selection_text_get(Evas_Object *widget)
return strdup(""); return strdup("");
if (pd->selection->start_line == pd->selection->end_line) 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 else
return _elm_code_widget_selection_text_multi_get(pd); return _elm_code_widget_selection_text_multi_get(widget, pd);
} }
static void static void
@ -299,23 +298,23 @@ elm_code_widget_selection_copy(Evas_Object *widget)
} }
static void 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) unsigned int col, unsigned int row, const char *text, unsigned int len)
{ {
Elm_Code_Line *line; Elm_Code_Line *line;
unsigned int position, newcol; unsigned int position, newcol;
line = elm_code_file_line_get(code->file, 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_text_insert(line, position + 1, text, len); 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, eo_do(widget,
elm_obj_code_widget_cursor_position_set(newcol + 1, row)); elm_obj_code_widget_cursor_position_set(newcol, row));
} }
static void 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) unsigned int col, unsigned int row, const char *text, unsigned int len)
{ {
Elm_Code_Line *line; Elm_Code_Line *line;
@ -325,7 +324,7 @@ _selection_paste_multi(Elm_Code_Widget *widget, Elm_Code_Widget_Data *pd, Elm_Co
char *ptr; char *ptr;
line = elm_code_file_line_get(code->file, 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); elm_code_line_split_at(line, position);
newrow = row; 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) while ((nlpos = elm_code_text_newlinenpos(ptr, remain, &nllen)) != ELM_CODE_TEXT_NOT_FOUND)
{ {
if (newrow == row) if (newrow == row)
_selection_paste_single(widget, pd, code, col, row, text, nlpos); _selection_paste_single(widget, code, col, row, text, nlpos);
else else
elm_code_file_line_insert(code->file, newrow, ptr, nlpos, NULL); 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++; 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 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 *code;
Elm_Code_Widget *widget; Elm_Code_Widget *widget;
Elm_Code_Widget_Data *pd;
unsigned int row, col; unsigned int row, col;
widget = (Elm_Code_Widget *)data; widget = (Elm_Code_Widget *)data;
pd = eo_data_scope_get(widget, ELM_CODE_WIDGET_CLASS);
if (ev->format != ELM_SEL_FORMAT_TEXT) if (ev->format != ELM_SEL_FORMAT_TEXT)
return EINA_TRUE; return EINA_TRUE;
if (ev->len <= 0) if (ev->len <= 0)
return EINA_TRUE; 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)); elm_obj_code_widget_cursor_position_get(&col, &row));
if (elm_code_text_newlinenpos(ev->data, ev->len, NULL) == ELM_CODE_TEXT_NOT_FOUND) 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 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; return EINA_TRUE;
} }

View File

@ -33,3 +33,73 @@ _elm_code_widget_text_left_gutter_width_get(Eo *obj, Elm_Code_Widget_Data *pd)
return width; 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;
}

View File

@ -32,7 +32,7 @@ START_TEST (elm_code_text_insert_test)
elm_code_file_line_append(file, "test", 4, NULL); elm_code_file_line_append(file, "test", 4, NULL);
line = elm_code_file_line_get(file, 1); 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)); ck_assert_str_eq("testing", elm_code_line_text_get(line, NULL));
} }
END_TEST END_TEST

View File

@ -35,8 +35,8 @@ START_TEST (elm_code_widget_token_render_simple_test)
line = elm_code_file_line_get(file, 1); line = elm_code_file_line_get(file, 1);
length = line->length; 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, 6, 17, 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, 21, 22, 1, ELM_CODE_TOKEN_TYPE_COMMENT);
_elm_code_widget_fill_line_tokens(widget, cells, length+1, line); _elm_code_widget_fill_line_tokens(widget, cells, length+1, line);
_assert_cell_type(cells[1], ELM_CODE_TOKEN_TYPE_DEFAULT, 1); _assert_cell_type(cells[1], ELM_CODE_TOKEN_TYPE_DEFAULT, 1);

View File

@ -257,7 +257,7 @@ _edi_range_color_set(Edi_Editor *editor, Edi_Range range, Elm_Code_Token_Type ty
ecore_thread_main_loop_begin(); 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); range.end.line - range.start.line + 1, type);
elm_code_widget_line_refresh(editor->entry, line); elm_code_widget_line_refresh(editor->entry, line);

View File

@ -56,7 +56,7 @@ _edi_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search)
code = elm_code_widget_code_get(entry); code = elm_code_widget_code_get(entry);
elm_code_widget_cursor_position_get(entry, &pos_col, &pos_line); 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) search->current_search_col == pos_col)
{ {
try_next = EINA_TRUE; try_next = EINA_TRUE;
@ -70,15 +70,15 @@ _edi_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search)
offset = 0; offset = 0;
if (line->number == pos_line) 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); found = elm_code_line_text_strpos(line, text, offset);
if (found == ELM_CODE_TEXT_NOT_FOUND) if (found == ELM_CODE_TEXT_NOT_FOUND)
continue; continue;
search->current_search_line = line->number; search->current_search_line = line->number;
// TODO make this unicode search->current_search_col =
search->current_search_col = found + 1; elm_code_widget_line_text_column_width_to_position(entry, line, found);
break; break;
} }
@ -87,20 +87,10 @@ _edi_search_in_entry(Evas_Object *entry, Edi_Editor_Search *search)
if (!search->term_found) if (!search->term_found)
return EINA_FALSE; 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, elm_code_widget_selection_start(entry, search->current_search_line,
search->current_search_col); search->current_search_col);
// TODO make that strlen unicode strlen
elm_code_widget_selection_end(entry, search->current_search_line, 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; return EINA_TRUE;
} }