gdbus-tool: Add tab completion support to gdbus emit

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://bugzilla.gnome.org/show_bug.cgi?id=788594
This commit is contained in:
Philip Withnall 2017-10-09 10:46:55 +01:00
parent 51e91e35c1
commit faf9440908

View File

@ -137,9 +137,11 @@ modify_argv0_for_command (gint *argc, gchar **argv[], const gchar *command)
/* ---------------------------------------------------------------------------------------------------- */
static void
print_methods (GDBusConnection *c,
const gchar *name,
const gchar *path)
print_methods_and_signals (GDBusConnection *c,
const gchar *name,
const gchar *path,
gboolean print_methods,
gboolean print_signals)
{
GVariant *result;
GError *error;
@ -181,11 +183,16 @@ print_methods (GDBusConnection *c,
for (n = 0; node->interfaces != NULL && node->interfaces[n] != NULL; n++)
{
const GDBusInterfaceInfo *iface = node->interfaces[n];
for (m = 0; iface->methods != NULL && iface->methods[m] != NULL; m++)
for (m = 0; print_methods && iface->methods != NULL && iface->methods[m] != NULL; m++)
{
const GDBusMethodInfo *method = iface->methods[m];
g_print ("%s.%s \n", iface->name, method->name);
}
for (m = 0; print_signals && iface->signals != NULL && iface->signals[m] != NULL; m++)
{
const GDBusSignalInfo *signal = iface->signals[m];
g_print ("%s.%s \n", iface->name, signal->name);
}
}
g_dbus_node_info_unref (node);
@ -565,6 +572,7 @@ handle_emit (gint *argc,
gboolean skip_dashes;
guint parm;
guint n;
gboolean complete_names, complete_paths, complete_signals;
ret = FALSE;
c = NULL;
@ -580,6 +588,27 @@ handle_emit (gint *argc,
g_option_context_add_main_entries (o, emit_entries, GETTEXT_PACKAGE);
g_option_context_add_group (o, connection_get_group ());
complete_names = FALSE;
if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--dest") == 0)
{
complete_names = TRUE;
remove_arg ((*argc) - 1, argc, argv);
}
complete_paths = FALSE;
if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--object-path") == 0)
{
complete_paths = TRUE;
remove_arg ((*argc) - 1, argc, argv);
}
complete_signals = FALSE;
if (request_completion && *argc > 1 && g_strcmp0 ((*argv)[(*argc)-1], "--signal") == 0)
{
complete_signals = TRUE;
remove_arg ((*argc) - 1, argc, argv);
}
if (!g_option_context_parse (o, argc, argv, NULL))
{
if (!request_completion)
@ -616,36 +645,99 @@ handle_emit (gint *argc,
goto out;
}
/* All done with completion now */
if (request_completion)
goto out;
if (opt_emit_object_path == NULL)
/* validate and complete destination (bus name) */
if (complete_names)
{
g_printerr (_("Error: object path not specified.\n"));
print_names (c, FALSE);
goto out;
}
if (!g_variant_is_object_path (opt_emit_object_path))
if (opt_emit_dest == NULL)
{
if (request_completion)
g_print ("--dest \n");
else
g_printerr (_("Error: Destination is not specified\n"));
goto out;
}
if (request_completion && g_strcmp0 ("--dest", completion_prev) == 0)
{
print_names (c, g_str_has_prefix (opt_emit_dest, ":"));
goto out;
}
if (!request_completion && !g_dbus_is_unique_name (opt_emit_dest))
{
g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest);
goto out;
}
/* validate and complete object path */
if (complete_paths)
{
print_paths (c, opt_emit_dest, "/");
goto out;
}
if (opt_emit_object_path == NULL)
{
if (request_completion)
g_print ("--object-path \n");
else
g_printerr (_("Error: Object path is not specified\n"));
goto out;
}
if (request_completion && g_strcmp0 ("--object-path", completion_prev) == 0)
{
gchar *p;
s = g_strdup (opt_emit_object_path);
p = strrchr (s, '/');
if (p != NULL)
{
if (p == s)
p++;
*p = '\0';
}
print_paths (c, opt_emit_dest, s);
g_free (s);
goto out;
}
if (!request_completion && !g_variant_is_object_path (opt_emit_object_path))
{
g_printerr (_("Error: %s is not a valid object path\n"), opt_emit_object_path);
goto out;
}
if (opt_emit_signal == NULL)
/* validate and complete signal (interface + signal name) */
if (complete_signals)
{
g_printerr (_("Error: signal not specified.\n"));
print_methods_and_signals (c, opt_emit_dest, opt_emit_object_path, FALSE, TRUE);
goto out;
}
s = strrchr (opt_emit_signal, '.');
if (s == NULL)
if (opt_emit_signal == NULL)
{
g_printerr (_("Error: signal must be the fully-qualified name.\n"));
if (request_completion)
g_print ("--signal \n");
else
g_printerr (_("Error: Signal name is not specified\n"));
goto out;
}
if (request_completion && g_strcmp0 ("--signal", completion_prev) == 0)
{
print_methods_and_signals (c, opt_emit_dest, opt_emit_object_path, FALSE, TRUE);
goto out;
}
s = strrchr (opt_emit_signal, '.');
if (!request_completion && s == NULL)
{
g_printerr (_("Error: Signal name “%s” is invalid\n"), opt_emit_signal);
goto out;
}
signal_name = g_strdup (s + 1);
interface_name = g_strndup (opt_emit_signal, s - opt_emit_signal);
/* All done with completion now */
if (request_completion)
goto out;
if (!g_dbus_is_interface_name (interface_name))
{
g_printerr (_("Error: %s is not a valid interface name\n"), interface_name);
@ -658,12 +750,6 @@ handle_emit (gint *argc,
goto out;
}
if (opt_emit_dest != NULL && !g_dbus_is_unique_name (opt_emit_dest))
{
g_printerr (_("Error: %s is not a valid unique bus name.\n"), opt_emit_dest);
goto out;
}
/* Read parameters */
g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
skip_dashes = TRUE;
@ -925,7 +1011,7 @@ handle_call (gint *argc,
/* validate and complete method (interface + method name) */
if (complete_methods)
{
print_methods (c, opt_call_dest, opt_call_object_path);
print_methods_and_signals (c, opt_call_dest, opt_call_object_path, TRUE, FALSE);
goto out;
}
if (opt_call_method == NULL)
@ -938,7 +1024,7 @@ handle_call (gint *argc,
}
if (request_completion && g_strcmp0 ("--method", completion_prev) == 0)
{
print_methods (c, opt_call_dest, opt_call_object_path);
print_methods_and_signals (c, opt_call_dest, opt_call_object_path, TRUE, FALSE);
goto out;
}
s = strrchr (opt_call_method, '.');