[bug #18695] tab completion vs. spaces and escaping



URL:
  <http://savannah.gnu.org/bugs/?18695>

                 Summary: tab completion vs. spaces and escaping
                 Project: GNU Midnight Commander
            Submitted by: egmont
            Submitted on: Friday 01/05/2007 at 13:07
                Category: None
                Severity: 3 - Normal
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
                 Release: current (CVS or snapshot)
        Operating System: GNU/Linux

    _______________________________________________________

Details:

Tab completion (Alt+Tab or Escape+Tab, I'll refer to these simply as Tab)
works exactly the same way in the command line and in dialog boxes (such as
copy/move file). The function complete() in src/complete.c only takes a
widget as its input and performs the completion.

This approach is wrong, since the dialog boxes and the command line have
different word splitting and escaping rules, they cannot be treated the same
way. Currently they both have bugs. (I found these while trying to tidy up my
mp3s, where lots of file and directory names contain spaces.)

In the file copy and similar dialogs, filenames are typed as pure strings
without any kind of escaping, and a text entry only takes one filename.
However, splitting at spaces is still performed. Suppose I have a directory
named "/tmp/a bcde". I press F5/F6 on a file, and type "/tmp/a" and then Tab,
it completes to "/tmp/a bcde". This is okay. But if I type "/tmp/a bc" and
press Tab now, it completes to the files in the current directory whose name
begins with "bc", due to the splitting at the space. Similarly, if I already
have "/tmp/a bcde/" in the edit field, it won't complete to subdirectories or
files of this directory. In this case the whole content of the field should be
treated as one, not being split at spaces.

In the command line, splitting at spaces is okay, however, we would need some
escaping and unescaping too, which doesn't happen. (Note: Esc followed by
Enter correctly escapes the filename when it puts it into the cmdline.)
Example: type "ls /tmp/a" and then Tab, you'll have "ls /tmp/a bcdefgh/" in
the command line, which clearly won't list the contents of that directory due
to the unescaped space character. Another example: type "ls /tmp/a\ b" and hit
Tab, it won't complete to "ls /tmp/a\ bcde/", but it should.

I understand that it is beyond the scope of mc to perform a full shell syntax
parsing (single and double quotes, nesting them etc.). This doesn't even
happen when Esc Enter is pressed: backslashes are inserted even between
quotes, but I'm fine with that. However, mc should produce proper escaping
when inserting spaces or other special chars as a result of completion, and
should be able to parse the backslash escaping it created (or the user typed)
when doing further completion.

Obviously the current design of the complete() function to take only a widget
is not okay (unless there's some room in the widget to store splitting and
escaping rules). There are two main possible solutions I can see, but
probably they'd eventually lead to basically the same code.

1) modify complete() so that it receives information on word splitting and
escaping, so that it becomes more complex and probably more buggy and harder
to maintain, but solves everything we need.

2) remove the word splitting code from complete(), so that it becomes simpler
and perfect for the file copy/move widgets. Slightly modify its interface to
take and return string and cursor positions instead of widget. Then make the
command line editor split at unescaped spaces, unescape the resulted word,
call complete() on this temporary string, escape the result of completion and
put back in the command line.

Finally, we should check how the internal "cd" command handles its arguments.
Currently it seems to do a lot of heuristics. For example, if I type "cd
a\\\\b" (four backslashes) then it tries to change to the directory called
"a\\\\b" (four backslashes) but if there's no such directory, it changes to
"a\\b" (two backslashes). This seems to be terrible, and leads to bugs, e.g.
if the cursor is on "a\\b" and I type "cd " followed by a Tab, I get the
command "cd a\\\\b" and hence it'll change to "a\\\\b" which is not the
desired directory. I'd remove all the heuristics and perform the usual
command line unescaping, just as if it was an external command.





    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?18695>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]