From 068949a25a6d3159f4816740c230a54bf327e087 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 11 Jan 2017 12:48:28 +0000 Subject: [PATCH] suggest: Simplify sugggest API Moving to a language provider so fewer entry points if possible --- src/bin/editor/edi_editor.c | 43 ++---- src/bin/editor/edi_editor_suggest_provider.c | 14 +- src/bin/editor/edi_editor_suggest_provider.h | 18 ++- .../editor/edi_editor_suggest_provider_c.c | 130 ++++++------------ .../edi_test_editor_suggest_provider_c.c | 28 ++-- 5 files changed, 90 insertions(+), 143 deletions(-) diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c index 5422c2e..351a1be 100644 --- a/src/bin/editor/edi_editor.c +++ b/src/bin/editor/edi_editor.c @@ -107,7 +107,7 @@ _suggest_list_content_get(void *data, Evas_Object *obj, const char *part) Edi_Mainview_Item *item; Edi_Editor_Suggest_Item *suggest_it = data; char *format, *display; - const char *font, *summary; + const char *font; int font_size, displen; if (strcmp(part, "elm.swallow.content")) @@ -121,11 +121,10 @@ _suggest_list_content_get(void *data, Evas_Object *obj, const char *part) editor = (Edi_Editor *)evas_object_data_get(item->view, "editor"); elm_code_widget_font_get(editor->entry, &font, &font_size); - summary = edi_editor_suggest_provider_get(editor)->summary_get(editor, suggest_it); format = " %s"; - displen = strlen(summary) + strlen(format) + strlen(font); + displen = strlen(suggest_it->summary) + strlen(format) + strlen(font); display = malloc(sizeof(char) * displen); - snprintf(display, displen, format, font, font_size, summary); + snprintf(display, displen, format, font, font_size, suggest_it->summary); Evas_Object *label = elm_label_add(obj); elm_label_ellipsis_set(label, EINA_TRUE); @@ -140,30 +139,18 @@ _suggest_list_content_get(void *data, Evas_Object *obj, const char *part) static void _suggest_list_cb_selected(void *data, Evas_Object *obj EINA_UNUSED, void *event_info) { - Edi_Editor *editor; - Edi_Mainview_Item *item; Edi_Editor_Suggest_Item *suggest_it; Evas_Object *label = data; - char *display; suggest_it = elm_object_item_data_get(event_info); - item = edi_mainview_item_current_get(); - if (!item) - return; - - editor = (Edi_Editor *)evas_object_data_get(item->view, "editor"); - display = edi_editor_suggest_provider_get(editor)->detail_get(editor, suggest_it); - - elm_object_text_set(label, display); - free(display); + elm_object_text_set(label, suggest_it->detail); } static void _suggest_list_update(Edi_Editor *editor, char *word) { Edi_Editor_Suggest_Item *suggest_it; - Edi_Editor_Suggest_Provider *provider; Eina_List *list, *l; Elm_Genlist_Item_Class *ic; Elm_Object_Item *item; @@ -176,13 +163,9 @@ _suggest_list_update(Edi_Editor *editor, char *word) ic->item_style = "full"; ic->func.content_get = _suggest_list_content_get; - provider = edi_editor_suggest_provider_get(editor); EINA_LIST_FOREACH(list, l, suggest_it) { - const char *term; - term = provider->summary_get(editor, suggest_it); - - if (eina_str_has_prefix(term, word)) + if (eina_str_has_prefix(suggest_it->summary, word)) { elm_genlist_item_append(editor->suggest_genlist, ic, @@ -211,10 +194,8 @@ _suggest_list_set(Edi_Editor *editor) { char *curword; unsigned int row, col; - Edi_Editor_Suggest_Provider *provider; Eina_List *list = NULL; - provider = edi_editor_suggest_provider_get(editor); list = (Eina_List *)evas_object_data_get(editor->suggest_genlist, "suggest_list"); if (list) @@ -222,7 +203,7 @@ _suggest_list_set(Edi_Editor *editor) Edi_Editor_Suggest_Item *suggest_it; EINA_LIST_FREE(list, suggest_it) - provider->item_free(suggest_it); + edi_editor_suggest_item_free(suggest_it); list = NULL; evas_object_data_del(editor->suggest_genlist, "suggest_list"); @@ -267,10 +248,8 @@ _suggest_bg_cb_hide(void *data, Evas *e EINA_UNUSED, { Eina_List *list = NULL; Edi_Editor *editor; - Edi_Editor_Suggest_Provider *provider; editor = (Edi_Editor *)data; - provider = edi_editor_suggest_provider_get(editor); list = (Eina_List *)evas_object_data_get(editor->suggest_genlist, "suggest_list"); if (list) @@ -278,7 +257,7 @@ _suggest_bg_cb_hide(void *data, Evas *e EINA_UNUSED, Edi_Editor_Suggest_Item *suggest_it; EINA_LIST_FREE(list, suggest_it) - provider->item_free(suggest_it); + edi_editor_suggest_item_free(suggest_it); list = NULL; evas_object_data_del(editor->suggest_genlist, "suggest_list"); @@ -300,13 +279,10 @@ _suggest_list_cb_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, if (!strcmp(ev->key, "Return")) { - const char *term; - it = elm_genlist_selected_item_get(genlist); suggest_it = elm_object_item_data_get(it); - term = edi_editor_suggest_provider_get(editor)->summary_get(editor, suggest_it); - _suggest_list_selection_insert(editor, term); + _suggest_list_selection_insert(editor, suggest_it->summary); evas_object_hide(editor->suggest_bg); } else if (!strcmp(ev->key, "Up")) @@ -336,8 +312,7 @@ _suggest_list_cb_clicked_double(void *data, Evas_Object *obj EINA_UNUSED, Edi_Editor *editor = (Edi_Editor *)data; suggest_it = elm_object_item_data_get(it); - _suggest_list_selection_insert(editor, - edi_editor_suggest_provider_get(editor)->summary_get(editor, suggest_it)); + _suggest_list_selection_insert(editor, suggest_it->summary); evas_object_hide(editor->suggest_bg); } diff --git a/src/bin/editor/edi_editor_suggest_provider.c b/src/bin/editor/edi_editor_suggest_provider.c index 4eb6bbe..d7982a4 100644 --- a/src/bin/editor/edi_editor_suggest_provider.c +++ b/src/bin/editor/edi_editor_suggest_provider.c @@ -14,11 +14,10 @@ static Edi_Editor_Suggest_Provider _edi_editor_suggest_provider_registry[] = { { "c", _edi_editor_sugggest_c_add, _edi_editor_sugget_c_del, - _edi_editor_suggest_c_lookup, _edi_editor_suggest_c_summary_get, - _edi_editor_suggest_c_detail_get, _edi_editor_suggest_c_item_free + _edi_editor_suggest_c_lookup }, - {NULL, NULL, NULL, NULL, NULL, NULL, NULL} + {NULL, NULL, NULL, NULL} }; Edi_Editor_Suggest_Provider *edi_editor_suggest_provider_get(Edi_Editor *editor) @@ -55,3 +54,12 @@ edi_editor_suggest_provider_has(Edi_Editor *editor) return !!edi_editor_suggest_provider_get(editor); } +void +edi_editor_suggest_item_free(Edi_Editor_Suggest_Item *item) +{ + free((char *)item->summary); + free((char *)item->detail); + + free(item); +} + diff --git a/src/bin/editor/edi_editor_suggest_provider.h b/src/bin/editor/edi_editor_suggest_provider.h index 5e80c97..9dbd4d6 100644 --- a/src/bin/editor/edi_editor_suggest_provider.h +++ b/src/bin/editor/edi_editor_suggest_provider.h @@ -17,7 +17,11 @@ extern "C" { * @typedef Edi_Editor_Suggest_Item * A handle for passig a suggest item to the ui and back */ -typedef void *Edi_Editor_Suggest_Item; +typedef struct _Edi_Editor_Suggest_Item +{ + const char *summary; + const char *detail; +} Edi_Editor_Suggest_Item; /** * @struct Edi_Editor_Suggest_Provider @@ -32,9 +36,6 @@ typedef struct _Edi_Editor_Suggest_Provider void (*add)(Edi_Editor *editor); void (*del)(Edi_Editor *editor); Eina_List *(*lookup)(Edi_Editor *editor, unsigned int row, unsigned int col); - const char *(*summary_get)(Edi_Editor *editor, Edi_Editor_Suggest_Item *item); - char *(*detail_get)(Edi_Editor *editor, Edi_Editor_Suggest_Item *item); - void (*item_free)(Edi_Editor_Suggest_Item *item); } Edi_Editor_Suggest_Provider; /** @@ -62,6 +63,15 @@ Edi_Editor_Suggest_Provider *edi_editor_suggest_provider_get(Edi_Editor *editor) */ Eina_Bool edi_editor_suggest_provider_has(Edi_Editor *editor); +/** + * Free a suggest item. + * + * @param item the suggest item to free + * + * @ingroup Lookup + */ +void edi_editor_suggest_item_free(Edi_Editor_Suggest_Item *item); + /** * @} */ diff --git a/src/bin/editor/edi_editor_suggest_provider_c.c b/src/bin/editor/edi_editor_suggest_provider_c.c index 360a13b..2cb0a66 100644 --- a/src/bin/editor/edi_editor_suggest_provider_c.c +++ b/src/bin/editor/edi_editor_suggest_provider_c.c @@ -16,15 +16,6 @@ #include "edi_private.h" #if HAVE_LIBCLANG -typedef struct -{ - enum CXCursorKind kind; - char *ret; - char *name; - char *param; - Eina_Bool is_param_cand; -} _Clang_Suggest_Item; - static void _clang_autosuggest_setup(Edi_Editor *editor) { @@ -57,28 +48,6 @@ _clang_autosuggest_dispose(Edi_Editor *editor) } #endif -static const char * -_suggest_item_return_get(Edi_Editor_Suggest_Item *item) -{ -#if HAVE_LIBCLANG - if (((_Clang_Suggest_Item *)item)->ret) - return ((_Clang_Suggest_Item *)item)->ret; -#endif - - return ""; -} - -static const char * -_suggest_item_parameter_get(Edi_Editor_Suggest_Item *item) -{ -#if HAVE_LIBCLANG - if (((_Clang_Suggest_Item *)item)->param) - return ((_Clang_Suggest_Item *)item)->param; -#endif - - return ""; -} - void _edi_editor_sugggest_c_add(Edi_Editor *editor) { @@ -95,6 +64,32 @@ _edi_editor_sugget_c_del(Edi_Editor *editor) #endif } +#if HAVE_LIBCLANG +char * +_edi_editor_suggest_c_detail_get(Edi_Editor *editor, const char *term_str, + const char *ret_str, const char *param_str) +{ + char *format, *display; + const char *font; + int font_size, displen; + unsigned int row, col; + Evas_Coord w; + + elm_code_widget_font_get(editor->entry, &font, &font_size); + elm_code_widget_cursor_position_get(editor->entry, &row, &col); + elm_code_widget_geometry_for_position_get(editor->entry, row, col, + NULL, NULL, &w, NULL); + + format = "%s
%s
%s"; + displen = strlen(ret_str) + strlen(param_str) + strlen(term_str) + + strlen(format) + strlen(font); + display = malloc(sizeof(char) * displen); + snprintf(display, displen, format, w, font, font_size, ret_str, term_str, param_str); + + return display; +} +#endif + Eina_List * _edi_editor_suggest_c_lookup(Edi_Editor *editor, unsigned int row, unsigned int col) { @@ -128,13 +123,12 @@ _edi_editor_suggest_c_lookup(Edi_Editor *editor, unsigned int row, unsigned int for (unsigned int i = 0; i < res->NumResults; i++) { const CXCompletionString str = res->Results[i].CompletionString; - _Clang_Suggest_Item *suggest_it; + const char *name = NULL, *ret = NULL; + char *param = NULL; + Edi_Editor_Suggest_Item *suggest_it; Eina_Strbuf *buf = NULL; - suggest_it = calloc(1, sizeof(_Clang_Suggest_Item)); - suggest_it->kind = res->Results[i].CursorKind; - if (suggest_it->kind == CXCursor_OverloadCandidate) - suggest_it->is_param_cand = EINA_TRUE; + suggest_it = calloc(1, sizeof(Edi_Editor_Suggest_Item)); for (unsigned int j = 0; j < clang_getNumCompletionChunks(str); j++) { @@ -146,13 +140,14 @@ _edi_editor_suggest_c_lookup(Edi_Editor *editor, unsigned int row, unsigned int switch (ch_kind) { case CXCompletionChunk_ResultType: - suggest_it->ret = strdup(clang_getCString(str_out)); + ret = clang_getCString(str_out); break; case CXCompletionChunk_TypedText: case CXCompletionChunk_Text: - suggest_it->name = strdup(clang_getCString(str_out)); + name = clang_getCString(str_out); break; case CXCompletionChunk_LeftParen: + // todo buf == eina_strbuf_new(); case CXCompletionChunk_Placeholder: case CXCompletionChunk_Comma: case CXCompletionChunk_CurrentParameter: @@ -162,7 +157,7 @@ _edi_editor_suggest_c_lookup(Edi_Editor *editor, unsigned int row, unsigned int break; case CXCompletionChunk_RightParen: eina_strbuf_append(buf, clang_getCString(str_out)); - suggest_it->param = eina_strbuf_string_steal(buf); + param = eina_strbuf_string_steal(buf); eina_strbuf_free(buf); buf = NULL; break; @@ -170,6 +165,13 @@ _edi_editor_suggest_c_lookup(Edi_Editor *editor, unsigned int row, unsigned int break; } } + + if (name) + suggest_it->summary = strdup(name); + suggest_it->detail = _edi_editor_suggest_c_detail_get(editor, name, ret?ret:"", param?param:""); + if (param) + free(param); + list = eina_list_append(list, suggest_it); } clang_disposeCodeCompleteResults(res); @@ -178,53 +180,3 @@ _edi_editor_suggest_c_lookup(Edi_Editor *editor, unsigned int row, unsigned int return list; } -const char * -_edi_editor_suggest_c_summary_get(Edi_Editor *editor EINA_UNUSED, Edi_Editor_Suggest_Item *item) -{ -#if HAVE_LIBCLANG - return ((_Clang_Suggest_Item *)item)->name; -#else - return ""; -#endif -} - -static void -_edi_editor_suggest_c_item_free(Edi_Editor_Suggest_Item *item) -{ -#if HAVE_LIBCLANG - _Clang_Suggest_Item *clang_item = (_Clang_Suggest_Item *)item; - - if (clang_item->ret) free(clang_item->ret); - if (clang_item->name) free(clang_item->name); - if (clang_item->param) free(clang_item->param); - free(clang_item); -#endif -} - -char * -_edi_editor_suggest_c_detail_get(Edi_Editor *editor, Edi_Editor_Suggest_Item *item) -{ - char *format, *display; - const char *font, *term_str, *ret_str, *param_str; - int font_size, displen; - unsigned int row, col; - Evas_Coord w; - - elm_code_widget_font_get(editor->entry, &font, &font_size); - elm_code_widget_cursor_position_get(editor->entry, &row, &col); - elm_code_widget_geometry_for_position_get(editor->entry, row, col, - NULL, NULL, &w, NULL); - - term_str = _edi_editor_suggest_c_summary_get(editor, item); - ret_str = _suggest_item_return_get(item); - param_str = _suggest_item_parameter_get(item); - - format = "%s
%s
%s"; - displen = strlen(ret_str) + strlen(param_str) + strlen(term_str) - + strlen(format) + strlen(font); - display = malloc(sizeof(char) * displen); - snprintf(display, displen, format, w, font, font_size, ret_str, term_str, param_str); - - return display; -} - diff --git a/src/tests/edi_test_editor_suggest_provider_c.c b/src/tests/edi_test_editor_suggest_provider_c.c index a7f45c4..37b4e01 100644 --- a/src/tests/edi_test_editor_suggest_provider_c.c +++ b/src/tests/edi_test_editor_suggest_provider_c.c @@ -15,29 +15,28 @@ _setup(Edi_Editor *editor, Evas_Object *win) Elm_Code *code; Elm_Code_Widget *widget; + editor->mimetype = "text/x-csrc"; + code = elm_code_create(); elm_code_file_open(code, PACKAGE_TESTS_DIR "test.c"); widget = elm_code_widget_add(win, code); editor->entry = widget; elm_code_widget_cursor_position_set(widget, 3, 12); + elm_code_widget_font_set(widget, "Mono", 14); return code; } static Eina_List * -_filtered_list_get(Edi_Editor *editor, Edi_Editor_Suggest_Provider *provider, - Eina_List *list, const char *word) +_filtered_list_get(Eina_List *list, const char *word) { Edi_Editor_Suggest_Item *suggest_it; Eina_List *l, *ret = NULL; EINA_LIST_FOREACH(list, l, suggest_it) { - const char *term; - term = provider->summary_get(editor, suggest_it); - - if (eina_str_has_prefix(term, word)) + if (eina_str_has_prefix(suggest_it->summary, word)) ret = eina_list_append(ret, suggest_it); } @@ -50,17 +49,20 @@ START_TEST (edi_test_editor_suggest_provider_c_lookup) Evas_Object *win; Edi_Editor editor; Edi_Editor_Suggest_Provider *provider; + Edi_Editor_Suggest_Item *item; Eina_List *list; elm_init(1, NULL); win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); - editor.mimetype = "text/x-csrc"; code = _setup(&editor, win); provider = edi_editor_suggest_provider_get(&editor); provider->add(&editor); list = provider->lookup(&editor, 3, 12); - ck_assert_int_eq(eina_list_count(_filtered_list_get(&editor, provider, list, "_xyzabc_")), 1); + ck_assert_int_eq(eina_list_count(_filtered_list_get(list, "_xyzabc_")), 1); + + EINA_LIST_FREE(list, item) + edi_editor_suggest_item_free(item); provider->del(&editor); elm_code_free(code); @@ -76,19 +78,19 @@ START_TEST (edi_test_editor_suggest_provider_c_summary) Edi_Editor_Suggest_Provider *provider; Edi_Editor_Suggest_Item *item; Eina_List *list; - const char *key; elm_init(1, NULL); win = elm_win_add(NULL, "entry", ELM_WIN_BASIC); - editor.mimetype = "text/x-csrc"; code = _setup(&editor, win); provider = edi_editor_suggest_provider_get(&editor); provider->add(&editor); list = provider->lookup(&editor, 3, 12); - item = eina_list_nth(_filtered_list_get(&editor, provider, list, "_xyzabc_"), 0); - key = provider->summary_get(&editor, item); - ck_assert_str_eq(key, "_xyzabc_test"); + item = eina_list_nth(_filtered_list_get(list, "_xyzabc_"), 0); + ck_assert_str_eq(item->summary, "_xyzabc_test"); + + EINA_LIST_FREE(list, item) + edi_editor_suggest_item_free(item); provider->del(&editor); elm_code_free(code);