-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Search and Replace Widget #1755
Conversation
1b2a8d8
to
bd9c5c1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've noticed that the search does not find everything for me. Try to search for foo
, it finds storage-service.spec.ts
then adjust to fo
, it does not find it anymore. Should be fixed separately?
@@ -0,0 +1,6 @@ | |||
<!--Copyright (c) Microsoft Corporation. All rights reserved.--> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbicker please check that files have our copyrights in addition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
const widget = currentTitle.owner; | ||
const result = this.resultTree.get(widget.editor.uri.withoutScheme().toString()); | ||
if (result) { | ||
this.decorateEditor(result, widget); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cases when result
are undefined should be handled as well otherwise decoration won't be ever removed
return new URI(uri).withScheme(MEMORY_TEXT).withQuery(lines.join("\n")); | ||
} | ||
|
||
protected decorateEditor(node: ResultNode, editorWidget: EditorWidget) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following code should handle removing decorations:
protected decorateEditor(node: ResultNode | undefined, editorWidget: EditorWidget) {
const oldDecorations = this.appliedDecorations.get(key) || [];
const appliedDecorations = editorWidget.editor.deltaDecorations({
newDecorations: this.createEditorDecorations(node),
oldDecorations,
uri: editorWidget.editor.uri.toString()
});
this.appliedDecorations.set('search-in-workspace-matches', appliedDecorations);
}
* Replaces the text of source given in ReplacetextParams. | ||
* @param params: ReplaceTextParams | ||
*/ | ||
replaceText(params: ReplaceTextParams): Promise<boolean>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to have the general solution: #1756
Please open a follow-up issue to refactor it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -142,6 +142,12 @@ is not optimized for dense, information rich UIs. | |||
--theia-removed-color0: rgba(230, 0, 0, 0.8); | |||
--theia-modified-color0: rgba(0, 100, 150, 0.8); | |||
|
|||
--theia-search-match-color0: rgba(234, 92, 0, 0.33); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we consider to move them to the search in workspace extension? They are not supposed to be used in core. If it is hard, please at least file a follow-up issue to make it easier to define themed variables for extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved them to the extension and added new variables here. Not the best solution, a bit arbitrary maybe. I guess we should edit this with #1486.
Regarding themed variables for extensions: we shouldn't do such thing and leave every theme related variable in core.
@@ -29,4 +49,16 @@ export default new ContainerModule(bind => { | |||
const client = ctx.container.get(SearchInWorkspaceClientImpl); | |||
return WebSocketConnectionProvider.createProxy(ctx.container, '/search-in-workspace', client); | |||
}).inSingletonScope(); | |||
|
|||
bind(MemoryTextResourceResolver).toSelf().inSingletonScope(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about InMemoryTextResource
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, sounds better.
import { MEMORY_TEXT } from "./memory-text-resource"; | ||
import { FileResourceResolver } from "@theia/filesystem/lib/browser"; | ||
|
||
export interface ResultNode extends ExpandableTreeNode, SelectableTreeNode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about putting supplementary types under SearchInWorkspaceResultTreeWidget
. ResultNode
, ResultLineNode
sound generic. please review for other generic top level concepts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
|
||
protected changeEmitter: Emitter<Map<string, ResultNode>>; | ||
|
||
constructor( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/theia-ide/theia/wiki/Coding-Guidelines#property-injection please review for other occurences
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -0,0 +1,315 @@ | |||
.searchContainer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please review for missing copyrights in css
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
background: var(--theia-icon-clear); | ||
} | ||
|
||
.searchContainer .searchHeader .search-field { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please use more specific top level css class names to avoid collisions: theia-search-in-workspace-container
@kittaakos was suggesting to use t-
prefix instead to make it shorter: t-siw-container
We can discuss css convention on next dev meeting, agree on something as a team and follow it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
43e34d2
to
bf219ec
Compare
|
8024ad7
to
53b4380
Compare
92fd1b9
to
42e4397
Compare
42e4397
to
60fa482
Compare
93cb8f1
to
6eec2e2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
43936ac
to
b52950b
Compare
@jbicker, here is an earlier issue that was dealing with |
children: [] | ||
}; | ||
|
||
model.onSelectionChanged(nodes => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it will leak, please collect all listeners
exclude: [], | ||
maxResults: 500 | ||
}; | ||
this.resultTreeWidget.onChange(r => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it will leak, please collect all listeners with this.toDispose.push
const node = nodes[0]; | ||
if (SearchInWorkspaceResultLineNode.is(node)) { | ||
this.doOpen(node, true); | ||
} | ||
}); | ||
})); | ||
|
||
model.onNodeRefreshed(() => this.changeEmitter.fire(this.resultTree)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this event listener also should be captured, please review all new widgets in this PR that they capture all event listeners
seems like we are back to only flaky tests failing. |
Signed-off-by: Jan Bicker <jan.bicker@typefox.io>
8eb712e
to
84b26f7
Compare
Cool, please merge |
Hi Jan, Awesome work! Could you add a test that searches for a string that contains a double quote? I think it now fails because we use You can also input fun things like
which writes to /tmp/lol... So either we should not use |
@simark, thanks for the hint. I will take care of it. |
Also, please clean up the branch if you do not need it, @jbicker. Thanks! |
Can you explain why? From what I understand, the glob expressions are handled by rg, the shell should not play a role. More over, we probably don't want to depend on the particular shell that runs in the backend, different shells can have different behaviors. |
@simark: honestly I don't see anymore what the problem was without the shell option. So I removed it and also the quotes around the search term and the glob terms. So rg should handle the arguments, right? |
Search in workspace allows the user to search the whole workspace for textual occurences.
By default it searches for all text occurrences in all files in workspace case insensitive.
One can refine the search result by selecting "Match Case", "Match Whole Words" and "Use Regular Expressions" as well as using include and exclude fields with glob patterns.
The result tree is navigable by keyboard using cursor keys.
Additional control buttons above the search form will update the search results, collapse the result tree or reset the search form.
One can remove unwanted occurrences from the result tree by clicking the x on the right side of every tree element.
In addition to searching for text occurrences in the workspace the possibility to replace all matches are provided. The replace form field is hidden by default and can be expanded by clicking the small button on the left side of the search field.
In replace mode the selection of a result opens a diff editor widget where the left side shows the
original and the right side a preview with the replacements.
One is able to replace all or single occurrences in workspace.