introduce new feature, auto completion.

This commit is contained in:
ChunEon Park 2014-07-19 13:31:08 +09:00
parent 4c8f205d2c
commit adae9b6fd3
13 changed files with 990 additions and 46 deletions

1
README
View File

@ -47,6 +47,7 @@ F12 = Setting
Ctrl+S = Quick Save + Compile EDC
Ctrl+I = On/Off Auto Indentation
Ctrl+O = On/Off Auto Completion
Ctrl+W = Show/Hide Dummy Swallow
Ctrl+H = On/Off Part Highlighting
Ctrl+, = Full Edit View / Split View

View File

@ -30,6 +30,7 @@ enventor_SOURCES = \
search.c \
goto.c \
newfile.c \
auto_comp.c \
globals.c
enventor_LDADD = @ENVENTOR_LIBS@

553
src/bin/auto_comp.c Normal file
View File

@ -0,0 +1,553 @@
#include <Elementary.h>
#include "auto_comp_code.h"
#include "common.h"
#define QUEUE_SIZE 20
#define COMPSET_PAIR_MINIMUM 1
typedef struct comp_set_s
{
Eina_Stringshare *key;
char **txt;
int cursor_offset;
int line_back;
int line_cnt;
} comp_set;
typedef struct autocomp_s
{
char queue[QUEUE_SIZE];
int queue_pos;
comp_set compset[COMPSET_CNT];
edit_data *ed;
Evas_Object *anchor;
Evas_Object *list;
Eina_List *compset_list;
Ecore_Thread *init_thread;
Eina_Bool anchor_visible : 1;
Eina_Bool initialized : 1;
} autocomp_data;
static autocomp_data *g_ad = NULL;
#define COMPDATA_SET(ad, key, txt, cursor_offset, line_back) \
compdata_set(ad, idx++, key, (char **)(&txt), cursor_offset, line_back, txt##_LINE_CNT)
static void
compdata_set(autocomp_data *ad, int idx, char *key, char **txt, int cursor_offset, int line_back, int line_cnt)
{
ad->compset[idx].key = eina_stringshare_add(key);
ad->compset[idx].txt = txt;
ad->compset[idx].cursor_offset = cursor_offset;
ad->compset[idx].line_back = line_back;
ad->compset[idx].line_cnt = line_cnt;
}
static void
init_thread_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
{
autocomp_data *ad = data;
int idx = 0;
COMPDATA_SET(ad, "collections",AUTOCOMP_COLLECTIONS, 2, 1);
COMPDATA_SET(ad, "image",AUTOCOMP_IMAGE, 7, 0);
COMPDATA_SET(ad, "images",AUTOCOMP_IMAGES, 2, 1);
COMPDATA_SET(ad, "group",AUTOCOMP_GROUP, 4, 1);
COMPDATA_SET(ad, "type",AUTOCOMP_TYPE, 0, 0);
COMPDATA_SET(ad, "part",AUTOCOMP_PART, 4, 1);
COMPDATA_SET(ad, "parts",AUTOCOMP_PARTS, 2, 1);
COMPDATA_SET(ad, "description",AUTOCOMP_DESCRIPTION, 8, 1);
COMPDATA_SET(ad, "inherit",AUTOCOMP_INHERIT, 6, 0);
COMPDATA_SET(ad, "program",AUTOCOMP_PROGRAM, 4, 1);
COMPDATA_SET(ad, "programs",AUTOCOMP_PROGRAMS, 2, 1);
COMPDATA_SET(ad, "signal",AUTOCOMP_SIGNAL, 2, 0);
COMPDATA_SET(ad, "source",AUTOCOMP_SOURCE, 2, 0);
COMPDATA_SET(ad, "target",AUTOCOMP_TARGET, 2, 0);
COMPDATA_SET(ad, "scale",AUTOCOMP_SCALE, 0, 0);
COMPDATA_SET(ad, "rel1",AUTOCOMP_REL1, 2, 1);
COMPDATA_SET(ad, "rel2",AUTOCOMP_REL2, 2, 1);
COMPDATA_SET(ad, "relatvie",AUTOCOMP_RELATIVE, 1, 0);
COMPDATA_SET(ad, "offset", AUTOCOMP_OFFSET, 1, 0);
COMPDATA_SET(ad, "color", AUTOCOMP_COLOR, 1, 0);
COMPDATA_SET(ad, "color2", AUTOCOMP_COLOR2, 1, 0);
COMPDATA_SET(ad, "color3", AUTOCOMP_COLOR3, 1, 0);
COMPDATA_SET(ad, "aspect", AUTOCOMP_ASPECT, 1, 0);
COMPDATA_SET(ad, "aspect_preference", AUTOCOMP_ASPECT_PREFERENCE, 1, 0);
COMPDATA_SET(ad, "normal", AUTOCOMP_NORMAL, 2, 0);
COMPDATA_SET(ad, "effect", AUTOCOMP_EFFECT, 0, 0);
COMPDATA_SET(ad, "text", AUTOCOMP_TEXT, 2, 1);
COMPDATA_SET(ad, "font", AUTOCOMP_FONT, 2, 0);
COMPDATA_SET(ad, "align", AUTOCOMP_ALIGN, 1, 0);
COMPDATA_SET(ad, "size", AUTOCOMP_SIZE, 1, 0);
COMPDATA_SET(ad, "action", AUTOCOMP_ACTION, 6, 0);
COMPDATA_SET(ad, "transition", AUTOCOMP_TRANSITION, 1, 0);
COMPDATA_SET(ad, "after", AUTOCOMP_AFTER, 2, 0);
COMPDATA_SET(ad, "styles", AUTOCOMP_STYLES, 2, 1);
COMPDATA_SET(ad, "style", AUTOCOMP_STYLE, 4, 1);
COMPDATA_SET(ad, "base", AUTOCOMP_BASE, 2, 0);
COMPDATA_SET(ad, "sounds", AUTOCOMP_SOUNDS, 2, 1);
COMPDATA_SET(ad, "sample", AUTOCOMP_SAMPLE, 13, 1);
COMPDATA_SET(ad, "map", AUTOCOMP_MAP, 2, 1);
COMPDATA_SET(ad, "on", AUTOCOMP_ON, 1, 0);
COMPDATA_SET(ad, "visible", AUTOCOMP_VISIBLE, 1, 0);
COMPDATA_SET(ad, "perspective_on", AUTOCOMP_PERSPECTIVE_ON, 1, 0);
COMPDATA_SET(ad, "perspective", AUTOCOMP_PERSPECTIVE, 2, 0);
COMPDATA_SET(ad, "backface_cull", AUTOCOMP_BACKFACE_CULL, 1, 0);
COMPDATA_SET(ad, "rotation", AUTOCOMP_ROTATION, 2, 1);
COMPDATA_SET(ad, "min", AUTOCOMP_MIN, 1, 0);
COMPDATA_SET(ad, "max", AUTOCOMP_MAX, 1, 0);
COMPDATA_SET(ad, "fixed", AUTOCOMP_FIXED, 1, 0);
COMPDATA_SET(ad, "clip_to", AUTOCOMP_CLIP_TO, 2, 0);
COMPDATA_SET(ad, "tween", AUTOCOMP_TWEEN, 2, 0);
}
static void
init_thread_end_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
{
autocomp_data *ad = data;
ad->initialized = EINA_TRUE;
ad->init_thread = NULL;
}
static void
init_thread_cancel_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
{
autocomp_data *ad = data;
ad->init_thread = NULL;
}
static void
entry_anchor_off(autocomp_data *ad)
{
if (ad->anchor_visible) elm_object_tooltip_hide(ad->anchor);
ad->anchor_visible = EINA_FALSE;
ad->compset_list = eina_list_free(ad->compset_list);
}
static void
anchor_unfocused_cb(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
autocomp_data *ad = data;
entry_anchor_off(ad);
}
static void
queue_reset(autocomp_data *ad)
{
if (ad->queue_pos == -1) return;
ad->queue_pos = -1;
memset(ad->queue, 0x0, sizeof(ad->queue));
entry_anchor_off(ad);
}
static void
compset_list_update(autocomp_data *ad)
{
if (!config_auto_complete_get() || !ad->initialized) return;
if (ad->queue_pos < COMPSET_PAIR_MINIMUM) return;
int i;
ad->compset_list = eina_list_free(ad->compset_list);
for (i = 0; i < COMPSET_CNT; i++)
{
if (ad->queue[0] == ad->compset[i].key[0])
{
if (!strncmp(ad->queue, ad->compset[i].key, ad->queue_pos + 1))
{
ad->compset_list = eina_list_append(ad->compset_list,
&ad->compset[i]);
}
}
}
}
static void
push_char(autocomp_data *ad, char c)
{
ad->queue_pos++;
if (ad->queue_pos == QUEUE_SIZE)
{
memset(ad->queue, 0x0, sizeof(ad->queue));
ad->queue_pos = 0;
}
ad->queue[ad->queue_pos] = c;
compset_list_update(ad);
}
static void
pop_char(autocomp_data *ad, int cnt)
{
if (ad->queue_pos == -1) return;
int i;
for (i = 0; i < cnt; i++)
{
ad->queue[ad->queue_pos] = 0x0;
ad->queue_pos--;
if (ad->queue_pos < 0) break;
}
if (ad->queue_pos == -1) return;
compset_list_update(ad);
}
static void
insert_completed_text(autocomp_data *ad)
{
if (!ad->compset_list) return;
Elm_Object_Item *it = elm_list_selected_item_get(ad->list);
comp_set *compset = elm_object_item_data_get(it);
char **txt = compset->txt;
Evas_Object *entry = edit_entry_get(ad->ed);
int space = edit_cur_indent_depth_get(ad->ed);
//Insert the first line.
elm_entry_entry_insert(entry, txt[0]+ (ad->queue_pos + 1));
//Insert last lines
if (compset->line_cnt > 1)
{
//Alloc Empty spaces
char *p = alloca(space + 1);
memset(p, ' ', space);
p[space] = '\0';
int i;
for (i = 1; i < (compset->line_cnt -1); i++)
{
elm_entry_entry_insert(entry, p);
elm_entry_entry_insert(entry, txt[i]);
}
elm_entry_entry_insert(entry, p);
elm_entry_entry_insert(entry, txt[i]);
}
int cursor_pos = elm_entry_cursor_pos_get(entry);
cursor_pos -= (compset->cursor_offset + (compset->line_back * space));
elm_entry_cursor_pos_set(entry, cursor_pos);
edit_line_increase(ad->ed, (compset->line_cnt - 1));
}
static void
list_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
autocomp_data *ad = data;
ad->list = NULL;
}
static Evas_Object *
entry_tooltip_content_cb(void *data, Evas_Object *obj EINA_UNUSED,
Evas_Object *tt EINA_UNUSED)
{
autocomp_data *ad = data;
ad->list = elm_list_add(obj);
elm_object_focus_allow_set(ad->list, EINA_FALSE);
elm_list_mode_set(ad->list, ELM_LIST_EXPAND);
Eina_List *l;
comp_set *compset;
EINA_LIST_FOREACH(ad->compset_list, l, compset)
elm_list_item_append(ad->list, compset->key, NULL, NULL, NULL, compset);
Elm_Object_Item *it = elm_list_first_item_get(ad->list);
elm_list_item_selected_set(it, EINA_TRUE);
evas_object_smart_callback_add(ad->list, "unfocused", anchor_unfocused_cb,
ad);
evas_object_event_callback_add(ad->list, EVAS_CALLBACK_DEL, list_del_cb, ad);
elm_list_go(ad->list);
evas_object_show(ad->list);
return ad->list;
}
static void
anchor_list_update(autocomp_data *ad)
{
comp_set *compset;
Eina_List *items = (Eina_List *) elm_list_items_get(ad->list);
Eina_List *l, *ll, *l2;
Elm_Object_Item *it;
Eina_Bool found;
const char *it_name;
//Remove the non-candidates
EINA_LIST_FOREACH_SAFE(items, l, ll, it)
{
found = EINA_FALSE;
it_name = elm_object_item_text_get(it);
EINA_LIST_FOREACH(ad->compset_list, l2, compset)
{
if (compset->key == it_name)
{
found = EINA_TRUE;
break;
}
}
if (!found) elm_object_item_del(it);
}
items = (Eina_List *) elm_list_items_get(ad->list);
//Append new candidates
EINA_LIST_FOREACH(ad->compset_list, l, compset)
{
found = EINA_FALSE;
EINA_LIST_FOREACH(items, l2, it)
{
it_name = elm_object_item_text_get(it);
if (it_name != compset->key) continue;
found = EINA_TRUE;
break;
}
if (!found) elm_list_item_append(ad->list, compset->key, NULL,
NULL, NULL, compset);
}
it = elm_list_first_item_get(ad->list);
elm_list_item_selected_set(it, EINA_TRUE);
elm_list_go(ad->list);
}
static void
candidate_list_show(autocomp_data *ad)
{
if (!ad->compset_list)
{
entry_anchor_off(ad);
return;
}
Evas_Object *entry = edit_entry_get(ad->ed);
//Update anchor position
Evas_Coord x, y, h;
Evas_Coord cx, cy, cw, ch;
evas_object_geometry_get(entry, &x, &y, NULL, NULL);
elm_entry_cursor_geometry_get(entry, &cx, &cy, &cw, &ch);
evas_object_move(ad->anchor, cx + x, cy + y);
evas_object_resize(ad->anchor, cw, ch);
//Show the tooltip
if (!ad->anchor_visible)
{
//Decide the Tooltip direction
Elm_Tooltip_Orient tooltip_orient = ELM_TOOLTIP_ORIENT_BOTTOM;
Evas_Object *layout = base_layout_get();
evas_object_geometry_get(layout, NULL, NULL, NULL, &h);
if ((cy + y) > (h / 2)) tooltip_orient = ELM_TOOLTIP_ORIENT_TOP;
//Tooltip set
elm_object_tooltip_content_cb_set(ad->anchor,
entry_tooltip_content_cb, ad, NULL);
elm_object_tooltip_orient_set(ad->anchor, tooltip_orient);
elm_object_tooltip_show(ad->anchor);
ad->anchor_visible = EINA_TRUE;
}
//Already tooltip is visible, just update the list item
else anchor_list_update(ad);
}
static void
entry_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
{
Elm_Entry_Change_Info *info = event_info;
autocomp_data *ad = data;
if (info->insert)
{
if ((strlen(info->change.insert.content) > 1) ||
(info->change.insert.content[0] == ' ') ||
(info->change.insert.content[0] == '.'))
{
entry_anchor_off(ad);
queue_reset(ad);
}
else
{
push_char(ad, info->change.insert.content[0]);
candidate_list_show(ad);
}
}
else
{
if (info->change.del.content[0] != ' ')
{
entry_anchor_off(ad);
int cnt = abs(info->change.del.end - info->change.del.start);
pop_char(ad, cnt);
}
}
}
static void
entry_cursor_changed_manual_cb(void *data, Evas_Object *obj,
void *event_info EINA_UNUSED)
{
autocomp_data *ad = data;
entry_anchor_off(ad);
}
static void
entry_cursor_changed_cb(void *data, Evas_Object *obj,
void *event_info EINA_UNUSED)
{
autocomp_data *ad = data;
//Update anchor position
Evas_Coord x, y, cx, cy, cw, ch;
evas_object_geometry_get(obj, &x, &y, NULL, NULL);
elm_entry_cursor_geometry_get(obj, &cx, &cy, &cw, &ch);
evas_object_move(ad->anchor, cx + x, cy + y);
evas_object_resize(ad->anchor, cw, ch);
}
static void
entry_press_cb(void *data, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
autocomp_data *ad = data;
entry_anchor_off(ad);
}
static void
entry_move_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
autocomp_data *ad = data;
entry_anchor_off(ad);
}
static void
list_item_move(autocomp_data *ad, Eina_Bool up)
{
Evas_Object *entry = edit_entry_get(ad->ed);
evas_object_smart_callback_del(entry, "unfocused", anchor_unfocused_cb);
Elm_Object_Item *it = elm_list_selected_item_get(ad->list);
if (up) it = elm_list_item_prev(it);
else it = elm_list_item_next(it);
if (it) elm_list_item_selected_set(it, EINA_TRUE);
evas_object_smart_callback_add(entry, "unfocused", anchor_unfocused_cb, ad);
}
void
autocomp_target_set(edit_data *ed)
{
autocomp_data *ad = g_ad;
Evas_Object *entry;
queue_reset(ad);
//Unset previous target
if (ad->ed)
{
entry = edit_entry_get(ad->ed);
evas_object_smart_callback_del(entry, "changed,user", entry_changed_cb);
evas_object_smart_callback_del(entry, "cursor,changed",
entry_cursor_changed_cb);
evas_object_smart_callback_del(entry, "cursor,changed,manual",
entry_cursor_changed_manual_cb);
evas_object_smart_callback_del(entry, "unfocused", anchor_unfocused_cb);
evas_object_smart_callback_del(entry, "press", entry_press_cb);
evas_object_event_callback_del(entry, EVAS_CALLBACK_MOVE,
entry_move_cb);
ad->ed = NULL;
}
if (!ed) return;
entry = edit_entry_get(ed);
evas_object_smart_callback_add(entry, "changed,user", entry_changed_cb, ad);
evas_object_smart_callback_add(entry, "cursor,changed,manual",
entry_cursor_changed_manual_cb, ad);
evas_object_smart_callback_add(entry, "cursor,changed",
entry_cursor_changed_cb, ad);
evas_object_smart_callback_add(entry, "unfocused", anchor_unfocused_cb, ad);
evas_object_smart_callback_add(entry, "press", entry_press_cb, ad);
evas_object_event_callback_add(entry, EVAS_CALLBACK_MOVE,
entry_move_cb, ad);
ad->ed = ed;
}
void
autocomp_init(Evas_Object *parent)
{
autocomp_data *ad = calloc(1, sizeof(autocomp_data));
ad->init_thread = ecore_thread_run(init_thread_cb, init_thread_end_cb,
init_thread_cancel_cb, ad);
ad->anchor = elm_button_add(parent);
ad->queue_pos = -1;
g_ad = ad;
}
void
autocomp_term()
{
autocomp_data *ad = g_ad;
evas_object_del(ad->anchor);
ecore_thread_cancel(ad->init_thread);
int i;
for (i = 0; i < COMPSET_CNT; i++)
eina_stringshare_del(ad->compset[i].key);
free(ad);
g_ad = NULL;
}
void
autocomp_toggle()
{
Eina_Bool toggle = !config_auto_complete_get();
if (toggle) stats_info_msg_update("Auto Completion Enabled.");
else stats_info_msg_update("Auto Completion Disabled.");
config_auto_complete_set(toggle);
}
Eina_Bool
autocomp_key_event_hook(const char *key)
{
autocomp_data *ad = g_ad;
if (!ad || !ad->anchor_visible) return EINA_FALSE;
//Cancel the auto complete.
if (!strcmp(key, "BackSpace"))
{
queue_reset(ad);
entry_anchor_off(ad);
return EINA_TRUE;
}
if (!strcmp(key, "Return"))
{
insert_completed_text(ad);
queue_reset(ad);
edit_syntax_color_partial_apply(ad->ed);
return EINA_TRUE;
}
if (!strcmp(key, "Up"))
{
list_item_move(ad, EINA_TRUE);
return EINA_TRUE;
}
if (!strcmp(key, "Down"))
{
list_item_move(ad, EINA_FALSE);
return EINA_TRUE;
}
return EINA_FALSE;
}

View File

@ -28,6 +28,7 @@ typedef struct config_s
Eina_Bool dummy_swallow;
Eina_Bool auto_indent;
Eina_Bool tools;
Eina_Bool auto_complete;
} config_data;
static config_data *g_cd = NULL;
@ -128,6 +129,7 @@ config_load()
cd->dummy_swallow = EINA_TRUE;
cd->auto_indent = EINA_TRUE;
cd->tools = EINA_FALSE;
cd->auto_complete = EINA_TRUE;
}
g_cd = cd;
@ -200,6 +202,8 @@ eddc_init()
auto_indent, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_base, config_data, "tools",
tools, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(edd_base, config_data, "auto_complete",
auto_complete, EET_T_UCHAR);
}
void
@ -572,6 +576,13 @@ config_auto_indent_get()
return cd->auto_indent;
}
Eina_Bool
config_auto_complete_get()
{
config_data *cd = g_cd;
return cd->auto_complete;
}
void
config_font_size_set(float font_size)
{
@ -592,6 +603,13 @@ config_font_size_get()
return cd->font_size;
}
void
config_auto_complete_set(Eina_Bool auto_complete)
{
config_data *cd = g_cd;
cd->auto_complete = auto_complete;
}
void
config_auto_indent_set(Eina_Bool auto_indent)
{

View File

@ -58,45 +58,6 @@ line_init(edit_data *ed)
elm_entry_entry_set(ed->en_line, buf);
}
static void
line_increase(edit_data *ed, int cnt)
{
char buf[MAX_LINE_DIGIT_CNT];
int i;
for (i = 0; i < cnt; i++)
{
ed->line_max++;
snprintf(buf, sizeof(buf), "<br/>%d", ed->line_max);
elm_entry_entry_append(ed->en_line, buf);
}
}
static void
line_decrease(edit_data *ed, int cnt)
{
if (cnt < 1) return;
Evas_Object *textblock = elm_entry_textblock_get(ed->en_line);
Evas_Textblock_Cursor *cur1 = evas_object_textblock_cursor_new(textblock);
evas_textblock_cursor_line_set(cur1, (ed->line_max - cnt - 1));
evas_textblock_cursor_line_char_last(cur1);
Evas_Textblock_Cursor *cur2 = evas_object_textblock_cursor_new(textblock);
evas_textblock_cursor_paragraph_last(cur2);
evas_textblock_cursor_range_delete(cur1, cur2);
evas_textblock_cursor_free(cur1);
evas_textblock_cursor_free(cur2);
elm_entry_calc_force(ed->en_line);
ed->line_max -= cnt;
if (ed->line_max < 1) line_init(ed);
}
static void
visible_text_region_get(edit_data *ed, int *from_line, int *to_line)
{
@ -275,14 +236,14 @@ edit_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
if (!strcmp(info->change.insert.content, EOL))
{
line_increase(ed, 1);
edit_line_increase(ed, 1);
syntax_color = EINA_FALSE;
}
else
{
int increase =
parser_line_cnt_get(ed->pd, info->change.insert.content);
line_increase(ed, increase);
edit_line_increase(ed, increase);
}
if (config_auto_indent_get())
@ -301,7 +262,7 @@ edit_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info)
decrease++;
}
line_decrease(ed, decrease);
edit_line_decrease(ed, decrease);
if (info->change.del.content[0] == ' ') return;
}
@ -407,7 +368,7 @@ edit_syntax_color_full_apply(edit_data *ed, Eina_Bool force)
void
edit_syntax_color_partial_apply(edit_data *ed)
{
ed->syntax_color_lock--;
if (ed->syntax_color_lock > 0) ed->syntax_color_lock = 0;
syntax_color_partial_update(ed, SYNTAX_COLOR_DEFAULT_TIME);
}
@ -474,7 +435,7 @@ edit_template_insert(edit_data *ed)
elm_entry_entry_insert(ed->en_edit, p);
elm_entry_entry_insert(ed->en_edit, t[i]);
}
line_increase(ed, (line_cnt - 1));
edit_line_increase(ed, (line_cnt -1));
elm_entry_entry_insert(ed->en_edit, p);
elm_entry_entry_insert(ed->en_edit, t[i]);
@ -485,6 +446,12 @@ edit_template_insert(edit_data *ed)
stats_info_msg_update(buf);
}
int
edit_cur_indent_depth_get(edit_data *ed)
{
return indent_space_get(syntax_indent_data_get(ed->sh), ed->en_edit);
}
void
edit_template_part_insert(edit_data *ed, Edje_Part_Type type)
{
@ -552,7 +519,7 @@ edit_template_part_insert(edit_data *ed, Edje_Part_Type type)
elm_entry_entry_insert(ed->en_edit, p);
elm_entry_entry_insert(ed->en_edit, t[i]);
//Incease line by (line count - 1)
line_increase(ed, 1);
edit_line_increase(ed, 1);
}
elm_entry_entry_insert(ed->en_edit, p);
@ -872,7 +839,7 @@ edit_line_delete(edit_data *ed)
evas_textblock_cursor_free(cur2);
elm_entry_calc_force(ed->en_edit);
line_decrease(ed, 1);
edit_line_decrease(ed, 1);
cur_line_pos_set(ed, EINA_TRUE);
edit_changed_set(ed, EINA_TRUE);
@ -1068,6 +1035,8 @@ edit_edc_read(edit_data *ed, const char *file_path)
ed->line_max = 0;
autocomp_target_set(NULL);
file = eina_file_open(file_path, EINA_FALSE);
if (!file) goto err;
@ -1110,6 +1079,8 @@ edit_edc_read(edit_data *ed, const char *file_path)
ecore_animator_add(syntax_color_timer_cb, ed);
autocomp_target_set(ed);
err:
//Even any text is not inserted, line number should start with 1
if (ed->line_max == 0) line_init(ed);
@ -1236,3 +1207,42 @@ edit_entry_get(edit_data *ed)
{
return ed->en_edit;
}
void
edit_line_increase(edit_data *ed, int cnt)
{
char buf[MAX_LINE_DIGIT_CNT];
int i;
for (i = 0; i < cnt; i++)
{
ed->line_max++;
snprintf(buf, sizeof(buf), "<br/>%d", ed->line_max);
elm_entry_entry_append(ed->en_line, buf);
}
}
void
edit_line_decrease(edit_data *ed, int cnt)
{
if (cnt < 1) return;
Evas_Object *textblock = elm_entry_textblock_get(ed->en_line);
Evas_Textblock_Cursor *cur1 = evas_object_textblock_cursor_new(textblock);
evas_textblock_cursor_line_set(cur1, (ed->line_max - cnt - 1));
evas_textblock_cursor_line_char_last(cur1);
Evas_Textblock_Cursor *cur2 = evas_object_textblock_cursor_new(textblock);
evas_textblock_cursor_paragraph_last(cur2);
evas_textblock_cursor_range_delete(cur1, cur2);
evas_textblock_cursor_free(cur1);
evas_textblock_cursor_free(cur2);
elm_entry_calc_force(ed->en_line);
ed->line_max -= cnt;
if (ed->line_max < 1) line_init(ed);
}

View File

@ -171,6 +171,12 @@ ctrl_func(app_data *ad, const char *key)
auto_indentation_toggle();
return ECORE_CALLBACK_DONE;
}
//Auto Completion
if (!strcmp(key, "o") || !strcmp(key, "O"))
{
autocomp_toggle();
return ECORE_CALLBACK_DONE;
}
return ECORE_CALLBACK_PASS_ON;
}
@ -180,6 +186,8 @@ main_key_down_cb(void *data, int type EINA_UNUSED, void *ev)
Ecore_Event_Key *event = ev;
app_data *ad = data;
if (autocomp_key_event_hook(event->key)) return ECORE_CALLBACK_DONE;
//Shift Key
if (!strcmp("Shift_L", event->key))
{
@ -522,6 +530,7 @@ init(app_data *ad, int argc, char **argv)
if (!edc_default_setup()) return EINA_FALSE;
if (!base_gui_init()) return EINA_FALSE;
autocomp_init(base_layout_get());
edj_mgr_set();
statusbar_set();
edc_edit_set(ad);
@ -549,6 +558,7 @@ term(app_data *ad)
stats_term();
base_gui_term();
config_term();
autocomp_term();
elm_shutdown();
}

View File

@ -21,6 +21,7 @@ struct menu_s
Evas_Object *toggle_highlight;
Evas_Object *toggle_swallow;
Evas_Object *toggle_indent;
Evas_Object *toggle_autocomp;
Evas_Object *ctxpopup;
const char *last_accessed_path;
@ -287,6 +288,7 @@ setting_apply_btn_cb(void *data, Evas_Object *obj EINA_UNUSED,
config_part_highlight_set(elm_check_state_get(md->toggle_highlight));
config_dummy_swallow_set(elm_check_state_get(md->toggle_swallow));
config_auto_indent_set(elm_check_state_get(md->toggle_indent));
config_auto_complete_set(elm_check_state_get(md->toggle_autocomp));
config_apply();
@ -381,6 +383,7 @@ setting_reset_btn_cb(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED,
elm_check_state_set(md->toggle_highlight, config_part_highlight_get());
elm_check_state_set(md->toggle_swallow, config_dummy_swallow_get());
elm_check_state_set(md->toggle_indent, config_auto_indent_get());
elm_check_state_set(md->toggle_autocomp, config_auto_complete_get());
}
static Evas_Object *
@ -558,6 +561,11 @@ setting_open(menu_data *md)
config_auto_indent_get());
elm_box_pack_end(box, toggle_indent);
//Toggle (Auto Complete)
Evas_Object *toggle_autocomp = toggle_create(box, "Auto Completion",
config_auto_complete_get());
elm_box_pack_end(box, toggle_autocomp);
Evas_Object *btn;
//Apply Button
@ -594,6 +602,7 @@ setting_open(menu_data *md)
md->toggle_highlight = toggle_highlight;
md->toggle_swallow = toggle_swallow;
md->toggle_indent = toggle_indent;
md->toggle_autocomp = toggle_autocomp;
md->open_depth++;
}

View File

@ -20,4 +20,6 @@ EXTRA_DIST = common.h \
template_code.h \
tools.h \
newfile.h \
auto_comp.h \
auto_comp_code.h \
search.h

5
src/include/auto_comp.h Normal file
View File

@ -0,0 +1,5 @@
void autocomp_init(Evas_Object *parent);
void autocomp_term();
void autocomp_target_set(edit_data *ed);
void autocomp_toggle();
Eina_Bool autocomp_key_event_hook(const char *key);

View File

@ -0,0 +1,329 @@
#define AUTOCOMP_COLLECTIONS_LINE_CNT 3
const char *AUTOCOMP_COLLECTIONS[AUTOCOMP_COLLECTIONS_LINE_CNT] =
{
"collections {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_GROUP_LINE_CNT 2
const char *AUTOCOMP_GROUP[AUTOCOMP_GROUP_LINE_CNT] =
{
"group { name: \"\";<br/>",
"}"
};
#define AUTOCOMP_PARTS_LINE_CNT 3
const char *AUTOCOMP_PARTS[AUTOCOMP_PARTS_LINE_CNT] =
{
"parts {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_PART_LINE_CNT 2
const char *AUTOCOMP_PART[AUTOCOMP_PART_LINE_CNT] =
{
"part { name: \"\";<br/>",
"}"
};
#define AUTOCOMP_DESCRIPTION_LINE_CNT 2
const char *AUTOCOMP_DESCRIPTION[AUTOCOMP_DESCRIPTION_LINE_CNT] =
{
"description { state: \"\" 0.0;<br/>",
"}"
};
#define AUTOCOMP_IMAGES_LINE_CNT 3
const char *AUTOCOMP_IMAGES[AUTOCOMP_IMAGES_LINE_CNT] =
{
"images {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_IMAGE_LINE_CNT 1
const char *AUTOCOMP_IMAGE[AUTOCOMP_IMAGE_LINE_CNT] =
{
"image: \"\" COMP;",
};
#define AUTOCOMP_TYPE_LINE_CNT 1
const char *AUTOCOMP_TYPE[AUTOCOMP_TYPE_LINE_CNT] =
{
"type: IMAGE;",
};
#define AUTOCOMP_INHERIT_LINE_CNT 1
const char *AUTOCOMP_INHERIT[AUTOCOMP_INHERIT_LINE_CNT] =
{
"inherit: \"\" 0.0;",
};
#define AUTOCOMP_PROGRAMS_LINE_CNT 3
const char *AUTOCOMP_PROGRAMS[AUTOCOMP_PROGRAMS_LINE_CNT] =
{
"programs {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_PROGRAM_LINE_CNT 2
const char *AUTOCOMP_PROGRAM[AUTOCOMP_PROGRAM_LINE_CNT] =
{
"program { name: \"\";<br/>",
"}"
};
#define AUTOCOMP_SIGNAL_LINE_CNT 1
const char *AUTOCOMP_SIGNAL[AUTOCOMP_SIGNAL_LINE_CNT] =
{
"signal: \"\";",
};
#define AUTOCOMP_SOURCE_LINE_CNT 1
const char *AUTOCOMP_SOURCE[AUTOCOMP_SOURCE_LINE_CNT] =
{
"source: \"\";",
};
#define AUTOCOMP_TARGET_LINE_CNT 1
const char *AUTOCOMP_TARGET[AUTOCOMP_TARGET_LINE_CNT] =
{
"target: \"\";",
};
#define AUTOCOMP_SCALE_LINE_CNT 1
const char *AUTOCOMP_SCALE[AUTOCOMP_SCALE_LINE_CNT] =
{
"scale: 1;"
};
#define AUTOCOMP_REL1_LINE_CNT 3
const char *AUTOCOMP_REL1[AUTOCOMP_REL1_LINE_CNT] =
{
"rel1 {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_REL2_LINE_CNT 3
const char *AUTOCOMP_REL2[AUTOCOMP_REL2_LINE_CNT] =
{
"rel2 {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_RELATIVE_LINE_CNT 1
const char *AUTOCOMP_RELATIVE[AUTOCOMP_RELATIVE_LINE_CNT] =
{
"relative: ;",
};
#define AUTOCOMP_OFFSET_LINE_CNT 1
const char *AUTOCOMP_OFFSET[AUTOCOMP_OFFSET_LINE_CNT] =
{
"offset: ;",
};
#define AUTOCOMP_COLOR_LINE_CNT 1
const char *AUTOCOMP_COLOR[AUTOCOMP_COLOR_LINE_CNT] =
{
"color: ;",
};
#define AUTOCOMP_COLOR2_LINE_CNT 1
const char *AUTOCOMP_COLOR2[AUTOCOMP_COLOR2_LINE_CNT] =
{
"color2: ;",
};
#define AUTOCOMP_COLOR3_LINE_CNT 1
const char *AUTOCOMP_COLOR3[AUTOCOMP_COLOR3_LINE_CNT] =
{
"color3: ;",
};
#define AUTOCOMP_ASPECT_LINE_CNT 1
const char *AUTOCOMP_ASPECT[AUTOCOMP_ASPECT_LINE_CNT] =
{
"aspect: ;",
};
#define AUTOCOMP_ASPECT_PREFERENCE_LINE_CNT 1
const char *AUTOCOMP_ASPECT_PREFERENCE[AUTOCOMP_ASPECT_PREFERENCE_LINE_CNT] =
{
"aspect_preference: BOTH;",
};
#define AUTOCOMP_NORMAL_LINE_CNT 1
const char *AUTOCOMP_NORMAL[AUTOCOMP_NORMAL_LINE_CNT] =
{
"normal: \"\";",
};
#define AUTOCOMP_TWEEN_LINE_CNT 1
const char *AUTOCOMP_TWEEN[AUTOCOMP_TWEEN_LINE_CNT] =
{
"tween: \"\";",
};
#define AUTOCOMP_EFFECT_LINE_CNT 1
const char *AUTOCOMP_EFFECT[AUTOCOMP_EFFECT_LINE_CNT] =
{
"effect: NONE;",
};
#define AUTOCOMP_TEXT_LINE_CNT 3
const char *AUTOCOMP_TEXT[AUTOCOMP_TEXT_LINE_CNT] =
{
"text {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_FONT_LINE_CNT 1
const char *AUTOCOMP_FONT[AUTOCOMP_FONT_LINE_CNT] =
{
"font: \"\";"
};
#define AUTOCOMP_ALIGN_LINE_CNT 1
const char *AUTOCOMP_ALIGN[AUTOCOMP_ALIGN_LINE_CNT] =
{
"align: ;"
};
#define AUTOCOMP_SIZE_LINE_CNT 1
const char *AUTOCOMP_SIZE[AUTOCOMP_SIZE_LINE_CNT] =
{
"size: ;"
};
#define AUTOCOMP_ACTION_LINE_CNT 1
const char *AUTOCOMP_ACTION[AUTOCOMP_ACTION_LINE_CNT] =
{
"action: STATE_SET \"\" 0.0;"
};
#define AUTOCOMP_TRANSITION_LINE_CNT 1
const char *AUTOCOMP_TRANSITION[AUTOCOMP_TRANSITION_LINE_CNT] =
{
"transition: LINEAR ;"
};
#define AUTOCOMP_AFTER_LINE_CNT 1
const char *AUTOCOMP_AFTER[AUTOCOMP_AFTER_LINE_CNT] =
{
"after: \"\";"
};
#define AUTOCOMP_STYLES_LINE_CNT 3
const char *AUTOCOMP_STYLES[AUTOCOMP_STYLES_LINE_CNT] =
{
"styles {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_STYLE_LINE_CNT 2
const char *AUTOCOMP_STYLE[AUTOCOMP_STYLE_LINE_CNT] =
{
"style { name: \"\";<br/>",
"}"
};
#define AUTOCOMP_BASE_LINE_CNT 1
const char *AUTOCOMP_BASE[AUTOCOMP_BASE_LINE_CNT] =
{
"base: \"\";",
};
#define AUTOCOMP_SOUNDS_LINE_CNT 3
const char *AUTOCOMP_SOUNDS[AUTOCOMP_SOUNDS_LINE_CNT] =
{
"sounds {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_SAMPLE_LINE_CNT 2
const char *AUTOCOMP_SAMPLE[AUTOCOMP_SAMPLE_LINE_CNT] =
{
"sample { name: \"\" LOSSY 64;<br/>",
"}"
};
#define AUTOCOMP_MAP_LINE_CNT 3
const char *AUTOCOMP_MAP[AUTOCOMP_MAP_LINE_CNT] =
{
"map {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_ROTATION_LINE_CNT 3
const char *AUTOCOMP_ROTATION[AUTOCOMP_ROTATION_LINE_CNT] =
{
"rotation {<br/>",
" <br/>",
"}"
};
#define AUTOCOMP_ON_LINE_CNT 1
const char *AUTOCOMP_ON[AUTOCOMP_ON_LINE_CNT] =
{
"on: ;",
};
#define AUTOCOMP_VISIBLE_LINE_CNT 1
const char *AUTOCOMP_VISIBLE[AUTOCOMP_VISIBLE_LINE_CNT] =
{
"visible: ;",
};
#define AUTOCOMP_PERSPECTIVE_ON_LINE_CNT 1
const char *AUTOCOMP_PERSPECTIVE_ON[AUTOCOMP_PERSPECTIVE_ON_LINE_CNT] =
{
"perspective_on: ;",
};
#define AUTOCOMP_PERSPECTIVE_LINE_CNT 1
const char *AUTOCOMP_PERSPECTIVE[AUTOCOMP_PERSPECTIVE_LINE_CNT] =
{
"perspective: \"\";",
};
#define AUTOCOMP_BACKFACE_CULL_LINE_CNT 1
const char *AUTOCOMP_BACKFACE_CULL[AUTOCOMP_BACKFACE_CULL_LINE_CNT] =
{
"backface_cull: ;",
};
#define AUTOCOMP_MIN_LINE_CNT 1
const char *AUTOCOMP_MIN[AUTOCOMP_MIN_LINE_CNT] =
{
"min: ;",
};
#define AUTOCOMP_MAX_LINE_CNT 1
const char *AUTOCOMP_MAX[AUTOCOMP_MAX_LINE_CNT] =
{
"max: ;",
};
#define AUTOCOMP_FIXED_LINE_CNT 1
const char *AUTOCOMP_FIXED[AUTOCOMP_FIXED_LINE_CNT] =
{
"fixed: ;",
};
#define AUTOCOMP_CLIP_TO_LINE_CNT 1
const char *AUTOCOMP_CLIP_TO[AUTOCOMP_CLIP_TO_LINE_CNT] =
{
"clip_to: \"\";",
};
#define COMPSET_CNT 50

View File

@ -29,5 +29,6 @@ typedef struct indent_s indent_data;
#include "search.h"
#include "goto.h"
#include "newfile.h"
#include "auto_comp.h"
#endif

View File

@ -34,6 +34,8 @@ Eina_Bool config_dummy_swallow_get();
void config_dummy_swallow_set(Eina_Bool dummy_swallow);
void config_auto_indent_set(Eina_Bool auto_indent);
Eina_Bool config_auto_indent_get();
void config_auto_complete_set(Eina_Bool auto_complete);
Eina_Bool config_auto_complete_get();
void config_font_size_set(float font_size);
float config_font_size_get();
void config_view_scale_set(double view_scale);

View File

@ -24,3 +24,6 @@ void edit_goto(edit_data *ed, int line);
void edit_syntax_color_full_apply(edit_data *ed, Eina_Bool force);
void edit_syntax_color_partial_apply(edit_data *ed);
Evas_Object * edit_entry_get(edit_data *ed);
void edit_line_increase(edit_data *ed, int cnt);
void edit_line_decrease(edit_data *ed, int cnt);
int edit_cur_indent_depth_get(edit_data *ed);