elm_code unicode: highlight tokens correctly

When encountering unicode characters make sure we highlight
in the correct columns rather than at the byte locations.
This commit is contained in:
Andy Williams 2015-03-14 16:42:56 +00:00
parent ec58b84e3e
commit 7c5d0e3873
5 changed files with 62 additions and 42 deletions

View File

@ -55,7 +55,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, 14, 21, 1, ELM_CODE_TOKEN_TYPE_COMMENT);
elm_code_line_token_add(line, 18, 25, 1, ELM_CODE_TOKEN_TYPE_COMMENT);
else if (line->number == 4)
line->status = ELM_CODE_STATUS_TYPE_ERROR;
@ -76,7 +76,7 @@ _elm_code_test_welcome_setup(Evas_Object *parent)
eo_event_callback_add(&ELM_CODE_EVENT_LINE_LOAD_DONE, _elm_code_test_line_done_cb, NULL);
eo_event_callback_add(ELM_CODE_WIDGET_EVENT_LINE_CLICKED, _elm_code_test_line_clicked_cb, code));
_append_line(code->file, "Hello World, Elm Code! ❤");
_append_line(code->file, "Hello World, Elm Code! ❤");
_append_line(code->file, "");
_append_line(code->file, "This is a demo of elm_code's capabilities.");
_append_line(code->file, "⚑ *** Currently experimental ***");

View File

@ -21,22 +21,6 @@ static Elm_Code_Line *_elm_code_file_line_blank_create(Elm_Code_File *file, int
return ecl;
}
static unsigned int
_elm_code_file_line_unicode_strlen(const char *chars, unsigned int length)
{
unsigned int count = 0;
int index = 0;
while ((unsigned int) index < length)
{
eina_unicode_utf8_next_get(chars, &index);
count++;
}
return count;
}
static void _elm_code_file_line_insert_data(Elm_Code_File *file, const char *content, unsigned int length,
unsigned int row, Eina_Bool mapped, void *data)
{
@ -57,7 +41,7 @@ static void _elm_code_file_line_insert_data(Elm_Code_File *file, const char *con
line->modified[length] = 0;
line->length = length;
}
line->unicode_length = _elm_code_file_line_unicode_strlen(content, length);
line->unicode_length = elm_code_text_unicode_strlen(content, length);
if (row == 1)
file->lines = eina_list_prepend(file->lines, line);

View File

@ -36,8 +36,7 @@ elm_code_line_text_set(Elm_Code_Line *line, const char *chars, unsigned int leng
strncpy(newtext, chars, length);
line->modified = newtext;
line->length = length;
// TODO update calculation
line->unicode_length = length;
line->unicode_length = elm_code_text_unicode_strlen(line->modified, line->length);
file = line->file;
elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, line);
@ -112,9 +111,7 @@ elm_code_line_text_insert(Elm_Code_Line *line, unsigned int position, const char
line->modified = inserted;
line->length += length;
// TODO update calculation
line->unicode_length += length;
line->unicode_length = elm_code_text_unicode_strlen(line->modified, line->length);
file = line->file;
elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, line);
@ -152,10 +149,32 @@ elm_code_line_text_remove(Elm_Code_Line *line, unsigned int position, int length
line->modified = removed;
line->length -= length;
// TODO update calculation
line->unicode_length -= length;
line->unicode_length = elm_code_text_unicode_strlen(line->modified, line->length);
file = line->file;
elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, line);
}
/* generic text functions */
EAPI unsigned int
elm_code_text_unicode_strlen(const char *chars, unsigned int length)
{
Eina_Unicode unicode;
unsigned int count = 0;
int index = 0;
if (chars == NULL)
return 0;
while ((unsigned int) index < length)
{
unicode = eina_unicode_utf8_next_get(chars, &index);
if (unicode == 0)
break;
count++;
}
return count;
}

View File

@ -11,8 +11,8 @@ extern "C" {
*/
/**
* @brief Text handling functions.
* @defgroup Text access and manipulation
* @brief Line text handling functions.
* @defgroup Text access and manipulation within lines
*
* @{
*
@ -28,6 +28,20 @@ EAPI void elm_code_line_text_insert(Elm_Code_Line *line, unsigned int position,
EAPI void elm_code_line_text_remove(Elm_Code_Line *line, unsigned int position, int length);
/**
* @}
*
* @brief Generic text handling functions.
* @defgroup Text helper functions
*
* @{
*
* Functions for managing unicode text.
*
*/
EAPI unsigned int elm_code_text_unicode_strlen(const char *chars, unsigned int length);
/**
* @}
*/

View File

@ -155,24 +155,30 @@ _elm_code_widget_fill_line_tokens(Elm_Code_Widget *widget, Evas_Textgrid_Cell *c
{
Eina_List *item;
Elm_Code_Token *token;
int start, end, length, offset;
const char *content;
unsigned int start, end, length, offset;
unsigned int token_start_col, token_end_col;
offset = elm_code_widget_text_left_gutter_width_get(widget) - 1;
start = offset + 1;
offset = elm_code_widget_text_left_gutter_width_get(widget);
start = offset;
content = elm_code_line_text_get(line, NULL);
length = line->unicode_length + offset;
EINA_LIST_FOREACH(line->tokens, item, token)
{
if (token->start > start)
_elm_code_widget_fill_line_token(cells, count, start, token->start + offset, ELM_CODE_TOKEN_TYPE_DEFAULT);
token_start_col = elm_code_text_unicode_strlen(content, token->start - 1) + offset;
token_end_col = elm_code_text_unicode_strlen(content, token->end - 1) + offset;
if (token_start_col > start)
_elm_code_widget_fill_line_token(cells, count, start, token_start_col, ELM_CODE_TOKEN_TYPE_DEFAULT);
// TODO handle a token starting before the previous finishes
end = token->end;
end = token_end_col;
if (token->end_line > line->number)
end = count;
_elm_code_widget_fill_line_token(cells, count, token->start + offset, end + offset, token->type);
end = length + offset;
_elm_code_widget_fill_line_token(cells, count, token_start_col, end, token->type);
start = end + offset + 1;
start = end + 1;
}
_elm_code_widget_fill_line_token(cells, count, start, length, ELM_CODE_TOKEN_TYPE_DEFAULT);
@ -261,10 +267,7 @@ _elm_code_widget_fill_line(Elm_Code_Widget *widget, Elm_Code_Line *line)
length = elm_code_line_utf8_length_get(line);
chrpos = 0;
if (line->modified)
chr = line->modified;
else
chr = (char *)line->content;
chr = (char *)elm_code_line_text_get(line, NULL);
for (x = gutter; x < (unsigned int) w && x < length + gutter; x++)
{