This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository efm2.

View the commit online.

commit 9ea6297fbd3698631479182146050f6c592457ea
Author: Carsten Haitzler (Rasterman) <[email protected]>
AuthorDate: Wed Jan 21 19:04:17 2026 +0000

    make typebuf select and enter "open" things
    
    some shared run code - some glob selecting code.... might not be great
    on 1000's of files.. but hey... future things to optimize by making
    them background async...
---
 src/efm/efm.c         |   8 ++-
 src/efm/efm_key.c     |  23 +-------
 src/efm/efm_structs.h |  11 +++-
 src/efm/efm_typebuf.c | 157 ++++++++++++++++++++++++++++++++++++++------------
 src/efm/efm_util.c    |  67 +++++++++++++++++++++
 src/efm/efm_util.h    |   5 +-
 6 files changed, 207 insertions(+), 64 deletions(-)

diff --git a/src/efm/efm.c b/src/efm/efm.c
index 019510e..21a7269 100644
--- a/src/efm/efm.c
+++ b/src/efm/efm.c
@@ -17,6 +17,7 @@
 #include "efm_private.h"
 #include "efm_key.h"
 #include "efm_typebuf.h"
+#include "eina_stringshare.h"
 
 int _log_dom = -1;
 
@@ -495,7 +496,9 @@ _smart_add(Evas_Object *obj)
   sd->config.sort_mode = EFM_SORT_MODE_NAME | EFM_SORT_MODE_LABEL_NOT_PATH
                          | EFM_SORT_MODE_NOCASE | EFM_SORT_MODE_DIRS_FIRST;
   // XXX: get this from config...
-  sd->config.icon_size         = 40;
+  sd->config.typebuf_history_max = 256;
+  sd->config.icon_size           = 40;
+
   sd->config.detail_min_w[0]   = 50;
   sd->config.detail_min_w[1]   = 120;
   sd->config.detail_min_w[2]   = 130;
@@ -576,6 +579,7 @@ _smart_del(Evas_Object *obj)
   Evas             *e;
   int               i;
   Smart_Data_Timer *st;
+  const char       *s;
   ENTRY;
 
   efm_menu_provider_select(sd->o_smart, -1);
@@ -749,6 +753,8 @@ _smart_del(Evas_Object *obj)
     ecore_timer_del(st->timer);
     free(st);
   }
+  EINA_LIST_FREE(sd->typebuf_history, s) { eina_stringshare_del(s); }
+  eina_stringshare_replace(&sd->typebuf_restore, NULL);
   if (sd->dnd_drop_data)
     {
       free(sd->dnd_drop_data);
diff --git a/src/efm/efm_key.c b/src/efm/efm_key.c
index c311c04..4ce18c6 100644
--- a/src/efm/efm_key.c
+++ b/src/efm/efm_key.c
@@ -21,28 +21,7 @@ _efm_key_handle(Smart_Data *sd, Evas_Event_Key_Down *ev)
     handled = _icon_focus_dir(sd, EFM_FOCUS_DIR_PGDN);
   else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
     {
-      if (sd->last_focused)
-        {
-          Icon        *icon   = sd->last_focused;
-          Eina_Strbuf *strbuf = eina_strbuf_new();
-
-          if (!icon->selected) _icon_select(icon);
-
-          if (strbuf)
-            {
-              if (_selected_icons_uri_strbuf_append(sd, strbuf))
-                {
-                  Eina_Strbuf *buf = cmd_strbuf_new("file-run");
-
-                  _icon_open_with_cmd_strbuf_append(buf, "open-with", sd);
-                  _uri_list_cmd_strbuf_append(buf, "path",
-                                              eina_strbuf_string_get(strbuf));
-                  cmd_strbuf_exe_consume(buf, sd->exe_open);
-                }
-              eina_strbuf_free(strbuf);
-            }
-          handled = EINA_TRUE;
-        }
+      handled = _efm_icons_run(sd, EINA_TRUE);
     }
   else if (!strcmp(ev->key, "space"))
     {
diff --git a/src/efm/efm_structs.h b/src/efm/efm_structs.h
index 55265f6..50855c1 100644
--- a/src/efm/efm_structs.h
+++ b/src/efm/efm_structs.h
@@ -1,3 +1,4 @@
+#include "eina_stringshare.h"
 #ifndef EFM_STRUCTS_H
 #define EFM_STRUCTS_H 1
 
@@ -81,7 +82,10 @@ struct _Smart_Data
   Icon      *rename_icon;
   Icon      *dnd_over_icon;
 
-  int typebuf_cursor_ignore;
+  Eina_Stringshare *typebuf_restore;
+  Eina_List        *typebuf_history;
+  int               typebuf_history_pos;
+  int               typebuf_cursor_ignore;
 
   Evas_Coord      icon_min_w, icon_min_h;
   Evas_Coord      list_min_w, list_min_h;
@@ -141,8 +145,9 @@ struct _Smart_Data
   {
     Efm_View_Mode     view_mode;
     Efm_Sort_Mode     sort_mode;
-    Evas_Coord        icon_size;
-    Evas_Coord        detail_min_w[6];
+    int               icon_size;
+    int               typebuf_history_max;
+    int               detail_min_w[6];
     Eina_Stringshare *path;
     Eina_Stringshare *backend;
     Eina_Stringshare *icon_style;
diff --git a/src/efm/efm_typebuf.c b/src/efm/efm_typebuf.c
index 3e76c52..60c422f 100644
--- a/src/efm/efm_typebuf.c
+++ b/src/efm/efm_typebuf.c
@@ -1,7 +1,5 @@
 #include "efm_typebuf.h"
-#include "Edje.h"
-#include "Evas.h"
-#include "eina_types.h"
+#include "efm_util.h"
 
 static int
 _typebuf_command_detect(const char *str)
@@ -40,44 +38,47 @@ _typebuf_command_str_build_args(Eina_Strbuf *buf, const char *str,
 }
 
 static void
-_typebuf_complete(Smart_Data *sd)
-{ // find where cursor is (just after) and complete it if possible
-  int cpos = elm_entry_cursor_pos_get(sd->o_typebuf);
-}
-
-static void
-_typebuf_history(Smart_Data *sd, int dir)
-{ // replace typebuf with history typebuf item in direction given
-}
-
-static void
-_cb_typebuf_aborted(void *data, Evas_Object *obj EINA_UNUSED,
-                    void *event_info EINA_UNUSED)
+_typebuf_update(Smart_Data *sd, const char *str)
 {
-  Smart_Data *sd = data;
+  int pos = _typebuf_command_detect(str);
 
-  printf("XXX: typebuf aborted\n");
-  typebuf_del(sd);
+  if (pos > 0)
+    { // we have a cmd
+    }
+  else
+    { // just have a file match glob
+      // XXX: what if we have 1000's of files?
+      if (!str) _efm_sel_none(sd);
+      else
+        {
+          size_t tblen = strlen(str);
+
+          if (tblen == 0) _efm_sel_none(sd);
+          else
+            {
+              if ((str[tblen - 1] != '*')
+                  && (str[tblen - 1] != ']')
+                  && (str[tblen - 1] != '?'))
+                { // if we don't end in * or ] or ? assume a * on the end
+                  char *tb = alloca(tblen + 2);
+
+                  // add a * on the end of our glob search
+                  memcpy(tb, str, tblen);
+                  tb[tblen]     = '*';
+                  tb[tblen + 1] = '\0';
+                  _efm_sel_glob(sd, tb, EINA_TRUE);
+                }
+              else _efm_sel_glob(sd, str, EINA_TRUE);
+            }
+        }
+    }
 }
 
 static void
-_cb_typebuf_activated(void *data, Evas_Object *obj EINA_UNUSED,
-                      void *event_info EINA_UNUSED)
+_typebuf_format(Smart_Data *sd)
 {
-  Smart_Data *sd = data;
-
-  printf("XXX: typebuf activated\n");
-  // XXX: "run" the cmd (eg run selected files or run detected cmd)
-  typebuf_del(sd);
-}
-
-static void
-_cb_typebuf_changed(void *data, Evas_Object *obj EINA_UNUSED,
-                    void *event_info EINA_UNUSED)
-{
-  Smart_Data *sd  = data;
-  const char *str = elm_entry_entry_get(sd->o_typebuf);
-  char       *s   = elm_entry_markup_to_utf8(str);
+  const char *str  = elm_entry_entry_get(sd->o_typebuf);
+  char       *s    = elm_entry_markup_to_utf8(str);
   int         cpos = elm_entry_cursor_pos_get(sd->o_typebuf);
   int         pos;
 
@@ -100,9 +101,90 @@ _cb_typebuf_changed(void *data, Evas_Object *obj EINA_UNUSED,
   else if (pos <= 0) _typebuf_command_clear(sd, cpos, s);
   // pur cursor back where it was
   elm_entry_cursor_pos_set(sd->o_typebuf, cpos);
+  _typebuf_update(sd, s);
   free(s);
 }
 
+static void
+_typebuf_complete(Smart_Data *sd)
+{ // find where cursor is (just after) and complete it if possible
+  int cpos = elm_entry_cursor_pos_get(sd->o_typebuf);
+}
+
+static void
+_typebuf_history(Smart_Data *sd, int dir)
+{ // replace typebuf with history typebuf item in direction given
+  const char *s;
+  int         len = eina_list_count(sd->typebuf_history);
+  Eina_Bool   restore = EINA_FALSE;
+
+  if (sd->typebuf_history_pos == -1)
+    {
+      const char *str = elm_entry_entry_get(sd->o_typebuf);
+      char       *s   = elm_entry_markup_to_utf8(str);
+      eina_stringshare_replace(&sd->typebuf_restore, s);
+      printf("XXX: restore = [%s]", s);
+      free(s);
+    }
+  sd->typebuf_history_pos += dir;
+  if (sd->typebuf_history_pos < 0)
+    {
+      restore = EINA_TRUE;
+      sd->typebuf_history_pos = -1;
+      printf("XXX: restore!\n");
+    }
+  else if (sd->typebuf_history_pos >= len) sd->typebuf_history_pos = len - 1;
+  if (restore) s = sd->typebuf_restore;
+  else s = eina_list_nth(sd->typebuf_history, sd->typebuf_history_pos);
+  elm_entry_entry_set(sd->o_typebuf, s);
+  elm_entry_cursor_end_set(sd->o_typebuf);
+  _typebuf_format(sd);
+}
+
+static void
+_cb_typebuf_aborted(void *data, Evas_Object *obj EINA_UNUSED,
+                    void *event_info EINA_UNUSED)
+{
+  Smart_Data *sd = data;
+
+  printf("XXX: typebuf aborted\n");
+  typebuf_del(sd);
+}
+
+static void
+_cb_typebuf_activated(void *data, Evas_Object *obj EINA_UNUSED,
+                      void *event_info EINA_UNUSED)
+{
+  Smart_Data *sd  = data;
+  const char *str = elm_entry_entry_get(sd->o_typebuf);
+  char       *s   = elm_entry_markup_to_utf8(str);
+
+  printf("XXX: typebuf activated\n");
+  // XXX: "run" the cmd (eg run selected files or run detected cmd)
+  sd->typebuf_history
+    = eina_list_prepend(sd->typebuf_history, eina_stringshare_add(s));
+  while (eina_list_count(sd->typebuf_history) > sd->config.typebuf_history_max)
+    {
+      Eina_List *last = eina_list_last(sd->typebuf_history);
+      if (last)
+        {
+          eina_stringshare_del(last->data);
+          sd->typebuf_history
+            = eina_list_remove_list(sd->typebuf_history, last);
+        }
+    }
+  typebuf_del(sd);
+  free(s);
+  _efm_icons_run(sd, EINA_FALSE);
+}
+
+static void
+_cb_typebuf_changed(void *data, Evas_Object *obj EINA_UNUSED,
+                    void *event_info EINA_UNUSED)
+{
+  _typebuf_format(data);
+}
+
 static void
 _cb_typebuf_cursor(void *data, Evas_Object *obj EINA_UNUSED,
                    void *event_info EINA_UNUSED)
@@ -137,12 +219,12 @@ _cb_typebuf_key(void *data, Evas_Object *obj EINA_UNUSED,
     }
   if (!strcmp(ev->key, "Up"))
     {
-      _typebuf_history(sd, -1);
+      _typebuf_history(sd, 1);
       return EINA_TRUE;
     }
   if (!strcmp(ev->key, "Down"))
     {
-      _typebuf_history(sd, 1);
+      _typebuf_history(sd, -1);
       return EINA_TRUE;
     }
   // allow left/right arrow through if the cursor is not at the start/end
@@ -186,6 +268,7 @@ typebuf_add(Smart_Data *sd, Evas_Event_Key_Down *ev)
   sd->typebuf = EINA_TRUE;
   // new entry obj to start fresh
   if (sd->o_typebuf) evas_object_del(sd->o_typebuf);
+  sd->typebuf_history_pos = -1;
   sd->o_typebuf = o = elm_entry_add(sd->o_scroller);
   elm_object_style_set(o, "blank");
   // when entry changes min size - handle it...
diff --git a/src/efm/efm_util.c b/src/efm/efm_util.c
index 4d7fc43..afe5b3b 100644
--- a/src/efm/efm_util.c
+++ b/src/efm/efm_util.c
@@ -2884,6 +2884,49 @@ _efm_sel_rename(Smart_Data *sd)
   _icon_rename_begin(ic);
 }
 
+static Eina_Bool
+_glob_match(const char *str, const char *pattern)
+{
+  if ((!str) || (!pattern)) return EINA_FALSE;
+  if (pattern[0] == 0)
+    {
+      if (str[0] == 0) return EINA_TRUE;
+      return EINA_FALSE;
+    }
+  if (str == pattern) return EINA_TRUE;
+  if (!strcmp(pattern, "*")) return EINA_TRUE;
+  if (eina_fnmatch(pattern, str, EINA_FNMATCH_CASEFOLD)) return EINA_TRUE;
+  return EINA_FALSE;
+}
+
+void
+_efm_sel_glob(Smart_Data *sd, const char *glob, Eina_Bool scroll)
+{
+  Eina_List *l;
+  Icon      *ic;
+  Icon      *first = NULL;
+
+  EINA_LIST_FOREACH(sd->icons, l, ic)
+  {
+    printf("match[%s] in [%s]\n", glob, ic->info.file);
+    if (_glob_match(ic->info.file, glob) || _glob_match(ic->info.label, glob))
+      {
+        if (!first) first = ic;
+        _icon_select(ic);
+      }
+    else _icon_unselect(ic);
+  }
+  if ((scroll) && (first) && (sd->o_scroller))
+    {
+      int ix = first->geom.x;
+      int iy = first->geom.y;
+      int iw = first->geom.w;
+      int ih = first->geom.h;
+
+      elm_scroller_region_bring_in(sd->o_scroller, ix, iy, iw, ih);
+    }
+}
+
 void
 _efm_icons_custom_xy_reset(Smart_Data *sd)
 {
@@ -2902,3 +2945,27 @@ _efm_icons_custom_xy_reset(Smart_Data *sd)
       }
   }
 }
+
+Eina_Bool
+_efm_icons_run(Smart_Data *sd, Eina_Bool last_sel)
+{
+  Icon        *icon   = sd->last_focused;
+  Eina_Strbuf *strbuf;
+
+  if ((icon) && (!icon->selected) && (last_sel)) _icon_select(icon);
+
+  strbuf = eina_strbuf_new();
+  if (!strbuf) return EINA_TRUE;
+
+  if (_selected_icons_uri_strbuf_append(sd, strbuf))
+    {
+      Eina_Strbuf *buf = cmd_strbuf_new("file-run");
+
+      _icon_open_with_cmd_strbuf_append(buf, "open-with", sd);
+      _uri_list_cmd_strbuf_append(buf, "path",
+                                  eina_strbuf_string_get(strbuf));
+      cmd_strbuf_exe_consume(buf, sd->exe_open);
+    }
+  eina_strbuf_free(strbuf);
+  return EINA_TRUE;
+}
diff --git a/src/efm/efm_util.h b/src/efm/efm_util.h
index 0298fe4..827b2b4 100644
--- a/src/efm/efm_util.h
+++ b/src/efm/efm_util.h
@@ -72,7 +72,10 @@ int   _efm_sel_not_count(Smart_Data *sd);
 Icon *_efm_sel_first_get(Smart_Data *sd);
 Icon *_efm_sel_last_get(Smart_Data *sd);
 void  _efm_sel_rename(Smart_Data *sd);
+void  _efm_sel_glob(Smart_Data *sd, const char *glob, Eina_Bool scroll);
 
-void  _efm_icons_custom_xy_reset(Smart_Data *sd);
+void _efm_icons_custom_xy_reset(Smart_Data *sd);
+
+Eina_Bool _efm_icons_run(Smart_Data *sd, Eina_Bool last_sel);
 
 #endif

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to