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 e02d4d4eb95a6287e9e9cb57b0a80a5999e2b365
Author: Carsten Haitzler (Rasterman) <[email protected]>
AuthorDate: Mon Mar 30 14:15:01 2026 +0100
typebuf - move builtins into their own funcs in a func table
this makes the code cleaner and less copy+pasta
---
src/backends/default/typebuf.c | 559 +++++++++++++++++++++++------------------
1 file changed, 309 insertions(+), 250 deletions(-)
diff --git a/src/backends/default/typebuf.c b/src/backends/default/typebuf.c
index ccee411..6f96ccd 100644
--- a/src/backends/default/typebuf.c
+++ b/src/backends/default/typebuf.c
@@ -118,12 +118,248 @@ _complete_last_arg_path_cmd(char **args, Eina_Strbuf *cmd, const char *cmd_arg)
return ret;
}
+static Eina_Bool
+_has_args(char **args, int min)
+{
+ int i;
+
+ for (i = 0; i < min; i++)
+ {
+ if ((!args[i]) || (!args[i][0])) return EINA_FALSE;
+ }
+ return EINA_TRUE;
+}
+
+static void
+_common_complete_last_arg(char **args)
+{
+ Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
+ if (_complete_last_arg_path_cmd(args, strbuf, "string"))
+ cmd_strbuf_print_consume(strbuf);
+ else eina_strbuf_free(strbuf);
+}
+
+static void
+_common_complete_last_arg_dir_only(char **args)
+{ // XXX: make this only complete directories, not other files
+ _common_complete_last_arg(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// ls
+static void
+_bi_ls_run(char **args)
+{
+ if (_has_args(args, 1)) _typebuf_cd(args[1]);
+ else
+ {
+ Eina_Strbuf *strbuf = cmd_strbuf_new("view-refresh");
+ cmd_strbuf_print_consume(strbuf);
+ }
+}
+
+static void
+_bi_ls_complete(char **args)
+{
+ _common_complete_last_arg_dir_only(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// rm
+static void
+_bi_rm_run(char **args)
+{
+ Eina_List *files = NULL;
+ int i, j;
+ Eina_Bool opt_f = EINA_FALSE;
+ char *full = NULL;
+
+ if (!_has_args(args, 1)) return;
+ for (i = 1; args[i]; i++)
+ {
+ const char *arg = args[i];
+
+ if (arg[0] == '-')
+ { // its an option
+ for (j = 1; arg[j]; j++)
+ {
+ if (arg[j] == 'f') opt_f = EINA_TRUE;
+ // ignore other: we're fuzzy not 100% compat
+ }
+ }
+ else if (arg[0])
+ { // it's a file - convert to path if needed
+ full = _path_arg_rel_to_abs(arg);
+ if (full) files = eina_list_append(files, full);
+ }
+ }
+ if (files)
+ { // only run if we have files
+ if (opt_f) op_run("rm", files, NULL);
+ else op_run("trash", files, NULL);
+ EINA_LIST_FREE(files, full) free(full);
+ }
+}
+
+static void
+_bi_rm_complete(char **args)
+{
+ _common_complete_last_arg(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// unlink
+static void
+_bi_unlink_run(char **args)
+{
+ Eina_List *files = NULL;
+ int i;
+ char *full = NULL;
+
+ if (!_has_args(args, 1)) return;
+ for (i = 1; args[i]; i++)
+ {
+ const char *arg = args[i];
+
+ if (arg[0])
+ { // it's a file - convert to path if needed
+ full = _path_arg_rel_to_abs(arg);
+ if (full) files = eina_list_append(files, full);
+ }
+ }
+ if (files)
+ { // only run if we have files
+ op_run("rm", files, NULL);
+ EINA_LIST_FREE(files, full) free(full);
+ }
+}
+
+static void
+_bi_unlink_complete(char **args)
+{
+ _common_complete_last_arg(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// mv
+static void
+_bi_mv_run(char **args)
+{
+}
+
+static void
+_bi_mv_complete(char **args)
+{
+ _common_complete_last_arg(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// cp
+static void
+_bi_cp_run(char **args)
+{
+}
+
+static void
+_bi_cp_complete(char **args)
+{
+ _common_complete_last_arg(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// ln
+static void
+_bi_ln_run(char **args)
+{
+ Eina_List *files = NULL;
+ int i;
+ char *full = NULL;
+
+ if (!_has_args(args, 2)) return;
+ for (i = 1; args[i]; i++)
+ {
+ const char *arg = args[i];
+
+ if (arg[0] == '-')
+ { // its an option - ignore it - we ALWAYS do -s
+ }
+ else if (arg[0])
+ { // it's a file - convert to path if needed
+ if (!files) full = strdup(arg);
+ else full = _path_arg_rel_to_abs(arg);
+ if (full) files = eina_list_append(files, full);
+ }
+ }
+ if (files)
+ { // only run if we have files
+ char *link_src = eina_list_nth(files, 0);
+ const char *link_file = eina_list_nth(files, 1);
+ if (link_src && link_file)
+ {
+ status_begin();
+ status_op("ln");
+ fs_ln(link_src, link_file, EINA_FALSE);
+ status_end();
+ }
+ EINA_LIST_FREE(files, full) free(full);
+ }
+}
+
+static void
+_bi_ln_complete(char **args)
+{
+ _common_complete_last_arg(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+// cd
+static void
+_bi_cd_run(char **args)
+{
+ if (_has_args(args, 1)) _typebuf_cd(args[1]);
+ else
+ { // no arg - go to $HOME
+ const char *home = getenv("HOME");
+ if (home) _typebuf_cd(home);
+ }
+}
+
+static void
+_bi_cd_complete(char **args)
+{
+ _common_complete_last_arg_dir_only(args);
+}
+
+////////////////////////////////////////////////////////////////////////////
+typedef struct
+{
+ const char *cmd;
+ const char *stdicon;
+ struct
+ {
+ void (*run)(char **args);
+ void (*complete)(char **args);
+ } func;
+} Typebuf_Builtin;
+
+Typebuf_Builtin _typebuf_builtins[] = {
+#define ENTRY(_cmd, _icn) \
+ { \
+ #_cmd, _icn, { _bi_##_cmd##_run, _bi_##_cmd##_complete } \
+ }
+ ENTRY(ls, "std:view-refresh"), ENTRY(rm, "std:edit-delete"),
+ ENTRY(unlink, "std:edit-delete"), ENTRY(mv, "std:edit-rename"),
+ ENTRY(cp, "std:edit-copy"), ENTRY(ln, "std:insert-link"),
+ ENTRY(cd, "std:folder"), { NULL, NULL, { NULL, NULL } }
+#undef ENTRY
+};
+////////////////////////////////////////////////////////////////////////////
+
void
typebuf_cmd(Cmd *c)
{
char **args = NULL;
- const char *op
- = cmd_key_find(c, "op"); // "update", "complete", "run", "cursor"
+ const char *op = cmd_key_find(c, "op"); // update, complete, run, cursor
const char *line_str = cmd_key_find(c, "line");
// dont need this atm.
// const char *cpos_str = cmd_key_find(c, "cursor-pos");
@@ -132,272 +368,95 @@ typebuf_cmd(Cmd *c)
if (line_str) args = eina_str_split(line_str, " ", -1);
if (args)
{
- if (!strcmp(args[0], "ls"))
- { // built-in cmd: ls [file1]
- _cmd_typebuf_icon_send("std:view-refresh");
- if ((op) && (!strcmp(op, "run")))
- { // only support 1 arg (first) if there - "cd arg"
- if ((args[1]) && (args[1][0])) _typebuf_cd(args[1]);
- else
- {
- Eina_Strbuf *strbuf = cmd_strbuf_new("view-refresh");
- cmd_strbuf_print_consume(strbuf);
- }
- }
- else if ((op) && (!strcmp(op, "complete")))
- { // only support 1 arg (first) if there - "cd arg"
- if ((args[1]) && (args[1][0]))
- { // we have 1 or more args - assume 1 and its a file/path
- Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
- if (_complete_last_arg_path_cmd(args, strbuf, "string"))
- cmd_strbuf_print_consume(strbuf);
- else eina_strbuf_free(strbuf);
- }
- }
- }
- else if (!strcmp(args[0], "rm"))
- { // built-in cmd: rm [-f] file1 [file2] [file3] ...
- _cmd_typebuf_icon_send("std:edit-delete");
- if ((op) && (!strcmp(op, "run")))
+ int i;
+ Eina_Bool found = EINA_FALSE;
+
+ for (i = 0; _typebuf_builtins[i].cmd; i++)
+ {
+ if (!strcmp(args[0], _typebuf_builtins[i].cmd))
{
- if ((args[1]) && (args[1][0]))
+ found = EINA_TRUE;
+ _cmd_typebuf_icon_send(_typebuf_builtins[i].stdicon);
+ if (op)
{
- Eina_List *files = NULL;
- int i, j;
- Eina_Bool opt_f = EINA_FALSE;
- char *full = NULL;
-
- for (i = 1; args[i]; i++)
- {
- const char *arg = args[i];
-
- if (arg[0] == '-')
- { // its an option
- for (j = 1; arg[j]; j++)
- {
- if (arg[j] == 'f') opt_f = EINA_TRUE;
- // ignore other: we're fuzzy not 100% compat
- }
- }
- else if (arg[0])
- { // it's a file - convert to path if needed
- full = _path_arg_rel_to_abs(arg);
- if (full) files = eina_list_append(files, full);
- }
- }
- if (files)
- { // only run if we have files
- if (opt_f) op_run("rm", files, NULL);
- else op_run("trash", files, NULL);
- EINA_LIST_FREE(files, full) free(full);
- }
- }
- }
- else if ((op) && (!strcmp(op, "complete")))
- {
- if ((args[1]) && (args[1][0]))
- { // we have 1 or more args - complete last
- Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
- if (_complete_last_arg_path_cmd(args, strbuf, "string"))
- cmd_strbuf_print_consume(strbuf);
- else eina_strbuf_free(strbuf);
+ if (!strcmp(op, "run"))
+ _typebuf_builtins[i].func.run(args);
+ else if ((!strcmp(op, "complete"))
+ && (_has_args(args, 1))) // min 1 arg for complete
+ _typebuf_builtins[i].func.complete(args);
}
}
}
- else if (!strcmp(args[0], "unlink"))
- { // built-in cmd: unlink file1 [file2] [file3] ...
- _cmd_typebuf_icon_send("std:edit-delete");
- if ((op) && (!strcmp(op, "run")))
- {
- if ((args[1]) && (args[1][0]))
- {
- Eina_List *files = NULL;
- int i;
- char *full = NULL;
+ if (!found)
+ { // no built-in - then look for .desktop file command matching
+ if (args[0])
+ { // generic typebuf matches a desktop file for an app/command you
+ // have installed and indexed - thus can be extended with more
+ // installed desktop files that are found/indexed
+ // first try - match by the exec command in the desktop
+ Efreet_Desktop *d = efreet_util_desktop_exec_find(args[0]);
- for (i = 1; args[i]; i++)
- {
- const char *arg = args[i];
+ if (!d) // that didn't work
+ { // can't find by exec - let's find by desktop filename/oid
+ char buf[1024];
- if (arg[0])
- { // it's a file - convert to path if needed
- full = _path_arg_rel_to_abs(arg);
- if (full) files = eina_list_append(files, full);
- }
- }
- if (files)
- { // only run if we have files
- op_run("rm", files, NULL);
- EINA_LIST_FREE(files, full) free(full);
- }
+ snprintf(buf, sizeof(buf), "%s.desktop", args[0]);
+ d = efreet_util_desktop_file_id_find(buf);
}
- }
- else if ((op) && (!strcmp(op, "complete")))
- {
- if ((args[1]) && (args[1][0]))
- { // we have 1 or more args - complete last
- Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
- if (_complete_last_arg_path_cmd(args, strbuf, "string"))
- cmd_strbuf_print_consume(strbuf);
- else eina_strbuf_free(strbuf);
- }
- }
- }
- else if (!strcmp(args[0], "mv"))
- { // built-in cmd: mv file1 [file2] [file3] [destdir] ...
- // built-in cmd: mv file newfilename
- // at least 2 args. last arg is dest dir OR new filename
- _cmd_typebuf_icon_send("std:edit-rename");
- // _op_run("mv", files, NULL);
- }
- else if (!strcmp(args[0], "cp"))
- { // built-in cmd: cp file1 [file2] [file3] [destdir] ...
- // built-in cmd: cp file copyfilename
- // at least 2 args. last arg is dest dir OR new copy filename
- _cmd_typebuf_icon_send("std:edit-copy");
- // _op_run("cp", files, NULL);
- }
- else if (!strcmp(args[0], "ln"))
- { // built-in cmd: ln [-s] dest linkfilename
- _cmd_typebuf_icon_send("std:insert-link");
- if ((op) && (!strcmp(op, "run")))
- { // must have 2 args minimum
- if ((args[1]) && (args[1][0]) && (args[2]) && (args[2][0]))
- {
- Eina_List *files = NULL;
- int i;
- char *full = NULL;
+ // if that didn't work find by name field in desktop
+ if (!d) d = efreet_util_desktop_name_find(args[0]);
+ if (d)
+ { // found some desktop matching the cmd
+ Eina_Strbuf *buf2 = eina_strbuf_new();
- for (i = 1; args[i]; i++)
- {
- const char *arg = args[i];
-
- if (arg[0] == '-')
- { // its an option - ignore it - we ALWAYS do -s
- }
- else if (arg[0])
- { // it's a file - convert to path if needed
- if (!files) full = strdup(arg);
- else full = _path_arg_rel_to_abs(arg);
- if (full) files = eina_list_append(files, full);
- }
+ if (buf2)
+ { // provide the icon from the desktop file for typebuf
+ eina_strbuf_append_printf(buf2, "std:%s", d->icon);
+ _cmd_typebuf_icon_send(eina_strbuf_string_get(buf2));
+ eina_strbuf_free(buf2);
}
- if (files)
- { // only run if we have files
- char *link_src = eina_list_nth(files, 0);
- const char *link_file = eina_list_nth(files, 1);
- if (link_src && link_file)
+ if ((op) && (!strcmp(op, "run")))
+ { // ask front end to "run" files provided as args
+ Eina_Strbuf *strbuf = cmd_strbuf_new("file-run");
+
+ if (strbuf)
{
- status_begin();
- status_op("ln");
- fs_ln(link_src, link_file, EINA_FALSE);
- status_end();
- }
- EINA_LIST_FREE(files, full) free(full);
- }
- }
- }
- else if ((op) && (!strcmp(op, "complete")))
- { // complete last arg
- if ((args[1]) && (args[1][0]))
- { // we have 1 or more args
- Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
- if (_complete_last_arg_path_cmd(args, strbuf, "string"))
- cmd_strbuf_print_consume(strbuf);
- else eina_strbuf_free(strbuf);
- }
- }
- }
- else if (!strcmp(args[0], "cd"))
- { // built-in cmd: cd dirname
- _cmd_typebuf_icon_send("std:folder");
- if ((op) && (!strcmp(op, "run")))
- { // only support 1 arg (first) if there - "cd arg"
- if ((args[1]) && (args[1][0])) _typebuf_cd(args[1]);
- else
- { // no arg - go to $HOME
- const char *home = getenv("HOME");
- if (home) _typebuf_cd(home);
- }
- }
- else if ((op) && (!strcmp(op, "complete")))
- { // complete last arg
- if ((args[1]) && (args[1][0]))
- { // we have 1 or more args
- Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
- if (_complete_last_arg_path_cmd(args, strbuf, "string"))
- cmd_strbuf_print_consume(strbuf);
- else eina_strbuf_free(strbuf);
- }
- }
- }
- else if (args[0])
- { // generic typebuf matches a desktop file for an app/command you
- // have installed and indexed - thus can be extended with more
- // installed desktop files that are found/indexed
- // first try - match by the exec command in the desktop
- Efreet_Desktop *d = efreet_util_desktop_exec_find(args[0]);
+ int i;
+ const char *mondir = ecore_file_monitor_path_get(mon);
- if (!d) // that didn't work
- { // can't find by exec - let's find by desktop filename/oid
- char buf[1024];
-
- snprintf(buf, sizeof(buf), "%s.desktop", args[0]);
- d = efreet_util_desktop_file_id_find(buf);
- }
- // if that didn't work find by name field in desktop
- if (!d) d = efreet_util_desktop_name_find(args[0]);
- if (d)
- { // found some desktop matching the cmd
- Eina_Strbuf *buf2 = eina_strbuf_new();
-
- if (buf2)
- { // provide the icon from the desktop file for typebuf
- eina_strbuf_append_printf(buf2, "std:%s", d->icon);
- _cmd_typebuf_icon_send(eina_strbuf_string_get(buf2));
- eina_strbuf_free(buf2);
- }
- if ((op) && (!strcmp(op, "run")))
- { // ask front end to "run" files provided as args
- Eina_Strbuf *strbuf = cmd_strbuf_new("file-run");
-
- if (strbuf)
- {
- int i;
- const char *mondir = ecore_file_monitor_path_get(mon);
-
- if (mondir)
- { // cwd is this dir for cmds as if we were in a
- // terminal in cwd
- cmd_strbuf_append(strbuf, "cwd", mondir);
- cmd_strbuf_append(strbuf, "open-with", d->orig_path);
- // add args as files
- for (i = 1; args[i]; i++)
- {
- if ((args[i]) && (args[i][0]))
- cmd_strbuf_append(strbuf, "path", args[i]);
+ if (mondir)
+ { // cwd is this dir for cmds as if we were in a
+ // terminal in cwd
+ cmd_strbuf_append(strbuf, "cwd", mondir);
+ cmd_strbuf_append(strbuf, "open-with",
+ d->orig_path);
+ // add args as files
+ for (i = 1; args[i]; i++)
+ {
+ if ((args[i]) && (args[i][0]))
+ cmd_strbuf_append(strbuf, "path", args[i]);
+ }
+ // send file-run cmd back to front end
+ cmd_strbuf_print_consume(strbuf);
}
- // send file-run cmd back to front end
- cmd_strbuf_print_consume(strbuf);
}
}
- }
- else if ((op) && (!strcmp(op, "complete")))
- { // complete last arg as file
- if ((args[1]) && (args[1][0]))
- {
- Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
- if (_complete_last_arg_path_cmd(args, strbuf, "string"))
- cmd_strbuf_print_consume(strbuf);
- else eina_strbuf_free(strbuf);
+ else if ((op) && (!strcmp(op, "complete")))
+ { // complete last arg as file
+ if ((args[1]) && (args[1][0]))
+ {
+ Eina_Strbuf *strbuf = cmd_strbuf_new("typebuf-set");
+ if (_complete_last_arg_path_cmd(args, strbuf,
+ "string"))
+ cmd_strbuf_print_consume(strbuf);
+ else eina_strbuf_free(strbuf);
+ }
}
+ efreet_desktop_free(d);
}
- efreet_desktop_free(d);
}
}
- // for (p = args; *p != NULL; p++)
- // fprintf(stderr, "XXX:ZZZ: [%s]\n", *p);
+ free(*args);
+ free(args);
}
- free(*args);
- free(args);
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.