Complete: Show All
Pavel Tsekov
ptsekov at gmx.net
Fri Feb 18 15:57:29 UTC 2005
Hello,
On Wed, 26 Jan 2005, Thomas Zajic wrote:
> Hi,
>
> I just stumbled across another long-standing bug in mc again.
>
> With "Complete: Show All" enabled in F9->Options->Configuration, mc does
> not autocomplete paths or filenames when there's only one alternative.
>
> Eg. given a directory structure like "x/y/z" (with "y" being the only dir
> entry in "x", and "z" being the only dir entry in "y"), having "x" in one
> panel and some other directory in the other panel, mc stops autocompletion
> in "y" (or even "x", if "x" is the only file/directory in that panel) when
> trying to copy/move a file to "z".
>
> This works fine with "Complete: Show All" disabled.
Attached is a patch which solves the issue. Please, test.
In short this is what happend in the case that Thomas described:
Consider the following directory structure:
.../x/y/z
In MC (Complete: show all - enabled) go to 'x' and type 'Alt + C'
and then type 'Alt + Tab'.
1) The code detects that is must display any ambiguous matches
immediatly. In this case two calls to complete_engine () will
be made - the first one with the DO_INSERTION option and the
second one with the DO_QUERY option.
2) The first call get only one match - the 'y' dir. It displays
it, calls free_completions () (effectively leaving in->completions ==
0) and returns.
3) The second call is supposed to display a dialog with all matches
although in this particular case there aren't any other matches except
the 'y' dir. Still this call is made, it fills 'in->completions' and it
matches the 'y/z' dir. This match is not displayed though since
complete_engine (..., DO_QUERY) is supposed to work with more than a
single match and the function returns but it doesn't clean
'in->completions'.
4) Further calls to complete () (i.e. if you press Alt + tab again) are
fooled by the fact that 'in->completions' is not empty and try to display
a list of ambiguous entries but obviously they fail silently.
A simple description of what is in the patch:
The first hunk is there just as precaution - if it happens so that
complete_engine () is passed the DO_QUERY flag but there aren't
multiple matches (this cannot happent with this patch, but just in
case). The second hunk prevents null pointer dereference which might
occur if complete_engine () is called with DO_QUERY set and there is
only one match. The third hunk simplifies (IMO) the complete () routine
and delegates the additional work required by the 'Complete: show all'
functionality to complete_engine ().
The second and the third hunks actually do fix the "Complete: show all"
issue.
-------------- next part --------------
Index: src/complete.c
===================================================================
RCS file: /cvsroot/mc/mc/src/complete.c,v
retrieving revision 1.54
diff -u -p -r1.54 complete.c
--- src/complete.c 8 Feb 2005 09:04:03 -0000 1.54
+++ src/complete.c 18 Feb 2005 15:20:05 -0000
@@ -921,7 +921,7 @@ complete_engine (WInput *in, int what_to
in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
}
if (in->completions){
- if (what_to_do & DO_INSERTION) {
+ if (what_to_do & DO_INSERTION || ((what_to_do & DO_QUERY) && !in->completions[1])) {
if (insert_text (in, in->completions [0], strlen (in->completions [0]))){
if (in->completions [1])
beep ();
@@ -930,11 +930,7 @@ complete_engine (WInput *in, int what_to
} else
beep ();
}
- /* FIXME: evil evil evil. We do not go into the query completion engine
- * because we do not have a Gtk dialog for it. Gtk-ted does not like
- * this; if we enable this code, it will crash.
- */
- if ((what_to_do & DO_QUERY) && in->completions [1]) {
+ if ((what_to_do & DO_QUERY) && in->completions && in->completions [1]) {
int maxlen = 0, i, count = 0;
int x, y, w, h;
int start_x, start_y;
@@ -999,11 +995,17 @@ complete_engine (WInput *in, int what_to
void complete (WInput *in)
{
+ int engine_flags;
+
if (in->completions)
- while (complete_engine (in, DO_QUERY));
- else if (show_all_if_ambiguous){
- complete_engine (in, DO_INSERTION);
- while (complete_engine (in, DO_QUERY));
- } else
- complete_engine (in, DO_INSERTION);
+ engine_flags = DO_QUERY;
+ else
+ {
+ engine_flags = DO_INSERTION;
+
+ if (show_all_if_ambiguous)
+ engine_flags |= DO_QUERY;
+ }
+
+ while (complete_engine (in, engine_flags));
}
More information about the mc-devel
mailing list