cli: implement TAB completion for connection and interface names
For commands like nmcli -a dev disconnect nmcli -a con up ...
This commit is contained in:
@@ -71,6 +71,7 @@
|
||||
#define PROMPT_BOND_MASTER _("Bond master: ")
|
||||
#define PROMPT_TEAM_MASTER _("Team master: ")
|
||||
#define PROMPT_BRIDGE_MASTER _("Bridge master: ")
|
||||
#define PROMPT_CONNECTION _("Connection (name, UUID, or path): ")
|
||||
|
||||
static const char *nmc_known_vpns[] =
|
||||
{ "openvpn", "vpnc", "pptp", "openconnect", "openswan", "libreswan",
|
||||
@@ -1963,10 +1964,8 @@ do_connection_up (NmCli *nmc, int argc, char **argv)
|
||||
|
||||
if (argc == 0) {
|
||||
if (nmc->ask) {
|
||||
line = nmc_readline (_("Connection (name, UUID, or path): "));
|
||||
line = nmc_readline (PROMPT_CONNECTION);
|
||||
name = line ? line : "";
|
||||
// TODO: enhancement: when just Enter is pressed (line is NULL), list
|
||||
// available connections so that the user can select one
|
||||
}
|
||||
} else if (strcmp (*argv, "ifname") != 0) {
|
||||
if ( strcmp (*argv, "id") == 0
|
||||
@@ -2075,7 +2074,7 @@ do_connection_down (NmCli *nmc, int argc, char **argv)
|
||||
|
||||
if (argc == 0) {
|
||||
if (nmc->ask) {
|
||||
line = nmc_readline (_("Connection (name, UUID, or path): "));
|
||||
line = nmc_readline (PROMPT_CONNECTION);
|
||||
nmc_string_to_arg_array (line, "", &arg_arr, &arg_num);
|
||||
arg_ptr = arg_arr;
|
||||
}
|
||||
@@ -8199,7 +8198,7 @@ do_connection_delete (NmCli *nmc, int argc, char **argv)
|
||||
|
||||
if (argc == 0) {
|
||||
if (nmc->ask) {
|
||||
line = nmc_readline (_("Connection (name, UUID, or path): "));
|
||||
line = nmc_readline (PROMPT_CONNECTION);
|
||||
nmc_string_to_arg_array (line, "", &arg_arr, &arg_num);
|
||||
arg_ptr = arg_arr;
|
||||
}
|
||||
@@ -8375,12 +8374,53 @@ connection_editor_thread_func (gpointer data)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
gen_func_connection_names (char *text, int state)
|
||||
{
|
||||
int i = 0;
|
||||
GSList *iter;
|
||||
const char **connections;
|
||||
char *ret;
|
||||
|
||||
if (!nm_cli.system_connections)
|
||||
return NULL;
|
||||
|
||||
connections = g_new (const char *, g_slist_length (nm_cli.system_connections) + 1);
|
||||
for (iter = nm_cli.system_connections; iter; iter = g_slist_next (iter)) {
|
||||
NMConnection *con = NM_CONNECTION (iter->data);
|
||||
const char *id = nm_connection_get_id (con);
|
||||
connections[i++] = id;
|
||||
}
|
||||
connections[i] = NULL;
|
||||
|
||||
ret = nmc_rl_gen_func_basic (text, state, connections);
|
||||
|
||||
g_free (connections);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char **
|
||||
nmcli_con_tab_completion (char *text, int start, int end)
|
||||
{
|
||||
char **match_array = NULL;
|
||||
CPFunction *generator_func = NULL;
|
||||
|
||||
/* Disable readline's default filename completion */
|
||||
rl_attempted_completion_over = 1;
|
||||
return NULL;
|
||||
|
||||
/* Disable appending space after completion */
|
||||
rl_completion_append_character = '\0';
|
||||
|
||||
if (!is_single_word (rl_line_buffer))
|
||||
return NULL;
|
||||
|
||||
if (g_strcmp0 (rl_prompt, PROMPT_CONNECTION) == 0)
|
||||
generator_func = gen_func_connection_names;
|
||||
|
||||
if (generator_func)
|
||||
match_array = rl_completion_matches (text, generator_func);
|
||||
|
||||
return match_array;
|
||||
}
|
||||
|
||||
static NMCResultCode
|
||||
|
@@ -66,6 +66,8 @@
|
||||
#include "common.h"
|
||||
#include "devices.h"
|
||||
|
||||
/* define some prompts */
|
||||
#define PROMPT_INTERFACE _("Interface: ")
|
||||
|
||||
/* Available fields for 'device status' */
|
||||
static NmcOutputField nmc_fields_dev_status[] = {
|
||||
@@ -1383,7 +1385,7 @@ do_device_connect (NmCli *nmc, int argc, char **argv)
|
||||
|
||||
if (argc == 0) {
|
||||
if (nmc->ask)
|
||||
ifname = ifname_ask = nmc_readline (_("Interface: "));
|
||||
ifname = ifname_ask = nmc_readline (PROMPT_INTERFACE);
|
||||
|
||||
if (!ifname_ask) {
|
||||
g_string_printf (nmc->return_text, _("Error: No interface specified."));
|
||||
@@ -1517,7 +1519,7 @@ do_device_disconnect (NmCli *nmc, int argc, char **argv)
|
||||
|
||||
if (argc == 0) {
|
||||
if (nmc->ask)
|
||||
ifname = ifname_ask = nmc_readline (_("Interface: "));
|
||||
ifname = ifname_ask = nmc_readline (PROMPT_INTERFACE);
|
||||
|
||||
if (!ifname_ask) {
|
||||
g_string_printf (nmc->return_text, _("Error: No interface specified."));
|
||||
@@ -2559,12 +2561,73 @@ do_device_wimax (NmCli *nmc, int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
is_single_word (const char* line)
|
||||
{
|
||||
size_t n1, n2, n3;
|
||||
|
||||
n1 = strspn (line, " \t");
|
||||
n2 = strcspn (line+n1, " \t\0") + n1;
|
||||
n3 = strspn (line+n2, " \t");
|
||||
|
||||
if (n3 == 0)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Global variable defined in nmcli.c */
|
||||
extern NmCli nm_cli;
|
||||
|
||||
static char *
|
||||
gen_func_ifnames (char *text, int state)
|
||||
{
|
||||
int i, j = 0;
|
||||
const GPtrArray *devices;
|
||||
const char **ifnames;
|
||||
char *ret;
|
||||
|
||||
nm_cli.get_client (&nm_cli);
|
||||
devices = nm_client_get_devices (nm_cli.client);
|
||||
if (!devices || devices->len < 1)
|
||||
return NULL;
|
||||
|
||||
ifnames = g_new (const char *, devices->len + 1);
|
||||
for (i = 0; i < devices->len; i++) {
|
||||
NMDevice *dev = g_ptr_array_index (devices, i);
|
||||
const char *ifname = nm_device_get_iface (dev);
|
||||
ifnames[j++] = ifname;
|
||||
}
|
||||
ifnames[j] = NULL;
|
||||
|
||||
ret = nmc_rl_gen_func_basic (text, state, ifnames);
|
||||
|
||||
g_free (ifnames);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char **
|
||||
nmcli_device_tab_completion (char *text, int start, int end)
|
||||
{
|
||||
char **match_array = NULL;
|
||||
CPFunction *generator_func = NULL;
|
||||
|
||||
/* Disable readline's default filename completion */
|
||||
rl_attempted_completion_over = 1;
|
||||
return NULL;
|
||||
|
||||
/* Disable appending space after completion */
|
||||
rl_completion_append_character = '\0';
|
||||
|
||||
if (!is_single_word (rl_line_buffer))
|
||||
return NULL;
|
||||
|
||||
if (g_strcmp0 (rl_prompt, PROMPT_INTERFACE) == 0)
|
||||
generator_func = gen_func_ifnames;
|
||||
|
||||
if (generator_func)
|
||||
match_array = rl_completion_matches (text, generator_func);
|
||||
|
||||
return match_array;
|
||||
}
|
||||
|
||||
NMCResultCode
|
||||
|
Reference in New Issue
Block a user