summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Giudici <fgiudici@redhat.com>2016-06-13 18:59:31 +0200
committerFrancesco Giudici <fgiudici@redhat.com>2016-06-14 15:18:02 +0200
commit280187c4133d9a8bade3d48a485a7c0aaff28fb9 (patch)
treecd97c02ee3607ac179540a773b78983c6d003fbe
parentbf22e5ccdacc44acd8129f1e38bf30554858c4fc (diff)
downloadNetworkManager-fg/autcomplete_fix_rh1301226.tar.gz
nmcli: enable connection autocompletion for 802.1x propertiesfg/autcomplete_fix_rh1301226
nmcli bash autocompletion leveraged on "nmcli connection edit", "print" to retrieve the specific properties of a connection. Anyway, the interactive editor is smart and just prints the used components, so in a connection where 802.1x is not enabled we had no autocompletion. Solved adding an "hidden" command "nmcli connection modify --complete" as suggested in bgo #724860 in order to retrieve ALL the available properties for use in autocompletion. https://bugzilla.gnome.org/show_bug.cgi?id=724860 https://bugzilla.redhat.com/show_bug.cgi?id=1301226
-rw-r--r--clients/cli/connections.c65
-rw-r--r--clients/cli/nmcli-completion11
2 files changed, 72 insertions, 4 deletions
diff --git a/clients/cli/connections.c b/clients/cli/connections.c
index 0c61667d92..b3e5c51fd2 100644
--- a/clients/cli/connections.c
+++ b/clients/cli/connections.c
@@ -2900,6 +2900,38 @@ get_valid_settings_array (const char *con_type)
return NULL;
}
+static char *
+get_valid_autocompletion_string (const NameItem *array, const NameItem *array_slv)
+{
+ const NameItem *iter = array;
+ const NmcOutputField *field_iter;
+ GString *str;
+ int i;
+
+ str = g_string_sized_new (1024);
+
+ for (i = 0; i < 2; i++, iter = array_slv) {
+ while (iter && iter->name) {
+ int j = 0;
+
+ while ((nmc_fields_settings_names[j].name) &&
+ g_strcmp0 (iter->name, nmc_fields_settings_names[j].name))
+ j++;
+
+ field_iter = nmc_fields_settings_names[j].group;
+ j = 0;
+ while (field_iter[j].name) {
+ g_string_append_printf (str, "%s.%s ", iter->name, field_iter[j].name);
+ if (iter->alias)
+ g_string_append_printf (str, "%s.%s ", iter->alias, field_iter[j].name);
+ j++;
+ }
+ iter++;
+ }
+ }
+ return g_string_free (str, FALSE);
+}
+
/*
* Check if 'val' is valid string in either array->name or array->alias for
* both array parameters (array & array_slv).
@@ -10128,6 +10160,7 @@ modify_connection_cb (GObject *connection,
static NMCResultCode
do_connection_modify (NmCli *nmc,
gboolean temporary,
+ gboolean complete,
int argc,
char **argv)
{
@@ -10177,6 +10210,30 @@ do_connection_modify (NmCli *nmc,
goto finish;
}
+ /* Query comes from shell autocomplete function */
+ if (complete) {
+ NMSettingConnection *s_con;
+ const NameItem *valid_settings_main = NULL;
+ const NameItem *valid_settings_slave = NULL;
+ const char *connection_type = NULL;
+ const char *slave_type = NULL;
+ gs_free char *slv_type = NULL;
+ gs_free char *word_list = NULL;
+
+ connection_type = nm_connection_get_connection_type (connection);
+ s_con = nm_connection_get_setting_connection (connection);
+ if (s_con)
+ slave_type = nm_setting_connection_get_slave_type (s_con);
+ slv_type = g_strdup_printf ("%s-slave", slave_type ? slave_type : "no");
+ valid_settings_main = get_valid_settings_array (connection_type);
+ valid_settings_slave = get_valid_settings_array (slv_type);
+
+ word_list = get_valid_autocompletion_string (valid_settings_main, valid_settings_slave);
+ if (word_list)
+ g_print ("%s", word_list);
+ goto finish;
+ }
+
if (next_arg (&argc, &argv) != 0) {
g_string_printf (nmc->return_text, _("Error: <setting>.<property> argument is missing."));
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
@@ -11114,13 +11171,19 @@ do_connections (NmCli *nmc, int argc, char **argv)
nmc->return_value = do_connection_load (nmc, argc-1, argv+1);
} else if (matches (*argv, "modify") == 0) {
gboolean temporary = FALSE;
+ gboolean complete = FALSE;
next_arg (&argc, &argv);
+ /* Check modify options [--complete] or [--temporary] */
if (nmc_arg_is_option (*argv, "temporary")) {
temporary = TRUE;
next_arg (&argc, &argv);
}
- nmc->return_value = do_connection_modify (nmc, temporary, argc, argv);
+ if (nmc_arg_is_option (*argv, "complete")) {
+ complete = TRUE;
+ next_arg (&argc, &argv);
+ }
+ nmc->return_value = do_connection_modify (nmc, temporary, complete, argc, argv);
} else if (matches (*argv, "clone") == 0) {
gboolean temporary = FALSE;
diff --git a/clients/cli/nmcli-completion b/clients/cli/nmcli-completion
index 2e9a149f5b..7b653da414 100644
--- a/clients/cli/nmcli-completion
+++ b/clients/cli/nmcli-completion
@@ -763,19 +763,24 @@ _nmcli_compl_PROPERTIES()
{
while [[ "${#words[@]}" -gt 0 ]]; do
if [[ ${#words[@]} -le 1 ]]; then
- local PREFIX=""
+ local PREFIX="" item list=""
if [[ "${words[0]:0:1}" == [+-] ]]; then
PREFIX="${words[0]:0:1}"
fi
- _nmcli_list_nl "$(echo -e 'print\nquit\nyes' |nmcli c edit "$@" 2>/dev/null |awk -F: '/\..*:/ {print "'$PREFIX'"$1}')"
+ item="$(nmcli c modify --complete "$@" 2>/dev/null)"
+ ### add prefix to each element
+ for item in $item; do
+ list="${list}${PREFIX}${item} "
+ done
+ _nmcli_list "$list"
return 0
elif [[ ${#words[@]} -le 2 ]]; then
return 0
fi
_nmcli_array_delete_at words 0 1
done
- _nmcli_list_nl "$(echo -e 'print\nquit\nyes' |nmcli c edit "$@" 2>/dev/null |awk -F: '/\..*:/ {print $1}')"
+ _nmcli_list "$(nmcli c modify --complete "$@" 2>/dev/null)"
}
_nmcli()