hermet pushed a commit to branch master. http://git.enlightenment.org/tools/enventor.git/commit/?id=97941ff3784974f05443287c6af9f1eac2ef84f9
commit 97941ff3784974f05443287c6af9f1eac2ef84f9 Author: ChunEon Park <her...@hermet.pe.kr> Date: Tue Jun 16 13:35:44 2015 +0900 Indent: auto indentation when code is pasted. Summary: if some edc code is pasted, the indentation could be corrupted. let's make it fix automatically, even if indentation of the pasted code is not correct, only when auto indent mode is enabled. Reviewers: Jaehyun, Hermet Projects: #enventor Maniphest Tasks: T2174 Differential Revision: https://phab.enlightenment.org/D2601 --- src/lib/edc_editor.c | 10 ++++- src/lib/enventor_private.h | 1 + src/lib/indent.c | 102 +++++++++++++++++++++++++++++++++++++++++++-- src/lib/redoundo.c | 12 ++++++ 4 files changed, 119 insertions(+), 6 deletions(-) diff --git a/src/lib/edc_editor.c b/src/lib/edc_editor.c index 6572689..6d9a9f0 100644 --- a/src/lib/edc_editor.c +++ b/src/lib/edc_editor.c @@ -255,8 +255,14 @@ edit_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) } if (ed->auto_indent) - indent_insert_apply(syntax_indent_data_get(ed->sh), ed->en_edit, - info->change.insert.content, ed->cur_line); + { + indent_insert_apply(syntax_indent_data_get(ed->sh), ed->en_edit, + info->change.insert.content, ed->cur_line); + int increase = + parser_line_cnt_get(ed->pd, info->change.insert.content); + edit_line_increase(ed, increase); + } + } else { diff --git a/src/lib/enventor_private.h b/src/lib/enventor_private.h index b072cc1..ffd1070 100644 --- a/src/lib/enventor_private.h +++ b/src/lib/enventor_private.h @@ -173,6 +173,7 @@ void redoundo_text_relative_push(redoundo_data *rd, const char *text); void redoundo_entry_region_push(redoundo_data *rd, int cursor_pos, int cursor_pos2); int redoundo_undo(redoundo_data *rd, Eina_Bool *changed); int redoundo_redo(redoundo_data *rd, Eina_Bool *changed); +void redoundo_n_diff_cancel(redoundo_data *rd, unsigned int n); /* edj_viewer */ diff --git a/src/lib/indent.c b/src/lib/indent.c index 18bdbeb..a5ed761 100644 --- a/src/lib/indent.c +++ b/src/lib/indent.c @@ -231,12 +231,106 @@ indent_delete_apply(indent_data *id EINA_UNUSED, Evas_Object *entry, return EINA_FALSE; } +static void +indent_text_auto_format(indent_data *id EINA_UNUSED, + Evas_Object *entry, const char *insert) +{ + char *utf8 = evas_textblock_text_markup_to_utf8(NULL, insert); + int utf8_size = strlen(utf8); + + Evas_Object *tb = elm_entry_textblock_get(entry); + Evas_Textblock_Cursor *cur_start = evas_object_textblock_cursor_new(tb); + Evas_Textblock_Cursor *cur_end = evas_object_textblock_cursor_get(tb); + redoundo_data *rd = evas_object_data_get(entry, "redoundo"); + + char *utf8_ptr = utf8; + char *utf8_lexem = utf8_ptr; + char *utf8_end = utf8 + utf8_size; + Eina_List *code_lines = NULL; + Eina_Strbuf *buf = eina_strbuf_new(); + + int tb_cur_pos = 0; + + while (utf8_ptr <= utf8_end) + { + if (*utf8_ptr != ' ' && *utf8_ptr != '\t' && *utf8_ptr != '\n' ) + { + utf8_lexem = utf8_ptr; + while (utf8_ptr <= utf8_end) + { + if (*utf8_ptr == '{' || *utf8_ptr == '}' || *utf8_ptr == ';') + { + if (utf8_ptr + 1 == utf8_end) + code_lines = eina_list_append(code_lines, + eina_stringshare_add(utf8_lexem)); + else + code_lines = eina_list_append(code_lines, + eina_stringshare_add_length(utf8_lexem, + utf8_ptr - utf8_lexem + 1)); + break; + } + utf8_ptr++; + } + } + utf8_ptr++; + } + free(utf8); + + if (!code_lines) return; + tb_cur_pos = evas_textblock_cursor_pos_get(cur_end); + evas_textblock_cursor_pos_set(cur_start, tb_cur_pos - utf8_size); + evas_textblock_cursor_range_delete(cur_start, cur_end); + + char *frmt_buf = NULL; + Eina_List *l = NULL; + Eina_Stringshare *line; + evas_textblock_cursor_line_char_first(cur_start); + int space = indent_space_get(id, entry); + + EINA_LIST_FOREACH(code_lines, l, line) + { + if (strstr(line, "}")) space -= TAB_SPACE; + char *p = alloca(space + 1); + memset(p, ' ', space); + p[space] = '\0'; + eina_strbuf_append_printf(buf, "%s%s<br/>", p, line); + memset(p, 0x0, space); + if (strstr(line, "{")) space += TAB_SPACE; + eina_stringshare_del(line); + } + + frmt_buf = eina_strbuf_string_steal(buf); + tb_cur_pos = evas_textblock_cursor_pos_get(cur_start); + evas_textblock_cursor_pos_set(cur_end, tb_cur_pos); + tb_cur_pos = evas_textblock_cursor_pos_get(cur_end); + evas_object_textblock_text_markup_prepend(cur_start, frmt_buf); + + // Cancel last added diff, that was created when text pasted into entry. + redoundo_n_diff_cancel(rd, 1); + //Add data about formatted change into the redoundo queue. + redoundo_text_push(rd, frmt_buf, tb_cur_pos, 0, EINA_TRUE); + + eina_strbuf_free(buf); + free(frmt_buf); + evas_textblock_cursor_free(cur_start); + return; +} + void indent_insert_apply(indent_data *id, Evas_Object *entry, const char *insert, int cur_line) { - if (!strcmp(insert, EOL)) - indent_insert_br_case(id, entry); - else if (insert[0] == '}') - indent_insert_bracket_case(id, entry, cur_line); + int len = strlen(insert); + if (len == 1) + { + if (insert[0] == '}') + indent_insert_bracket_case(id, entry, cur_line); + } + else + { + if (!strcmp(insert, EOL)) + indent_insert_br_case(id, entry); + else + indent_text_auto_format(id, entry, insert); + } } diff --git a/src/lib/redoundo.c b/src/lib/redoundo.c index 2b9dbf7..819d951 100644 --- a/src/lib/redoundo.c +++ b/src/lib/redoundo.c @@ -383,3 +383,15 @@ redoundo_text_relative_push(redoundo_data *rd, const char *text) free(utf8); } + +void +redoundo_n_diff_cancel(redoundo_data *rd, unsigned int n) +{ + if (!rd || !rd->queue || !n) return; + + unsigned int i; + for (i = 0; i < n && rd->current_node; i++) + rd->current_node = eina_list_prev(rd->current_node); + rd->last_diff = (diff_data *)eina_list_data_get(rd->current_node); + untracked_diff_free(rd); +} --