Skip to content

Commit b00a45e

Browse files
committed
feat(vscode-search): add full workspace search provider integrated with VSCode file system
1 parent 7a02da8 commit b00a45e

7 files changed

Lines changed: 1063 additions & 95 deletions

File tree

README.md

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# @codingame/monaco-vscode-api · [![monthly downloads](https://img.shields.io/npm/dm/@codingame/monaco-vscode-api)](https://www.npmjs.com/package/@codingame/monaco-vscode-api) [![npm version](https://img.shields.io/npm/v/@codingame/monaco-vscode-api.svg?style=flat)](https://www.npmjs.com/package/@codingame/monaco-vscode-api) [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/codingame/monaco-vscode-api/pulls)
22

3-
This [NPM module](https://www.npmjs.com/) allows to integrate full VSCode functionality into your `monaco-editor`.
3+
This [NPM module](https://www.npmjs.com/) allows to integrate full VSCode functionality into your `monaco-editor`.
44

55
For more information, please checkout the project's [wiki](https://github.com/CodinGame/monaco-vscode-api/wiki).
66

@@ -18,36 +18,43 @@ npm install monaco-editor@npm:@codingame/monaco-vscode-editor-api
1818
`@codingame/monaco-vscode-editor-api` is installed as an alias to `monaco-editor` because it provides the same api as the official `monaco-editor`
1919

2020
# Usage
21+
2122
If you are just starting with `monaco-editor` and `monaco-vscode-api` you may find helpful the [Getting Started Guide](https://github.com/CodinGame/monaco-vscode-api/wiki/Getting-started-guide) in the wiki.
23+
2224
## Monaco service override
2325

24-
Most of VSCode functionality implemented as "services", e.g.
26+
Most of VSCode functionality implemented as "services", e.g.
27+
2528
- theme service, providing support for VSCode themes
2629
- languages service, providing support for different language features.
2730

28-
By default, Monaco uses a simplified versions of the VSCode services, called `standalone` services.
29-
This package allows to
30-
1) override them with fully-functional alternatives from VSCode
31-
2) add new services that were not included in Monaco
31+
By default, Monaco uses a simplified versions of the VSCode services, called `standalone` services.
32+
This package allows to
33+
34+
1. override them with fully-functional alternatives from VSCode
35+
2. add new services that were not included in Monaco
3236

3337
Here is an example usage that overrides Monaco default configuration with VSCode json-based settings:
38+
3439
```typescript
3540
// default monaco-editor imports
36-
import * as monaco from 'monaco-editor';
37-
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
41+
import * as monaco from 'monaco-editor'
42+
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
3843

3944
// utilities to override Monaco services
4045
import { initialize } from '@codingame/monaco-vscode-api'
41-
import getConfigurationServiceOverride, { updateUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override'
46+
import getConfigurationServiceOverride, {
47+
updateUserConfiguration
48+
} from '@codingame/monaco-vscode-configuration-service-override'
4249

4350
window.MonacoEnvironment = {
4451
getWorker: (_moduleId, _label) => new editorWorker()
4552
}
4653

4754
// overriding Monaco service with VSCode
4855
await initialize({
49-
...getConfigurationServiceOverride(),
50-
});
56+
...getConfigurationServiceOverride()
57+
})
5158

5259
// json config like in vscode settings.json
5360
updateUserConfiguration(`{
@@ -60,17 +67,19 @@ updateUserConfiguration(`{
6067

6168
// creating an editor with VSCode configuration
6269
monaco.editor.create(document.getElementById('editor')!, {
63-
value: "Editor with VSCode config and large bold fonts",
64-
});
70+
value: 'Editor with VSCode config and large bold fonts'
71+
})
6572
```
73+
6674
> [!NOTE]
6775
> `initialize` can only be called once (and it should be called BEFORE creating your first editor).
6876
69-
7077
Each `get<service-name>ServiceOverride` contains the service and some glue to make VSCode service work with Monaco.
7178

7279
### List of service overrides
80+
7381
Some basic service overrides are coming with this package as dependencies:
82+
7483
- **Base**: `@codingame/monaco-vscode-base-service-override`
7584
- Contains some general-use services that are mandatory to most of the other features
7685
- **Host**: `@codingame/monaco-vscode-host-service-override`
@@ -84,10 +93,12 @@ Some basic service overrides are coming with this package as dependencies:
8493
- It supports adding overlay filesystems for `file://` files
8594
- **QuickAccess**: `@codingame/monaco-vscode-quickaccess-service-override`
8695
- Enables the quickaccess menu in the editor (press F1 or ctrl+shift+p)
96+
- **Search**: `@codingame/monaco-vscode-search-service-override`
97+
- Provides workspace search functionality for both Command Palette file search (Ctrl+P) and Search panel (Ctrl+Shift+F)
98+
- Enables searching through files and text content within your workspace
8799

88100
However, most of the services are separated into different modules, so they can be imported as required. You can find a full list of services in the [corresponding wiki page](https://github.com/CodinGame/monaco-vscode-api/wiki/List-of-service-overrides).
89101

90-
91102
### Default vscode extensions
92103

93104
VSCode uses a bunch of default extensions. Most of them are used to load the default languages and grammars (see <https://github.com/microsoft/vscode/tree/main/extensions>).
@@ -104,31 +115,31 @@ Here is an example of usage of default VSCode theme extension with theme service
104115

105116
```typescript
106117
// importing default VSCode theme extension
107-
import "@codingame/monaco-vscode-theme-defaults-default-extension";
118+
import '@codingame/monaco-vscode-theme-defaults-default-extension'
108119

109120
// default monaco-editor imports
110-
import * as monaco from 'monaco-editor';
111-
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
121+
import * as monaco from 'monaco-editor'
122+
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
112123

113124
// utilities to override Monaco services
114125
import { initialize } from '@codingame/monaco-vscode-api'
115-
import getThemeServiceOverride from "@codingame/monaco-vscode-theme-service-override";
126+
import getThemeServiceOverride from '@codingame/monaco-vscode-theme-service-override'
116127

117128
window.MonacoEnvironment = {
118129
getWorker: function (_moduleId, _label) {
119-
return new editorWorker();
130+
return new editorWorker()
120131
}
121132
}
122133

123134
// overriding Monaco service with VSCode
124135
await initialize({
125-
...getThemeServiceOverride(),
126-
});
136+
...getThemeServiceOverride()
137+
})
127138

128139
// creating an editor with VSCode theme
129140
monaco.editor.create(document.getElementById('editor')!, {
130-
value: "Editor with VSCode Theme Support",
131-
});
141+
value: 'Editor with VSCode Theme Support'
142+
})
132143
```
133144

134145
See [the full list of ported default extensions](https://www.npmjs.com/search?q=%40codingame%2Fmonaco-vscode-*-default-extension)
@@ -176,7 +187,6 @@ This library also offers the possibility to localize vscode and the extensions i
176187

177188
⚠️ The language pack should be imported and loaded BEFORE anything else from this library is loaded. Otherwise, some translations would be missing and an error would be displayed in the console. ⚠️
178189

179-
180190
## Model creation
181191

182192
The official `monaco-editor` package provides a function to create models: `monaco.editor.createModel`.
@@ -192,6 +202,7 @@ It has some pros:
192202
- It is possible to call the method multiple times on the same file to get multiple references. The model is disposed when there is no reference left
193203

194204
To work, it needs the file to exist on the virtual filesystem. It can be achieved either by:
205+
195206
- using the `registerFileSystemOverlay` from the files service override, which can be cleaned when not needed anymore (recommended)
196207
- by using the second argument of the `createModelReference` function, which writes the file content to the virtual filesystem before creating the model
197208

@@ -286,6 +297,7 @@ Try it out on <https://monaco-vscode-api.netlify.app/>
286297

287298
There is a demo that showcases the service-override features.
288299
It includes:
300+
289301
- Languages
290302
- VSCode themes
291303
- Textmate grammars (requires VSCode themes)
@@ -330,6 +342,7 @@ The library supports shadow-dom.
330342
⚠️ VSCode itself doesn't support shadow dom, and there are multiple parts that needed to be patched in order for it to work.
331343

332344
There are multiple benefits of using it:
345+
333346
- Your custom global style won't impact the VSCode workbench style (for instance if you did override the default [box-sizing](https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing))
334347
- The VSCode styles won't impact other parts of your app
335348
- You page head won't be polluted with dozen of css files from VSCode
@@ -406,19 +419,20 @@ To still be able to do it, a possibility is to run all VSCode code inside an ifr
406419
To better integrate it, it's also possible to run the code in the iframe, but make the code interact with the main page dom.
407420

408421
This library supports that mode. To enable that, you should
422+
409423
- have a secondary html entrypoint, that initialize the services
410424
- load that secondary html in an iframe
411425
- in the iframe, set `window.vscodeWindow` to the parent window, also initialize the service with a container mounted in that window
412426
- do not import any monaco-vscode-library from the top window, but you can declare functions on the iframe window to get objects to the top window
413427

414428
To "unload" the workbench, you should:
429+
415430
- remove the iframe element from the top frame
416431
- remove or empty the workbench container
417432
- cleanup the elements that VSCode has injected in the page head: `document.querySelectorAll('[data-vscode]').forEach((el) => el.remove())`
418433

419434
⚠️ `window.vscodeWindow` should be set BEFORE any VSCode code is loaded
420435

421-
422436
Note: it can be used in combination with shadow dom
423437

424438
It's demonstrated in the demo, by adding `?sandbox` query parameter to the demo url

demo/src/features/search.ts

Lines changed: 0 additions & 66 deletions
This file was deleted.

demo/src/main.common.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { ExtensionHostKind, registerExtension } from '@codingame/monaco-vscode-a
44
import { useHtmlFileSystemProvider } from './setup.common'
55
import './features/output'
66
import './features/debugger'
7-
import './features/search'
87
import './features/intellisense'
98
import './features/notifications'
109
import './features/terminal'

src/service-override/search.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,18 @@ import { SearchProviderType } from 'vs/workbench/services/search/common/search'
2323
import { Schemas } from 'vs/base/common/network'
2424
import type { IFileSystemProvider } from 'vs/platform/files/common/files'
2525
import { HTMLFileSystemProvider } from 'vs/platform/files/browser/htmlFileSystemProvider'
26+
import { WorkspaceSearchProvider } from './tools/search-providers/workspace-search-provider'
27+
import { IWorkspaceContextService } from '../services'
28+
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService.service'
29+
import { IConfigurationService } from 'vs/platform/configuration/common/configuration.service'
2630

2731
function isHTMLFileSystemProvider(
2832
provider: IFileSystemProvider
2933
): provider is HTMLFileSystemProvider {
3034
return (provider as HTMLFileSystemProvider).directories != null
3135
}
3236

33-
// Duplicated from RemoteSearchService, with a check on the file system provider being an HTMLFileSystemProvider
37+
// Custom search service that handles different file system types and remote connections
3438
class CustomSearchService extends SearchService {
3539
constructor(
3640
@IModelService modelService: IModelService,
@@ -40,7 +44,10 @@ class CustomSearchService extends SearchService {
4044
@IExtensionService extensionService: IExtensionService,
4145
@IFileService fileService: IFileService,
4246
@IInstantiationService private readonly instantiationService: IInstantiationService,
43-
@IUriIdentityService uriIdentityService: IUriIdentityService
47+
@IUriIdentityService uriIdentityService: IUriIdentityService,
48+
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService,
49+
@IRemoteAgentService remoteAgentService: IRemoteAgentService,
50+
@IConfigurationService configurationService: IConfigurationService
4451
) {
4552
super(
4653
modelService,
@@ -51,10 +58,37 @@ class CustomSearchService extends SearchService {
5158
fileService,
5259
uriIdentityService
5360
)
61+
62+
const hasRemoteConnection = remoteAgentService.getConnection() !== null
63+
if (hasRemoteConnection) {
64+
// Don't register custom providers to avoid conflicts
65+
return
66+
}
67+
68+
// For local scenarios, choose the appropriate search provider
5469
if (isHTMLFileSystemProvider(fileService.getProvider(Schemas.file)!)) {
5570
const searchProvider = this.instantiationService.createInstance(LocalFileSearchWorkerClient)
5671
this.registerSearchResultProvider(Schemas.file, SearchProviderType.file, searchProvider)
5772
this.registerSearchResultProvider(Schemas.file, SearchProviderType.text, searchProvider)
73+
} else {
74+
const workspaceSearchProvider = new WorkspaceSearchProvider(
75+
fileService,
76+
logService,
77+
workspaceContextService,
78+
undefined,
79+
configurationService
80+
)
81+
82+
this.registerSearchResultProvider(
83+
Schemas.file,
84+
SearchProviderType.file,
85+
workspaceSearchProvider
86+
)
87+
this.registerSearchResultProvider(
88+
Schemas.file,
89+
SearchProviderType.text,
90+
workspaceSearchProvider
91+
)
5892
}
5993
}
6094
}

0 commit comments

Comments
 (0)