Skip to content
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

Some minor fixes #235

Merged
merged 9 commits into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/stale_issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ jobs:
days-before-issue-close: 14
days-before-pr-stale: 30
days-before-pr-close: 14
exempt-issue-labels: "waiting-external"
exempt-pr-labels: "waiting-external"
stale-issue-label: "stale"
stale-pr-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity."
Expand Down
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,15 +282,27 @@ The api will use the manifest of a default vscode extension, which can be overri

You can also register a new extension from its manifest:
```typescript
import { registerExtension, initialize } from 'vscode/extensions'
import { registerExtension, initialize, ExtensionHostKind } from 'vscode/extensions'

await initialize()

const { registerFile: registerExtensionFile, getApi } = registerExtension(defaultThemesExtensions)
const extension = {
name: 'my-extension',
publisher: 'someone',
version: '1.0.0',
engines: {
vscode: '*'
},
contributes: {
}
}
const { registerFileUrl, getApi } = registerExtension(extension, ExtensionHostKind.LocalProcess)

registerExtensionFile('/file.json', async () => fileContent)
registerFileUrl('/file-extension-path.json', new URL('./file-real-path.json', import.meta.url).toString())

getApi().then(vscodeApi => vscodeApi.languages.registerCompletionItemProvider(...))
const vscode = await getApi()

vscode.languages.registerCompletionItemProvider(...)

```

Expand Down
34 changes: 4 additions & 30 deletions demo/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { registerFileSystemOverlay, HTMLFileSystemProvider } from '@codingame/mo
import * as vscode from 'vscode'
import { ILogService, StandaloneServices, IPreferencesService, IEditorService, IDialogService, getService } from 'vscode/services'
import { ConfirmResult, Parts, isPartVisibile, setPartVisibility } from '@codingame/monaco-vscode-views-service-override'
import { defaultUserConfigurationFile } from '@codingame/monaco-vscode-configuration-service-override'
import { defaultUserKeybindindsFile } from '@codingame/monaco-vscode-keybindings-service-override'
import { clearStorage, remoteAuthority } from './setup'
import { CustomEditorInput } from './features/customView'
import './features/debugger'
Expand Down Expand Up @@ -94,29 +96,7 @@ diagnostics.set(modelRef.object.textEditorModel!.uri, [{
source: 'Demo',
code: 42
}])

const settingsModelReference = await createModelReference(monaco.Uri.from({ scheme: 'user-store', path: '/User/settings.json' }), `{
"workbench.colorTheme": "Default Dark+",
"workbench.iconTheme": "vs-seti",
"editor.autoClosingBrackets": "languageDefined",
"editor.autoClosingQuotes": "languageDefined",
"editor.scrollBeyondLastLine": true,
"editor.mouseWheelZoom": true,
"editor.wordBasedSuggestions": false,
"editor.acceptSuggestionOnEnter": "on",
"editor.foldingHighlight": false,
"editor.semanticHighlighting.enabled": true,
"editor.bracketPairColorization.enabled": false,
"editor.fontSize": 12,
"audioCues.lineHasError": "on",
"audioCues.onDebugBreak": "on",
"files.autoSave": "afterDelay",
"files.autoSaveDelay": 1000,
"debug.toolBarLocation": "docked",
"editor.experimental.asyncTokenization": true,
"terminal.integrated.tabs.title": "\${sequence}",
"typescript.tsserver.log": "normal"
}`)
const settingsModelReference = await createModelReference(defaultUserConfigurationFile)
const settingEditor = createConfiguredEditor(document.getElementById('settings-editor')!, {
model: settingsModelReference.object.textEditorModel,
automaticLayout: true
Expand All @@ -134,13 +114,7 @@ settingEditor.addAction({
contextMenuGroupId: 'custom'
})

const keybindingsModelReference = await createModelReference(monaco.Uri.from({ scheme: 'user-store', path: '/User/keybindings.json' }), `[
{
"key": "ctrl+d",
"command": "editor.action.deleteLines",
"when": "editorTextFocus"
}
]`)
const keybindingsModelReference = await createModelReference(defaultUserKeybindindsFile)
createConfiguredEditor(document.getElementById('keybindings-editor')!, {
model: keybindingsModelReference.object.textEditorModel,
automaticLayout: true
Expand Down
37 changes: 35 additions & 2 deletions demo/src/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { initialize as initializeVscodeExtensions } from 'vscode/extensions'
import getModelServiceOverride from '@codingame/monaco-vscode-model-service-override'
import getNotificationServiceOverride from '@codingame/monaco-vscode-notifications-service-override'
import getDialogsServiceOverride from '@codingame/monaco-vscode-dialogs-service-override'
import getConfigurationServiceOverride from '@codingame/monaco-vscode-configuration-service-override'
import getKeybindingsServiceOverride from '@codingame/monaco-vscode-keybindings-service-override'
import getConfigurationServiceOverride, { initUserConfiguration } from '@codingame/monaco-vscode-configuration-service-override'
import getKeybindingsServiceOverride, { initUserKeybindings } from '@codingame/monaco-vscode-keybindings-service-override'
import getTextmateServiceOverride from '@codingame/monaco-vscode-textmate-service-override'
import getThemeServiceOverride from '@codingame/monaco-vscode-theme-service-override'
import getLanguagesServiceOverride from '@codingame/monaco-vscode-languages-service-override'
Expand Down Expand Up @@ -68,6 +68,39 @@ export const remoteAuthority = params.get('remoteAuthority') ?? undefined
const connectionToken = params.get('connectionToken') ?? undefined
const remotePath = remoteAuthority != null ? params.get('remotePath') ?? undefined : undefined

// Set configuration before initializing service so it's directly available (especially for the theme, to prevent a flicker)
await Promise.all([
initUserConfiguration(`{
"workbench.colorTheme": "Default Dark+",
"workbench.iconTheme": "vs-seti",
"editor.autoClosingBrackets": "languageDefined",
"editor.autoClosingQuotes": "languageDefined",
"editor.scrollBeyondLastLine": true,
"editor.mouseWheelZoom": true,
"editor.wordBasedSuggestions": false,
"editor.acceptSuggestionOnEnter": "on",
"editor.foldingHighlight": false,
"editor.semanticHighlighting.enabled": true,
"editor.bracketPairColorization.enabled": false,
"editor.fontSize": 12,
"audioCues.lineHasError": "on",
"audioCues.onDebugBreak": "on",
"files.autoSave": "afterDelay",
"files.autoSaveDelay": 1000,
"debug.toolBarLocation": "docked",
"editor.experimental.asyncTokenization": true,
"terminal.integrated.tabs.title": "\${sequence}",
"typescript.tsserver.log": "normal"
}`),
initUserKeybindings(`[
{
"key": "ctrl+d",
"command": "editor.action.deleteLines",
"when": "editorTextFocus"
}
]`)
])

// Override services
await initializeMonacoService({
...getExtensionServiceOverride(toWorkerConfig(ExtensionHostWorker)),
Expand Down
13 changes: 13 additions & 0 deletions scripts/vscode.patch
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,19 @@ index f23c48b7db1..3a638425a2d 100644
}

isVisible(): boolean {
diff --git a/src/vs/workbench/common/views.ts b/src/vs/workbench/common/views.ts
index 84cee2b04a6..63167893dd7 100644
--- a/src/vs/workbench/common/views.ts
+++ b/src/vs/workbench/common/views.ts
@@ -217,7 +217,7 @@ class ViewContainersRegistryImpl extends Disposable implements IViewContainersRe
const viewContainers = getOrSet(this.viewContainers, viewContainerLocation, []);
viewContainers.push(viewContainer);
if (options?.isDefault) {
- this.defaultViewContainers.push(viewContainer);
+ this.defaultViewContainers.unshift(viewContainer);
}
this._onDidRegister.fire({ viewContainer, viewContainerLocation });
return viewContainer;
diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
index e6ae569ad9d..3b2ac782391 100644
--- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
Expand Down
22 changes: 19 additions & 3 deletions src/service-override/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ConfigurationScope } from 'vscode/src/vs/platform/configuration/common/
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, IConfigurationNode, IConfigurationDefaults } from 'vs/platform/configuration/common/configurationRegistry'
import { Registry } from 'vs/platform/registry/common/platform'
import { VSBuffer } from 'vs/base/common/buffer'
import { IFileService } from 'vs/platform/files/common/files'
import { IFileService, IFileWriteOptions } from 'vs/platform/files/common/files'
import { ILogService } from 'vs/platform/log/common/log'
import { IColorCustomizations, IThemeScopedColorCustomizations } from 'vs/workbench/services/themes/common/workbenchThemeService'
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'
Expand All @@ -32,12 +32,26 @@ import { AbstractWorkspaceEditingService } from 'vs/workbench/services/workspace
import { URI } from 'vs/base/common/uri'
import 'vs/workbench/api/common/configurationExtensionPoint'
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService'
import getFileServiceOverride from './files'
import getFileServiceOverride, { initFile } from './files'
import { memoizedConstructor, unsupported } from '../tools'
import { registerServiceInitializePreParticipant } from '../lifecycle'
import { getService } from '../services'

// This is the default value, but can be overriden by overriding the Environment or UserDataProfileService service
const defaultUserConfigurationFile = URI.from({ scheme: Schemas.vscodeUserData, path: '/User/settings.json' })

/**
* Should be called only BEFORE the service are initialized to initialize the file on the filesystem before the configuration service initializes
*/
async function initUserConfiguration (configurationJson: string, options?: Partial<IFileWriteOptions>, file: URI = defaultUserConfigurationFile): Promise<void> {
await initFile(defaultUserConfigurationFile.scheme, file, configurationJson, options)
}

/**
* Can be called at any time after the services are initialized to update the user configuration
*/
async function updateUserConfiguration (configurationJson: string): Promise<void> {
const userDataProfilesService = StandaloneServices.get(IUserDataProfilesService)
const userDataProfilesService = await getService(IUserDataProfilesService)
await StandaloneServices.get(IFileService).writeFile(userDataProfilesService.defaultProfile.settingsResource, VSBuffer.fromString(configurationJson))
}

Expand Down Expand Up @@ -125,6 +139,8 @@ export default function getServiceOverride (defaultWorkspace: URI | IAnyWorkspac
}

export {
defaultUserConfigurationFile,
initUserConfiguration,
updateUserConfiguration,
getUserConfiguration,
onUserConfigurationChange,
Expand Down
27 changes: 25 additions & 2 deletions src/service-override/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -460,11 +460,16 @@ const fileSystemProvider = new OverlayFileSystemProvider()
fileSystemProvider.register(0, new MkdirpOnWriteInMemoryFileSystemProvider())

const extensionFileSystemProvider = new RegisteredFileSystemProvider(true)
const userDataFileSystemProvider = new InMemoryFileSystemProvider()

// Initialize /User/ folder to be able to write configuration and keybindings in it before the fileService is initialized
// The `mkdirp` logic is inside the service, and the provider will just fail if asked to write a file in a non-existent directory
void userDataFileSystemProvider.mkdir(URI.from({ scheme: Schemas.vscodeUserData, path: '/User/' }))

const providers: Record<string, IFileSystemProvider> = {
extension: extensionFileSystemProvider,
logs: new InMemoryFileSystemProvider(),
[Schemas.vscodeUserData]: new InMemoryFileSystemProvider(),
[Schemas.vscodeUserData]: userDataFileSystemProvider,
[Schemas.tmp]: new InMemoryFileSystemProvider(),
file: fileSystemProvider
}
Expand All @@ -478,7 +483,7 @@ class MemoryFileService extends FileService {
if (provider instanceof OverlayFileSystemProvider) {
provider.onDidChangeOverlays(() => {
disposable.dispose()
disposable = this.registerProvider('file', fileSystemProvider)
disposable = this.registerProvider(scheme, fileSystemProvider)
})
}
}
Expand All @@ -503,6 +508,24 @@ export function registerExtensionFile (extensionLocation: URI, filePath: string,
return extensionFileSystemProvider.registerFile(new RegisteredReadOnlyFile(joinPath(extensionLocation, filePath), getContent))
}

/**
* Can be used to create a file before the fileService is initialized
*/
export async function initFile (scheme: string, file: URI, content: Uint8Array | string, options?: Partial<IFileWriteOptions>): Promise<void> {
const provider = providers[scheme]
if (provider == null || provider.writeFile == null) {
throw new Error(`${scheme} provider doesn't exist or doesn't support writing files`)
}

await provider.writeFile(file, content instanceof Uint8Array ? content : encoder.encode(content), {
atomic: false,
create: true,
overwrite: false,
unlock: false,
...options
})
}

/**
* Register a file system overlay
*
Expand Down
26 changes: 22 additions & 4 deletions src/service-override/keybindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { VSBuffer } from 'vs/base/common/buffer'
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile'
import { IKeyboardLayoutService } from 'vs/platform/keyboardLayout/common/keyboardLayout'
import { BrowserKeyboardLayoutService } from 'vs/workbench/services/keybinding/browser/keyboardLayoutService'
import { IFileService } from 'vs/platform/files/common/files'
import { IFileService, IFileWriteOptions } from 'vs/platform/files/common/files'
import { ICommandService } from 'vs/platform/commands/common/commands'
import { CommandService } from 'vs/workbench/services/commands/common/commandService'
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem'
Expand All @@ -21,12 +21,28 @@ import { IHostService } from 'vs/workbench/services/host/browser/host'
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'
import { ILogService } from 'vs/platform/log/common/log'
import { WorkbenchContextKeysHandler } from 'vs/workbench/browser/contextkeys'
import getFileServiceOverride from './files'
import { Schemas } from 'vs/base/common/network'
import { URI } from 'vs/base/common/uri'
import getFileServiceOverride, { initFile } from './files'
import { DynamicKeybindingService } from '../monaco'
import 'vs/workbench/browser/workbench.contribution'
import 'vs/workbench/contrib/keybindings/browser/keybindings.contribution'
import { onRenderWorkbench } from '../lifecycle'
import { IInstantiationService } from '../services'
import 'vs/workbench/browser/workbench.contribution'
import 'vs/workbench/contrib/keybindings/browser/keybindings.contribution'

// This is the default value, but can be overriden by overriding the Environment or UserDataProfileService service
const defaultUserKeybindindsFile = URI.from({ scheme: Schemas.vscodeUserData, path: '/User/keybindings.json' })

/**
* Should be called only BEFORE the service are initialized to initialize the file on the filesystem before the keybindings service initializes
*/
async function initUserKeybindings (configurationJson: string, options?: Partial<IFileWriteOptions>, file: URI = defaultUserKeybindindsFile): Promise<void> {
await initFile(defaultUserKeybindindsFile.scheme, file, configurationJson, options)
}

/**
* Can be called at any time after the services are initialized to update the user configuration
*/

async function updateUserKeybindings (keybindingsJson: string): Promise<void> {
const userDataProfilesService: IUserDataProfilesService = StandaloneServices.get(IUserDataProfilesService)
Expand Down Expand Up @@ -100,6 +116,8 @@ export default function getServiceOverride ({ shouldUseGlobalKeybindings = () =>
}

export {
defaultUserKeybindindsFile,
initUserKeybindings,
updateUserKeybindings,
IUserFriendlyKeybinding
}
11 changes: 3 additions & 8 deletions src/service-override/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ import { WebviewService } from 'vs/workbench/contrib/webview/browser/webviewServ
import { IWebviewWorkbenchService, WebviewEditorService } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService'
import { IWebviewService } from 'vs/workbench/contrib/webview/browser/webview'
import { IWebviewViewService, WebviewViewService } from 'vs/workbench/contrib/webviewView/browser/webviewViewService'
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'
import { IWorkbenchLayoutService, Parts, Position, positionToString } from 'vs/workbench/services/layout/browser/layoutService'
import { EditorPaneDescriptor, IEditorPaneRegistry } from 'vs/workbench/browser/editor'
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane'
Expand Down Expand Up @@ -349,7 +348,9 @@ function registerCustomView (options: CustomViewOption): IDisposable {
ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [options.id, { mergeViewWithContainerWhenSingleView: true }]),
hideIfEmpty: true,
icon: iconUrl
}, options.location)
}, options.location, {
isDefault: options.default
})

const views: IViewDescriptor[] = [{
id: options.id,
Expand Down Expand Up @@ -389,12 +390,6 @@ function registerCustomView (options: CustomViewOption): IDisposable {

Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry).registerViews(views, VIEW_CONTAINER)

if (options.default ?? false) {
void StandaloneServices.get(ILifecycleService).when(LifecyclePhase.Eventually).then(() => {
void StandaloneServices.get(IViewsService).openViewContainer(options.id)
})
}

const disposableCollection = new DisposableStore()
disposableCollection.add({
dispose () {
Expand Down