forked from enlightenment/efl
efreet - improve edstop exec find to use the command with less args
efreet will just match any desktop file (at random basically - whatever is first in the list), thjat has the base command looked at. if you have various desktip files with the same command, like: mycommand mycommand %U mycommand -a -b -c /path/to/file /usr/bin/mycommand etc. - which one does it match? it'll pick the first and the list ordering is arbitrary, so this is pretty bad. this strips off the base command at the start (full path or whatever) and then uses the command with the shortest argument length. this means the generic command is found first if we look for "mycommand" in the above list, whihc ends up the best... ESPECIALLY for steam which does just this.
This commit is contained in:
parent
e40c223181
commit
2f4fb3edac
|
@ -5,6 +5,7 @@
|
||||||
/* TODO: add no_display check, as we might want only displayable items */
|
/* TODO: add no_display check, as we might want only displayable items */
|
||||||
|
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <Ecore_File.h>
|
#include <Ecore_File.h>
|
||||||
|
|
||||||
|
@ -170,11 +171,80 @@ efreet_util_desktop_file_id_find(const char *file_id)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
efreet_util_cmd_args_get(const char *cmd)
|
||||||
|
{
|
||||||
|
Eina_Strbuf *buf;
|
||||||
|
char *args;
|
||||||
|
const char *p;
|
||||||
|
Eina_Bool in_qout_double = EINA_FALSE;
|
||||||
|
Eina_Bool in_qout_single = EINA_FALSE;
|
||||||
|
Eina_Bool atargs = EINA_FALSE;
|
||||||
|
Eina_Bool ingap = EINA_FALSE;
|
||||||
|
|
||||||
|
buf = eina_strbuf_new();
|
||||||
|
if (!buf) return NULL;
|
||||||
|
|
||||||
|
// get the arguments to the command as a string on its own
|
||||||
|
for (p = cmd; *p; p++)
|
||||||
|
{
|
||||||
|
if (!atargs)
|
||||||
|
{
|
||||||
|
if (in_qout_double)
|
||||||
|
{
|
||||||
|
if (*p == '\\')
|
||||||
|
{
|
||||||
|
if (p[1]) p++;
|
||||||
|
}
|
||||||
|
else if (*p == '"') in_qout_double = EINA_FALSE;
|
||||||
|
}
|
||||||
|
else if (in_qout_single)
|
||||||
|
{
|
||||||
|
if (*p == '\\')
|
||||||
|
{
|
||||||
|
if (p[1]) p++;
|
||||||
|
}
|
||||||
|
else if (*p == '\'') in_qout_single = EINA_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*p == '\\')
|
||||||
|
{
|
||||||
|
if (p[1]) p++;
|
||||||
|
}
|
||||||
|
else if (*p == '"') in_qout_double = EINA_TRUE;
|
||||||
|
else if (*p == '\'') in_qout_single = EINA_TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isspace((unsigned char)(*p)))
|
||||||
|
{
|
||||||
|
atargs = EINA_TRUE;
|
||||||
|
ingap = EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ingap)
|
||||||
|
{
|
||||||
|
if (!isspace((unsigned char)(*p))) ingap = EINA_FALSE;
|
||||||
|
}
|
||||||
|
if (!ingap) eina_strbuf_append_char(buf, *p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
args = eina_strbuf_string_steal(buf);
|
||||||
|
eina_strbuf_free(buf);
|
||||||
|
if (!args) return strdup("");
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI Efreet_Desktop *
|
EAPI Efreet_Desktop *
|
||||||
efreet_util_desktop_exec_find(const char *exec)
|
efreet_util_desktop_exec_find(const char *exec)
|
||||||
{
|
{
|
||||||
Efreet_Cache_Hash *hash = NULL;
|
Efreet_Cache_Hash *hash = NULL;
|
||||||
Efreet_Desktop *ret = NULL;
|
Efreet_Desktop *ret = NULL, *bestret = NULL;
|
||||||
Efreet_Cache_Array_String *names = NULL;
|
Efreet_Cache_Array_String *names = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
@ -207,11 +277,44 @@ efreet_util_desktop_exec_find(const char *exec)
|
||||||
for (j = 0; j < array->array_count; j++)
|
for (j = 0; j < array->array_count; j++)
|
||||||
{
|
{
|
||||||
ret = efreet_desktop_get(array->array[j]);
|
ret = efreet_desktop_get(array->array[j]);
|
||||||
if (ret) break;
|
if (ret)
|
||||||
|
{
|
||||||
|
if (!bestret) bestret = ret;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ret->exec)
|
||||||
|
{
|
||||||
|
// perfect match - best
|
||||||
|
if (!strcmp(ret->exec, exec))
|
||||||
|
{
|
||||||
|
bestret = ret;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
else if (bestret->exec)
|
||||||
|
{
|
||||||
|
char *f1, *f2;
|
||||||
|
|
||||||
|
f1 = efreet_util_cmd_args_get(ret->exec);
|
||||||
|
f2 = efreet_util_cmd_args_get(bestret->exec);
|
||||||
|
if ((f1) && (f2))
|
||||||
|
{
|
||||||
|
// if this is shorter (less arguments) than best
|
||||||
|
// match so far, thewn this is the best match
|
||||||
|
if (strlen(f1) < strlen(f2))
|
||||||
|
{
|
||||||
|
bestret = ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(f1);
|
||||||
|
free(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ret) break;
|
|
||||||
}
|
}
|
||||||
return ret;
|
done:
|
||||||
|
return bestret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Efreet_Desktop *
|
EAPI Efreet_Desktop *
|
||||||
|
|
Loading…
Reference in New Issue