cli: complete file names for properties whose value is a file name

Note:
Tilde expansion is enabled, so ~/abc<TAB> expands the string to /home/joe/abc.
However, when user did not use the completion and typed "~/myfile" manually,
the path could not be opened.

nmcli 802-1x.ca-cert> set ~/newca.crt
Error: failed to set 'ca-cert' property: Failed to open file '~/newca.crt': No such file or directory
This commit is contained in:
Jiří Klimeš
2013-10-03 20:20:58 +02:00
parent a3c06afc12
commit cdec23d314

View File

@@ -4588,6 +4588,7 @@ typedef struct {
char **rl_line_buffer_x;
char **rl_prompt_x;
int *rl_attempted_completion_over_x;
int *rl_complete_with_tilde_expansion_x;
int *rl_completion_append_character_x;
const char **rl_completer_word_break_characters_x;
void (*rl_free_line_state_func) (void);
@@ -4905,6 +4906,63 @@ should_complete_cmd (const char *line, int end, const char *cmd,
return ret;
}
static gboolean
should_complete_files (const char *prompt, const char *line)
{
char *prop = NULL;
gboolean found = FALSE;
const char *file_properties[] = {
/* '802-1x' properties */
"ca-cert",
"ca-path",
"client-cert",
"pac-file",
"phase2-ca-cert",
"phase2-ca-path",
"phase2-client-cert",
"private-key",
"phase2-private-key",
/* 'team' and 'team-port' properties */
"config",
NULL
};
/* If prompt is set take the property name from it, else extract it from line */
if (!prompt) {
const char *p1;
size_t num;
p1 = strchr (line, '.');
if (p1) {
p1++;
} else {
size_t n1, n2, n3;
n1 = strspn (line, " \t");
n2 = strcspn (line+n1, " \t\0") + n1;
n3 = strspn (line+n2, " \t") + n2;
p1 = line + n3;
}
num = strcspn (p1, " \t\0");
prop = g_strndup (p1, num);
} else {
const char *p1, *dot;
size_t num;
p1 = strchr (prompt, ' ');
/* prompt looks like this: "nmcli 802-1x>" or "nmcli 802-1x.pac-file>" */
if (p1) {
dot = strchr (p1 + 1, '.');
p1 = dot ? dot + 1 : p1;
num = strcspn (p1, ">");
prop = g_strndup (p1, num);
}
}
if (prop) {
found = !!nmc_string_is_valid (prop, file_properties, NULL);
g_free (prop);
}
return found;
}
/*
* Attempt to complete on the contents of TEXT. START and END show the
* region of TEXT that contains the word to complete. We can use the
@@ -4928,6 +4986,12 @@ nmcli_editor_tab_completion (char *text, int start, int end)
/* Restore standard append character to space */
*edit_lib_symbols.rl_completion_append_character_x = ' ';
/* Disable default filename completion */
*edit_lib_symbols.rl_attempted_completion_over_x = 1;
/* Enable tilde expansion when filenames are completed */
*edit_lib_symbols.rl_complete_with_tilde_expansion_x = 1;
/* Filter out possible ANSI color escape sequences */
p1 = prompt;
p2 = prompt_tmp = g_strdup (prompt);
@@ -4967,8 +5031,17 @@ nmcli_editor_tab_completion (char *text, int start, int end)
generator_func = gen_setting_names;
else
generator_func = gen_property_names;
} else if ( ( should_complete_cmd (line, end, "set", &num, NULL)
|| should_complete_cmd (line, end, "remove", &num, NULL)
} else if (should_complete_cmd (line, end, "set", &num, NULL)) {
if (num < 3) {
if (level == 0 && (!dot || dot >= line + end)) {
generator_func = gen_setting_names;
*edit_lib_symbols.rl_completion_append_character_x = '.';
} else
generator_func = gen_property_names;
} else if (num == 3 && should_complete_files (NULL, line)) {
*edit_lib_symbols.rl_attempted_completion_over_x = 0;
}
} else if ( ( should_complete_cmd (line, end, "remove", &num, NULL)
|| should_complete_cmd (line, end, "describe", &num, NULL))
&& num <= 2) {
if (level == 0 && (!dot || dot >= line + end)) {
@@ -4995,6 +5068,11 @@ nmcli_editor_tab_completion (char *text, int start, int end)
if (start == n1)
generator_func = gen_nmcli_cmds_submenu;
else {
if ( should_complete_cmd (line, end, "add", &num, NULL)
|| should_complete_cmd (line, end, "set", &num, NULL)) {
if (num <= 2 && should_complete_files (prompt_tmp, line))
*edit_lib_symbols.rl_attempted_completion_over_x = 0;
}
if (should_complete_cmd (line, end, "print", &num, NULL) && num <= 2)
generator_func = gen_cmd_print2;
else if (should_complete_cmd (line, end, "help", &num, NULL) && num <= 2)
@@ -5006,10 +5084,6 @@ nmcli_editor_tab_completion (char *text, int start, int end)
if (generator_func)
match_array = edit_lib_symbols.completion_matches_func (text, generator_func);
/* Disable default filename completion */
if (!match_array)
*edit_lib_symbols.rl_attempted_completion_over_x = 1;
g_free (prompt_tmp);
g_free (word);
return match_array;
@@ -5063,6 +5137,9 @@ load_cmd_line_edit_lib (void)
if (!g_module_symbol (module, "rl_attempted_completion_over",
(gpointer) (&edit_lib_symbols.rl_attempted_completion_over_x)))
goto error;
if (!g_module_symbol (module, "rl_complete_with_tilde_expansion",
(gpointer) (&edit_lib_symbols.rl_complete_with_tilde_expansion_x)))
goto error;
if (!g_module_symbol (module, "rl_completion_append_character",
(gpointer) (&edit_lib_symbols.rl_completion_append_character_x)))
goto error;