jaehyun pushed a commit to branch master.

http://git.enlightenment.org/tools/enventor.git/commit/?id=ff7ca0ee79976675b9477256cd132d4374d30ba3

commit ff7ca0ee79976675b9477256cd132d4374d30ba3
Author: Jaehyun Cho <jae_hyun....@samsung.com>
Date:   Tue Mar 29 19:21:04 2016 +0900

    indent: Refactoring indentation.
    
    Fix indentation issues by refactoring indentation logic.
---
 src/lib/edc_editor.c       |   9 +-
 src/lib/enventor_private.h |   2 +-
 src/lib/indent.c           | 823 +++++++++++++++++++++++----------------------
 3 files changed, 428 insertions(+), 406 deletions(-)

diff --git a/src/lib/edc_editor.c b/src/lib/edc_editor.c
index 14bae66..7d739a1 100644
--- a/src/lib/edc_editor.c
+++ b/src/lib/edc_editor.c
@@ -451,16 +451,13 @@ edit_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, 
void *event_info)
      }
    else
      {
-        int decrease = parser_line_cnt_get(ed->pd, info->change.del.content);
-
         if (edit_auto_indent_get(ed))
           {
-             if (indent_delete_apply(syntax_indent_data_get(ed->sh),
-                                     ed->en_edit, info->change.del.content,
-                                     ed->cur_line))
-               decrease++;
+             indent_delete_apply(syntax_indent_data_get(ed->sh), ed->en_edit,
+                                 info->change.del.content, ed->cur_line);
           }
 
+        int decrease = parser_line_cnt_get(ed->pd, info->change.del.content);
         edit_line_decrease(ed, decrease);
         if (info->change.del.content[0] == ' ') return;
      }
diff --git a/src/lib/enventor_private.h b/src/lib/enventor_private.h
index 2054c50..a87b9ae 100644
--- a/src/lib/enventor_private.h
+++ b/src/lib/enventor_private.h
@@ -161,7 +161,7 @@ indent_data *indent_init(Eina_Strbuf *strbuf);
 void indent_term(indent_data *id);
 int indent_space_get(indent_data *id, Evas_Object *entry);
 int indent_insert_apply(indent_data *id, Evas_Object *entry, const char 
*insert, int cur_line);
-Eina_Bool indent_delete_apply(indent_data *id, Evas_Object *entry, const char 
*del, int cur_line);
+void indent_delete_apply(indent_data *id, Evas_Object *entry, const char *del, 
int cur_line);
 Eina_Bool indent_text_check(indent_data *id EINA_UNUSED, const char *utf8);
 char * indent_text_create(indent_data *id, const char *utf8, int 
*indented_line_cnt);
 
diff --git a/src/lib/indent.c b/src/lib/indent.c
index 1f62bc4..9380f12 100644
--- a/src/lib/indent.c
+++ b/src/lib/indent.c
@@ -10,6 +10,13 @@ struct indent_s
    Eina_Strbuf *strbuf;
 };
 
+typedef struct indent_line_s
+{
+   Eina_Stringshare *str;
+   Eina_Bool indent_apply;
+   int indent_depth;
+} indent_line;
+
 /*****************************************************************************/
 /* Internal method implementation                                            */
 /*****************************************************************************/
@@ -185,71 +192,75 @@ indent_space_get(indent_data *id, Evas_Object *entry)
    return space;
 }
 
-Eina_Bool
+void
 indent_delete_apply(indent_data *id EINA_UNUSED, Evas_Object *entry,
                     const char *del, int cur_line)
 {
-   if (del[0] != ' ') return EINA_FALSE;
+   if (del[0] != ' ') return;
 
    Evas_Object *tb = elm_entry_textblock_get(entry);
    Evas_Textblock_Cursor *cur = evas_object_textblock_cursor_new(tb);
    evas_textblock_cursor_line_set(cur, cur_line - 1);
    const char *text = evas_textblock_cursor_paragraph_text_get(cur);
    char *utf8 = elm_entry_markup_to_utf8(text);
+   char *last_markup = NULL;
    Eina_Strbuf* diff = eina_strbuf_new();
+
    int rd_cur_pos = evas_textblock_cursor_pos_get(cur);
    redoundo_data *rd = evas_object_data_get(entry, "redoundo");
 
    int len = strlen(utf8);
-   if (len < 0) return EINA_FALSE;
+   if (len <= 0) goto end;
 
    evas_textblock_cursor_paragraph_char_last(cur);
+   last_markup = evas_textblock_cursor_content_get(cur);
+   if (last_markup && !strncmp(last_markup, "<br/>", 5))
+     evas_textblock_cursor_char_prev(cur);
 
    while (len > 0)
      {
         if ((utf8[(len - 1)] == ' '))
           {
-             evas_textblock_cursor_char_prev(cur);
              eina_strbuf_append(diff, evas_textblock_cursor_content_get(cur));
              evas_textblock_cursor_char_delete(cur);
+             evas_textblock_cursor_char_prev(cur);
           }
         else break;
         len--;
      }
-
-   if (len == 0)
-     {
-        eina_strbuf_append(diff, evas_textblock_cursor_content_get(cur));
-        evas_textblock_cursor_char_delete(cur);
-     }
    redoundo_text_push(rd, eina_strbuf_string_get(diff), rd_cur_pos, 0,
                       EINA_FALSE);
    elm_entry_calc_force(entry);
+
+end:
    evas_textblock_cursor_free(cur);
-   free(utf8);
+   if (utf8) free(utf8);
+   if (last_markup) free(last_markup);
    eina_strbuf_free(diff);
-   if (len == 0)
-     {
-        elm_entry_cursor_prev(entry);
-        return EINA_TRUE;
-     }
-   return EINA_FALSE;
 }
 
 static Eina_List *
-indent_code_lines_create(indent_data *id EINA_UNUSED, const char *utf8)
+indent_code_line_list_create(indent_data *id EINA_UNUSED, const char *utf8)
 {
-   Eina_List *code_lines = NULL;
+   Eina_List *code_line_list = NULL;
+   indent_line *code_line = NULL;
 
    char *utf8_ptr = NULL;
    char *utf8_end = NULL;
    char *utf8_lexem = NULL;
-   char *utf8_append_ptr = NULL;
+   char *utf8_appended = NULL;
 
-   Eina_Bool keep_lexem_start_pos = EINA_FALSE;
-   Eina_Bool single_comment_found = EINA_FALSE;
-   Eina_Bool multi_comment_found = EINA_FALSE;
-   Eina_Bool macro_found = EINA_FALSE;
+   Eina_Bool keep_lexem = EINA_FALSE;
+   Eina_Bool single_comment_begin = EINA_FALSE;
+   Eina_Bool single_comment_middle = EINA_FALSE;
+   Eina_Bool multi_comment_begin = EINA_FALSE;
+   Eina_Bool multi_comment_middle = EINA_FALSE;
+   Eina_Bool multi_comment_end = EINA_FALSE;
+   Eina_Bool macro_begin = EINA_FALSE;
+   Eina_Bool macro_middle = EINA_FALSE;
+
+   int cur_indent_depth = 0;
+   int new_indent_depth = 0;
 
    if (!utf8) return NULL;
 
@@ -258,151 +269,172 @@ indent_code_lines_create(indent_data *id EINA_UNUSED, 
const char *utf8)
 
    /* Create a list of code line strings from inserted string.
       Each code line string is generated based on lexeme.
-      Here, lexeme starts with nonspace character and ends with the followings.
-      '{', '}', ';', "//", "*\/"
-    */
-   while (utf8_ptr < utf8_end)
+      Here, lexeme starts with nonspace character and ends with newline. */
+   for ( ; utf8_ptr < utf8_end; utf8_ptr++)
      {
-        if (*utf8_ptr != ' ' && *utf8_ptr != '\t' &&  *utf8_ptr != '\n' &&
-            *utf8_ptr != '\r')
+        if (*utf8_ptr == '\n')
           {
-             //Renew the start position of lexeme.
-             if (!keep_lexem_start_pos) utf8_lexem = utf8_ptr;
+             if (!keep_lexem)
+               utf8_lexem = utf8_ptr;
+             keep_lexem = EINA_FALSE;
+
+             code_line = (indent_line *)calloc(1, sizeof(indent_line));
 
-             //Check line comment.
-             if (*utf8_ptr == '/' && utf8_ptr + 1 < utf8_end)
+             char *append_begin = NULL;
+             if (!utf8_appended) append_begin = (char *)utf8;
+
+             if (single_comment_begin || multi_comment_begin ||
+                 multi_comment_end || macro_begin || macro_middle)
                {
-                  //Start of single line comment.
-                  if (*(utf8_ptr + 1) == '/')
-                    single_comment_found = EINA_TRUE;
-                  //Start of multi line comment.
-                  else if (*(utf8_ptr + 1) == '*')
-                    multi_comment_found = EINA_TRUE;
+                  if (!append_begin)
+                    append_begin = utf8_appended + 1;
 
-                  if (single_comment_found || multi_comment_found)
-                    utf8_ptr += 2;
+                  code_line->indent_apply = EINA_FALSE;
                }
-             //Check macro.
-             if (*utf8_ptr == '#')
+             else
                {
-                  macro_found = EINA_TRUE;
-                  utf8_ptr++;
+                  if (!append_begin)
+                    append_begin = utf8_lexem;
+
+                  //Newline only string does not need indentation.
+                  if (utf8_ptr == append_begin)
+                    code_line->indent_apply = EINA_FALSE;
+                  else
+                    code_line->indent_apply = EINA_TRUE;
                }
+             code_line->str
+                = eina_stringshare_add_length(append_begin,
+                                              utf8_ptr - append_begin + 1);
+             code_line->indent_depth = cur_indent_depth;
+             cur_indent_depth = new_indent_depth;
+
+             code_line_list = eina_list_append(code_line_list, code_line);
+             utf8_appended = utf8_ptr;
+
+             if (single_comment_begin)
+               single_comment_begin = EINA_FALSE;
+             if (single_comment_middle)
+               single_comment_middle = EINA_FALSE;
+             if (multi_comment_middle)
+               {
+                  multi_comment_middle = EINA_FALSE;
+                  multi_comment_begin = EINA_TRUE;
+               }
+             if (multi_comment_end)
+               multi_comment_end = EINA_FALSE;
 
-             while (utf8_ptr < utf8_end)
+             //Check if macro ends.
+             if (macro_begin || macro_middle)
                {
-                  if (*utf8_ptr == '\n')
+                  if (*(utf8_ptr - 1) != '\\')
                     {
-                       //End of single line comment.
-                       if (single_comment_found)
-                         single_comment_found = EINA_FALSE;
+                       macro_begin = EINA_FALSE;
+                       macro_middle = EINA_FALSE;
+                    }
+               }
+          }
+        else if ((*utf8_ptr != ' ') && (*utf8_ptr != '\t') &&
+                 (*utf8_ptr != '\r'))
+          {
+             if (!keep_lexem)
+               {
+                  utf8_lexem = utf8_ptr;
+                  keep_lexem = EINA_TRUE;
+               }
 
-                       //End of macro.
-                       else if (macro_found)
+             if (!single_comment_begin && !single_comment_middle &&
+                 !multi_comment_begin && !multi_comment_middle &&
+                 !multi_comment_end)
+               {
+                  if ((*utf8_ptr == '/') && (utf8_ptr + 1 < utf8_end))
+                    {
+                       //Check if single line comment begins.
+                       if (*(utf8_ptr + 1) == '/')
                          {
-                            //Macro ends with "\n" but continues with "\\\n".
-                            if (!(utf8_ptr - 1 >= utf8 &&
-                                  *(utf8_ptr - 1) == '\\'))
-                              macro_found = EINA_FALSE;
+                            if (utf8_ptr == utf8_lexem)
+                              single_comment_begin = EINA_TRUE;
+                            else
+                              single_comment_middle = EINA_TRUE;
                          }
-
-                       code_lines = eina_list_append(code_lines,
-                                       eina_stringshare_add_length(utf8_lexem,
-                                       utf8_ptr - utf8_lexem));
-                       utf8_append_ptr = utf8_ptr;
-                       break;
-                    }
-                  else if (multi_comment_found)
-                    {
-                       //End of multi line comment.
-                       if (*utf8_ptr == '/' && utf8_ptr - 1 >= utf8 &&
-                           *(utf8_ptr - 1) == '*')
+                       //Check if multi line comment begins.
+                       else if (*(utf8_ptr + 1) == '*')
                          {
-                            if (utf8_ptr + 1 == utf8_end)
-                              code_lines = eina_list_append(code_lines,
-                                              
eina_stringshare_add(utf8_lexem));
+                            if (utf8_ptr == utf8_lexem)
+                              multi_comment_begin = EINA_TRUE;
                             else
-                              code_lines =
-                                 eina_list_append(code_lines,
-                                    eina_stringshare_add_length(utf8_lexem,
-                                    utf8_ptr - utf8_lexem + 1));
-                            utf8_append_ptr = utf8_ptr;
-                            multi_comment_found = EINA_FALSE;
-                            break;
+                              multi_comment_middle = EINA_TRUE;
                          }
                     }
-                  //No line comment and No macro.
-                  else if (!single_comment_found && !macro_found)
+                  else if (*utf8_ptr == '#')
                     {
-                       if (*utf8_ptr == '{' || *utf8_ptr == '}' ||
-                           *utf8_ptr == ';')
-                         {
-                            if (*utf8_ptr == '{')
-                              {
-                                 char *bracket_right_ptr = utf8_ptr + 1;
-                                 while (bracket_right_ptr < utf8_end)
-                                   {
-                                      if (*bracket_right_ptr != ' ' &&
-                                          *bracket_right_ptr != '\t')
-                                        break;
-                                      bracket_right_ptr++;
-                                   }
-                                 if (bracket_right_ptr < utf8_end)
-                                   {
-                                      /* To preserve code line until block 
name,
-                                         keep start position of lexeme and
-                                         append code line until ';'. */
-                                      Eina_Bool block_name_found = EINA_FALSE;
-
-                                      if (*bracket_right_ptr == '\"')
-                                        block_name_found = EINA_TRUE;
-                                      else if (bracket_right_ptr + 4 < 
utf8_end)
-                                        {
-                                           if (!strncmp(bracket_right_ptr,
-                                                        "name:", 5))
-                                             block_name_found = EINA_TRUE;
-                                           else if (!strncmp(bracket_right_ptr,
-                                                             "state:", 5))
-                                             block_name_found = EINA_TRUE;
-                                        }
-
-                                      if (block_name_found)
-                                        {
-                                           keep_lexem_start_pos = EINA_TRUE;
-                                           break;
-                                        }
-                                   }
-                              }
-                            else if (*utf8_ptr == ';')
-                              keep_lexem_start_pos = EINA_FALSE;
+                       if (utf8_ptr == utf8_lexem)
+                         macro_begin = EINA_TRUE;
+                       else
+                         macro_middle = EINA_TRUE;
+                    }
+                  else if (*utf8_ptr == '{')
+                    new_indent_depth++;
+                  else if (*utf8_ptr == '}')
+                    {
+                       new_indent_depth--;
 
-                            if (utf8_ptr + 1 == utf8_end)
-                              code_lines = eina_list_append(code_lines,
-                                              
eina_stringshare_add(utf8_lexem));
-                            else
-                              //FIXME: Here stringshare occurs memory leak. :(
-                              code_lines =
-                                 eina_list_append(code_lines,
-                                    eina_stringshare_add_length(utf8_lexem,
-                                    utf8_ptr - utf8_lexem + 1));
-                            utf8_append_ptr = utf8_ptr;
-                            break;
-                         }
+                       /* Indentation depth decreases from the current code 
line
+                          if string begins with '}'. */
+                       if (utf8_ptr == utf8_lexem)
+                         cur_indent_depth = new_indent_depth;
+                    }
+               }
+
+             //Check if multi line comment ends.
+             if (multi_comment_begin || multi_comment_middle)
+               {
+                  if ((*utf8_ptr == '*') && (utf8_ptr + 1 < utf8_end) &&
+                      (*(utf8_ptr + 1) == '/'))
+                    {
+                       multi_comment_begin = EINA_FALSE;
+                       multi_comment_middle = EINA_FALSE;
+                       multi_comment_end = EINA_TRUE;
                     }
-                  utf8_ptr++;
                }
           }
-        utf8_ptr++;
      }
-   //FIXME: Now string is not added to code line and indentation is not applied
-   //       if string does not contain keywords which cause a new line.
-   //       (e.g. string not containing ';')
-   //Append rest of the input string.
-   if (utf8_append_ptr && (utf8_lexem > utf8_append_ptr))
-     code_lines = eina_list_append(code_lines,
-                                   eina_stringshare_add(utf8_lexem));
-
-   return code_lines;
+
+   /* Append rest of the input string which does not end with newline. */
+   if (!utf8_appended || (utf8_appended < utf8_end - 1))
+     {
+        char *append_begin = NULL;
+        if (!utf8_appended) append_begin = (char *)utf8;
+
+        code_line = (indent_line *)calloc(1, sizeof(indent_line));
+
+        if (single_comment_begin || multi_comment_begin || macro_begin ||
+            multi_comment_end)
+          {
+             if (!append_begin)
+               append_begin = utf8_appended + 1;
+
+             code_line->indent_apply = EINA_FALSE;
+          }
+        else
+          {
+             if (!append_begin)
+               append_begin = utf8_lexem;
+
+             //Newline only string does not need indentation.
+             if ((*append_begin == '\n') && (append_begin == utf8_end - 1))
+               code_line->indent_apply = EINA_FALSE;
+             else
+               code_line->indent_apply = EINA_TRUE;
+          }
+        code_line->str
+           = eina_stringshare_add_length(append_begin,
+                                         utf8_end - append_begin);
+        code_line->indent_depth = cur_indent_depth;
+
+        code_line_list = eina_list_append(code_line_list, code_line);
+     }
+
+   return code_line_list;
 }
 
 static int
@@ -421,158 +453,180 @@ indent_text_auto_format(indent_data *id,
 
    redoundo_data *rd = evas_object_data_get(entry, "redoundo");
 
-   char *utf8_ptr = utf8;
-
-   Eina_List *code_lines = indent_code_lines_create(id, utf8);
+   Eina_List *code_line_list = indent_code_line_list_create(id, utf8);
+   indent_line *code_line = NULL;
    free(utf8);
-   if (!code_lines) return line_cnt;
+   if (!code_line_list) goto end;
 
-   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);
+   /* Check if indentation should be applied to the first code line.
+      Indentation is applied if prior string has only spaces. */
+   code_line= eina_list_data_get(code_line_list);
+   if (code_line->indent_apply)
+     {
+        Evas_Textblock_Cursor *check_start
+           = evas_object_textblock_cursor_new(tb);
+        Evas_Textblock_Cursor *check_end
+           = evas_object_textblock_cursor_new(tb);
 
-   Eina_List *l = NULL;
-   Eina_Stringshare *line;
-   evas_textblock_cursor_line_char_first(cur_start);
+        tb_cur_pos = evas_textblock_cursor_pos_get(cur_end);
+        evas_textblock_cursor_pos_set(check_end, tb_cur_pos - utf8_size);
+        evas_textblock_cursor_pos_set(check_start, tb_cur_pos - utf8_size);
+        evas_textblock_cursor_line_char_first(check_start);
 
-   /* Checking the string from start till cursor position is empty.
-    * And in case if this range is empty - formatted text will be
-    * inserted above the current line */
-   char *check_range = evas_textblock_cursor_range_text_get(cur_start,
-                                       cur_end, EVAS_TEXTBLOCK_TEXT_PLAIN);
-   Eina_Bool above = EINA_TRUE;
-   if (check_range)
-     {
-        int check_len = strlen(check_range);
-        int space_cnt = 0;
-        for (; space_cnt < check_len; space_cnt++)
+        char *check_range
+           = evas_textblock_cursor_range_text_get(check_start, check_end,
+                                                  EVAS_TEXTBLOCK_TEXT_PLAIN);
+
+        evas_textblock_cursor_free(check_start);
+        evas_textblock_cursor_free(check_end);
+
+        Eina_Bool nonspace_found = EINA_FALSE;
+        if (check_range)
           {
-             if (check_range[space_cnt] != ' ')
+             int check_len = strlen(check_range);
+             int index = 0;
+             for ( ; index < check_len; index++)
                {
-                  above = EINA_FALSE;
-                  break;
+                  if (check_range[index] != ' ')
+                    {
+                       nonspace_found = EINA_TRUE;
+                       break;
+                    }
                }
+             free(check_range);
           }
-     }
-
-   if (!above)
-     evas_textblock_cursor_line_char_last(cur_end);
-   int space = indent_space_get(id, entry);
-
-   utf8 = evas_textblock_cursor_range_text_get(cur_start, cur_end,
-                                               EVAS_TEXTBLOCK_TEXT_PLAIN);
-   utf8_ptr = utf8 + strlen(utf8);
-   while (utf8_ptr && (utf8_ptr >= utf8))
-     {
-        if (utf8_ptr[0] != ' ')
+        if (nonspace_found)
           {
-             if ((utf8_ptr[0] == '}') && (space > 0))
-               space -= TAB_SPACE;
-             if (!above && !evas_textblock_cursor_paragraph_next(cur_start))
+             code_line->indent_apply = EINA_FALSE;
+          }
+        else
+          {
+             int str_len = eina_stringshare_strlen(code_line->str);
+             int index = 0;
+             for ( ; index < str_len; index++)
+               {
+                  if ((code_line->str[index] != ' ') &&
+                      (code_line->str[index] != '\t') &&
+                      (code_line->str[index] != '\r'))
+                    break;
+               }
+             if (index < str_len)
                {
-                  code_lines = eina_list_prepend(code_lines,
-                                                 eina_stringshare_add("\n"));
-                  evas_textblock_cursor_line_char_last(cur_start);
+                  char *new_str = strdup(&code_line->str[index]);
+                  if (new_str)
+                    {
+                       eina_stringshare_del(code_line->str);
+                       code_line->str = eina_stringshare_add(new_str);
+                       free(new_str);
+                    }
                }
-             break;
           }
-        utf8_ptr--;
      }
-   free(utf8);
 
-   Eina_Strbuf *buf = eina_strbuf_new();
-   int saved_space = 0;
-   Eina_Bool single_comment_found = EINA_FALSE;
-   Eina_Bool multi_comment_found = EINA_FALSE;
-   Eina_Bool macro_found = EINA_FALSE;
-   EINA_LIST_FOREACH(code_lines, l, line)
+   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);
+
+   //Cancel last added diff, that was created when text pasted into entry.
+   redoundo_n_diff_cancel(rd, 1);
+
+   evas_textblock_cursor_line_char_first(cur_start);
+
+   //Move cursor to the position where the inserted string will be prepended.
+   code_line= eina_list_data_get(code_line_list);
+   if (code_line->indent_apply)
      {
-        if (!single_comment_found && !multi_comment_found && !macro_found)
+        evas_textblock_cursor_line_char_first(cur_start);
+        int space_pos_start = evas_textblock_cursor_pos_get(cur_start);
+        int space_pos_end = evas_textblock_cursor_pos_get(cur_end);
+
+        if (space_pos_start < space_pos_end)
           {
-             if (!strncmp(line, "//", 2))
-               {
-                  single_comment_found = EINA_TRUE;
-                  saved_space = space;
-               }
-             else if (!strncmp(line, "/*", 2))
-               {
-                  multi_comment_found = EINA_TRUE;
-                  saved_space = space;
-               }
-             else if (line[0] == '#')
+             //Delete prior spaces.
+             char *prior_space =
+                evas_textblock_cursor_range_text_get(cur_start, cur_end,
+                   EVAS_TEXTBLOCK_TEXT_MARKUP);
+
+             if (prior_space)
                {
-                  macro_found = EINA_TRUE;
-                  saved_space = space;
+                  evas_textblock_cursor_range_delete(cur_start, cur_end);
+
+                  tb_cur_pos = evas_textblock_cursor_pos_get(cur_end);
+                  /* Add data about removal of prior spaces into the redoundo
+                     queue. */
+                  redoundo_text_push(rd, prior_space, tb_cur_pos, 0,
+                                     EINA_FALSE);
+                  free(prior_space);
                }
           }
-        if ((line[0] == '}') && (space > 0))
-          space -= TAB_SPACE;
+     }
+   else
+     {
+        tb_cur_pos = evas_textblock_cursor_pos_get(cur_end);
+        evas_textblock_cursor_pos_set(cur_start, tb_cur_pos);
+     }
 
-        char *p = alloca(space + 1);
-        memset(p, ' ', space);
-        p[space] = '\0';
-        if (strcmp(line, "\n"))
-          eina_strbuf_append_printf(buf, "%s%s\n", p, line);
-        else
-          eina_strbuf_append(buf, "\n");
-        memset(p, 0x0, space);
+   int space = indent_space_get(id, entry);
 
-        /* Based on the code line generation logic, "{" and "}" can exist
-           multiple times in a line within line comment and macro. */
-        char *bracket_ptr = strstr(line, "{");
-        while (bracket_ptr)
-          {
-             space += TAB_SPACE;
-             bracket_ptr++;
-             bracket_ptr = strstr(bracket_ptr, "{");
-          }
-        //Restore space.
-        if (line[0] == '}') space += TAB_SPACE;
-        bracket_ptr = strstr(line, "}");
-        while (bracket_ptr && space > 0)
-          {
-             space -= TAB_SPACE;
-             bracket_ptr++;
-             bracket_ptr = strstr(bracket_ptr, "}");
-          }
+   Eina_List *l = NULL;
+   Eina_Strbuf *buf = eina_strbuf_new();
 
-        if (single_comment_found)
-          {
-             single_comment_found = EINA_FALSE;
-             space = saved_space;
-          }
-        else if (multi_comment_found && strstr(line, "*/"))
+   EINA_LIST_FOREACH(code_line_list, l, code_line)
+     {
+        Eina_Stringshare *line_str = code_line->str;
+
+        if (code_line->indent_apply == EINA_FALSE)
           {
-             multi_comment_found = EINA_FALSE;
-             space = saved_space;
+             eina_strbuf_append_printf(buf, "%s", line_str);
           }
-        else if (macro_found && line[strlen(line) - 1] != '\\')
+        else
           {
-             macro_found = EINA_FALSE;
-             space = saved_space;
+             int cur_space = space + (code_line->indent_depth * TAB_SPACE);
+             if (cur_space <= 0)
+               {
+                  eina_strbuf_append_printf(buf, "%s", line_str);
+               }
+             else
+               {
+                  char *p = alloca(cur_space + 1);
+                  memset(p, ' ', cur_space);
+                  p[cur_space] = '\0';
+                  eina_strbuf_append_printf(buf, "%s%s", p, line_str);
+                  memset(p, 0x0, cur_space);
+               }
           }
-
-        eina_stringshare_del(line);
-        line_cnt++;
+        eina_stringshare_del(line_str);
+        free(code_line);
      }
+   eina_list_free(code_line_list);
 
    char *utf8_buf = eina_strbuf_string_steal(buf);
+   char *newline_ptr = utf8_buf;
+   line_cnt = 1;
+   if (*newline_ptr == '\n') line_cnt++;
+   while (newline_ptr = strstr(newline_ptr + 1, "\n"))
+     line_cnt++;
+
    //FIXME: To improve performance, change logic not to translate text.
    char *markup_buf = evas_textblock_text_utf8_to_markup(NULL, utf8_buf);
    eina_strbuf_free(buf);
    free(utf8_buf);
 
+   //Initialize cursor position to the beginning of the pasted string.
    tb_cur_pos = evas_textblock_cursor_pos_get(cur_start);
    evas_textblock_cursor_pos_set(cur_end, tb_cur_pos);
 
    evas_object_textblock_text_markup_prepend(cur_start, markup_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, markup_buf, tb_cur_pos, 0, EINA_TRUE);
-
    free(markup_buf);
+
+   //Update cursor position to the end of the pasted string.
+   tb_cur_pos = evas_textblock_cursor_pos_get(cur_start);
+   evas_textblock_cursor_pos_set(cur_end, tb_cur_pos);
+
+end:
    evas_textblock_cursor_free(cur_start);
    return line_cnt;
 }
@@ -582,7 +636,11 @@ indent_insert_apply(indent_data *id, Evas_Object *entry, 
const char *insert,
                     int cur_line)
 {
    int len = strlen(insert);
-   if (len == 1)
+   if (len == 0)
+     {
+        return 0;
+     }
+   else if (len == 1)
      {
         if (insert[0] == '}')
           indent_insert_bracket_case(id, entry, cur_line);
@@ -604,7 +662,11 @@ indent_insert_apply(indent_data *id, Evas_Object *entry, 
const char *insert,
         else if (!strcmp(insert, AMP))
           return 0;
         else
-          return indent_text_auto_format(id, entry, insert);
+          {
+             int increase = indent_text_auto_format(id, entry, insert);
+             if (increase > 0) increase--;
+             return increase;
+          }
      }
 }
 
@@ -621,8 +683,7 @@ indent_text_check(indent_data *id EINA_UNUSED, const char 
*utf8)
    int saved_depth = 0;
    int space = 0;
    Eina_Bool nonspace_found = EINA_FALSE;
-   Eina_Bool single_comment_found = EINA_FALSE;
-   Eina_Bool multi_comment_found = EINA_FALSE;
+   Eina_Bool comment_found = EINA_FALSE;
    Eina_Bool macro_found = EINA_FALSE;
 
    if (!utf8) return EINA_TRUE;
@@ -631,13 +692,13 @@ indent_text_check(indent_data *id EINA_UNUSED, const char 
*utf8)
    utf8_size = strlen(utf8);
    utf8_end = (char *)utf8 + utf8_size;
 
-   /* Check spaces based on depth before nonspace character in each line.
-      Check a new line after the followings.
-      '{', '}', ';', "*\/"
-      Depth is not calculated within line comment.
-    */
+   /* Check indentation spaces of each line.
+      Indentation spaces are checked within line comment and macro. */
    while (utf8_ptr < utf8_end)
      {
+        comment_found = EINA_FALSE;
+        macro_found = EINA_FALSE;
+
         if (*utf8_ptr == '}')
           {
              depth--;
@@ -654,76 +715,93 @@ indent_text_check(indent_data *id EINA_UNUSED, const char 
*utf8)
           }
         else if (*utf8_ptr == '\n')
           {
-             //End of single line comment.
-             if (single_comment_found)
-               {
-                  depth = saved_depth;
-                  single_comment_found = EINA_FALSE;
-               }
+             //Do not allow space only line.
+             if (!nonspace_found && (space > 0))
+               return EINA_FALSE;
 
-             //End of macro.
-             else if (macro_found)
-               {
-                  //Macro ends with "\n" but continues with "\\\n".
-                  if (!(utf8_ptr - 1 >= utf8 && *(utf8_ptr - 1) == '\\'))
-                    {
-                       depth = saved_depth;
-                       macro_found = EINA_FALSE;
-                    }
-               }
-             if (utf8_ptr >= utf8_end - 1)
+             //Do not allow newline at the end.
+             if (utf8_ptr == utf8_end - 1)
                return EINA_FALSE;
+
              space = 0;
              nonspace_found = EINA_FALSE;
           }
-        else
+        else if (*utf8_ptr != '\r')
           {
-             if (!nonspace_found)
-               {
-                  if (space != depth * TAB_SPACE) return EINA_FALSE;
-                  nonspace_found = EINA_TRUE;
-               }
+             char *comment_end = NULL;
 
-             if (multi_comment_found)
+             //Check line comment
+             if ((*utf8_ptr == '/') && (utf8_ptr + 1 < utf8_end))
                {
-                  //End of multi line comment.
-                  if (*utf8_ptr == '/' && (utf8_ptr - 1) >= utf8 &&
-                      *(utf8_ptr - 1) == '*')
+                  //Start of single line comment.
+                  if (*(utf8_ptr + 1) == '/')
                     {
-                       if ((utf8_ptr + 1 < utf8_end) &&
-                           (*(utf8_ptr + 1) != '\n'))
-                         return EINA_FALSE;
+                       comment_found = EINA_TRUE;
 
-                       depth = saved_depth;
-                       multi_comment_found = EINA_FALSE;
+                       comment_end = strstr(utf8_ptr + 2, "\n");
+                       if (comment_end) comment_end--;
+                    }
+                  //Start of multi line comment.
+                  else if (*(utf8_ptr + 1) == '*')
+                    {
+                       comment_found = EINA_TRUE;
+
+                       comment_end = strstr(utf8_ptr + 2, "*/");
+                       if (comment_end) comment_end++;
+                    }
+
+                  if (comment_found)
+                    {
+                       if (comment_end)
+                         utf8_ptr = comment_end;
+                       else
+                         return EINA_TRUE;
                     }
                }
-             //No line comment and No macro.
-             else if (!single_comment_found && !macro_found)
+
+             //Check macro
+             else if (*utf8_ptr == '#')
                {
-                  //Check line comment.
-                  if (*utf8_ptr == '/' && utf8_ptr + 1 < utf8_end)
+                  macro_found = EINA_TRUE;
+
+                  char *macro_end = utf8_ptr;
+                  while (macro_end)
                     {
-                       //Start of single line comment.
-                       if (*(utf8_ptr + 1) == '/')
+                       char *backslash = strstr(macro_end + 1, "\\");
+                       macro_end = strstr(macro_end + 1, "\n");
+                       if (macro_end)
                          {
-                            saved_depth = depth;
-                            single_comment_found = EINA_TRUE;
-                         }
-                       //Start of multi line comment.
-                       else if (*(utf8_ptr + 1) == '*')
-                         {
-                            saved_depth = depth;
-                            multi_comment_found = EINA_TRUE;
+                            if (!backslash || (macro_end < backslash))
+                              break;
                          }
                     }
-                  //Check macro.
-                  else if (*utf8_ptr == '#')
+
+                  if (macro_end)
                     {
-                       saved_depth = depth;
-                       macro_found = EINA_TRUE;
+                       macro_end--;
+                       utf8_ptr = macro_end;
                     }
-                  else if (*utf8_ptr == '}')
+                  else
+                    return EINA_TRUE;
+               }
+
+             if (comment_found || macro_found)
+               {
+                  if (!nonspace_found)
+                    nonspace_found = EINA_TRUE;
+               }
+             //No line comment and No macro.
+             else
+               {
+                  if (!nonspace_found)
+                    {
+                       if (space != depth * TAB_SPACE)
+                         return EINA_FALSE;
+
+                       nonspace_found = EINA_TRUE;
+                    }
+
+                  if (*utf8_ptr == '}')
                     {
                        if ((utf8_ptr + 1 < utf8_end) &&
                            (*(utf8_ptr + 1) != '\n'))
@@ -771,7 +849,9 @@ indent_text_check(indent_data *id EINA_UNUSED, const char 
*utf8)
                }
           }
 
-        if (*utf8_ptr == '{') depth++;
+        if (!comment_found && !macro_found && (*utf8_ptr == '{'))
+          depth++;
+
         utf8_ptr++;
      }
 
@@ -791,113 +871,58 @@ indent_text_create(indent_data *id,
         return NULL;
      }
 
-   Eina_List *code_lines = indent_code_lines_create(id, utf8);
-   if (!code_lines)
+   Eina_List *code_line_list = indent_code_line_list_create(id, utf8);
+   if (!code_line_list)
      {
         if (indented_line_cnt) *indented_line_cnt = 0;
         return NULL;
      }
 
+   indent_line *code_line = NULL;
    Eina_List *l = NULL;
-   Eina_List *l_last = eina_list_last(code_lines);
-   Eina_Stringshare *line;
    Eina_Strbuf *buf = eina_strbuf_new();
 
-   int line_cnt = 1;
-   int space = 0;
-   int saved_space = 0;
-   Eina_Bool single_comment_found = EINA_FALSE;
-   Eina_Bool multi_comment_found = EINA_FALSE;
-   Eina_Bool macro_found = EINA_FALSE;
-   EINA_LIST_FOREACH(code_lines, l, line)
+   EINA_LIST_FOREACH(code_line_list, l, code_line)
      {
-        if (!single_comment_found && !multi_comment_found && !macro_found)
+        Eina_Stringshare *line_str = code_line->str;
+
+        if (!code_line->indent_apply)
           {
-             if (!strncmp(line, "//", 2))
-               {
-                  single_comment_found = EINA_TRUE;
-                  saved_space = space;
-               }
-             else if (!strncmp(line, "/*", 2))
-               {
-                  multi_comment_found = EINA_TRUE;
-                  saved_space = space;
-               }
-             else if (line[0] == '#')
-               {
-                  macro_found = EINA_TRUE;
-                  saved_space = space;
-               }
+             eina_strbuf_append_printf(buf, "%s", line_str);
           }
-        if ((line[0] == '}') && (space > 0))
-          space -= TAB_SPACE;
-
-        char *p = alloca(space + 1);
-        memset(p, ' ', space);
-        p[space] = '\0';
-        if (strcmp(line, "\n"))
+        else
           {
-             if (l == l_last)
-               eina_strbuf_append_printf(buf, "%s%s", p, line);
+             int space = code_line->indent_depth * TAB_SPACE;
+             if (space <= 0)
+               {
+                  eina_strbuf_append_printf(buf, "%s", line_str);
+               }
              else
                {
-                  eina_strbuf_append_printf(buf, "%s%s\n", p, line);
-                  line_cnt++;
+                  char *p = alloca(space + 1);
+                  memset(p, ' ', space);
+                  p[space] = '\0';
+                  eina_strbuf_append_printf(buf, "%s%s", p, line_str);
+                  memset(p, 0x0, space);
                }
           }
-        else
-          {
-             eina_strbuf_append(buf, "\n");
-             line_cnt++;
-          }
-        memset(p, 0x0, space);
-
-        /* Based on the code line generation logic, "{" and "}" can exist
-           multiple times in a line within line comment and macro. */
-        char *bracket_ptr = strstr(line, "{");
-        while (bracket_ptr)
-          {
-             space += TAB_SPACE;
-             bracket_ptr++;
-             bracket_ptr = strstr(bracket_ptr, "{");
-          }
-        //Restore space.
-        if (line[0] == '}') space += TAB_SPACE;
-        bracket_ptr = strstr(line, "}");
-        while (bracket_ptr && space > 0)
-          {
-             space -= TAB_SPACE;
-             bracket_ptr++;
-             bracket_ptr = strstr(bracket_ptr, "}");
-          }
-
-        if (single_comment_found)
-          {
-             single_comment_found = EINA_FALSE;
-             space = saved_space;
-          }
-        else if (multi_comment_found && strstr(line, "*/"))
-          {
-             multi_comment_found = EINA_FALSE;
-             space = saved_space;
-          }
-        else if (macro_found && line[strlen(line) - 1] != '\\')
-          {
-             macro_found = EINA_FALSE;
-             space = saved_space;
-          }
-
-        eina_stringshare_del(line);
+        eina_stringshare_del(line_str);
+        free(code_line);
      }
+   eina_list_free(code_line_list);
 
    char *utf8_buf = eina_strbuf_string_steal(buf);
+   char *newline_ptr = utf8_buf;
+   int line_cnt = 1;
+   if (*newline_ptr == '\n') line_cnt++;
+   while (newline_ptr = strstr(newline_ptr + 1, "\n"))
+     line_cnt++;
+
    //FIXME: This translation may cause low performance.
    char *indented_markup = evas_textblock_text_utf8_to_markup(NULL, utf8_buf);
    eina_strbuf_free(buf);
    free(utf8_buf);
 
-   eina_list_free(code_lines);
-
    if (indented_line_cnt) *indented_line_cnt = line_cnt;
    return indented_markup;
 }

-- 


Reply via email to