#ifdef HAVE_CONFIG_H # include "elementary_config.h" #endif #include "Elementary.h" #include "elm_code_private.h" EAPI void elm_code_line_free(Elm_Code_Line *line) { if (!line) return; if (line->status_text) free((char *)line->status_text); if (line->modified) free(line->modified); free(line); } static void _elm_code_line_tokens_split_at(Elm_Code_Line *oldline, Elm_Code_Line *newline, Eina_List *tokens, int position) { Eina_List *item, *next; Elm_Code_Token *token, *newtoken; EINA_LIST_FOREACH_SAFE(tokens, item, next, token) { if (!token->continues && token->end < position) { oldline->tokens = eina_list_append(oldline->tokens, token); continue; } if (token->start >= position) { token->start -= position; token->end -= position; newline->tokens = eina_list_append(newline->tokens, token); continue; } if (token->continues) elm_code_line_token_add(newline, 0, token->end, 1, token->type); else { elm_code_line_token_add(newline, 0, token->end - position, 1, token->type); token->end = position - 1; } newtoken = eina_list_data_get(newline->tokens); newtoken->continues = token->continues; token->continues = EINA_TRUE; oldline->tokens = eina_list_append(oldline->tokens, token); } elm_code_callback_fire(oldline->file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, oldline); elm_code_callback_fire(newline->file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, newline); } EAPI void elm_code_line_split_at(Elm_Code_Line *line, unsigned int position) { Elm_Code_Line *newline; Elm_Code_Token *token EINA_UNUSED; Eina_List *tokens; char *content; unsigned int length; content = (char *) elm_code_line_text_get(line, &length); if (!content) return; content = strndup(content, length); if (!content) return; elm_code_file_line_insert(line->file, line->number + 1, "", 0, NULL); newline = elm_code_file_line_get(line->file, line->number + 1); tokens = line->tokens; line->tokens = NULL; elm_code_line_text_set(newline, content + position, length - position); elm_code_line_text_set(line, content, position); _elm_code_line_tokens_split_at(line, newline, tokens, position); EINA_LIST_FREE(tokens, token) {} // don't free tokens, we re-used them free(content); } static void _elm_code_line_merge_into(Elm_Code_Line *line1, Elm_Code_Line *line2) { Eina_List *tokens1, *tokens2; Elm_Code_Token *token; const char *text1, *text2; char *newtext; unsigned int length1, length2; text1 = elm_code_line_text_get(line1, &length1); text2 = elm_code_line_text_get(line2, &length2); newtext = malloc(sizeof(char) * (length1 + length2 + 1)); if (length1 > 0) snprintf(newtext, length1 + 1, "%s", text1); if (length2 > 0) snprintf(newtext + length1, length2 + 1, "%s", text2); tokens1 = line1->tokens; line1->tokens = NULL; tokens2 = line2->tokens; line2->tokens = NULL; elm_code_file_line_remove(line2->file, line2->number); elm_code_line_text_set(line1, newtext, length1 + length2); EINA_LIST_FREE(tokens1, token) { token->continues = EINA_FALSE; line1->tokens = eina_list_append(line1->tokens, token); } EINA_LIST_FREE(tokens2, token) { token->start += length1; token->end += length1; line1->tokens = eina_list_append(line1->tokens, token); } elm_code_callback_fire(line1->file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, line1); free(newtext); } EAPI void elm_code_line_merge_up(Elm_Code_Line *line) { Elm_Code_Line *other; other = elm_code_file_line_get(line->file, line->number - 1); if (other) _elm_code_line_merge_into(other, line); } EAPI void elm_code_line_merge_down(Elm_Code_Line *line) { Elm_Code_Line *other; other = elm_code_file_line_get(line->file, line->number + 1); if (other) _elm_code_line_merge_into(line, other); } EAPI void elm_code_line_status_set(Elm_Code_Line *line, Elm_Code_Status_Type status) { if (!line) return; line->status = status; } EAPI void elm_code_line_status_text_set(Elm_Code_Line *line, const char *text) { if (line->status_text) free(line->status_text); if (text) line->status_text = strdup(text); else line->status_text = NULL; } EAPI void elm_code_line_token_add(Elm_Code_Line *line, int start, int end, int lines, Elm_Code_Token_Type type) { Elm_Code_Token *tok; Elm_Code_Line *next_line; if (!line) return; tok = calloc(1, sizeof(Elm_Code_Token)); tok->start = start; tok->end = end; tok->continues = lines > 1; tok->type = type; line->tokens = eina_list_append(line->tokens, tok); if (lines > 1) { next_line = elm_code_file_line_get(line->file, line->number + 1); elm_code_line_token_add(next_line, 0, end, lines - 1, type); } } EAPI void elm_code_line_tokens_clear(Elm_Code_Line *line) { Elm_Code_Token *token; if (!line->tokens) return; EINA_LIST_FREE(line->tokens, token) free(token); line->tokens = NULL; } EAPI void elm_code_line_status_clear(Elm_Code_Line *line) { line->status = ELM_CODE_STATUS_TYPE_DEFAULT; if (line->status_text) { free((char *)line->status_text); line->status_text = NULL; } } EAPI Eina_Bool elm_code_line_contains_widget_cursor(Elm_Code_Line *line) { Elm_Code *code = line->file->parent; Eina_List *item; Eo *widget; unsigned int col, number; if (!code) return EINA_FALSE; EINA_LIST_FOREACH(code->widgets, item, widget) { elm_code_widget_cursor_position_get(widget, &number, &col); if (number == line->number) return EINA_TRUE; } return EINA_FALSE; }