On Sat Apr 26 17:10:07 2025 +0000, Joe Souza wrote:
> Paths need to be quoted if they are long file names or they contain
> spaces, hence the check for findData.cAlternateFileName.
To do what you're asking here we would need to track whether each level in the path requires quotes, not just the current filename.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7843#note_101950
On Sat Apr 26 15:12:32 2025 +0000, eric pouech wrote:
> I think quote handling is not done as it should
> from what I see on native: quotes are added when generated word does
> contain characters that would need to be escaped (eg ' ', but didn't
> check all the others)
> need quote is an attribute of current filename (ie they are removed when
> the new (partial) matching file no longer needs them) ; so quotes
> shouldn't be part of the SEARCH_CONTEXT, but only used for display
> (basically: go to beg of word; if needs quotes, print quote; print
> (partial) word; print ending quotes (if needed)
Paths need to be quoted if they are long file names or they contain spaces, hence the check for findData.cAlternateFileName.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7843#note_101949
didn't play a lot with resulting code, mostly reviewed it
note: dir "c:\\Programs Files\\"\<tab\> should circle among the subdirectories... current code doesn't
also dir c\<tab\> (with a first file displayed), then reduce size of console window to be shorter than input line, will display input on line after the prompt
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7843#note_101938
eric pouech (@epo) commented about programs/cmd/lineedit.c:
> + }
> + lstrcatW(searchstr, L"*");
> + TRACE("New search: [%s]\n", wine_dbgstr_w(searchstr));
> +
> + sc.isDirSearch = IsDirectoryOperation(inputBuffer, inputBufferLength);
> + }
> +
> + FindNextMatchingDirectoryEntry(searchstr, &sc);
> +
> + if (sc.haveSearchResult) {
> + /* If this is our first time through here for this search, we need to find the insert position
> + * for the results. Note that this is very likely not the same location as the search position.
> + */
> + if (!sc.insertPos) {
> + /* If user entered a backslash after quotes, remove the quotes. */
> + if (curPos > 2 && inputBuffer[curPos-2] == L'\"' && inputBuffer[curPos-1] == L'\\') {
I think quote handling is not done as it should
from what I see on native: quotes are added when generated word does contain characters that would need to be escaped (eg ' ', but didn't check all the others)
need quote is an attribute of current filename (ie they are removed when the new (partial) matching file no longer needs them) ; so quotes shouldn't be part of the SEARCH_CONTEXT, but only used for display (basically: go to beg of word; if needs quotes, print quote; print (partial) word; print ending quotes (if needed)
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7843#note_101937
eric pouech (@epo) commented about programs/cmd/lineedit.c:
> + } else {
> + cc = len;
> + while (cc > 0 && inputBuffer[cc] != L' ' && inputBuffer[cc] != L'\t') {
> + cc--;
> + }
> + }
> + }
> +
> + if (cc != sc->searchPos || inputBuffer[sc->searchPos] == L'\\') {
> + cc++;
> + }
> +
> + sc->insertPos = cc;
> +}
> +
> +static void FindNextMatchingDirectoryEntry(const WCHAR *searchstr, PSEARCH_CONTEXT sc)
a couple of comments here:
* actually, this is not exactly how native (Win10) behaves: native captures the list of matching files at first tab usage, and doesn't update that list if eg. a file matching the pattern is added
* the way done here is a bit more dynamic (as it would capture file creation/deletion), and I don't think it matters much from a user perspective
the main thing I'm concerned about is that code to handle backwards shift-tab will be a bit more painful, and also the restart case (when the matched file is deleted)
I think code would be simpler and more readable when storing the list of files, but I won't block on that. I let you pick up your favorite one.
if you keep current logic, it seems to me that:
* \-\>hadOneMatch is only used locally, and should rather be a local variable
* \-\>hasSearchResult would make more sense be return value from this function
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7843#note_101936
eric pouech (@epo) commented about programs/cmd/lineedit.c:
> + int lastStartQuote;
> + int searchPos;
> + int insertPos;
> +} SEARCH_CONTEXT, *PSEARCH_CONTEXT;
> +
> +
> +static BOOL IsDirectoryOperation(const WCHAR *inputBuffer, const ULONG inputBufferLength)
> +{
> + int cc = 0;
> + BOOL ret = FALSE;
> +
> + while (cc < inputBufferLength && (inputBuffer[cc] == L' ' || inputBuffer[cc] == L'\t')) {
> + cc++;
> + }
> +
> + if ((cc + 2 < inputBufferLength && (inputBuffer[cc + 2] == L' ' || inputBuffer[cc + 2] == L'\t')) &&
questionning about finding the end of first word algorithm
native behavior is very inconsistent
`>cd\windows`
(note that there's no space between "cd" and "\\"). is supported as command, but tab-completion on "windows" doesn't work
**but**
`>cd"\windows"`
(idem no space, but with quotes). isn't supported as a command, but tab-completion does work
since this relates to corner cases of user interaction, I'm not sure we want to mimic all these broken behaviors
for consistency I'd rather suggest that you use `WCMD_parameter` to split the edit line into separate words you can then work upon
this at least will provide consistency across all the code
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/7843#note_101935