diff --git a/clients/cli/connections.c b/clients/cli/connections.c index 506bfe0fd0..97be9450be 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). @@ -10169,6 +10201,30 @@ do_connection_modify (NmCli *nmc, goto finish; } + /* Query comes from shell autocomplete function */ + if (nmc->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: . argument is missing.")); nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; 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() diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 7e788654d5..730f6a1d49 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -256,6 +256,8 @@ parse_command_line (NmCli *nmc, int argc, char **argv) /* ignore for backward compatibility */ } else if (matches (opt, "-ask") == 0) { nmc->ask = TRUE; + } else if (matches (opt, "-complete") == 0) { + nmc->complete = TRUE; } else if (matches (opt, "-show-secrets") == 0) { nmc->show_secrets = TRUE; } else if (matches (opt, "-wait") == 0) { @@ -628,6 +630,9 @@ main (int argc, char *argv[]) loop = g_main_loop_new (NULL, FALSE); /* create main loop */ g_main_loop_run (loop); /* run main loop */ + if (nm_cli.complete) + nm_cli.return_value = NMC_RESULT_SUCCESS; + /* Print result descripting text */ if (nm_cli.return_value != NMC_RESULT_SUCCESS) { g_printerr ("%s\n", nm_cli.return_text->str); diff --git a/clients/cli/nmcli.h b/clients/cli/nmcli.h index 34100f0026..c867ad5f9f 100644 --- a/clients/cli/nmcli.h +++ b/clients/cli/nmcli.h @@ -153,6 +153,7 @@ typedef struct _NmCli { GPtrArray *output_data; /* GPtrArray of arrays of NmcOutputField structs - accumulates data for output */ NmcPrintFields print_fields; /* Structure with field indices to print */ gboolean ask; /* Ask for missing parameters: option '--ask' */ + gboolean complete; /* Autocomplete the command line */ gboolean show_secrets; /* Whether to display secrets (both input and output): option '--show-secrets' */ gboolean in_editor; /* Whether running the editor - nmcli con edit' */ gboolean editor_status_line; /* Whether to display status line in connection editor */