GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Fix tab completion for filename contains literal wildcard character by kwkam · Pull Request #7407 · PowerShell/PowerShell Conversation
Contributor
PR Summary*System.Management.Automation/engine/CommandCompletion/CompletionCompleters: *System.Management.Automation/engine/regex: *System.Management.Automation/namespaces/LocationGlobber: PR Checklist
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions*System.Management.Automation/engine/CommandCompletion/CompletionCompleters: Use WildcardPattern::Escape to escape completion text of filename. *System.Management.Automation/engine/regex: WildcardPattern::Escape should also escape "`" since WildcardPattern::Unescape would unescape it, and the matcher parse it as escape character. *System.Management.Automation/namespaces/LocationGlobber: Do not pass regex escaped string to WildcardPattern::Get. This fails tab completion when doing "./path/to/`[f"<TAB>.
kwkam
requested review from
Bruce Payette (BrucePay),
Andrew (anmenaga) and
Dongbo Wang (daxian-dbw)
as code owners
This was referenced
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was an error while loading. Please reload this page.
|
kwkam Please remove "[Feature]" from title in your PRs. We need this prefix only in commit header to force run feature tests. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
This PR has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed if no further activity occurs within 10 days. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| @{ inputStr = "Get-Process >'.\My ``[Path``]\'"; expected = "'.${separator}My ``[Path``]${separator}test.ps1'" } | ||
| @{ inputStr = "Get-Process >${tempDir}\My"; expected = "'${tempDir}${separator}My ``[Path``]'" } | ||
| @{ inputStr = "Get-Process > '${tempDir}\My ``[Path``]\'"; expected = "'${tempDir}${separator}My ``[Path``]${separator}test.ps1'" } | ||
| @{ inputStr = "cd 'My ``["; expected = "'.${separator}My ``[Path``]'" } |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
-Path (which support globbing), just like we do in bash (eg. touch \[test\]). But if you typed escape and auto completion still did not work, that is because by default, powershell treats "unquoted string without space" like "double-quoted string", that "double-quoted string" will consume escape character. For file name [test], either Get-Content -Path ```[ or Get-Content -Path '`[ will work.-LiteraPath?Get-Item -LiteralPath [(TAB) for a file named [test] and it did auto complete.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
dir and then type directory or file name as one see on screen - without escapes. In the scenario both the user and PowerShell know right name. And more, we can have both names - with escape char too.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
-Path support wildcard. When a path can be an expression, the special characters should always be escaped otherwise it will become too complicated. For example, in a directory there are A.txt, B.txt and [AB].txt, what should Get-Item -Path [AB].txt return?-Path and -LiteralPath and both will complete the file name. eg.New-Item -Name 'My [test]'Get-Item '.\My `[ will be completed to Get-Item '.\My `[test`]', andGet-Item -LiteralPath '.\My [ will be completed to Get-Item -LiteralPath '.\My [test]'
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
| // | ||
| if (IsWildcardChar(ch) && !charsNotToEscape.Contains(ch)) | ||
| if ((IsWildcardChar(ch) || ch == escapeChar) && | ||
| !charsNotToEscape.Contains(ch)) |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Why we always should escape the escape char? What scenario don't work without fix?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
`[test`]2 due to the incorrect handling of wildcard character, we cannot remove it using the -Path parameter with the tab completed name.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that we should test if a file/directory/path exists before trying escape. If exist then return the path. Then continue with escaping wildcard chars. Then continue with expansion wildcards if -Path.
Also what if there is some special symbols in the path? Seems we should process them in cycle.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Okay, I know what is wrong here. This part is to fix the WildcardPattern::Escape function itself, which is not necessary related to the file system.
When WildcardPattern::Get parse a pattern string, it always treats the escape character as escape character of an escape character. That means, `` will be parsed to `.
And so is the WildcardPattern::Unescape method, [WildcardPattern]::Unescape('``') will return ` instead of ``.
But, [WildcardPattern]::Escape('`') does not escape the escape character, which conflicts with the others.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
kwkam I see your point.
We have the public API
public static string Escape(string pattern)
So the change is a breaking change and it is not desirable to change this behavior until it is established that this is a significant bug.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Ilya (@iSazonov) Yes, we should be careful with changes in public API, but I doubt if this is not a significant bug. For example, there is a list of text:
`[HIGH] patch 1`
`[MED] update 1`
`[LOW] patch 1`
`[MED] patch 2`
`[HIGH] hotfix 3`
`[LOW] patch 2`
`[LOW] hotfix 3`
Now, I want to search for `[LOW] patch 1` and `[LOW] patch 2`, and I am using WildcardPattern:
$prefix = '`[LOW] patch ' $pattern = '[1-2]' $suffix = '`' $sarg = [WildcardPattern]::Escape($prefix) + $pattern + [WildcardPattern]::Escape($suffix) $opts = [Management.Automation.WildcardOptions]::Compiled $matcher = [WildcardPattern]::Get($sarg, $opts) $ListOfText | ? {$matcher.IsMatch($_)}
No result will be return because of the inconsistency between the Escape method and the WildcardPattern parser. (And this is also the cause of the issue in auto-completed filename which contains escape character)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Thanks for good example!
We need PowerShell Committee conclusion.
/cc Steve Lee (@SteveL-MSFT)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
kwkam Sorry for delay - it is very sensetive aria and we should very careful. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Ilya (@iSazonov) Yes, that's why this PR was placed behind the cmdlet ones. Please let me know if something is not correct/not working. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
cc Bruce Payette (@BrucePay) to follow-up |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
This PR has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed if no further activity occurs within 10 days. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Steve Lee (@SteveL-MSFT) We have too many frozen PRs. How we can resolve the problem? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Bruce Payette (@BrucePay) will follow-up on this specific PR |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
This PR has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed if no further activity occurs within 10 days. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Co-Authored-By: Ilya <[email protected]>
| if (CompletionRequiresQuotes(completionText, !useLiteralPath)) | ||
| { | ||
| var quoteInUse = quote == string.Empty ? "'" : quote; | ||
|
|
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
should all changes be behind the experimental feature?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This was a condition of the committee
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Except filename completion will now also escape * and ? in non-literal path, the behaviour should be identical unless the experimental feature (the breaking part) is enabled.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
I tested a variation of this PR, while testing the PR I am preparing to fix all argument completion patterns along with variable and member completions, #10226. Previously, I could not use Get-Content to read the content of a file named I did not modify the WildCardPattern.Escape() method, but instead added Now Get-Content reads the content of that file. Even if changes to WildCardPattern.Escape() are considered too breaking, at least manually escape the backticks, in each call. Unfortunately this doesn't fix the issue with redirection, which accepts a wildcard path, but then sends it to out-file as a literal. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Carl Morris (@msftrncs) It was in another PR #9258 |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
kwkam Please resolve merge conflicts and address comments. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
|
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| @@ -0,0 +1,68 @@ | |||
| # Copyright (c) Microsoft Corporation. All rights reserved. | |||
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
| # Copyright (c) Microsoft Corporation. All rights reserved. | |
| # Copyright (c) Microsoft Corporation. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Dongbo Wang (@daxian-dbw) Can you review this? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 15 days. It will be closed if no further activity occurs within 10 days of this comment. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Ilya (@iSazonov) could this pr be reopened? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Florian Heberl (@floh96) It makes no sense to reopen. The work could be continue if anybody grabbed the work and MSFT team agreed to review. Now you could open new issue to discuss and vote. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.