mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 18:08:05 +02:00
cli: move completion for master connections to meta data
This change (improves) behavior. Before, we would only complete if (g_strcmp0 (con_type, nmc_tab_completion.con_type) != 0) which doesn't really make sense as it depends on the slave-type, not nmc_tab_completion.con_type.
This commit is contained in:
parent
1e4bc51a4a
commit
2a760897f2
6 changed files with 123 additions and 48 deletions
|
|
@ -3346,10 +3346,14 @@ _meta_abstract_complete (const NMMetaAbstractInfo *abstract_info, const char *te
|
|||
{
|
||||
const char *const*values;
|
||||
char **values_to_free = NULL;
|
||||
const NMMetaOperationContext ctx = {
|
||||
.connection = nmc_tab_completion.connection,
|
||||
};
|
||||
|
||||
values = nm_meta_abstract_info_complete (abstract_info,
|
||||
nmc_meta_environment,
|
||||
nmc_meta_environment_arg,
|
||||
&ctx,
|
||||
text,
|
||||
&values_to_free);
|
||||
if (values)
|
||||
|
|
@ -3717,42 +3721,6 @@ gen_func_bond_lacp_rate (const char *text, int state)
|
|||
return nmc_rl_gen_func_basic (text, state, words);
|
||||
}
|
||||
|
||||
static char *
|
||||
gen_func_master_ifnames (const char *text, int state)
|
||||
{
|
||||
int i;
|
||||
GPtrArray *ifnames;
|
||||
char *ret;
|
||||
NMConnection *con;
|
||||
NMSettingConnection *s_con;
|
||||
const char *con_type, *ifname;
|
||||
const GPtrArray *connections;
|
||||
|
||||
connections = nm_client_get_connections (nm_cli.client);
|
||||
|
||||
/* Disable appending space after completion */
|
||||
rl_completion_append_character = '\0';
|
||||
|
||||
ifnames = g_ptr_array_sized_new (20);
|
||||
for (i = 0; i < connections->len; i++) {
|
||||
con = NM_CONNECTION (connections->pdata[i]);
|
||||
s_con = nm_connection_get_setting_connection (con);
|
||||
g_assert (s_con);
|
||||
con_type = nm_setting_connection_get_connection_type (s_con);
|
||||
if (g_strcmp0 (con_type, nmc_tab_completion.con_type) != 0)
|
||||
continue;
|
||||
ifname = nm_connection_get_interface_name (con);
|
||||
g_ptr_array_add (ifnames, (gpointer) ifname);
|
||||
}
|
||||
g_ptr_array_add (ifnames, (gpointer) NULL);
|
||||
|
||||
ret = nmc_rl_gen_func_basic (text, state, (const char **) ifnames->pdata);
|
||||
|
||||
g_ptr_array_free (ifnames, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
static gboolean
|
||||
|
|
@ -4036,7 +4004,7 @@ _meta_abstract_get_option_info (const NMMetaAbstractInfo *abstract_info)
|
|||
}
|
||||
OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_TYPE, "type", set_connection_type, gen_connection_types),
|
||||
OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_INTERFACE_NAME, "ifname", set_connection_iface, NULL),
|
||||
OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, gen_func_master_ifnames),
|
||||
OPTION_INFO (CONNECTION, NM_SETTING_CONNECTION_MASTER, "master", set_connection_master, NULL),
|
||||
OPTION_INFO (BLUETOOTH, NM_SETTING_BLUETOOTH_TYPE, "bt-type", set_bluetooth_type, gen_func_bt_type),
|
||||
OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "mode", set_bond_option, gen_func_bond_mode),
|
||||
OPTION_INFO (BOND, NM_SETTING_BOND_OPTIONS, "primary", set_bond_option, nmc_rl_gen_func_ifnames),
|
||||
|
|
@ -4164,15 +4132,19 @@ run_rl_generator (rl_compentry_func_t *generator_func, const char *prefix)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix)
|
||||
complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix, NMConnection *context_connection)
|
||||
{
|
||||
const OptionInfo *candidate;
|
||||
const char *const*values;
|
||||
gs_strfreev char **values_to_free = NULL;
|
||||
const NMMetaOperationContext ctx = {
|
||||
.connection = context_connection,
|
||||
};
|
||||
|
||||
values = nm_meta_abstract_info_complete (abstract_info,
|
||||
nmc_meta_environment,
|
||||
nmc_meta_environment_arg,
|
||||
&ctx,
|
||||
prefix,
|
||||
&values_to_free);
|
||||
if (values) {
|
||||
|
|
@ -4191,21 +4163,19 @@ complete_option (const NMMetaAbstractInfo *abstract_info, const gchar *prefix)
|
|||
}
|
||||
|
||||
static void
|
||||
complete_property (const gchar *setting_name, const gchar *property, const gchar *prefix)
|
||||
complete_property (const gchar *setting_name, const gchar *property, const gchar *prefix, NMConnection *connection)
|
||||
{
|
||||
const NMMetaPropertyInfo *property_info;
|
||||
|
||||
property_info = nm_meta_property_info_find_by_name (setting_name, property);
|
||||
if (property_info) {
|
||||
if (complete_option ((const NMMetaAbstractInfo *) property_info, prefix))
|
||||
if (complete_option ((const NMMetaAbstractInfo *) property_info, prefix, connection))
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp (setting_name, NM_SETTING_CONNECTION_SETTING_NAME) == 0) {
|
||||
if (strcmp (property, NM_SETTING_CONNECTION_TYPE) == 0)
|
||||
run_rl_generator (gen_connection_types, prefix);
|
||||
else if (strcmp (property, NM_SETTING_CONNECTION_MASTER) == 0)
|
||||
run_rl_generator (gen_func_master_ifnames, prefix);
|
||||
} else if ( strcmp (setting_name, NM_SETTING_BLUETOOTH_SETTING_NAME) == 0
|
||||
&& strcmp (property, NM_SETTING_BLUETOOTH_TYPE) == 0)
|
||||
run_rl_generator (gen_func_bt_type, prefix);
|
||||
|
|
@ -4299,7 +4269,7 @@ nmc_read_connection_properties (NmCli *nmc,
|
|||
return FALSE;
|
||||
|
||||
if (!*argc && nmc->complete)
|
||||
complete_property (setting, strv[1], value ? value : "");
|
||||
complete_property (setting, strv[1], value ? value : "", connection);
|
||||
|
||||
if (!set_property (connection, setting_name, strv[1], value, modifier, error))
|
||||
return FALSE;
|
||||
|
|
@ -4378,7 +4348,7 @@ nmc_read_connection_properties (NmCli *nmc,
|
|||
return FALSE;
|
||||
|
||||
if (!*argc && nmc->complete)
|
||||
complete_option (chosen, value ? value : "");
|
||||
complete_option (chosen, value ? value : "", connection);
|
||||
|
||||
if (!set_option (nmc, connection, chosen, value, error))
|
||||
return FALSE;
|
||||
|
|
@ -4513,8 +4483,6 @@ nmcli_con_add_tab_completion (const char *text, int start, int end)
|
|||
next:
|
||||
if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_CON_TYPE))
|
||||
generator_func = gen_connection_types;
|
||||
else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_MASTER))
|
||||
generator_func = gen_func_master_ifnames;
|
||||
else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BT_TYPE))
|
||||
generator_func = gen_func_bt_type;
|
||||
else if (g_str_has_prefix (rl_prompt, NM_META_TEXT_PROMPT_BOND_MODE))
|
||||
|
|
@ -8422,7 +8390,7 @@ do_connection_import (NmCli *nmc, int argc, char **argv)
|
|||
}
|
||||
|
||||
if (argc == 1 && nmc->complete)
|
||||
complete_option ((const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, *argv);
|
||||
complete_option ((const NMMetaAbstractInfo *) nm_meta_property_info_vpn_service_type, *argv, NULL);
|
||||
|
||||
if (!type)
|
||||
type = *argv;
|
||||
|
|
|
|||
|
|
@ -480,11 +480,36 @@ _env_get_nm_devices (const NMMetaEnvironment *environment,
|
|||
return (NMDevice *const*) devices->pdata;
|
||||
}
|
||||
|
||||
static NMRemoteConnection *const*
|
||||
_env_get_nm_connections (const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
guint *out_len)
|
||||
{
|
||||
NmCli *nmc = environment_user_data;
|
||||
const GPtrArray *values;
|
||||
|
||||
nm_assert (nmc);
|
||||
|
||||
/* the returned list is *not* NULL terminated. Need to
|
||||
* provide and honor the out_len argument. */
|
||||
nm_assert (out_len);
|
||||
|
||||
values = nm_client_get_connections (nmc->client);
|
||||
if (!values) {
|
||||
*out_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*out_len = values->len;
|
||||
return (NMRemoteConnection *const*) values->pdata;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const NMMetaEnvironment *const nmc_meta_environment = &((NMMetaEnvironment) {
|
||||
.warn_fcn = _env_warn_fcn_handle,
|
||||
.get_nm_devices = _env_get_nm_devices,
|
||||
.get_nm_connections = _env_get_nm_connections,
|
||||
});
|
||||
|
||||
NmCli *const nmc_meta_environment_arg = &nm_cli;
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ const char *const*
|
|||
nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info,
|
||||
const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
const NMMetaOperationContext *operation_context,
|
||||
const char *text,
|
||||
char ***out_to_free)
|
||||
{
|
||||
|
|
@ -281,6 +282,7 @@ nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info,
|
|||
values = abstract_info->meta_type->complete_fcn (abstract_info,
|
||||
environment,
|
||||
environment_user_data,
|
||||
operation_context,
|
||||
text,
|
||||
out_to_free);
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ gconstpointer nm_meta_abstract_info_get (const NMMetaAbstractInfo *abstract_info
|
|||
const char *const*nm_meta_abstract_info_complete (const NMMetaAbstractInfo *abstract_info,
|
||||
const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
const NMMetaOperationContext *operation_context,
|
||||
const char *text,
|
||||
char ***out_to_free);
|
||||
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ _env_warn_fcn (const NMMetaEnvironment *environment,
|
|||
const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, NMSetting *setting, const char *value, guint32 idx, GError **error
|
||||
|
||||
#define ARGS_COMPLETE_FCN \
|
||||
const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const char *text, char ***out_to_free
|
||||
const NMMetaPropertyInfo *property_info, const NMMetaEnvironment *environment, gpointer environment_user_data, const NMMetaOperationContext *operation_context, const char *text, char ***out_to_free
|
||||
|
||||
#define ARGS_VALUES_FCN \
|
||||
const NMMetaPropertyInfo *property_info, char ***out_to_free
|
||||
|
|
@ -2359,6 +2359,68 @@ _set_fcn_connection_master (ARGS_SET_FCN)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static const char *const*
|
||||
_complete_fcn_connection_master (ARGS_COMPLETE_FCN)
|
||||
{
|
||||
NMRemoteConnection *const*connections = NULL;
|
||||
guint len = 0;
|
||||
guint i, j;
|
||||
char **result;
|
||||
NMSettingConnection *s_con;
|
||||
const char *expected_type = NULL;
|
||||
gsize text_len;
|
||||
|
||||
if ( environment
|
||||
&& environment->get_nm_connections) {
|
||||
connections = environment->get_nm_connections (environment,
|
||||
environment_user_data,
|
||||
&len);
|
||||
}
|
||||
if (!len)
|
||||
return NULL;
|
||||
|
||||
if ( (!text || !*text)
|
||||
&& operation_context
|
||||
&& operation_context->connection) {
|
||||
/* if we have no text yet, initially only complete for matching
|
||||
* slave-type. */
|
||||
s_con = nm_connection_get_setting_connection (operation_context->connection);
|
||||
if (s_con)
|
||||
expected_type = nm_setting_connection_get_slave_type (s_con);
|
||||
}
|
||||
|
||||
text_len = strlen (text);
|
||||
|
||||
result = g_new (char *, (2 * len) + 1);
|
||||
for (i = 0, j = 0; i < len; i++) {
|
||||
const char *v;
|
||||
|
||||
s_con = nm_connection_get_setting_connection (NM_CONNECTION (connections[i]));
|
||||
if (!s_con)
|
||||
continue;
|
||||
|
||||
if ( expected_type
|
||||
&& !nm_streq0 (nm_setting_connection_get_connection_type (s_con),
|
||||
expected_type))
|
||||
continue;
|
||||
|
||||
if (text && text[0]) {
|
||||
/* if we have text, also complete for the UUID. */
|
||||
v = nm_setting_connection_get_uuid (s_con);
|
||||
if (v && (!text || strncmp (text, v, text_len) == 0))
|
||||
result[j++] = g_strdup (v);
|
||||
}
|
||||
|
||||
v = nm_setting_connection_get_interface_name (s_con);
|
||||
if (v && (!text || strncmp (text, v, text_len) == 0))
|
||||
result[j++] = g_strdup (v);
|
||||
}
|
||||
result[j++] = NULL;
|
||||
|
||||
*out_to_free = NULL;
|
||||
return (const char *const*) result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_fcn_connection_secondaries (ARGS_SET_FCN)
|
||||
{
|
||||
|
|
@ -5452,6 +5514,7 @@ static const NMMetaPropertyInfo property_infos_CONNECTION[] = {
|
|||
.property_type = DEFINE_PROPERTY_TYPE (
|
||||
.get_fcn = _get_fcn_gobject,
|
||||
.set_fcn = _set_fcn_connection_master,
|
||||
.complete_fcn = _complete_fcn_connection_master,
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -7510,6 +7573,7 @@ static const char *const*
|
|||
_meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info,
|
||||
const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
const NMMetaOperationContext *operation_context,
|
||||
const char *text,
|
||||
char ***out_to_free)
|
||||
{
|
||||
|
|
@ -7521,6 +7585,7 @@ _meta_type_property_info_complete_fcn (const NMMetaAbstractInfo *abstract_info,
|
|||
return info->property_type->complete_fcn (info,
|
||||
environment,
|
||||
environment_user_data,
|
||||
operation_context,
|
||||
text,
|
||||
out_to_free);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,6 +168,14 @@ typedef struct _NMMetaSettingInfoEditor NMMetaSettingInfoEditor;
|
|||
typedef struct _NMMetaPropertyInfo NMMetaPropertyInfo;
|
||||
typedef struct _NMMetaPropertyType NMMetaPropertyType;
|
||||
typedef struct _NMMetaPropertyTypData NMMetaPropertyTypData;
|
||||
typedef struct _NMMetaOperationContext NMMetaOperationContext;
|
||||
|
||||
/* this gives some context information for virtual functions.
|
||||
* This command actually violates layering, and should be considered
|
||||
* a hack. In the future, try to replace it's use. */
|
||||
struct _NMMetaOperationContext {
|
||||
NMConnection *connection;
|
||||
};
|
||||
|
||||
struct _NMMetaPropertyType {
|
||||
|
||||
|
|
@ -201,6 +209,7 @@ struct _NMMetaPropertyType {
|
|||
const char *const*(*complete_fcn) (const NMMetaPropertyInfo *property_info,
|
||||
const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
const NMMetaOperationContext *operation_context,
|
||||
const char *text,
|
||||
char ***out_to_free);
|
||||
};
|
||||
|
|
@ -319,6 +328,7 @@ struct _NMMetaType {
|
|||
const char *const*(*complete_fcn) (const NMMetaAbstractInfo *info,
|
||||
const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
const NMMetaOperationContext *operation_context,
|
||||
const char *text,
|
||||
char ***out_to_free);
|
||||
};
|
||||
|
|
@ -359,6 +369,10 @@ struct _NMMetaEnvironment {
|
|||
gpointer environment_user_data,
|
||||
guint *out_len);
|
||||
|
||||
struct _NMRemoteConnection *const*(*get_nm_connections) (const NMMetaEnvironment *environment,
|
||||
gpointer environment_user_data,
|
||||
guint *out_len);
|
||||
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue