netstar pushed a commit to branch master.

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

commit 59a0ec1bae34d85c244b323a257cce7879b3ecec
Author: Al Poole <nets...@gmail.com>
Date:   Sat Sep 16 01:19:54 2017 +0100

    scm: add support for file listing file status.
    
    Add support for file listing status. Also some refactoring.
    More to do, more testing first.
---
 src/bin/edi_filepanel.c            | 140 +++++++++++++++++++++++++++++++++++--
 src/bin/edi_filepanel.h            |  16 +++++
 src/bin/edi_main.c                 |   3 +
 src/bin/screens/edi_file_screens.c |   3 +
 src/bin/screens/edi_scm_screens.c  | 114 ++++++++++++++++--------------
 src/lib/edi_exe.c                  |   2 +-
 src/lib/edi_scm.c                  |  54 +++++++++-----
 src/lib/edi_scm.h                  |   8 ++-
 8 files changed, 262 insertions(+), 78 deletions(-)

diff --git a/src/bin/edi_filepanel.c b/src/bin/edi_filepanel.c
index c558d39..a696fd2 100644
--- a/src/bin/edi_filepanel.c
+++ b/src/bin/edi_filepanel.c
@@ -210,6 +210,7 @@ _item_menu_scm_add_cb(void *data, Evas_Object *obj 
EINA_UNUSED,
    sd = data;
 
    edi_scm_add(sd->path);
+   edi_filepanel_update_path(sd->path);
 }
 
 static void
@@ -227,6 +228,8 @@ _item_menu_scm_del_do_cb(void *data)
      edi_scm_del(sd->path);
    else
      ecore_file_unlink(sd->path);
+
+   edi_filepanel_update_path(sd->path);
 }
 
 static void
@@ -422,12 +425,85 @@ _item_clicked_cb(void *data EINA_UNUSED, Evas *e 
EINA_UNUSED, Evas_Object *obj,
    evas_object_show(menu);
 }
 
+static const char *
+_file_icon_status(const char *path)
+{
+   Edi_Scm_Status_Code status;
+
+   if (!edi_scm_enabled() || ecore_file_is_dir(path))
+     return NULL;
+
+   status = edi_scm_file_status(path);
+   switch (status)
+     {
+        case EDI_SCM_STATUS_NONE:
+        case EDI_SCM_STATUS_RENAMED:
+        case EDI_SCM_STATUS_DELETED:
+        case EDI_SCM_STATUS_RENAMED_STAGED:
+        case EDI_SCM_STATUS_DELETED_STAGED:
+        case EDI_SCM_STATUS_UNKNOWN:
+        case EDI_SCM_STATUS_ADDED:
+           return NULL;
+        case EDI_SCM_STATUS_ADDED_STAGED:
+           return "document-new";
+        case EDI_SCM_STATUS_MODIFIED:
+        case EDI_SCM_STATUS_MODIFIED_STAGED:
+          return "document-save-as";
+        case EDI_SCM_STATUS_UNTRACKED:
+          return "dialog-question";
+     }
+
+   return NULL;
+}
+
+static char *
+_file_path_status(const char *path)
+{
+   char *orig;
+   Edi_Scm_Status_Code status;
+   static char text[4096];
+
+   orig = basename((char *)path);
+
+   if (!edi_scm_enabled() || ecore_file_is_dir(path))
+     return orig;
+
+   text[0] = '\0';
+   strcat(text, orig);
+
+   status = edi_scm_file_status(path);
+   switch (status)
+     {
+        case EDI_SCM_STATUS_NONE:
+        case EDI_SCM_STATUS_DELETED:
+        case EDI_SCM_STATUS_DELETED_STAGED:
+        case EDI_SCM_STATUS_UNKNOWN:
+           return text;
+        case EDI_SCM_STATUS_ADDED:
+           return strcat(text, _(" (Added & Unstaged)"));
+        case EDI_SCM_STATUS_ADDED_STAGED:
+           return strcat(text, _(" (Added)"));
+        case EDI_SCM_STATUS_RENAMED:
+           return strcat(text, _(" (Renamed & Unstaged)"));
+        case EDI_SCM_STATUS_RENAMED_STAGED:
+           return strcat(text, _(" (Renamed)"));
+        case EDI_SCM_STATUS_MODIFIED:
+           return strcat(text, _(" (Modified & Unstaged)"));
+        case EDI_SCM_STATUS_MODIFIED_STAGED:
+           return strcat(text, _(" (Modified)"));
+        case EDI_SCM_STATUS_UNTRACKED:
+           return strcat(text, _(" (Untracked)"));
+     }
+
+   return text;
+}
+
 static char *
 _text_get(void *data, Evas_Object *obj EINA_UNUSED, const char *source 
EINA_UNUSED)
 {
    Edi_Dir_Data *sd = data;
 
-   return strdup(basename((char *)sd->path));
+   return strdup(_file_path_status(sd->path));
 }
 
 static Eina_Hash *mime_entries = NULL;
@@ -454,6 +530,7 @@ _content_get(void *data, Evas_Object *obj, const char 
*source)
    Edi_Content_Provider *provider;
    Edi_Dir_Data *sd = data;
    Evas_Object *ic;
+   const char *icon_name;
 
    if (strcmp(source, "elm.swallow.icon"))
      return NULL;
@@ -461,10 +538,19 @@ _content_get(void *data, Evas_Object *obj, const char 
*source)
    provider = _get_provider_from_hashset(sd->path);
 
    ic = elm_icon_add(obj);
-   if (provider)
-     elm_icon_standard_set(ic, provider->icon);
+
+   icon_name = _file_icon_status(sd->path);
+   if (icon_name)
+     {
+        elm_icon_standard_set(ic, icon_name);
+     }
    else
-     elm_icon_standard_set(ic, "empty");
+     {
+        if (provider)
+          elm_icon_standard_set(ic, provider->icon);
+        else
+          elm_icon_standard_set(ic, "empty");
+     }
 
    evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
    evas_object_show(ic);
@@ -705,6 +791,48 @@ _file_listing_fill(Edi_Dir_Data *dir, Elm_Object_Item 
*parent_it)
 }
 
 static void
+_edi_filepanel_update_dir(const char *directory)
+{
+   Eina_List *files;
+   char *path;
+   char *file;
+
+   files = ecore_file_ls(directory);
+
+   EINA_LIST_FREE(files, file)
+     {
+        if (file[0] != '.')
+          {
+             path = edi_path_append(directory, file);
+             if (ecore_file_is_dir(path))
+               _edi_filepanel_update_dir(path);
+             else
+               edi_filepanel_update_path(path);
+             free(path);
+          }
+        free(file);
+     }
+
+   if (files)
+     eina_list_free(files);
+}
+
+void
+edi_filepanel_update_all(void)
+{
+  _edi_filepanel_update_dir(edi_project_get());
+}
+
+void edi_filepanel_update_path(const char *path)
+{
+   Elm_Object_Item *item = _file_listing_item_find(path);
+   if (!item)
+     return;
+
+   elm_genlist_item_update(item);
+}
+
+static void
 _file_listing_updated(void *data EINA_UNUSED, int type EINA_UNUSED,
                       void *event EINA_UNUSED)
 {
@@ -727,7 +855,9 @@ _file_listing_updated(void *data EINA_UNUSED, int type 
EINA_UNUSED,
    else if (type == EIO_MONITOR_DIRECTORY_DELETED)
      _file_listing_item_delete(ev->filename);
    else
-     DBG("Ignoring file update event for %s", ev->filename);
+    DBG("Ignoring file update event for %s", ev->filename);
+
+   edi_filepanel_update_path(ev->filename);
 }
 
 /* Panel filtering */
diff --git a/src/bin/edi_filepanel.h b/src/bin/edi_filepanel.h
index 83e08f7..046aeae 100644
--- a/src/bin/edi_filepanel.h
+++ b/src/bin/edi_filepanel.h
@@ -59,6 +59,22 @@ const char *edi_filepanel_selected_path_get(Evas_Object 
*obj);
 void edi_filepanel_select_path(const char *path);
 
 /**
+ * Notify a file change has occurred to trigger an update to item content.
+ *
+ * @param path The path of the file to be updated in the file panel.
+ *
+ * @ingroup UI
+ */
+void edi_filepanel_update_path(const char *path);
+
+/**
+ * Notify filepanel to update all file items.
+ *
+ * @ingroup UI
+ */
+void edi_filepanel_update_all(void);
+
+/**
  * Initialise a file panel search.
  *
  * @ingroup UI
diff --git a/src/bin/edi_main.c b/src/bin/edi_main.c
index 3813b5b..5679713 100644
--- a/src/bin/edi_main.c
+++ b/src/bin/edi_main.c
@@ -1023,6 +1023,7 @@ static void
 _edi_scm_stash_do_cb(void *data EINA_UNUSED)
 {
    edi_scm_stash();
+   edi_filepanel_update_all();
 }
 
 static void
@@ -1049,6 +1050,7 @@ _edi_menu_scm_pull_cb(void *data EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED,
    edi_consolepanel_clear();
    edi_consolepanel_show();
    edi_scm_pull();
+   edi_filepanel_update_all();
 }
 
 static void
@@ -1064,6 +1066,7 @@ _edi_menu_scm_push_cb(void *data EINA_UNUSED, Evas_Object 
*obj EINA_UNUSED,
    edi_consolepanel_clear();
    edi_consolepanel_show();
    edi_scm_push();
+   edi_filepanel_update_all();
 }
 
 static void
diff --git a/src/bin/screens/edi_file_screens.c 
b/src/bin/screens/edi_file_screens.c
index d9c9a55..05e55ff 100644
--- a/src/bin/screens/edi_file_screens.c
+++ b/src/bin/screens/edi_file_screens.c
@@ -1,6 +1,7 @@
 #include "Edi.h"
 #include "mainview/edi_mainview.h"
 #include "edi_file_screens.h"
+#include "edi_filepanel.h"
 #include "edi_private.h"
 
 static Evas_Object *_parent_obj, *_popup, *_popup_dir, 
*_edi_file_screens_message_popup;
@@ -156,6 +157,8 @@ _edi_file_screens_rename_cb(void *data,
           ecore_file_mv(existing_path, path);
         else
           edi_scm_move(existing_path, path);
+
+        edi_filepanel_update_path(path);
      }
 
    evas_object_del(_popup);
diff --git a/src/bin/screens/edi_scm_screens.c 
b/src/bin/screens/edi_scm_screens.c
index f15c991..8abb686 100644
--- a/src/bin/screens/edi_scm_screens.c
+++ b/src/bin/screens/edi_scm_screens.c
@@ -5,6 +5,8 @@
 #include "Edi.h"
 #include "mainview/edi_mainview.h"
 #include "edi_config.h"
+#include "edi_filepanel.h"
+#include "edi_file.h"
 #include "edi_consolepanel.h"
 #include "edi_scm_screens.h"
 #include "edi_private.h"
@@ -78,9 +80,9 @@ _edi_scm_screens_commit_cb(void *data,
 }
 
 static void
-_entry_lines_append(Elm_Code *code, char *diff)
+_entry_lines_append(Elm_Code *code, char *diff_text)
 {
-   char *pos = diff;
+   char *pos = diff_text;
    char *start, *end = NULL;
 
    if (!*pos) return;
@@ -103,6 +105,47 @@ _entry_lines_append(Elm_Code *code, char *diff)
       elm_code_file_line_append(code->file, start, end - start, NULL);
 }
 
+static void
+_set_icon_text(Evas_Object *icon, Eina_Strbuf *text, Edi_Scm_Status *status)
+{
+   eina_strbuf_append_printf(text, "%s ", status->path);
+
+   switch (status->change)
+     {
+        case EDI_SCM_STATUS_ADDED:
+        case EDI_SCM_STATUS_ADDED_STAGED:
+           elm_icon_standard_set(icon, "document-new");
+           eina_strbuf_append_printf(text, "(%s", _("Added"));
+           break;
+        case EDI_SCM_STATUS_MODIFIED:
+        case EDI_SCM_STATUS_MODIFIED_STAGED:
+           elm_icon_standard_set(icon, "document-save-as");
+           eina_strbuf_append_printf(text, "(%s", _("Modified"));
+           break;
+        case EDI_SCM_STATUS_DELETED:
+        case EDI_SCM_STATUS_DELETED_STAGED:
+           elm_icon_standard_set(icon, "edit-delete");
+           eina_strbuf_append_printf(text, "(%s", _("Deleted"));
+           break;
+        case EDI_SCM_STATUS_RENAMED:
+        case EDI_SCM_STATUS_RENAMED_STAGED:
+          elm_icon_standard_set(icon, "document-save-as");
+           eina_strbuf_append_printf(text, "(%s", _("Renamed"));
+           break;
+        case EDI_SCM_STATUS_UNTRACKED:
+           elm_icon_standard_set(icon, "dialog-question");
+           eina_strbuf_append_printf(text, "(%s", _("Untracked"));
+           break;
+        default:
+           elm_icon_standard_set(icon, "text-x-generic");
+     }
+
+   if (!status->staged && status->change != EDI_SCM_STATUS_UNTRACKED)
+     eina_strbuf_append(text,  _(" & Unstaged)"));
+   else
+     eina_strbuf_append(text, ")");
+}
+
 void
 edi_scm_screens_commit(Evas_Object *parent)
 {
@@ -110,11 +153,10 @@ edi_scm_screens_commit(Evas_Object *parent)
    Evas_Object *list, *icon;
    Elm_Code_Widget *entry;
    Elm_Code *code;
-   Eina_Strbuf *text, *user;
-   Eina_List *l;
+   Eina_Strbuf *text;
    Edi_Scm_Engine *engine;
    Edi_Scm_Status *status;
-   char *diff;
+   char *diff_text;
    Eina_Bool staged_changes;
 
    engine= edi_scm_engine_get();
@@ -155,11 +197,11 @@ edi_scm_screens_commit(Evas_Object *parent)
    evas_object_show(label);
    elm_box_pack_end(hbox, label);
 
-   user = eina_strbuf_new();
-   eina_strbuf_append_printf(user, "%s:<br><b>%s</b><br>&lt;%s&gt;", 
_("Author"),
+   text = eina_strbuf_new();
+   eina_strbuf_append_printf(text, "%s:<br><b>%s</b><br>&lt;%s&gt;", 
_("Author"),
                              engine->remote_name_get(), 
engine->remote_email_get());
-   elm_object_text_set(label, eina_strbuf_string_get(user));
-   eina_strbuf_free(user);
+   elm_object_text_set(label, eina_strbuf_string_get(text));
+   eina_strbuf_reset(text);
 
    avatar = elm_image_add(hbox);
    edi_scm_screens_avatar_load(avatar, engine->remote_email_get());
@@ -172,7 +214,7 @@ edi_scm_screens_commit(Evas_Object *parent)
    cbox = elm_box_add(box);
    evas_object_size_hint_weight_set(cbox, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(cbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
-   evas_object_size_hint_min_set(cbox, 250 * elm_config_scale_get(), 100 * 
elm_config_scale_get());
+   evas_object_size_hint_min_set(cbox, 350 * elm_config_scale_get(), 100 * 
elm_config_scale_get());
    evas_object_show(cbox);
 
    list = elm_list_add(box);
@@ -186,48 +228,14 @@ edi_scm_screens_commit(Evas_Object *parent)
 
    if (edi_scm_status_get())
      {
-        text = eina_strbuf_new();
-        EINA_LIST_FOREACH(engine->statuses, l, status)
+        EINA_LIST_FREE(engine->statuses, status)
           {
              icon = elm_icon_add(box);
-             if (status->staged)
-               staged_changes = EINA_TRUE;
-
-             eina_strbuf_append_printf(text, "%s ", status->path);
-
-             switch (status->change)
-               {
-                case EDI_SCM_STATUS_ADDED:
-                  elm_icon_standard_set(icon, "document-new");
-                  eina_strbuf_append_printf(text, "(%s) ", _("add"));
-                  break;
-                case EDI_SCM_STATUS_MODIFIED:
-                  elm_icon_standard_set(icon, "document-save-as");
-                  eina_strbuf_append_printf(text, "(%s) ", _("mod"));
-                  break;
-                case EDI_SCM_STATUS_DELETED:
-                  elm_icon_standard_set(icon, "edit-delete");
-                  eina_strbuf_append_printf(text, "(%s) ", _("del"));
-                  break;
-                case EDI_SCM_STATUS_RENAMED:
-                  elm_icon_standard_set(icon, "document-save-as");
-                  eina_strbuf_append_printf(text, "(%s) ", _("ren"));
-                  break;
-                case EDI_SCM_STATUS_UNTRACKED:
-                  elm_icon_standard_set(icon, "dialog-question");
-                  eina_strbuf_append_printf(text, "(%s)", _("untracked"));
-                  break;
-                default:
-                  elm_icon_standard_set(icon, "text-x-generic");
-               }
-
-             if (!status->staged && status->change != EDI_SCM_STATUS_UNTRACKED)
-               eina_strbuf_append_printf(text, "- %s", _("unstaged"));
-
+             _set_icon_text(icon, text, status);
              elm_list_item_append(list, eina_strbuf_string_get(text), icon, 
NULL, NULL, NULL);
-
              eina_strbuf_reset(text);
-
+             if (status->staged)
+               staged_changes = EINA_TRUE;
              eina_stringshare_del(status->path);
              free(status);
           }
@@ -265,8 +273,8 @@ edi_scm_screens_commit(Evas_Object *parent)
    elm_object_content_set(frame, input);
    elm_box_pack_end(box, frame);
 
-   diff = edi_scm_diff();
-   if (strlen(diff))
+   diff_text = edi_scm_diff();
+   if (diff_text[0] && diff_text[1])
      {
         frame = elm_frame_add(popup);
         evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
@@ -277,7 +285,7 @@ edi_scm_screens_commit(Evas_Object *parent)
         cbox = elm_box_add(popup);
         evas_object_size_hint_weight_set(cbox, EVAS_HINT_EXPAND, 
EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(cbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
-        evas_object_size_hint_min_set(cbox, 350 * elm_config_scale_get(), 250 
* elm_config_scale_get());
+        evas_object_size_hint_min_set(cbox, 500 * elm_config_scale_get(), 250 
* elm_config_scale_get());
         evas_object_show(cbox);
         elm_object_content_set(frame, cbox);
         elm_box_pack_end(box, frame);
@@ -294,10 +302,10 @@ edi_scm_screens_commit(Evas_Object *parent)
         evas_object_show(entry);
         elm_box_pack_end(cbox, entry);
 
-        _entry_lines_append(code, diff);
+        _entry_lines_append(code, diff_text);
      }
 
-   free(diff);
+   free(diff_text);
 
    button = elm_button_add(popup);
    elm_object_text_set(button, _("Cancel"));
diff --git a/src/lib/edi_exe.c b/src/lib/edi_exe.c
index bbfaf03..48d3ce9 100644
--- a/src/lib/edi_exe.c
+++ b/src/lib/edi_exe.c
@@ -135,7 +135,7 @@ edi_exe_response(const char *command)
 
    while ((fgets(buf, sizeof(buf), p)) != NULL)
      {
-        eina_strbuf_append_printf(lines, "%s", buf);
+        eina_strbuf_append(lines, buf);
      }
 
    pclose(p);
diff --git a/src/lib/edi_scm.c b/src/lib/edi_scm.c
index 2ab93be..f99ddc4 100644
--- a/src/lib/edi_scm.c
+++ b/src/lib/edi_scm.c
@@ -168,22 +168,34 @@ _parse_line(char *line)
    if (change[0] == 'A' || change[1] == 'A')
      {
         status->change = EDI_SCM_STATUS_ADDED;
-        if (change[0] == 'A') status->staged = EINA_TRUE;
+        if (change[0] == 'A')
+          {
+            status->staged = status->change = EDI_SCM_STATUS_ADDED_STAGED;
+          }
      }
    else if (change[0] == 'R' || change[1] == 'R')
      {
         status->change = EDI_SCM_STATUS_RENAMED;
-        if (change[0] == 'R') status->staged = EINA_TRUE;
+        if (change[0] == 'R')
+          {
+             status->staged = status->change = EDI_SCM_STATUS_RENAMED_STAGED;
+          }
      }
    else if (change[0] == 'M' || change[1] == 'M')
      {
         status->change = EDI_SCM_STATUS_MODIFIED;
-        if (change[0] == 'M') status->staged = EINA_TRUE;
+        if (change[0] == 'M')
+          {
+             status->staged = status->change = EDI_SCM_STATUS_MODIFIED_STAGED;
+          }
      }
    else if (change[0] == 'D' || change[1] == 'D')
      {
         status->change = EDI_SCM_STATUS_DELETED;
-        if (change[0] == 'D') status->staged = EINA_TRUE;
+        if (change[0] == 'D')
+          {
+             status->staged = status->change = EDI_SCM_STATUS_DELETED_STAGED;
+          }
      }
    else if (change[0] == '?' && change[1] == '?')
      {
@@ -200,26 +212,27 @@ _parse_line(char *line)
 static Edi_Scm_Status_Code
 _edi_scm_git_file_status(const char *path)
 {
-   Eina_Strbuf *command;
    Edi_Scm_Status *status;
-   Edi_Scm_Status_Code result;
+   char command[4096];
    char *line;
+   Edi_Scm_Status_Code result;
 
-   command = eina_strbuf_new();
-
-   eina_strbuf_append_printf(command, "git status --porcelain %s", path);
-
-   line = _edi_scm_exec_response(eina_strbuf_string_get(command));
-
-   status = _parse_line(line);
+   snprintf(command, sizeof(command), "git status --porcelain '%s'", path);
 
-   eina_strbuf_free(command);
+   line = _edi_scm_exec_response(command);
+   if (!line[0] || !line[1])
+     {
+        result = EDI_SCM_STATUS_NONE;
+     }
+   else
+     {
+        status = _parse_line(line);
+        result = status->change;
+        eina_stringshare_del(status->path);
+        free(status);
+     }
 
    free(line);
-   result = status->change;
-
-   eina_stringshare_del(status->path);
-   free(status);
 
    return result;
 }
@@ -468,6 +481,9 @@ edi_scm_enabled(void)
    if (!engine)
      return EINA_FALSE;
 
+   if (!engine->initialized)
+     return EINA_FALSE;
+
    return _edi_scm_enabled(engine);
 }
 
@@ -687,6 +703,8 @@ _edi_scm_git_init()
    engine->credentials_set = _edi_scm_git_credentials_set;
    engine->status_get = _edi_scm_git_status_get;
 
+   engine->initialized = EINA_TRUE;
+
    return engine;
 }
 
diff --git a/src/lib/edi_scm.h b/src/lib/edi_scm.h
index 3e8676a..c3842ca 100644
--- a/src/lib/edi_scm.h
+++ b/src/lib/edi_scm.h
@@ -11,11 +11,16 @@ extern "C" {
  */
 
 typedef enum {
-   EDI_SCM_STATUS_ADDED = 1,
+   EDI_SCM_STATUS_NONE = 0,
+   EDI_SCM_STATUS_ADDED,
    EDI_SCM_STATUS_DELETED,
    EDI_SCM_STATUS_MODIFIED,
    EDI_SCM_STATUS_RENAMED,
    EDI_SCM_STATUS_UNTRACKED,
+   EDI_SCM_STATUS_ADDED_STAGED,
+   EDI_SCM_STATUS_DELETED_STAGED,
+   EDI_SCM_STATUS_MODIFIED_STAGED,
+   EDI_SCM_STATUS_RENAMED_STAGED,
    EDI_SCM_STATUS_UNKNOWN,
 } Edi_Scm_Status_Code;
 
@@ -70,6 +75,7 @@ typedef struct _Edi_Scm_Engine
    scm_fn_remote_url   *remote_url_get;
    scm_fn_credentials  *credentials_set;
    scm_fn_status_get   *status_get;
+   Eina_Bool           initialized;
 } Edi_Scm_Engine;
 
 /**

-- 


Reply via email to