1
1

Merge branch '55_filename_complete'

* 55_filename_complete:
  lib/widget/input_complete.c: minor refactoring and optimization.
  Fix for input completions with spaces in names.
  lib/widget/input_complete.c: refactoring:
  Concretize the usage of autocompliting in different input fields.
  Extend QUICK_INPUT and QUICK_LABELED_INPUT macros for getting completion flags via parameters instead of using hardcoded value
  Ticket #55: savannah: tab completion vs. spaces and escaping
Этот коммит содержится в:
Slava Zanko 2013-02-04 15:52:02 +03:00
родитель 74d71e7523 0608af276e
Коммит 0501ac9ba6
28 изменённых файлов: 742 добавлений и 372 удалений

Просмотреть файл

@ -644,6 +644,7 @@ tests/lib/Makefile
tests/lib/mcconfig/Makefile tests/lib/mcconfig/Makefile
tests/lib/search/Makefile tests/lib/search/Makefile
tests/lib/vfs/Makefile tests/lib/vfs/Makefile
tests/lib/widget/Makefile
tests/src/Makefile tests/src/Makefile
tests/src/filemanager/Makefile tests/src/filemanager/Makefile
]) ])

Просмотреть файл

@ -349,7 +349,8 @@ vfs_die (const char *m)
char * char *
vfs_get_password (const char *msg) vfs_get_password (const char *msg)
{ {
return input_dialog (msg, _("Password:"), MC_HISTORY_VFS_PASSWORD, INPUT_PASSWORD); return input_dialog (msg, _("Password:"), MC_HISTORY_VFS_PASSWORD, INPUT_PASSWORD,
INPUT_COMPLETE_NONE);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

Просмотреть файл

@ -29,6 +29,7 @@ typedef enum
/* completion flags */ /* completion flags */
typedef enum typedef enum
{ {
INPUT_COMPLETE_NONE = 0,
INPUT_COMPLETE_FILENAMES = 1 << 0, INPUT_COMPLETE_FILENAMES = 1 << 0,
INPUT_COMPLETE_HOSTNAMES = 1 << 1, INPUT_COMPLETE_HOSTNAMES = 1 << 1,
INPUT_COMPLETE_COMMANDS = 1 << 2, INPUT_COMPLETE_COMMANDS = 1 << 2,
@ -36,9 +37,6 @@ typedef enum
INPUT_COMPLETE_USERNAMES = 1 << 4, INPUT_COMPLETE_USERNAMES = 1 << 4,
INPUT_COMPLETE_CD = 1 << 5, INPUT_COMPLETE_CD = 1 << 5,
INPUT_COMPLETE_SHELL_ESC = 1 << 6, INPUT_COMPLETE_SHELL_ESC = 1 << 6,
INPUT_COMPLETE_DEFAULT = INPUT_COMPLETE_FILENAMES
| INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
} input_complete_t; } input_complete_t;
/*** structures declarations (and typedefs of structures)*****************************************/ /*** structures declarations (and typedefs of structures)*****************************************/

Просмотреть файл

@ -3,11 +3,12 @@
(Let mc type for you...) (Let mc type for you...)
Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2007, 2011 2007, 2011, 2013
the Free Software Foundation, Inc. the Free Software Foundation, Inc.
Written by: Written by:
Jakub Jelinek, 1995 Jakub Jelinek, 1995
Slava Zanko <slavazanko@gmail.com>, 2013
This file is part of the Midnight Commander. This file is part of the Midnight Commander.
@ -79,6 +80,17 @@ extern char **environ;
typedef char *CompletionFunction (const char *text, int state, input_complete_t flags); typedef char *CompletionFunction (const char *text, int state, input_complete_t flags);
typedef struct
{
size_t in_command_position;
char *word;
char *p;
char *q;
char *r;
gboolean is_cd;
input_complete_t flags;
} try_complete_automation_state_t;
/*** file scope variables ************************************************************************/ /*** file scope variables ************************************************************************/
static char **hosts = NULL; static char **hosts = NULL;
@ -94,6 +106,9 @@ static int end = 0;
/*** file scope functions ************************************************************************/ /*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
char **try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags);
void complete_engine_fill_completions (WInput * in);
#ifdef DO_COMPLETION_DEBUG #ifdef DO_COMPLETION_DEBUG
/** /**
* Useful to print/debug completion flags * Useful to print/debug completion flags
@ -265,32 +280,25 @@ filename_completion_function (const char *text, int state, input_complete_t flag
users_dirname = NULL; users_dirname = NULL;
return NULL; return NULL;
} }
else
{ {
char *temp; GString *temp;
if (users_dirname && (users_dirname[0] != '.' || users_dirname[1])) temp = g_string_sized_new (16);
if (users_dirname != NULL && (users_dirname[0] != '.' || users_dirname[1] != '\0'))
{ {
size_t dirlen = strlen (users_dirname); g_string_append (temp, users_dirname);
temp = g_malloc (3 + dirlen + NLENGTH (entry));
strcpy (temp, users_dirname);
/* We need a `/' at the end. */ /* We need a `/' at the end. */
if (users_dirname[dirlen - 1] != PATH_SEP) if (temp->str[temp->len - 1] != PATH_SEP)
{ g_string_append_c (temp, PATH_SEP);
temp[dirlen] = PATH_SEP;
temp[dirlen + 1] = '\0';
}
strcat (temp, entry->d_name);
}
else
{
temp = g_malloc (2 + NLENGTH (entry));
strcpy (temp, entry->d_name);
} }
g_string_append (temp, entry->d_name);
if (isdir) if (isdir)
strcat (temp, PATH_SEP_STR); g_string_append_c (temp, PATH_SEP);
return temp; return g_string_free (temp, FALSE);
} }
} }
@ -338,7 +346,8 @@ static char *
variable_completion_function (const char *text, int state, input_complete_t flags) variable_completion_function (const char *text, int state, input_complete_t flags)
{ {
static char **env_p; static char **env_p;
static int varlen, isbrace; static unsigned int isbrace;
static size_t varlen;
const char *p = NULL; const char *p = NULL;
(void) flags; (void) flags;
@ -346,7 +355,7 @@ variable_completion_function (const char *text, int state, input_complete_t flag
if (state == 0) if (state == 0)
{ /* Initialization stuff */ { /* Initialization stuff */
isbrace = (text[1] == '{'); isbrace = (text[1] == '{') ? 1 : 0;
varlen = strlen (text + 1 + isbrace); varlen = strlen (text + 1 + isbrace);
env_p = environ; env_p = environ;
} }
@ -354,7 +363,7 @@ variable_completion_function (const char *text, int state, input_complete_t flag
while (*env_p) while (*env_p)
{ {
p = strchr (*env_p, '='); p = strchr (*env_p, '=');
if (p && p - *env_p >= varlen && !strncmp (text + 1 + isbrace, *env_p, varlen)) if (p && ((size_t) (p - *env_p) >= varlen) && !strncmp (text + 1 + isbrace, *env_p, varlen))
break; break;
env_p++; env_p++;
} }
@ -363,18 +372,20 @@ variable_completion_function (const char *text, int state, input_complete_t flag
return NULL; return NULL;
{ {
char *temp = g_malloc (2 + 2 * isbrace + p - *env_p); GString *temp;
temp = g_string_new_len (*env_p, p - *env_p);
if (isbrace != 0)
{
g_string_prepend_c (temp, '{');
g_string_append_c (temp, '}');
}
g_string_prepend_c (temp, '$');
*temp = '$';
if (isbrace)
temp[1] = '{';
memcpy (temp + 1 + isbrace, *env_p, p - *env_p);
if (isbrace)
strcpy (temp + 2 + (p - *env_p), "}");
else
temp[1 + p - *env_p] = 0;
env_p++; env_p++;
return temp;
return g_string_free (temp, FALSE);
} }
} }
@ -441,10 +452,11 @@ fetch_hosts (const char *filename)
if (hosts_p - hosts >= hosts_alloclen) if (hosts_p - hosts >= hosts_alloclen)
{ {
int j = hosts_p - hosts; int j;
hosts = j = hosts_p - hosts;
g_realloc ((void *) hosts, ((hosts_alloclen += 30) + 1) * sizeof (char *)); hosts_alloclen += 30;
hosts = g_renew (char *, hosts, hosts_alloclen + 1);
hosts_p = hosts + j; hosts_p = hosts + j;
} }
for (host_p = hosts; host_p < hosts_p; host_p++) for (host_p = hosts; host_p < hosts_p; host_p++)
@ -469,56 +481,54 @@ static char *
hostname_completion_function (const char *text, int state, input_complete_t flags) hostname_completion_function (const char *text, int state, input_complete_t flags)
{ {
static char **host_p; static char **host_p;
static int textstart, textlen; static unsigned int textstart;
static size_t textlen;
(void) flags; (void) flags;
SHOW_C_CTX ("hostname_completion_function"); SHOW_C_CTX ("hostname_completion_function");
if (!state) if (state == 0)
{ /* Initialization stuff */ { /* Initialization stuff */
const char *p; const char *p;
if (hosts != NULL) g_strfreev (hosts);
{ hosts_alloclen = 30;
for (host_p = hosts; *host_p; host_p++) hosts = g_new (char *, hosts_alloclen + 1);
g_free (*host_p);
g_free (hosts);
}
hosts = g_new (char *, (hosts_alloclen = 30) + 1);
*hosts = NULL; *hosts = NULL;
hosts_p = hosts; hosts_p = hosts;
fetch_hosts ((p = getenv ("HOSTFILE")) ? p : "/etc/hosts"); p = getenv ("HOSTFILE");
fetch_hosts (p != NULL ? p : "/etc/hosts");
host_p = hosts; host_p = hosts;
textstart = (*text == '@') ? 1 : 0; textstart = (*text == '@') ? 1 : 0;
textlen = strlen (text + textstart); textlen = strlen (text + textstart);
} }
while (*host_p) for (; *host_p != NULL; host_p++)
{ {
if (!textlen) if (textlen == 0)
break; /* Match all of them */ break; /* Match all of them */
else if (!strncmp (text + textstart, *host_p, textlen)) if (strncmp (text + textstart, *host_p, textlen) == 0)
break; break;
host_p++;
} }
if (!*host_p) if (*host_p == NULL)
{ {
for (host_p = hosts; *host_p; host_p++) g_strfreev (hosts);
g_free (*host_p);
g_free (hosts);
hosts = NULL; hosts = NULL;
return NULL; return NULL;
} }
else
{
char *temp = g_malloc (2 + strlen (*host_p));
if (textstart) {
*temp = '@'; GString *temp;
strcpy (temp + textstart, *host_p);
temp = g_string_sized_new (8);
if (textstart != 0)
g_string_append_c (temp, '@');
g_string_append (temp, *host_p);
host_p++; host_p++;
return temp;
return g_string_free (temp, FALSE);
} }
} }
@ -598,6 +608,7 @@ command_completion_function (const char *_text, int state, input_complete_t flag
if (p != NULL) if (p != NULL)
{ {
char *temp_p = p; char *temp_p = p;
p = strutils_shell_escape (p); p = strutils_shell_escape (p);
g_free (temp_p); g_free (temp_p);
} }
@ -610,27 +621,21 @@ command_completion_function (const char *_text, int state, input_complete_t flag
switch (phase) switch (phase)
{ {
case 0: /* Reserved words */ case 0: /* Reserved words */
while (*words) for (; *words != NULL; words++)
{
if (strncmp (*words, text, text_len) == 0) if (strncmp (*words, text, text_len) == 0)
{ {
g_free (text); g_free (text);
return g_strdup (*(words++)); return g_strdup (*(words++));
} }
words++;
}
phase++; phase++;
words = bash_builtins; words = bash_builtins;
case 1: /* Builtin commands */ case 1: /* Builtin commands */
while (*words) for (; *words != NULL; words++)
{
if (strncmp (*words, text, text_len) == 0) if (strncmp (*words, text, text_len) == 0)
{ {
g_free (text); g_free (text);
return g_strdup (*(words++)); return g_strdup (*(words++));
} }
words++;
}
phase++; phase++;
if (!path) if (!path)
break; break;
@ -702,24 +707,25 @@ static char **
completion_matches (const char *text, CompletionFunction entry_function, input_complete_t flags) completion_matches (const char *text, CompletionFunction entry_function, input_complete_t flags)
{ {
/* Number of slots in match_list. */ /* Number of slots in match_list. */
int match_list_size; size_t match_list_size = 30;
/* The list of matches. */ /* The list of matches. */
char **match_list = g_new (char *, (match_list_size = 30) + 1); char **match_list;
/* Number of matches actually found. */ /* Number of matches actually found. */
int matches = 0; size_t matches = 0;
/* Temporary string binder. */ /* Temporary string binder. */
char *string; char *string;
match_list = g_new (char *, match_list_size + 1);
match_list[1] = NULL; match_list[1] = NULL;
while ((string = (*entry_function) (text, matches, flags)) != NULL) while ((string = (*entry_function) (text, matches, flags)) != NULL)
{ {
if (matches + 1 == match_list_size) if (matches + 1 == match_list_size)
match_list = {
(char **) g_realloc (match_list, ((match_list_size += 30) + 1) * sizeof (char *)); match_list_size += 30;
match_list = (char **) g_renew (char *, match_list, match_list_size + 1);
}
match_list[++matches] = string; match_list[++matches] = string;
match_list[matches + 1] = NULL; match_list[matches + 1] = NULL;
} }
@ -728,7 +734,7 @@ completion_matches (const char *text, CompletionFunction entry_function, input_c
lowest common denominator. That then becomes match_list[0]. */ lowest common denominator. That then becomes match_list[0]. */
if (matches) if (matches)
{ {
register int i = 1; register size_t i = 1;
int low = 4096; /* Count of max-matched characters. */ int low = 4096; /* Count of max-matched characters. */
/* If only one match, just use that. */ /* If only one match, just use that. */
@ -739,7 +745,7 @@ completion_matches (const char *text, CompletionFunction entry_function, input_c
} }
else else
{ {
int j; size_t j;
qsort (match_list + 1, matches, sizeof (char *), match_compare); qsort (match_list + 1, matches, sizeof (char *), match_compare);
@ -819,155 +825,114 @@ check_is_cd (const char *text, int lc_start, input_complete_t flags)
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/** Returns an array of matches, or NULL if none. */
static char ** static void
try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags) try_complete_commands_prepare (try_complete_automation_state_t * state, char *text, int *lc_start)
{ {
size_t in_command_position = 0; const char *command_separator_chars = ";|&{(`";
char *word; char *ti;
char **matches = NULL;
char *p = NULL, *q = NULL, *r = NULL;
gboolean is_cd;
SHOW_C_CTX ("try_complete"); if (*lc_start == 0)
word = g_strndup (text + *lc_start, *lc_end - *lc_start); ti = text;
else
is_cd = check_is_cd (text, *lc_start, flags);
/* Determine if this could be a command word. It is if it appears at
the start of the line (ignoring preceding whitespace), or if it
appears after a character that separates commands. And we have to
be in a INPUT_COMPLETE_COMMANDS flagged Input line. */
if (!is_cd && (flags & INPUT_COMPLETE_COMMANDS))
{ {
const char *command_separator_chars = ";|&{(`"; ti = str_get_prev_char (&text[*lc_start]);
char *ti; while (ti > text && (ti[0] == ' ' || ti[0] == '\t'))
str_prev_char (&ti);
if (*lc_start == 0)
ti = text;
else
{
ti = str_get_prev_char (&text[*lc_start]);
while (ti > text && (ti[0] == ' ' || ti[0] == '\t'))
str_prev_char (&ti);
}
if (ti == text)
in_command_position++;
else if (strchr (command_separator_chars, ti[0]) != NULL)
{
int this_char, prev_char;
in_command_position++;
if (ti != text)
{
/* Handle the two character tokens `>&', `<&', and `>|'.
We are not in a command position after one of these. */
this_char = ti[0];
prev_char = str_get_prev_char (ti)[0];
/* Quoted */
if ((this_char == '&' && (prev_char == '<' || prev_char == '>'))
|| (this_char == '|' && prev_char == '>') || (ti != text
&& str_get_prev_char (ti)[0] ==
'\\'))
in_command_position = 0;
}
}
} }
if (flags & INPUT_COMPLETE_COMMANDS) if (ti == text)
p = strrchr (word, '`'); state->in_command_position++;
if (flags & (INPUT_COMPLETE_COMMANDS | INPUT_COMPLETE_VARIABLES)) else if (strchr (command_separator_chars, ti[0]) != NULL)
{ {
q = strrchr (word, '$'); int this_char, prev_char;
state->in_command_position++;
if (ti != text)
{
/* Handle the two character tokens `>&', `<&', and `>|'.
We are not in a command position after one of these. */
this_char = ti[0];
prev_char = str_get_prev_char (ti)[0];
/* Quoted */
if ((this_char == '&' && (prev_char == '<' || prev_char == '>'))
|| (this_char == '|' && prev_char == '>') || (ti != text
&& str_get_prev_char (ti)[0] == '\\'))
state->in_command_position = 0;
}
}
}
/* --------------------------------------------------------------------------------------------- */
static void
try_complete_find_start_sign (try_complete_automation_state_t * state)
{
if (state->flags & INPUT_COMPLETE_COMMANDS)
state->p = strrchr (state->word, '`');
if (state->flags & (INPUT_COMPLETE_COMMANDS | INPUT_COMPLETE_VARIABLES))
{
state->q = strrchr (state->word, '$');
/* don't substitute variable in \$ case */ /* don't substitute variable in \$ case */
if (q != NULL && q != word && q[-1] == '\\') if (strutils_is_char_escaped (state->word, state->q))
{ {
size_t qlen; size_t qlen;
qlen = strlen (q); qlen = strlen (state->q);
/* drop '\\' */ /* drop '\\' */
memmove (q - 1, q, qlen + 1); memmove (state->q - 1, state->q, qlen + 1);
/* adjust flags */ /* adjust flags */
flags &= ~INPUT_COMPLETE_VARIABLES; state->flags &= ~INPUT_COMPLETE_VARIABLES;
q = NULL; state->q = NULL;
} }
} }
if (flags & INPUT_COMPLETE_HOSTNAMES) if (state->flags & INPUT_COMPLETE_HOSTNAMES)
r = strrchr (word, '@'); state->r = strrchr (state->word, '@');
if (q && q[1] == '(' && (flags & INPUT_COMPLETE_COMMANDS)) if (state->q && state->q[1] == '(' && (state->flags & INPUT_COMPLETE_COMMANDS))
{ {
if (q > p) if (state->q > state->p)
p = str_get_next_char (q); state->p = str_get_next_char (state->q);
q = NULL; state->q = NULL;
} }
}
/* Command substitution? */ /* --------------------------------------------------------------------------------------------- */
if (p > q && p > r)
{
SHOW_C_CTX ("try_complete:cmd_backq_subst");
matches = completion_matches (str_cget_next_char (p),
command_completion_function,
flags & (~INPUT_COMPLETE_FILENAMES));
if (matches)
*lc_start += str_get_next_char (p) - word;
}
/* Variable name? */ static char **
else if (q > p && q > r) try_complete_all_possible (try_complete_automation_state_t * state, char *text, int *lc_start)
{ {
SHOW_C_CTX ("try_complete:var_subst"); char **matches = NULL;
matches = completion_matches (q, variable_completion_function, flags);
if (matches)
*lc_start += q - word;
}
/* Starts with '@', then look through the known hostnames for if (state->in_command_position != 0)
completion first. */
else if (r > p && r > q)
{
SHOW_C_CTX ("try_complete:host_subst");
matches = completion_matches (r, hostname_completion_function, flags);
if (matches)
*lc_start += r - word;
}
/* Starts with `~' and there is no slash in the word, then
try completing this word as a username. */
if (!matches && *word == '~' && (flags & INPUT_COMPLETE_USERNAMES) && !strchr (word, PATH_SEP))
{
SHOW_C_CTX ("try_complete:user_subst");
matches = completion_matches (word, username_completion_function, flags);
}
/* And finally if this word is in a command position, then
complete over possible command names, including aliases, functions,
and command names. */
if (!matches && in_command_position != 0)
{ {
SHOW_C_CTX ("try_complete:cmd_subst"); SHOW_C_CTX ("try_complete:cmd_subst");
matches = matches =
completion_matches (word, command_completion_function, completion_matches (state->word, command_completion_function,
flags & (~INPUT_COMPLETE_FILENAMES)); state->flags & (~INPUT_COMPLETE_FILENAMES));
} }
else if ((state->flags & INPUT_COMPLETE_FILENAMES) != 0)
else if (!matches && (flags & INPUT_COMPLETE_FILENAMES))
{ {
if (is_cd) if (state->is_cd)
flags &= ~(INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_COMMANDS); state->flags &= ~(INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_COMMANDS);
SHOW_C_CTX ("try_complete:filename_subst_1"); SHOW_C_CTX ("try_complete:filename_subst_1");
matches = completion_matches (word, filename_completion_function, flags); matches = completion_matches (state->word, filename_completion_function, state->flags);
if (!matches && is_cd && *word != PATH_SEP && *word != '~')
if (matches == NULL && state->is_cd && *state->word != PATH_SEP && *state->word != '~')
{ {
q = text + *lc_start; state->q = text + *lc_start;
for (p = text; *p && p < q && (*p == ' ' || *p == '\t'); str_next_char (&p)); for (state->p = text;
if (!strncmp (p, "cd", 2)) *state->p && state->p < state->q && (*state->p == ' ' || *state->p == '\t');
for (p += 2; *p && p < q && (*p == ' ' || *p == '\t'); str_next_char (&p)); str_next_char (&state->p))
if (p == q) ;
if (!strncmp (state->p, "cd", 2))
for (state->p += 2;
*state->p && state->p < state->q && (*state->p == ' ' || *state->p == '\t');
str_next_char (&state->p))
;
if (state->p == state->q)
{ {
char *const cdpath_ref = g_strdup (getenv ("CDPATH")); char *const cdpath_ref = g_strdup (getenv ("CDPATH"));
char *cdpath = cdpath_ref; char *cdpath = cdpath_ref;
@ -986,10 +951,12 @@ try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags)
*s = 0; *s = 0;
if (*cdpath) if (*cdpath)
{ {
r = mc_build_filename (cdpath, word, NULL); state->r = mc_build_filename (cdpath, state->word, NULL);
SHOW_C_CTX ("try_complete:filename_subst_2"); SHOW_C_CTX ("try_complete:filename_subst_2");
matches = completion_matches (r, filename_completion_function, flags); matches =
g_free (r); completion_matches (state->r, filename_completion_function,
state->flags);
g_free (state->r);
} }
*s = c; *s = c;
cdpath = str_get_next_char (s); cdpath = str_get_next_char (s);
@ -998,24 +965,24 @@ try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags)
} }
} }
} }
g_free (word);
return matches; return matches;
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
static int static gboolean
insert_text (WInput * in, char *text, ssize_t size) insert_text (WInput * in, char *text, ssize_t size)
{ {
int buff_len = str_length (in->buffer); int buff_len;
buff_len = str_length (in->buffer);
size = min (size, (ssize_t) strlen (text)) + start - end; size = min (size, (ssize_t) strlen (text)) + start - end;
if (strlen (in->buffer) + size >= (size_t) in->current_max_size) if (strlen (in->buffer) + size >= (size_t) in->current_max_size)
{ {
/* Expand the buffer */ /* Expand the buffer */
char *narea = g_try_realloc (in->buffer, in->current_max_size + size + in->field_width); char *narea;
narea = g_try_realloc (in->buffer, in->current_max_size + size + in->field_width);
if (narea != NULL) if (narea != NULL)
{ {
in->buffer = narea; in->buffer = narea;
@ -1024,20 +991,9 @@ insert_text (WInput * in, char *text, ssize_t size)
} }
if (strlen (in->buffer) + 1 < (size_t) in->current_max_size) if (strlen (in->buffer) + 1 < (size_t) in->current_max_size)
{ {
if (size > 0) if (size != 0)
{ memmove (in->buffer + end + size, in->buffer + end, strlen (&in->buffer[end]) + 1);
int i = strlen (&in->buffer[end]); memmove (in->buffer + start, text, size - (start - end));
for (; i >= 0; i--)
in->buffer[end + size + i] = in->buffer[end + i];
}
else if (size < 0)
{
char *p = in->buffer + end + size, *q = in->buffer + end;
while (*q)
*(p++) = *(q++);
*p = 0;
}
memcpy (in->buffer + start, text, size - start + end);
in->point += str_length (in->buffer) - buff_len; in->point += str_length (in->buffer) - buff_len;
input_update (in, TRUE); input_update (in, TRUE);
end += size; end += size;
@ -1224,43 +1180,16 @@ query_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/** Returns 1 if the user would like to see us again */
/** Returns 1 if the user would like to see us again */
static int static int
complete_engine (WInput * in, int what_to_do) complete_engine (WInput * in, int what_to_do)
{ {
if (in->completions != NULL && str_offset_to_pos (in->buffer, in->point) != end) if (in->completions != NULL && str_offset_to_pos (in->buffer, in->point) != end)
input_free_completions (in); input_free_completions (in);
if (in->completions == NULL) if (in->completions == NULL)
{ complete_engine_fill_completions (in);
char *s;
end = str_offset_to_pos (in->buffer, in->point);
s = in->buffer;
if (in->point != 0)
{
/* get symbol before in->point */
size_t i;
for (i = in->point - 1; i > 0; i--)
str_next_char (&s);
}
for (; s >= in->buffer; str_prev_char (&s))
{
start = s - in->buffer;
if (strchr (" \t;|<>", *s) != NULL)
break;
}
if (start < end)
{
str_next_char (&s);
start = s - in->buffer;
}
in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
}
if (in->completions != NULL) if (in->completions != NULL)
{ {
@ -1356,6 +1285,120 @@ complete_engine (WInput * in, int what_to_do)
/*** public functions ****************************************************************************/ /*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/** Returns an array of matches, or NULL if none. */
char **
try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags)
{
try_complete_automation_state_t state;
char **matches = NULL;
memset (&state, 0, sizeof (try_complete_automation_state_t));
state.flags = flags;
SHOW_C_CTX ("try_complete");
state.word = g_strndup (text + *lc_start, *lc_end - *lc_start);
state.is_cd = check_is_cd (text, *lc_start, state.flags);
/* Determine if this could be a command word. It is if it appears at
the start of the line (ignoring preceding whitespace), or if it
appears after a character that separates commands. And we have to
be in a INPUT_COMPLETE_COMMANDS flagged Input line. */
if (!state.is_cd && (flags & INPUT_COMPLETE_COMMANDS))
try_complete_commands_prepare (&state, text, lc_start);
try_complete_find_start_sign (&state);
/* Command substitution? */
if (state.p > state.q && state.p > state.r)
{
SHOW_C_CTX ("try_complete:cmd_backq_subst");
matches = completion_matches (str_cget_next_char (state.p),
command_completion_function,
state.flags & (~INPUT_COMPLETE_FILENAMES));
if (matches)
*lc_start += str_get_next_char (state.p) - state.word;
}
/* Variable name? */
else if (state.q > state.p && state.q > state.r)
{
SHOW_C_CTX ("try_complete:var_subst");
matches = completion_matches (state.q, variable_completion_function, state.flags);
if (matches)
*lc_start += state.q - state.word;
}
/* Starts with '@', then look through the known hostnames for
completion first. */
else if (state.r > state.p && state.r > state.q)
{
SHOW_C_CTX ("try_complete:host_subst");
matches = completion_matches (state.r, hostname_completion_function, state.flags);
if (matches)
*lc_start += state.r - state.word;
}
/* Starts with `~' and there is no slash in the word, then
try completing this word as a username. */
if (!matches && *state.word == '~' && (state.flags & INPUT_COMPLETE_USERNAMES)
&& !strchr (state.word, PATH_SEP))
{
SHOW_C_CTX ("try_complete:user_subst");
matches = completion_matches (state.word, username_completion_function, state.flags);
}
/* And finally if this word is in a command position, then
complete over possible command names, including aliases, functions,
and command names. */
if (matches == NULL)
matches = try_complete_all_possible (&state, text, lc_start);
g_free (state.word);
return matches;
}
/* --------------------------------------------------------------------------------------------- */
void
complete_engine_fill_completions (WInput * in)
{
char *s;
const char *word_separators;
word_separators = (in->completion_flags & INPUT_COMPLETE_SHELL_ESC) ? " \t;|<>" : "\t;|<>";
end = str_offset_to_pos (in->buffer, in->point);
s = in->buffer;
if (in->point != 0)
{
/* get symbol before in->point */
size_t i;
for (i = in->point - 1; i > 0; i--)
str_next_char (&s);
}
for (; s >= in->buffer; str_prev_char (&s))
{
start = s - in->buffer;
if (strchr (word_separators, *s) != NULL && !strutils_is_char_escaped (in->buffer, s))
break;
}
if (start < end)
{
str_next_char (&s);
start = s - in->buffer;
}
in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
}
/* --------------------------------------------------------------------------------------------- */
/* declared in lib/widget/input.h */ /* declared in lib/widget/input.h */
void void
complete (WInput * in) complete (WInput * in)

Просмотреть файл

@ -72,12 +72,10 @@ quick_create_input (int y, int x, const quick_widget_t * qw)
WInput *in; WInput *in;
in = input_new (y, x, input_get_default_colors (), 8, qw->u.input.text, qw->u.input.histname, in = input_new (y, x, input_get_default_colors (), 8, qw->u.input.text, qw->u.input.histname,
INPUT_COMPLETE_DEFAULT); qw->u.input.completion_flags);
in->is_password = (qw->u.input.flags == 1);
if ((qw->u.input.flags & 2) != 0) in->is_password = qw->u.input.is_passwd;
in->completion_flags |= INPUT_COMPLETE_CD; in->strip_password = qw->u.input.strip_passwd;
if ((qw->u.input.flags & 4) != 0)
in->strip_password = TRUE;
return in; return in;
} }
@ -587,7 +585,7 @@ quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip)
break; break;
case quick_input: case quick_input:
if ((quick_widget->u.input.flags & 2) != 0) if ((quick_widget->u.input.completion_flags & INPUT_COMPLETE_CD) != 0)
*item->quick_widget->u.input.result = *item->quick_widget->u.input.result =
tilde_expand (INPUT (item->widget)->buffer); tilde_expand (INPUT (item->widget)->buffer);
else else

Просмотреть файл

@ -38,7 +38,7 @@
} \ } \
} }
#define QUICK_INPUT(txt, flags_, hname, res, id_) \ #define QUICK_INPUT(txt, hname, res, id_, is_passwd_, strip_passwd_, completion_flags_) \
{ \ { \
.widget_type = quick_input, \ .widget_type = quick_input, \
.options = 0, \ .options = 0, \
@ -50,14 +50,16 @@
.label_location = input_label_none, \ .label_location = input_label_none, \
.label = NULL, \ .label = NULL, \
.text = txt, \ .text = txt, \
.flags = flags_, \ .completion_flags = completion_flags_, \
.is_passwd = is_passwd_, \
.strip_passwd = strip_passwd_, \
.histname = hname, \ .histname = hname, \
.result = res \ .result = res \
} \ } \
} \ } \
} }
#define QUICK_LABELED_INPUT(label_, label_loc, txt, flags_, hname, res, id_) \ #define QUICK_LABELED_INPUT(label_, label_loc, txt, hname, res, id_, is_passwd_, strip_passwd_, completion_flags_) \
{ \ { \
.widget_type = quick_input, \ .widget_type = quick_input, \
.options = 0, \ .options = 0, \
@ -69,7 +71,9 @@
.label_location = label_loc, \ .label_location = label_loc, \
.label = NULL, \ .label = NULL, \
.text = txt, \ .text = txt, \
.flags = flags_, \ .completion_flags = completion_flags_, \
.is_passwd = is_passwd_, \
.strip_passwd = strip_passwd_, \
.histname = hname, \ .histname = hname, \
.result = res \ .result = res \
} \ } \
@ -127,7 +131,6 @@
.u = { \ .u = { \
.input = { \ .input = { \
.text = NULL, \ .text = NULL, \
.flags = 0, \
.histname = NULL, \ .histname = NULL, \
.result = NULL \ .result = NULL \
} \ } \
@ -157,7 +160,6 @@
.u = { \ .u = { \
.input = { \ .input = { \
.text = NULL, \ .text = NULL, \
.flags = 0, \
.histname = NULL, \ .histname = NULL, \
.result = NULL \ .result = NULL \
} \ } \
@ -173,7 +175,6 @@
.u = { \ .u = { \
.input = { \ .input = { \
.text = NULL, \ .text = NULL, \
.flags = 0, \
.histname = NULL, \ .histname = NULL, \
.result = NULL \ .result = NULL \
} \ } \
@ -189,7 +190,6 @@
.u = { \ .u = { \
.input = { \ .input = { \
.text = NULL, \ .text = NULL, \
.flags = 0, \
.histname = NULL, \ .histname = NULL, \
.result = NULL \ .result = NULL \
} \ } \
@ -224,7 +224,6 @@
.u = { \ .u = { \
.input = { \ .input = { \
.text = NULL, \ .text = NULL, \
.flags = 0, \
.histname = NULL, \ .histname = NULL, \
.result = NULL \ .result = NULL \
} \ } \
@ -295,10 +294,11 @@ struct quick_widget_t
quick_input_label_location_t label_location; quick_input_label_location_t label_location;
quick_widget_t *label; quick_widget_t *label;
const char *text; const char *text;
int flags; /* 1 -- is_password, 2 -- INPUT_COMPLETE_CD */ input_complete_t completion_flags;
gboolean is_passwd; /* TRUE -- is password */
gboolean strip_passwd;
const char *histname; const char *histname;
char **result; char **result;
gboolean strip_password;
} input; } input;
struct struct

Просмотреть файл

@ -182,11 +182,12 @@ bg_message (int dummy, int *flags, char *title, const char *text)
*/ */
static char * static char *
fg_input_dialog_help (const char *header, const char *text, const char *help, fg_input_dialog_help (const char *header, const char *text, const char *help,
const char *history_name, const char *def_text, gboolean strip_password) const char *history_name, const char *def_text, gboolean strip_password,
input_complete_t completion_flags)
{ {
char *p_text; char *p_text;
char histname[64] = "inp|"; char histname[64] = "inp|";
int flags = strip_password ? 4 : 0; gboolean is_passwd = FALSE;
char *my_str; char *my_str;
int ret; int ret;
@ -201,7 +202,7 @@ fg_input_dialog_help (const char *header, const char *text, const char *help,
and hide characters with "*". Don't save passwords in history! */ and hide characters with "*". Don't save passwords in history! */
if (def_text == INPUT_PASSWORD) if (def_text == INPUT_PASSWORD)
{ {
flags = 1; is_passwd = TRUE;
histname[3] = '\0'; histname[3] = '\0';
def_text = ""; def_text = "";
} }
@ -209,8 +210,8 @@ fg_input_dialog_help (const char *header, const char *text, const char *help,
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (p_text, input_label_above, def_text, flags, histname, &my_str, QUICK_LABELED_INPUT (p_text, input_label_above, def_text, histname, &my_str,
NULL), NULL, is_passwd, strip_password, completion_flags),
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,
QUICK_END QUICK_END
/* *INDENT-ON* */ /* *INDENT-ON* */
@ -440,7 +441,8 @@ message (int flags, const char *title, const char *text, ...)
char * char *
input_dialog_help (const char *header, const char *text, const char *help, input_dialog_help (const char *header, const char *text, const char *help,
const char *history_name, const char *def_text, gboolean strip_password) const char *history_name, const char *def_text, gboolean strip_password,
input_complete_t completion_flags)
{ {
#ifdef ENABLE_BACKGROUND #ifdef ENABLE_BACKGROUND
if (mc_global.we_are_background) if (mc_global.we_are_background)
@ -449,40 +451,45 @@ input_dialog_help (const char *header, const char *text, const char *help,
{ {
void *p; void *p;
char *(*f) (const char *, const char *, const char *, const char *, const char *, char *(*f) (const char *, const char *, const char *, const char *, const char *,
gboolean); gboolean, input_complete_t);
} func; } func;
func.f = fg_input_dialog_help; func.f = fg_input_dialog_help;
return wtools_parent_call_string (func.p, 6, return wtools_parent_call_string (func.p, 7,
strlen (header), header, strlen (text), strlen (header), header, strlen (text),
text, strlen (help), help, text, strlen (help), help,
strlen (history_name), history_name, strlen (history_name), history_name,
strlen (def_text), def_text, strlen (def_text), def_text,
sizeof (gboolean), strip_password); sizeof (gboolean), strip_password,
sizeof (input_complete_t), completion_flags);
} }
else else
#endif /* ENABLE_BACKGROUND */ #endif /* ENABLE_BACKGROUND */
return fg_input_dialog_help (header, text, help, history_name, def_text, strip_password); return fg_input_dialog_help (header, text, help, history_name, def_text, strip_password,
completion_flags);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
/** Show input dialog with default help, background safe */ /** Show input dialog with default help, background safe */
char * char *
input_dialog (const char *header, const char *text, const char *history_name, const char *def_text) input_dialog (const char *header, const char *text, const char *history_name, const char *def_text,
input_complete_t completion_flags)
{ {
return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text, FALSE); return input_dialog_help (header, text, "[Input Line Keys]", history_name, def_text, FALSE,
completion_flags);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
char * char *
input_expand_dialog (const char *header, const char *text, input_expand_dialog (const char *header, const char *text,
const char *history_name, const char *def_text) const char *history_name, const char *def_text,
input_complete_t completion_flags)
{ {
char *result; char *result;
char *expanded; char *expanded;
result = input_dialog (header, text, history_name, def_text); result = input_dialog (header, text, history_name, def_text, completion_flags);
if (result) if (result)
{ {
expanded = tilde_expand (result); expanded = tilde_expand (result);

Просмотреть файл

@ -31,11 +31,13 @@ enum
/* The input dialogs */ /* The input dialogs */
char *input_dialog (const char *header, const char *text, char *input_dialog (const char *header, const char *text,
const char *history_name, const char *def_text); const char *history_name, const char *def_text,
input_complete_t completion_flags);
char *input_dialog_help (const char *header, const char *text, const char *help, char *input_dialog_help (const char *header, const char *text, const char *help,
const char *history_name, const char *def_text, gboolean strip_password); const char *history_name, const char *def_text, gboolean strip_password,
char *input_expand_dialog (const char *header, const char *text, input_complete_t completion_flags);
const char *history_name, const char *def_text); char *input_expand_dialog (const char *header, const char *text, const char *history_name,
const char *def_text, input_complete_t completion_flags);
int query_dialog (const char *header, const char *text, int flags, int count, ...); int query_dialog (const char *header, const char *text, int flags, int count, ...);
void query_set_sel (int new_sel); void query_set_sel (int new_sel);

Просмотреть файл

@ -82,8 +82,8 @@ mcdiffview_dialog_search (WDiff * dview)
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, INPUT_LAST_TEXT,
INPUT_LAST_TEXT, 0, MC_HISTORY_SHARED_SEARCH, &exp, NULL), MC_HISTORY_SHARED_SEARCH, &exp, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_START_COLUMNS, QUICK_START_COLUMNS,
QUICK_RADIO (num_of_types, (const char **) list_of_types, QUICK_RADIO (num_of_types, (const char **) list_of_types,

Просмотреть файл

@ -2908,7 +2908,9 @@ dview_goto_cmd (WDiff * dview, diff_place_t ord)
int newline; int newline;
char *input; char *input;
input = input_dialog (_(title[ord]), _("Enter line:"), MC_HISTORY_YDIFF_GOTO_LINE, prev); input =
input_dialog (_(title[ord]), _("Enter line:"), MC_HISTORY_YDIFF_GOTO_LINE, prev,
INPUT_COMPLETE_NONE);
if (input != NULL) if (input != NULL)
{ {
const char *s = input; const char *s = input;

Просмотреть файл

@ -462,8 +462,8 @@ edit_get_save_file_as (WEdit * edit)
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (N_("Enter file name:"), input_label_above, filename, 0, "save-as", QUICK_LABELED_INPUT (N_("Enter file name:"), input_label_above, filename, "save-as",
&filename_res, NULL), &filename_res, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_LABEL (N_("Change line breaks to:"), NULL), QUICK_LABEL (N_("Change line breaks to:"), NULL),
QUICK_RADIO (LB_NAMES, lb_names, (int *) &cur_lb, NULL), QUICK_RADIO (LB_NAMES, lb_names, (int *) &cur_lb, NULL),
@ -1602,8 +1602,8 @@ edit_save_mode_cmd (void)
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_RADIO (3, str, &option_save_mode, &edit_save_mode_radio_id), QUICK_RADIO (3, str, &option_save_mode, &edit_save_mode_radio_id),
QUICK_INPUT (option_backup_ext, 0, "edit-backup-ext", &str_result, QUICK_INPUT (option_backup_ext, "edit-backup-ext", &str_result,
&edit_save_mode_input_id), &edit_save_mode_input_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_CHECKBOX (N_("Check &POSIX new line"), &option_check_nl_at_eof, NULL), QUICK_CHECKBOX (N_("Check &POSIX new line"), &option_check_nl_at_eof, NULL),
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,
@ -1897,7 +1897,8 @@ edit_repeat_macro_cmd (WEdit * edit)
long count_repeat; long count_repeat;
char *error = NULL; char *error = NULL;
f = input_dialog (_("Repeat last commands"), _("Repeat times:"), MC_HISTORY_EDIT_REPEAT, NULL); f = input_dialog (_("Repeat last commands"), _("Repeat times:"), MC_HISTORY_EDIT_REPEAT, NULL,
INPUT_COMPLETE_NONE);
if (f == NULL || *f == '\0') if (f == NULL || *f == '\0')
{ {
g_free (f); g_free (f);
@ -2063,7 +2064,8 @@ edit_load_cmd (WDialog * h)
gboolean ret = TRUE; /* possible cancel */ gboolean ret = TRUE; /* possible cancel */
exp = input_expand_dialog (_("Load"), _("Enter file name:"), exp = input_expand_dialog (_("Load"), _("Enter file name:"),
MC_HISTORY_EDIT_LOAD, INPUT_LAST_TEXT); MC_HISTORY_EDIT_LOAD, INPUT_LAST_TEXT,
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
if (exp != NULL && *exp != '\0') if (exp != NULL && *exp != '\0')
{ {
@ -3058,7 +3060,8 @@ edit_goto_cmd (WEdit * edit)
char s[32]; char s[32];
g_snprintf (s, sizeof (s), "%ld", line); g_snprintf (s, sizeof (s), "%ld", line);
f = input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE, line ? s : ""); f = input_dialog (_("Goto line"), _("Enter line:"), MC_HISTORY_EDIT_GOTO_LINE, line ? s : "",
INPUT_COMPLETE_NONE);
if (!f) if (!f)
return; return;
@ -3101,7 +3104,7 @@ edit_save_block_cmd (WEdit * edit)
tmp = mc_config_get_full_path (EDIT_CLIP_FILE); tmp = mc_config_get_full_path (EDIT_CLIP_FILE);
exp = exp =
input_expand_dialog (_("Save block"), _("Enter file name:"), input_expand_dialog (_("Save block"), _("Enter file name:"),
MC_HISTORY_EDIT_SAVE_BLOCK, tmp); MC_HISTORY_EDIT_SAVE_BLOCK, tmp, INPUT_COMPLETE_FILENAMES);
g_free (tmp); g_free (tmp);
edit_push_undo_action (edit, KEY_PRESS + edit->start_display); edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
@ -3133,7 +3136,7 @@ edit_insert_file_cmd (WEdit * edit)
tmp = mc_config_get_full_path (EDIT_CLIP_FILE); tmp = mc_config_get_full_path (EDIT_CLIP_FILE);
exp = input_expand_dialog (_("Insert file"), _("Enter file name:"), exp = input_expand_dialog (_("Insert file"), _("Enter file name:"),
MC_HISTORY_EDIT_INSERT_FILE, tmp); MC_HISTORY_EDIT_INSERT_FILE, tmp, INPUT_COMPLETE_FILENAMES);
g_free (tmp); g_free (tmp);
edit_push_undo_action (edit, KEY_PRESS + edit->start_display); edit_push_undo_action (edit, KEY_PRESS + edit->start_display);
@ -3179,7 +3182,7 @@ edit_sort_cmd (WEdit * edit)
exp = input_dialog (_("Run sort"), exp = input_dialog (_("Run sort"),
_("Enter sort options (see manpage) separated by whitespace:"), _("Enter sort options (see manpage) separated by whitespace:"),
MC_HISTORY_EDIT_SORT, (old != NULL) ? old : ""); MC_HISTORY_EDIT_SORT, (old != NULL) ? old : "", INPUT_COMPLETE_NONE);
if (!exp) if (!exp)
return 1; return 1;
@ -3241,7 +3244,10 @@ edit_ext_cmd (WEdit * edit)
exp = exp =
input_dialog (_("Paste output of external command"), input_dialog (_("Paste output of external command"),
_("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD, NULL); _("Enter shell command(s):"), MC_HISTORY_EDIT_PASTE_EXTCMD, NULL,
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
| INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS |
INPUT_COMPLETE_SHELL_ESC);
if (!exp) if (!exp)
return 1; return 1;
@ -3308,14 +3314,14 @@ edit_mail_dialog (WEdit * edit)
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABEL (N_("mail -s <subject> -c <cc> <to>"), NULL), QUICK_LABEL (N_("mail -s <subject> -c <cc> <to>"), NULL),
QUICK_LABELED_INPUT (N_("To"), input_label_above, QUICK_LABELED_INPUT (N_("To"), input_label_above,
mail_to_last != NULL ? mail_to_last : "", 0, mail_to_last != NULL ? mail_to_last : "", "mail-dlg-input-3",
"mail-dlg-input-3", &tmail_to, NULL), &tmail_to, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
QUICK_LABELED_INPUT (N_("Subject"), input_label_above, QUICK_LABELED_INPUT (N_("Subject"), input_label_above,
mail_subject_last != NULL ? mail_subject_last : "", 0, mail_subject_last != NULL ? mail_subject_last : "", "mail-dlg-input-2",
"mail-dlg-input-2", &tmail_subject, NULL), &tmail_subject, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_LABELED_INPUT (N_("Copies to"), input_label_above, QUICK_LABELED_INPUT (N_("Copies to"), input_label_above,
mail_cc_last != NULL ? mail_cc_last : "", 0, mail_cc_last != NULL ? mail_cc_last : "", "mail-dlg-input",
"mail-dlg-input", &tmail_cc, NULL), &tmail_cc, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,
QUICK_END QUICK_END
/* *INDENT-ON* */ /* *INDENT-ON* */

Просмотреть файл

@ -101,8 +101,9 @@ editcmd_dialog_search_show (WEdit * edit)
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, INPUT_LAST_TEXT,
INPUT_LAST_TEXT, 0, MC_HISTORY_SHARED_SEARCH, &search_text, NULL), MC_HISTORY_SHARED_SEARCH, &search_text, NULL, FALSE, FALSE,
INPUT_COMPLETE_NONE),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_START_COLUMNS, QUICK_START_COLUMNS,
QUICK_RADIO (num_of_types, (const char **) list_of_types, QUICK_RADIO (num_of_types, (const char **) list_of_types,
@ -191,10 +192,11 @@ editcmd_dialog_replace_show (WEdit * edit, const char *search_default, const cha
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, search_default,
search_default, 0, MC_HISTORY_SHARED_SEARCH, search_text, NULL), MC_HISTORY_SHARED_SEARCH, search_text, NULL, FALSE, FALSE,
QUICK_LABELED_INPUT (N_("Enter replacement string:"), input_label_above, INPUT_COMPLETE_NONE),
replace_default, 0, "replace", replace_text, NULL), QUICK_LABELED_INPUT (N_("Enter replacement string:"), input_label_above, replace_default,
"replace", replace_text, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_START_COLUMNS, QUICK_START_COLUMNS,
QUICK_RADIO (num_of_types, (const char **) list_of_types, QUICK_RADIO (num_of_types, (const char **) list_of_types,
@ -316,7 +318,7 @@ editcmd_dialog_raw_key_query (const char *heading, const char *query, gboolean c
add_widget (raw_dlg, label_new (y, 3, query)); add_widget (raw_dlg, label_new (y, 3, query));
add_widget (raw_dlg, input_new (y++, 3 + wq + 1, input_get_default_colors (), add_widget (raw_dlg, input_new (y++, 3 + wq + 1, input_get_default_colors (),
w - (6 + wq + 1), "", 0, INPUT_COMPLETE_DEFAULT)); w - (6 + wq + 1), "", 0, INPUT_COMPLETE_NONE));
if (cancel) if (cancel)
{ {
add_widget (raw_dlg, hline_new (y++, -1, -1)); add_widget (raw_dlg, hline_new (y++, -1, -1));

Просмотреть файл

@ -156,8 +156,8 @@ edit_options_dialog (WDialog * h)
NULL), NULL),
QUICK_CHECKBOX (N_("Fill tabs with &spaces"), &option_fill_tabs_with_spaces, QUICK_CHECKBOX (N_("Fill tabs with &spaces"), &option_fill_tabs_with_spaces,
NULL), NULL),
QUICK_LABELED_INPUT (N_("Tab spacing:"), input_label_left, tab_spacing, 0, QUICK_LABELED_INPUT (N_("Tab spacing:"), input_label_left, tab_spacing,
"edit-tab-spacing", &q, NULL), "edit-tab-spacing", &q, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_STOP_GROUPBOX, QUICK_STOP_GROUPBOX,
QUICK_NEXT_COLUMN, QUICK_NEXT_COLUMN,
QUICK_START_GROUPBOX (N_("Other options")), QUICK_START_GROUPBOX (N_("Other options")),
@ -174,8 +174,8 @@ edit_options_dialog (WDialog * h)
QUICK_CHECKBOX (N_("Cursor be&yond end of line"), &option_cursor_beyond_eol, QUICK_CHECKBOX (N_("Cursor be&yond end of line"), &option_cursor_beyond_eol,
NULL), NULL),
QUICK_CHECKBOX (N_("&Group undo"), &option_group_undo, NULL), QUICK_CHECKBOX (N_("&Group undo"), &option_group_undo, NULL),
QUICK_LABELED_INPUT (N_("Word wrap line length:"), input_label_left, QUICK_LABELED_INPUT (N_("Word wrap line length:"), input_label_left, wrap_length,
wrap_length, 0, "edit-word-wrap", &p, NULL), "edit-word-wrap", &p, NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_STOP_GROUPBOX, QUICK_STOP_GROUPBOX,
QUICK_STOP_COLUMNS, QUICK_STOP_COLUMNS,
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,

Просмотреть файл

@ -464,8 +464,9 @@ configure_box (void)
QUICK_START_GROUPBOX (N_("Esc key mode")), QUICK_START_GROUPBOX (N_("Esc key mode")),
QUICK_CHECKBOX (N_("S&ingle press"), &old_esc_mode, &configure_old_esc_mode_id), QUICK_CHECKBOX (N_("S&ingle press"), &old_esc_mode, &configure_old_esc_mode_id),
QUICK_LABELED_INPUT (N_("Timeout:"), input_label_left, QUICK_LABELED_INPUT (N_("Timeout:"), input_label_left,
(const char *) time_out, 0, MC_HISTORY_ESC_TIMEOUT, (const char *) time_out, MC_HISTORY_ESC_TIMEOUT,
&time_out_new, &configure_time_out_id), &time_out_new, &configure_time_out_id, FALSE, FALSE,
INPUT_COMPLETE_NONE),
QUICK_STOP_GROUPBOX, QUICK_STOP_GROUPBOX,
QUICK_START_GROUPBOX (N_("Pause after run")), QUICK_START_GROUPBOX (N_("Pause after run")),
QUICK_RADIO (pause_options_num, pause_options, &pause_after_run, NULL), QUICK_RADIO (pause_options_num, pause_options, &pause_after_run, NULL),
@ -653,12 +654,12 @@ panel_listing_box (WPanel * panel, char **userp, char **minip, int *use_msformat
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_RADIO (LIST_TYPES, list_types, &result, &panel_listing_types_id), QUICK_RADIO (LIST_TYPES, list_types, &result, &panel_listing_types_id),
QUICK_INPUT (panel->user_format, INPUT_COMPLETE_DEFAULT, "user-fmt-input", QUICK_INPUT (panel->user_format, "user-fmt-input", &panel_user_format,
&panel_user_format, &panel_user_format_id), &panel_user_format_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_CHECKBOX (N_("User &mini status"), &mini_user_status, &mini_user_status_id), QUICK_CHECKBOX (N_("User &mini status"), &mini_user_status, &mini_user_status_id),
QUICK_INPUT (panel->user_status_format[panel->list_type], INPUT_COMPLETE_DEFAULT, QUICK_INPUT (panel->user_status_format[panel->list_type], "mini_input",
"mini_input", &mini_user_format, &mini_user_format_id), &mini_user_format, &mini_user_format_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,
QUICK_END QUICK_END
/* *INDENT-ON* */ /* *INDENT-ON* */
@ -974,17 +975,20 @@ configure_vfs (void)
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (N_("Timeout for freeing VFSs (sec):"), input_label_left, QUICK_LABELED_INPUT (N_("Timeout for freeing VFSs (sec):"), input_label_left,
buffer2, 0, "input-timo-vfs", &ret_timeout, NULL), buffer2, "input-timo-vfs", &ret_timeout, NULL, FALSE, FALSE,
INPUT_COMPLETE_NONE),
#ifdef ENABLE_VFS_FTP #ifdef ENABLE_VFS_FTP
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_LABELED_INPUT (N_("FTP anonymous password:"), input_label_left, QUICK_LABELED_INPUT (N_("FTP anonymous password:"), input_label_left,
ftpfs_anonymous_passwd, 0, "input-passwd", &ret_passwd, NULL), ftpfs_anonymous_passwd, "input-passwd", &ret_passwd, NULL,
FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_LABELED_INPUT (N_("FTP directory cache timeout (sec):"), input_label_left, QUICK_LABELED_INPUT (N_("FTP directory cache timeout (sec):"), input_label_left,
buffer3, 0, "input-timeout", &ret_directory_timeout, NULL), buffer3, "input-timeout", &ret_directory_timeout, NULL,
FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_CHECKBOX (N_("&Always use ftp proxy:"), &ftpfs_always_use_proxy, QUICK_CHECKBOX (N_("&Always use ftp proxy:"), &ftpfs_always_use_proxy,
&ftpfs_always_use_proxy_id), &ftpfs_always_use_proxy_id),
QUICK_INPUT (ftpfs_proxy_host, 0, "input-ftp-proxy", &ret_ftp_proxy, QUICK_INPUT (ftpfs_proxy_host, "input-ftp-proxy", &ret_ftp_proxy,
&ftpfs_proxy_host_id), &ftpfs_proxy_host_id, FALSE, FALSE, INPUT_COMPLETE_HOSTNAMES),
QUICK_CHECKBOX (N_("&Use ~/.netrc"), &ftpfs_use_netrc, NULL), QUICK_CHECKBOX (N_("&Use ~/.netrc"), &ftpfs_use_netrc, NULL),
QUICK_CHECKBOX (N_("Use &passive mode"), &ftpfs_use_passive_connections, NULL), QUICK_CHECKBOX (N_("Use &passive mode"), &ftpfs_use_passive_connections, NULL),
QUICK_CHECKBOX (N_("Use passive mode over pro&xy"), QUICK_CHECKBOX (N_("Use passive mode over pro&xy"),
@ -1042,7 +1046,8 @@ cd_dialog (void)
char *my_str; char *my_str;
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
QUICK_LABELED_INPUT (N_("cd"), input_label_left, "", 2, "input", &my_str, NULL), QUICK_LABELED_INPUT (N_("cd"), input_label_left, "", "input", &my_str, NULL, FALSE, TRUE,
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD),
QUICK_END QUICK_END
}; };
@ -1072,10 +1077,10 @@ symlink_dialog (const vfs_path_t * existing_vpath, const vfs_path_t * new_vpath,
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (N_("Existing filename (filename symlink will point to):"), QUICK_LABELED_INPUT (N_("Existing filename (filename symlink will point to):"),
input_label_above, input_label_above,
existing, 0, "input-2", ret_existing, NULL), existing, "input-2", ret_existing, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
QUICK_SEPARATOR (FALSE), QUICK_SEPARATOR (FALSE),
QUICK_LABELED_INPUT (N_("Symbolic link filename:"), input_label_above, QUICK_LABELED_INPUT (N_("Symbolic link filename:"), input_label_above,
new, 0, "input-1", ret_new, NULL), new, "input-1", ret_new, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,
QUICK_END QUICK_END
/* *INDENT-ON* */ /* *INDENT-ON* */
@ -1198,11 +1203,11 @@ vfs_smb_get_authinfo (const char *host, const char *share, const char *domain, c
QUICK_SEPARATOR (FALSE), QUICK_SEPARATOR (FALSE),
QUICK_LABEL (N_("Password:"), NULL), QUICK_LABEL (N_("Password:"), NULL),
QUICK_NEXT_COLUMN, QUICK_NEXT_COLUMN,
QUICK_INPUT (domain, 0, "auth_domain", &ret_domain, NULL), QUICK_INPUT (domain, "auth_domain", &ret_domain, NULL, FALSE, FALSE, INPUT_COMPLETE_HOSTNAMES),
QUICK_SEPARATOR (FALSE), QUICK_SEPARATOR (FALSE),
QUICK_INPUT (user, 0, "auth_name", &ret_user, NULL), QUICK_INPUT (user, "auth_name", &ret_user, NULL, FALSE, FALSE, INPUT_COMPLETE_USERNAMES),
QUICK_SEPARATOR (FALSE), QUICK_SEPARATOR (FALSE),
QUICK_INPUT ("", 1, "auth_password", &ret_password, NULL), QUICK_INPUT ("", "auth_password", &ret_password, NULL, TRUE, FALSE, INPUT_COMPLETE_NONE),
QUICK_STOP_COLUMNS, QUICK_STOP_COLUMNS,
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,
QUICK_END QUICK_END

Просмотреть файл

@ -197,7 +197,8 @@ set_panel_filter (WPanel * p)
reg_exp = input_dialog_help (_("Filter"), reg_exp = input_dialog_help (_("Filter"),
_("Set expression for filtering filenames"), _("Set expression for filtering filenames"),
"[Filter...]", MC_HISTORY_FM_PANEL_FILTER, x, FALSE); "[Filter...]", MC_HISTORY_FM_PANEL_FILTER, x, FALSE,
INPUT_COMPLETE_FILENAMES);
if (!reg_exp) if (!reg_exp)
return; return;
set_panel_filter_to (p, reg_exp); set_panel_filter_to (p, reg_exp);
@ -218,7 +219,8 @@ select_unselect_cmd (const char *title, const char *history_name, gboolean do_se
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_INPUT (INPUT_LAST_TEXT, 0, history_name, &reg_exp, NULL), QUICK_INPUT (INPUT_LAST_TEXT, history_name, &reg_exp, NULL,
FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
QUICK_START_COLUMNS, QUICK_START_COLUMNS,
QUICK_CHECKBOX (N_("&Files only"), &files_only, NULL), QUICK_CHECKBOX (N_("&Files only"), &files_only, NULL),
QUICK_CHECKBOX (N_("&Using shell patterns"), &shell_patterns, NULL), QUICK_CHECKBOX (N_("&Using shell patterns"), &shell_patterns, NULL),
@ -424,7 +426,8 @@ do_link (link_type_t link_type, const char *fname)
if (link_type == LINK_HARDLINK) if (link_type == LINK_HARDLINK)
{ {
src = g_strdup_printf (_("Link %s to:"), str_trunc (fname, 46)); src = g_strdup_printf (_("Link %s to:"), str_trunc (fname, 46));
dest = input_expand_dialog (_("Link"), src, MC_HISTORY_FM_LINK, ""); dest =
input_expand_dialog (_("Link"), src, MC_HISTORY_FM_LINK, "", INPUT_COMPLETE_FILENAMES);
if (!dest || !*dest) if (!dest || !*dest)
goto cleanup; goto cleanup;
save_cwds_stat (); save_cwds_stat ();
@ -494,7 +497,10 @@ nice_cd (const char *text, const char *xtext, const char *help,
if (!SELECTED_IS_PANEL) if (!SELECTED_IS_PANEL)
return; return;
machine = input_dialog_help (text, xtext, help, history_name, "", strip_password); machine =
input_dialog_help (text, xtext, help, history_name, "", strip_password,
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_HOSTNAMES |
INPUT_COMPLETE_USERNAMES);
if (machine == NULL) if (machine == NULL)
return; return;
@ -706,7 +712,8 @@ view_file_cmd (void)
filename = filename =
input_expand_dialog (_("View file"), _("Filename:"), input_expand_dialog (_("View file"), _("Filename:"),
MC_HISTORY_FM_VIEW_FILE, selection (current_panel)->fname); MC_HISTORY_FM_VIEW_FILE, selection (current_panel)->fname,
INPUT_COMPLETE_FILENAMES);
if (!filename) if (!filename)
return; return;
@ -740,7 +747,8 @@ view_filtered_cmd (void)
command = command =
input_dialog (_("Filtered view"), input_dialog (_("Filtered view"),
_("Filter command and arguments:"), _("Filter command and arguments:"),
MC_HISTORY_FM_FILTERED_VIEW, initial_command); MC_HISTORY_FM_FILTERED_VIEW, initial_command,
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_COMMANDS);
if (command != NULL) if (command != NULL)
{ {
@ -825,7 +833,7 @@ edit_cmd_new (void)
char *fname; char *fname;
fname = input_expand_dialog (_("Edit file"), _("Enter file name:"), fname = input_expand_dialog (_("Edit file"), _("Enter file name:"),
MC_HISTORY_EDIT_LOAD, ""); MC_HISTORY_EDIT_LOAD, "", INPUT_COMPLETE_FILENAMES);
if (fname == NULL) if (fname == NULL)
return; return;
@ -913,7 +921,8 @@ mkdir_cmd (void)
dir = dir =
input_expand_dialog (_("Create a new Directory"), input_expand_dialog (_("Create a new Directory"),
_("Enter directory name:"), MC_HISTORY_FM_MKDIR, name); _("Enter directory name:"), MC_HISTORY_FM_MKDIR, name,
INPUT_COMPLETE_FILENAMES);
if (dir != NULL && dir != '\0') if (dir != NULL && dir != '\0')
{ {
@ -1349,7 +1358,9 @@ edit_symlink_cmd (void)
if (i > 0) if (i > 0)
{ {
buffer[i] = 0; buffer[i] = 0;
dest = input_expand_dialog (_("Edit symlink"), q, MC_HISTORY_FM_EDIT_LINK, buffer); dest =
input_expand_dialog (_("Edit symlink"), q, MC_HISTORY_FM_EDIT_LINK, buffer,
INPUT_COMPLETE_FILENAMES);
if (dest) if (dest)
{ {
if (*dest && strcmp (buffer, dest)) if (*dest && strcmp (buffer, dest))

Просмотреть файл

@ -476,7 +476,8 @@ command_new (int y, int x, int cols)
}; };
cmd = input_new (y, x, (int *) command_colors, cols, "", "cmdline", cmd = input_new (y, x, (int *) command_colors, cols, "", "cmdline",
INPUT_COMPLETE_DEFAULT | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS | INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES
| INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_CD | INPUT_COMPLETE_COMMANDS |
INPUT_COMPLETE_SHELL_ESC); INPUT_COMPLETE_SHELL_ESC);
/* Add our hooks */ /* Add our hooks */

Просмотреть файл

@ -227,7 +227,9 @@ exec_make_shell_string (const char *lc_data, const vfs_path_t * filename_vpath)
char *parameter; char *parameter;
parameter_found = FALSE; parameter_found = FALSE;
parameter = input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_EXT_PARAMETER, ""); parameter =
input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_EXT_PARAMETER, "",
INPUT_COMPLETE_NONE);
if (parameter == NULL) if (parameter == NULL)
{ {
/* User canceled */ /* User canceled */

Просмотреть файл

@ -1180,15 +1180,15 @@ file_mask_dialog (FileOpContext * ctx, FileOperation operation,
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (fmd_buf, input_label_above, QUICK_LABELED_INPUT (fmd_buf, input_label_above,
easy_patterns ? "*" : "^(.*)$", 0, "input-def", &source_mask, easy_patterns ? "*" : "^(.*)$", "input-def", &source_mask,
NULL), NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
QUICK_START_COLUMNS, QUICK_START_COLUMNS,
QUICK_SEPARATOR (FALSE), QUICK_SEPARATOR (FALSE),
QUICK_NEXT_COLUMN, QUICK_NEXT_COLUMN,
QUICK_CHECKBOX (N_("&Using shell patterns"), &source_easy_patterns, NULL), QUICK_CHECKBOX (N_("&Using shell patterns"), &source_easy_patterns, NULL),
QUICK_STOP_COLUMNS, QUICK_STOP_COLUMNS,
QUICK_LABELED_INPUT (N_("to:"), input_label_above, QUICK_LABELED_INPUT (N_("to:"), input_label_above,
def_text_secure, 0, "input2", &dest_dir, NULL), def_text_secure, "input2", &dest_dir, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_START_COLUMNS, QUICK_START_COLUMNS,
QUICK_CHECKBOX (N_("Follow &links"), &ctx->follow_links, NULL), QUICK_CHECKBOX (N_("Follow &links"), &ctx->follow_links, NULL),

Просмотреть файл

@ -609,7 +609,7 @@ find_parameters (char **start_dir, ssize_t * start_dir_len,
add_widget (find_dlg, label_new (y1++, x1, _("Start at:"))); add_widget (find_dlg, label_new (y1++, x1, _("Start at:")));
in_start = in_start =
input_new (y1, x1, input_get_default_colors (), cols - b0 - 7, in_start_dir, "start", input_new (y1, x1, input_get_default_colors (), cols - b0 - 7, in_start_dir, "start",
INPUT_COMPLETE_DEFAULT); INPUT_COMPLETE_CD | INPUT_COMPLETE_FILENAMES);
add_widget (find_dlg, in_start); add_widget (find_dlg, in_start);
add_widget (find_dlg, button_new (y1++, cols - b0 - 3, B_TREE, NORMAL_BUTTON, buts[0], NULL)); add_widget (find_dlg, button_new (y1++, cols - b0 - 3, B_TREE, NORMAL_BUTTON, buts[0], NULL));
@ -621,7 +621,7 @@ find_parameters (char **start_dir, ssize_t * start_dir_len,
in_ignore = in_ignore =
input_new (y1++, x1, input_get_default_colors (), cols - 6, input_new (y1++, x1, input_get_default_colors (), cols - 6,
options.ignore_dirs != NULL ? options.ignore_dirs : "", "ignoredirs", options.ignore_dirs != NULL ? options.ignore_dirs : "", "ignoredirs",
INPUT_COMPLETE_DEFAULT); INPUT_COMPLETE_CD | INPUT_COMPLETE_FILENAMES);
widget_disable (WIDGET (in_ignore), !options.ignore_dirs_enable); widget_disable (WIDGET (in_ignore), !options.ignore_dirs_enable);
add_widget (find_dlg, in_ignore); add_widget (find_dlg, in_ignore);
@ -633,7 +633,7 @@ find_parameters (char **start_dir, ssize_t * start_dir_len,
add_widget (find_dlg, label_new (y1++, x1, file_name_label)); add_widget (find_dlg, label_new (y1++, x1, file_name_label));
in_name = in_name =
input_new (y1++, x1, input_get_default_colors (), cw, INPUT_LAST_TEXT, "name", input_new (y1++, x1, input_get_default_colors (), cw, INPUT_LAST_TEXT, "name",
INPUT_COMPLETE_DEFAULT); INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
add_widget (find_dlg, in_name); add_widget (find_dlg, in_name);
/* Start 2nd column */ /* Start 2nd column */
@ -641,7 +641,7 @@ find_parameters (char **start_dir, ssize_t * start_dir_len,
add_widget (find_dlg, content_label); add_widget (find_dlg, content_label);
in_with = in_with =
input_new (y2++, x2, input_get_default_colors (), cw, INPUT_LAST_TEXT, input_new (y2++, x2, input_get_default_colors (), cw, INPUT_LAST_TEXT,
MC_HISTORY_SHARED_SEARCH, INPUT_COMPLETE_DEFAULT); MC_HISTORY_SHARED_SEARCH, INPUT_COMPLETE_NONE);
in_with->label = content_label; in_with->label = content_label;
widget_disable (WIDGET (in_with), disable); widget_disable (WIDGET (in_with), disable);
add_widget (find_dlg, in_with); add_widget (find_dlg, in_with);

Просмотреть файл

@ -960,9 +960,11 @@ add_new_entry_input (const char *header, const char *text1, const char *text2,
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (text1, input_label_above, *r1, 0, "input-lbl", r1, NULL), QUICK_LABELED_INPUT (text1, input_label_above, *r1, "input-lbl", r1, NULL,
FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_SEPARATOR (FALSE), QUICK_SEPARATOR (FALSE),
QUICK_LABELED_INPUT (text2, input_label_above, *r2, 0, "input-lbl", r2, NULL), QUICK_LABELED_INPUT (text2, input_label_above, *r2, "input-lbl", r2, NULL,
FALSE, FALSE, INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD),
QUICK_START_BUTTONS (TRUE, TRUE), QUICK_START_BUTTONS (TRUE, TRUE),
QUICK_BUTTON (N_("&Append"), B_APPEND, NULL, NULL), QUICK_BUTTON (N_("&Append"), B_APPEND, NULL, NULL),
QUICK_BUTTON (N_("&Insert"), B_INSERT, NULL, NULL), QUICK_BUTTON (N_("&Insert"), B_INSERT, NULL, NULL),
@ -1023,7 +1025,8 @@ add_new_group_input (const char *header, const char *label, char **result)
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (label, input_label_above, "", 0, "input", result, NULL), QUICK_LABELED_INPUT (label, input_label_above, "", "input", result, NULL,
FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_START_BUTTONS (TRUE, TRUE), QUICK_START_BUTTONS (TRUE, TRUE),
QUICK_BUTTON (N_("&Append"), B_APPEND, NULL, NULL), QUICK_BUTTON (N_("&Append"), B_APPEND, NULL, NULL),
QUICK_BUTTON (N_("&Insert"), B_INSERT, NULL, NULL), QUICK_BUTTON (N_("&Insert"), B_INSERT, NULL, NULL),
@ -1565,7 +1568,9 @@ add2hotlist_cmd (void)
l = str_term_width1 (cp); l = str_term_width1 (cp);
label_string = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_PASSWORD); label_string = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_PASSWORD);
lc_prompt = g_strdup_printf (cp, str_trunc (label_string, COLS - 2 * UX - (l + 8))); lc_prompt = g_strdup_printf (cp, str_trunc (label_string, COLS - 2 * UX - (l + 8)));
label = input_dialog (_("Add to hotlist"), lc_prompt, MC_HISTORY_HOTLIST_ADD, label_string); label =
input_dialog (_("Add to hotlist"), lc_prompt, MC_HISTORY_HOTLIST_ADD, label_string,
INPUT_COMPLETE_NONE);
g_free (lc_prompt); g_free (lc_prompt);
if (label == NULL || *label == '\0') if (label == NULL || *label == '\0')

Просмотреть файл

@ -186,9 +186,13 @@ init_panelize (void)
add_widget (panelize_dlg, label_new (y++, UX, _("Command"))); add_widget (panelize_dlg, label_new (y++, UX, _("Command")));
pname = pname =
input_new (y++, UX, input_get_default_colors (), panelize_cols - UX * 2, "", "in", input_new (y++, UX, input_get_default_colors (), panelize_cols - UX * 2, "", "in",
INPUT_COMPLETE_DEFAULT); INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_COMMANDS |
INPUT_COMPLETE_VARIABLES | INPUT_COMPLETE_USERNAMES | INPUT_COMPLETE_CD |
INPUT_COMPLETE_SHELL_ESC);
add_widget (panelize_dlg, pname); add_widget (panelize_dlg, pname);
add_widget (panelize_dlg, hline_new (y++, -1, -1)); add_widget (panelize_dlg, hline_new (y++, -1, -1));
x = (panelize_cols - blen) / 2; x = (panelize_cols - blen) / 2;
@ -258,7 +262,8 @@ add2panelize_cmd (void)
if (pname->buffer && (*pname->buffer)) if (pname->buffer && (*pname->buffer))
{ {
label = input_dialog (_("Add to external panelize"), label = input_dialog (_("Add to external panelize"),
_("Enter command label:"), MC_HISTORY_FM_PANELIZE_ADD, ""); _("Enter command label:"), MC_HISTORY_FM_PANELIZE_ADD, "",
INPUT_COMPLETE_NONE);
if (!label) if (!label)
return; return;
if (!*label) if (!*label)

Просмотреть файл

@ -785,7 +785,8 @@ tree_copy (WTree * tree, const char *default_dest)
g_snprintf (msg, sizeof (msg), _("Copy \"%s\" directory to:"), g_snprintf (msg, sizeof (msg), _("Copy \"%s\" directory to:"),
str_trunc (selected_ptr_name, 50)); str_trunc (selected_ptr_name, 50));
dest = input_expand_dialog (Q_ ("DialogTitle|Copy"), dest = input_expand_dialog (Q_ ("DialogTitle|Copy"),
msg, MC_HISTORY_FM_TREE_COPY, default_dest); msg, MC_HISTORY_FM_TREE_COPY, default_dest,
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
if (dest != NULL && *dest != '\0') if (dest != NULL && *dest != '\0')
{ {
@ -824,7 +825,8 @@ tree_move (WTree * tree, const char *default_dest)
g_snprintf (msg, sizeof (msg), _("Move \"%s\" directory to:"), g_snprintf (msg, sizeof (msg), _("Move \"%s\" directory to:"),
str_trunc (selected_ptr_name, 50)); str_trunc (selected_ptr_name, 50));
dest = dest =
input_expand_dialog (Q_ ("DialogTitle|Move"), msg, MC_HISTORY_FM_TREE_MOVE, default_dest); input_expand_dialog (Q_ ("DialogTitle|Move"), msg, MC_HISTORY_FM_TREE_MOVE, default_dest,
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);
if (dest == NULL || *dest == '\0') if (dest == NULL || *dest == '\0')
goto ret; goto ret;

Просмотреть файл

@ -474,7 +474,10 @@ execute_menu_command (WEdit * edit_widget, const char *commands, gboolean show_p
char *tmp; char *tmp;
*parameter = 0; *parameter = 0;
parameter = parameter =
input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_FM_MENU_EXEC_PARAM, ""); input_dialog (_("Parameter"), lc_prompt, MC_HISTORY_FM_MENU_EXEC_PARAM, "",
INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD |
INPUT_COMPLETE_HOSTNAMES | INPUT_COMPLETE_VARIABLES |
INPUT_COMPLETE_USERNAMES);
if (!parameter || !*parameter) if (!parameter || !*parameter)
{ {
/* User canceled */ /* User canceled */

Просмотреть файл

@ -654,7 +654,8 @@ ftpfs_login_server (struct vfs_class *me, struct vfs_s_super *super, const char
p = g_strdup_printf (_("FTP: Account required for user %s"), p = g_strdup_printf (_("FTP: Account required for user %s"),
super->path_element->user); super->path_element->user);
op = input_dialog (p, _("Account:"), MC_HISTORY_FTPFS_ACCOUNT, ""); op = input_dialog (p, _("Account:"), MC_HISTORY_FTPFS_ACCOUNT, "",
INPUT_COMPLETE_USERNAMES);
g_free (p); g_free (p);
if (op == NULL) if (op == NULL)
ERRNOR (EPERM, 0); ERRNOR (EPERM, 0);

Просмотреть файл

@ -88,7 +88,8 @@ mcview_dialog_search (mcview_t * view)
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above, QUICK_LABELED_INPUT (N_("Enter search string:"), input_label_above,
INPUT_LAST_TEXT, 0, MC_HISTORY_SHARED_SEARCH, &exp, NULL), INPUT_LAST_TEXT, MC_HISTORY_SHARED_SEARCH, &exp,
NULL, FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_SEPARATOR (TRUE), QUICK_SEPARATOR (TRUE),
QUICK_START_COLUMNS, QUICK_START_COLUMNS,
QUICK_RADIO (num_of_types, (const char **) list_of_types, QUICK_RADIO (num_of_types, (const char **) list_of_types,
@ -197,7 +198,8 @@ mcview_dialog_goto (mcview_t * view, off_t * offset)
{ {
quick_widget_t quick_widgets[] = { quick_widget_t quick_widgets[] = {
/* *INDENT-OFF* */ /* *INDENT-OFF* */
QUICK_INPUT (INPUT_LAST_TEXT, 0, MC_HISTORY_VIEW_GOTO, &exp, NULL), QUICK_INPUT (INPUT_LAST_TEXT, MC_HISTORY_VIEW_GOTO, &exp, NULL,
FALSE, FALSE, INPUT_COMPLETE_NONE),
QUICK_RADIO (num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type, QUICK_RADIO (num_of_types, (const char **) mc_view_goto_str, (int *) &current_goto_type,
NULL), NULL),
QUICK_BUTTONS_OK_CANCEL, QUICK_BUTTONS_OK_CANCEL,

Просмотреть файл

@ -1,4 +1,4 @@
SUBDIRS = . mcconfig search vfs SUBDIRS = . mcconfig search vfs widget
AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) @CHECK_CFLAGS@ AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) @CHECK_CFLAGS@

19
tests/lib/widget/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,19 @@
AM_CPPFLAGS = \
$(GLIB_CFLAGS) \
-I$(top_srcdir) \
-I$(top_srcdir)/lib/vfs \
@CHECK_CFLAGS@
AM_LDFLAGS = @TESTS_LDFLAGS@
LIBS=@CHECK_LIBS@ \
$(top_builddir)/lib/libmc.la
TESTS = \
complete_engine
check_PROGRAMS = $(TESTS)
complete_engine_SOURCES = \
complete_engine.c

254
tests/lib/widget/complete_engine.c Обычный файл
Просмотреть файл

@ -0,0 +1,254 @@
/*
lib/widget - tests for autocomplete feature
Copyright (C) 2013
The Free Software Foundation, Inc.
Written by:
Slava Zanko <slavazanko@gmail.com>, 2013
This file is part of the Midnight Commander.
The Midnight Commander is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define TEST_SUITE_NAME "/lib/widget"
#include <config.h>
#include <check.h>
#include "lib/global.h"
#include "lib/strutil.h"
#include "lib/widget.h"
/* --------------------------------------------------------------------------------------------- */
void complete_engine_fill_completions (WInput * in);
char **try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags);
/* --------------------------------------------------------------------------------------------- */
/* @CapturedValue */
static char *try_complete__text__captured;
/* @CapturedValue */
static int try_complete__lc_start__captured;
/* @CapturedValue */
static int try_complete__lc_end__captured;
/* @CapturedValue */
static input_complete_t try_complete__flags__captured;
/* @ThenReturnValue */
static char **try_complete__return_value;
/* @Mock */
char **
try_complete (char *text, int *lc_start, int *lc_end, input_complete_t flags)
{
try_complete__text__captured = g_strdup (text);
try_complete__lc_start__captured = *lc_start;
try_complete__lc_end__captured = *lc_end;
try_complete__flags__captured = flags;
return try_complete__return_value;
}
static void
try_complete__init (void)
{
try_complete__text__captured = NULL;
try_complete__lc_start__captured = 0;
try_complete__lc_end__captured = 0;
try_complete__flags__captured = 0;
}
static void
try_complete__deinit (void)
{
g_free (try_complete__text__captured);
}
/* --------------------------------------------------------------------------------------------- */
/* @Before */
static void
setup (void)
{
str_init_strings (NULL);
try_complete__init ();
}
/* --------------------------------------------------------------------------------------------- */
/* @After */
static void
teardown (void)
{
try_complete__deinit ();
str_uninit_strings ();
}
/* --------------------------------------------------------------------------------------------- */
/* @DataSource("test_complete_engine_fill_completions_ds") */
/* *INDENT-OFF* */
static const struct test_complete_engine_fill_completions_ds
{
const char *input_buffer;
const int input_point;
const input_complete_t input_completion_flags;
int expected_start;
int expected_end;
} test_complete_engine_fill_completions_ds[] =
{
{
"string",
3,
INPUT_COMPLETE_NONE,
0,
3
},
{
"some string",
7,
INPUT_COMPLETE_NONE,
0,
7
},
{
"some string",
7,
INPUT_COMPLETE_SHELL_ESC,
5,
7
},
{
"some\\ string111",
9,
INPUT_COMPLETE_SHELL_ESC,
0,
9
},
{
"some\\\tstring111",
9,
INPUT_COMPLETE_SHELL_ESC,
0,
9
},
{
"some\tstring",
7,
INPUT_COMPLETE_NONE,
5,
7
},
{
"some;string",
7,
INPUT_COMPLETE_NONE,
5,
7
},
{
"some|string",
7,
INPUT_COMPLETE_NONE,
5,
7
},
{
"some<string",
7,
INPUT_COMPLETE_NONE,
5,
7
},
{
"some>string",
7,
INPUT_COMPLETE_NONE,
5,
7
},
{
"some!@#$%^&*()_\\+~`\"',./?:string",
30,
INPUT_COMPLETE_NONE,
0,
30
},
};
/* *INDENT-ON* */
// " \t;|<>"
/* @Test(dataSource = "test_complete_engine_fill_completions_ds") */
/* *INDENT-OFF* */
START_TEST (test_complete_engine_fill_completions)
/* *INDENT-ON* */
{
/* given */
WInput *w_input;
const struct test_complete_engine_fill_completions_ds *data =
&test_complete_engine_fill_completions_ds[_i];
w_input = g_new (WInput, 1);
w_input->buffer = g_strdup (data->input_buffer);
w_input->point = data->input_point;
w_input->completion_flags = data->input_completion_flags;
/* when */
complete_engine_fill_completions (w_input);
/* then */
g_assert_cmpstr (try_complete__text__captured, ==, data->input_buffer);
ck_assert_int_eq (try_complete__lc_start__captured, data->expected_start);
ck_assert_int_eq (try_complete__lc_end__captured, data->expected_end);
ck_assert_int_eq (try_complete__flags__captured, data->input_completion_flags);
}
/* *INDENT-OFF* */
END_TEST
/* *INDENT-ON* */
/* --------------------------------------------------------------------------------------------- */
int
main (void)
{
int number_failed;
Suite *s = suite_create (TEST_SUITE_NAME);
TCase *tc_core = tcase_create ("Core");
SRunner *sr;
tcase_add_checked_fixture (tc_core, setup, teardown);
/* Add new tests here: *************** */
tcase_add_loop_test (tc_core, test_complete_engine_fill_completions, 0,
sizeof (test_complete_engine_fill_completions_ds) /
sizeof (test_complete_engine_fill_completions_ds[0]));
/* *********************************** */
suite_add_tcase (s, tc_core);
sr = srunner_create (s);
srunner_set_log (sr, "complete_engine.log");
srunner_run_all (sr, CK_NORMAL);
number_failed = srunner_ntests_failed (sr);
srunner_free (sr);
return (number_failed == 0) ? 0 : 1;
}
/* --------------------------------------------------------------------------------------------- */