ajwillia-ms pushed a commit to branch master.

http://git.enlightenment.org/tools/edi.git/commit/?id=e03f234573172f353a7fad9beef7805fc5b39d1a

commit e03f234573172f353a7fad9beef7805fc5b39d1a
Author: Andy Williams <[email protected]>
Date:   Wed Sep 20 19:02:50 2017 +0100

    autosuggest: Show first match for tab completion
    
    Displays a hover that shows the match - and you can click it too.
    
    Closes T5902
    @feature
---
 src/bin/editor/edi_editor.c | 218 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 210 insertions(+), 8 deletions(-)

diff --git a/src/bin/editor/edi_editor.c b/src/bin/editor/edi_editor.c
index b9caa2a..9ca6bfd 100644
--- a/src/bin/editor/edi_editor.c
+++ b/src/bin/editor/edi_editor.c
@@ -17,6 +17,8 @@
 
 #include "edi_private.h"
 
+static Evas_Object *_suggest_hint;
+
 static void _suggest_popup_show(Edi_Editor *editor);
 
 typedef struct
@@ -598,8 +600,147 @@ _edi_editor_snippet_insert(Edi_Editor *editor, 
Evas_Event_Key_Down *ev)
    elm_code_widget_selection_delete(editor->entry);
    elm_code_widget_text_at_cursor_insert(editor->entry, snippet);
 
-   ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
+   if (ev)
+     ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
    free(key);
+   return;
+}
+
+static void
+_suggest_hint_hide(Edi_Editor *editor EINA_UNUSED)
+{
+   if (!_suggest_hint)
+     return;
+
+   evas_object_hide(_suggest_hint);
+}
+
+static Evas_Object *
+_suggest_hint_popup_add(Edi_Editor *editor, const char *content, Evas_Smart_Cb 
fn)
+{
+   Evas_Object *pop, *btn, *text;
+   unsigned int row, col;
+   Evas_Coord cx, cy, cw, ch;
+
+   elm_code_widget_cursor_position_get(editor->entry, &row, &col);
+
+   elm_code_widget_cursor_position_get(editor->entry, &row, &col);
+   elm_code_widget_geometry_for_position_get(editor->entry, row, col,
+                                             &cx, &cy, &cw, &ch);
+
+   pop = elm_box_add(editor->entry);
+   evas_object_size_hint_weight_set(pop, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(pop, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   evas_object_size_hint_weight_set(pop, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(pop, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_move(pop, cx, cy - ch);
+
+   btn = elm_button_add(pop);
+   evas_object_smart_callback_add(btn, "clicked", fn, editor);
+   evas_object_size_hint_weight_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(pop, btn);
+   evas_object_show(btn);
+
+   text = elm_label_add(btn);
+   evas_object_size_hint_weight_set(text, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(text, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_object_text_set(text, content);
+
+   elm_layout_content_set(btn, "elm.swallow.content", text);
+   evas_object_show(text);
+
+   return pop;
+}
+
+static void
+_suggest_hint_click_snippet(void *data, Evas_Object *obj EINA_UNUSED,
+                            void *event_info EINA_UNUSED)
+{
+   Edi_Editor *editor = data;
+
+   _suggest_hint_hide(editor);
+   _edi_editor_snippet_insert(editor, NULL);
+}
+
+static void
+_suggest_hint_show_snippet(Edi_Editor *editor, const char *word)
+{
+   unsigned int row, col;
+   const char *snippet;
+
+   if (!word || strlen(word) == 0)
+     return;
+
+   elm_code_widget_cursor_position_get(editor->entry, &row, &col);
+
+   snippet = edi_language_provider_get(editor)->snippet_get(word);
+   if (!snippet)
+     return;
+
+   _suggest_hint = _suggest_hint_popup_add(editor,
+      eina_slstr_printf("Press tab to insert snippet <hilight>%s</hilight>", 
word),
+      _suggest_hint_click_snippet);
+   evas_object_show(_suggest_hint);
+}
+
+Edi_Language_Suggest_Item *
+_suggest_match_get(Edi_Editor *editor, const char *word)
+{
+   Edi_Language_Suggest_Item *suggest_it;
+   unsigned int row, col, wordlen;
+
+   elm_code_widget_cursor_position_get(editor->entry, &row, &col);
+   Eina_List *l, *list = edi_language_provider_get(editor)->lookup(editor, 
row, col - strlen(word));
+
+   wordlen = strlen(word);
+   EINA_LIST_FOREACH(list, l, suggest_it)
+     {
+        if (strlen(suggest_it->summary) <= wordlen)
+          continue;
+        if (eina_str_has_prefix(suggest_it->summary, word))
+          return suggest_it;
+     }
+
+   return NULL;
+}
+
+static void
+_suggest_hint_click_suggest(void *data, Evas_Object *obj EINA_UNUSED,
+                            void *event_info EINA_UNUSED)
+{
+   Edi_Editor *editor = data;
+   Edi_Language_Suggest_Item *match;
+   unsigned int row, col;
+   char *word;
+
+   _suggest_hint_hide(editor);
+
+   elm_code_widget_cursor_position_get(editor->entry, &row, &col);
+   word = _edi_editor_current_word_get(editor, row, col);
+
+   match = _suggest_match_get(editor, word);
+   if (match)
+     _suggest_list_selection_insert(editor, match->summary);
+
+   free(word);
+}
+
+static void
+_suggest_hint_show_match(Edi_Editor *editor, const char *word)
+{
+   Edi_Language_Suggest_Item *match;
+
+   match = _suggest_match_get(editor, word);
+   if (!match)
+     return;
+
+   _suggest_hint = _suggest_hint_popup_add(editor,
+      eina_slstr_printf("Press tab to insert suggestion 
<hilight>%s</hilight>", match->summary),
+      _suggest_hint_click_suggest);
+
+   evas_object_show(_suggest_hint);
 }
 
 static void
@@ -608,6 +749,7 @@ _smart_cb_key_down(void *data EINA_UNUSED, Evas *e 
EINA_UNUSED,
 {
    Edi_Mainview_Item *item;
    Edi_Editor *editor;
+   Edi_Language_Provider *provider;
    Eina_Bool ctrl, alt, shift;
    Evas_Event_Key_Down *ev = event;
 
@@ -621,6 +763,7 @@ _smart_cb_key_down(void *data EINA_UNUSED, Evas *e 
EINA_UNUSED,
      return;
 
    editor = (Edi_Editor *)evas_object_data_get(item->view, "editor");
+   _suggest_hint_hide(editor);
 
    if ((!alt) && (ctrl) && (!shift))
      {
@@ -657,17 +800,45 @@ _smart_cb_key_down(void *data EINA_UNUSED, Evas *e 
EINA_UNUSED,
           }
      }
 
-   if ((!alt) && (!ctrl))
+   if (alt || ctrl)
+     return;
+
+   provider = edi_language_provider_get(editor);
+   if (!provider)
+     return;
+
+   if (evas_object_visible_get(editor->suggest_bg))
+     {
+        _suggest_popup_key_down_cb(editor, ev->key, ev->string);
+        return;
+     }
+
+   if (!strcmp(ev->key, "Tab"))
      {
-        if (!strcmp(ev->key, "Tab") && edi_language_provider_has(editor))
+        char *word;
+        const char *snippet;
+        unsigned int row, col;
+        Edi_Language_Suggest_Item *suggest;
+
+        elm_code_widget_cursor_position_get(editor->entry, &row, &col);
+        word = _edi_editor_current_word_get(editor, row, col);
+
+        snippet = provider->snippet_get(word);
+        if (snippet)
           _edi_editor_snippet_insert(editor, ev);
-        else if (edi_language_provider_has(editor))
-          _suggest_popup_key_down_cb(editor, ev->key, ev->string);
+        else if (strlen(word) >= 3)
+          {
+             suggest = _suggest_match_get(editor, word);
+             if (suggest)
+               _suggest_list_selection_insert(editor, suggest->summary);
+          }
+
+        free(word);
      }
 }
 
 static void
-_edit_cursor_moved(void *data EINA_UNUSED, Evas_Object *obj, void *event_info 
EINA_UNUSED)
+_edit_cursor_moved(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
    Elm_Code_Widget *widget;
    char buf[30];
@@ -682,9 +853,40 @@ _edit_cursor_moved(void *data EINA_UNUSED, Evas_Object 
*obj, void *event_info EI
 }
 
 static void
-_edit_file_changed(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void 
*event_info EINA_UNUSED)
+_edit_file_changed(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
 {
+   Elm_Code_Widget *widget;
+   Edi_Editor *editor;
+   Edi_Language_Provider *provider;
+   char *word;
+   const char *snippet;
+   unsigned int row, col;
+
    ecore_event_add(EDI_EVENT_FILE_CHANGED, NULL, NULL, NULL);
+
+   widget = (Elm_Code_Widget *)obj;
+   editor = (Edi_Editor *)data;
+
+   if (evas_object_visible_get(editor->suggest_bg))
+     return;
+
+   provider = edi_language_provider_get(editor);
+   if (!provider)
+     return;
+
+   elm_code_widget_cursor_position_get(widget, &row, &col);
+   word = _edi_editor_current_word_get(editor, row, col);
+
+   if (word && strlen(word) > 1)
+     {
+        snippet = provider->snippet_get(word);
+        if (snippet)
+          _suggest_hint_show_snippet(editor, word);
+        else if (strlen(word) >= 3)
+          _suggest_hint_show_match(editor, word);
+     }
+
+   free(word);
 }
 
 static void
@@ -738,7 +940,7 @@ _edi_editor_statusbar_add(Evas_Object *panel, Edi_Editor 
*editor, Edi_Mainview_I
 
    _edit_cursor_moved(position, editor->entry, NULL);
    evas_object_smart_callback_add(editor->entry, "cursor,changed", 
_edit_cursor_moved, position);
-   evas_object_smart_callback_add(editor->entry, "changed,user", 
_edit_file_changed, position);
+   evas_object_smart_callback_add(editor->entry, "changed,user", 
_edit_file_changed, editor);
 }
 
 #if HAVE_LIBCLANG

-- 


Reply via email to