Initial implementation: Support \U\u\L\l replace modifiers#96128
Initial implementation: Support \U\u\L\l replace modifiers#96128roblourens merged 10 commits intomicrosoft:masterfrom irridia:kb-filereplace-case
Conversation
…ement to alter word case; tests TBD
|
Thanks for the PR! We are wrapping up the April release this week but I will review it next week for May. It looks good at first glance. |
roblourens
left a comment
There was a problem hiding this comment.
This looks like a good approach, but it's only hooked up for the find widget in the editor, could you do it for both the editor and workspace replace? All you have to do is move it to a helper method that can be called from replacePattern.ts and also from somewhere in .../search/.... You can look at what we did for the "preserve case" feature for inspiration, see how buildReplaceStringWithCasePreserved is called.
|
I spent some time yesterday looking through the implementations of ReplacePattern in vs/editor/contrib/find/replacePattern.ts and vs/workbench/services/search/common/replace.ts. Each of these implements different mechanisms for the CharCode The alternative IMO is to choose (or combine) one of the ReplacePattern implementations, move it to vs/base/common/search.ts (or perhaps .../replace.ts) and tweak the small handful of callers. I'm probably not the best choice to perform a nuanced refactor since I'm a TS noob; however I can likely implement the replacement change in .../replace.ts as a parallel to .../replacePattern.ts. Thoughts? |
|
Yeah, I see why it will be a little complicated to do that and why it is different than what we did for |
|
I'd be happy to do the parallel PR on the workbench path. It's sort of continuing artificial code separation, but it will at least eliminate a new difference between the implementations. |
|
That sounds good to me! |
|
I've spent a couple of hours on implementing case operations in |
|
I am sorry that I don't remember everything. Here is a comment I could find -- #18111 (comment) ... I think I found the issue #18111 (searching for So I have changed the text buffer search to return captured groups while searching, so the capture groups are those of searching in a large string. But the search across files could not do that, so I believe that is the point where I forked things. |
|
Oh, that's right. So you are able to get the groups as you go. Search is not able to do that because ripgrep doesn't provide that detailed info, so we have to rerun the regex on the frontend, with hacks to make it work for lookaround. So given that limitation I think we would have to either
Haven't looked closely enough to eliminate either of those, I think the second sounds easier, what do you think @irridia? |
|
I'm not yet familiar with the regex handoffs between TS and ripgrep—would ripgrep have to support the same case change operations, or is TS performing the replacement and ripgrep is more of a file buffer, match-only iterator? A String.replace() replacer() function defeats the internal parameter handling AFAICT, which means that the replacer has to walk the replacement pattern character at a time and replace the various $N instances. This isn't hugely challenging but it's very reinvent-the-wheel-y and duplicates a lot of the work and logic I see in So while I agree the second sounds easier, it also feels like it's fairly significantly increasing the difference between these fundamentally identical code paths. The current codepath is already applying the regex twice, once into Moving the vs/editor/contrib/find logic to vs/base/common might be the best use of time, even if it delays the case ops support. Just IMHO, still very much a noob to this codebase. |
|
Ripgrep wouldn't have to support it. It only tells us what the matches are. So we are stuck at least rerunning the regex. And I wouldn't call the two code paths fundamentally identical, they have the same apparent effect but have to do it in different ways. Using a replacement function would be extra work but at least then it parses the replacement patterns for you, which I think is a lot of the work. And I am ok with implementing this feature separately but still I would support you if you want to look into trying to merge the two code paths, that would be awesome if it's possible, as long as it's not going to lead to breaking a bunch of stuff. |
Support \U\u\L\l modifiers to search replacement to alter word case in the per-file Find/Replace flow. This does not affect the "Replace in Files..." flow, which appears to rely on ripgrep.
The behavior is patterned after Boost, but only applied to the replacement text, not subsequent content. Thus the \E isn't relevant. This is also vaguely similar to other replacement syntax, like pcre2 and perl.
For example, to export a file full of non-exported functions in a Go file:
Find:
^func (\w+)\(Replace:
func \u$1(Example:
func myPrivateFunc(...Result:
func MyPrivateFunc(...With
\U:func MYPRIVATEFUNC(...With
\l\l\l\U:func mypRIVATEFUNC(...This PR partially addresses #12185