diff options
author | Jiří Klimeš <jklimes@redhat.com> | 2013-10-03 20:20:58 +0200 |
---|---|---|
committer | Jiří Klimeš <jklimes@redhat.com> | 2013-11-22 14:09:10 +0100 |
commit | cdec23d314347acbd2bdbe8d79de9cd2f5e164e4 (patch) | |
tree | 0229c2679cb8123c32a42228f8d83b6c11249d34 | |
parent | a3c06afc12e0cab6e09ec32139fa5cb0d4d98e2d (diff) | |
download | NetworkManager-cdec23d314347acbd2bdbe8d79de9cd2f5e164e4.tar.gz |
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
-rw-r--r-- | cli/src/connections.c | 89 |
1 files changed, 83 insertions, 6 deletions
diff --git a/cli/src/connections.c b/cli/src/connections.c index 05b3d3435b..fc4b10a300 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -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; |