Add documentation for using Milkdown with various frameworks
- Created a new document for using components in Milkdown. - Added a guide for using plugins in Milkdown, including toggling plugins programmatically and listing official plugins. - Introduced a recipe for integrating Milkdown with Angular, including installation steps and component creation. - Added a recipe for using Milkdown with Next.js, detailing installation and component setup. - Created a guide for integrating Milkdown with NuxtJS, including installation and component creation. - Added a comprehensive guide for using Milkdown with React, covering both Crepe and core Milkdown usage. - Introduced a recipe for SolidJS integration with Milkdown, including installation and component creation. - Added a guide for using Milkdown with Svelte, detailing installation and component setup. - Created a comprehensive guide for integrating Milkdown with Vue, covering both Crepe and core Milkdown usage. - Added a recipe for using Milkdown with Vue2, including installation and component creation.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { commands } from 'vscode';
|
||||
import { CodeReference } from '.';
|
||||
import { IAuthenticationService } from '../../../../../../platform/authentication/common/authentication';
|
||||
import { Disposable } from '../../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { onCopilotToken } from '../../../lib/src/auth/copilotTokenNotifier';
|
||||
import { ICompletionsCitationManager, IPDocumentCitation } from '../../../lib/src/citationManager';
|
||||
import { OutputPaneShowCommand } from '../../../lib/src/snippy/constants';
|
||||
import { copilotOutputLogTelemetry } from '../../../lib/src/snippy/telemetryHandlers';
|
||||
import { notify } from './matchNotifier';
|
||||
import { GitHubCopilotLogger } from './outputChannel';
|
||||
|
||||
/**
|
||||
* Citation manager that logs citations to the VS Code log. On the first citation encountered,
|
||||
* the user gets a notification.
|
||||
*/
|
||||
export class LoggingCitationManager extends Disposable implements ICompletionsCitationManager {
|
||||
declare _serviceBrand: undefined;
|
||||
|
||||
private logger?: GitHubCopilotLogger;
|
||||
private readonly codeReference: CodeReference;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IAuthenticationService authenticationService: IAuthenticationService,
|
||||
) {
|
||||
super();
|
||||
this.codeReference = this._register(this.instantiationService.createInstance(CodeReference));
|
||||
const disposable = onCopilotToken(authenticationService, _ => {
|
||||
if (this.logger) {
|
||||
return;
|
||||
}
|
||||
this.logger = instantiationService.createInstance(GitHubCopilotLogger);
|
||||
const initialNotificationCommand = commands.registerCommand(OutputPaneShowCommand, () =>
|
||||
this.logger?.forceShow()
|
||||
);
|
||||
this.codeReference.addDisposable(initialNotificationCommand);
|
||||
});
|
||||
this.codeReference.addDisposable(disposable);
|
||||
}
|
||||
|
||||
register() {
|
||||
return this.codeReference.register();
|
||||
}
|
||||
|
||||
async handleIPCodeCitation(citation: IPDocumentCitation): Promise<void> {
|
||||
if (!this.codeReference.enabled || !this.logger || citation.details.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const start = citation.location?.start;
|
||||
const matchLocation = start ? `[Ln ${start.line + 1}, Col ${start.character + 1}]` : 'Location not available';
|
||||
const shortenedMatchText = `${citation.matchingText
|
||||
?.slice(0, 100)
|
||||
.replace(/[\r\n\t]+|^[ \t]+/gm, ' ')
|
||||
.trim()}...`;
|
||||
|
||||
this.logger.info(citation.inDocumentUri, `Similar code at `, matchLocation, shortenedMatchText);
|
||||
for (const detail of citation.details) {
|
||||
const { license, url } = detail;
|
||||
this.logger.info(`License: ${license.replace('NOASSERTION', 'unknown')}, URL: ${url}`);
|
||||
}
|
||||
copilotOutputLogTelemetry.handleWrite({ instantiationService: this.instantiationService });
|
||||
await this.instantiationService.invokeFunction(notify);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextEditor, window } from 'vscode';
|
||||
import { Disposable } from '../../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { copilotOutputLogTelemetry } from '../../../lib/src/snippy/telemetryHandlers';
|
||||
import { citationsChannelName } from './outputChannel';
|
||||
|
||||
export class CodeRefEngagementTracker extends Disposable {
|
||||
private activeLog = false;
|
||||
|
||||
constructor(@IInstantiationService private instantiationService: IInstantiationService) {
|
||||
super();
|
||||
this._register(window.onDidChangeActiveTextEditor((e) => this.onActiveEditorChange(e)));
|
||||
this._register(window.onDidChangeVisibleTextEditors((e) => this.onVisibleEditorsChange(e)));
|
||||
}
|
||||
|
||||
onActiveEditorChange = (editor: TextEditor | undefined) => {
|
||||
if (this.isOutputLog(editor)) {
|
||||
copilotOutputLogTelemetry.handleFocus({ instantiationService: this.instantiationService });
|
||||
}
|
||||
};
|
||||
|
||||
onVisibleEditorsChange = (currEditors: readonly TextEditor[]) => {
|
||||
const copilotLog = currEditors.find(e => this.isOutputLog(e));
|
||||
|
||||
if (this.activeLog) {
|
||||
if (!copilotLog) {
|
||||
this.activeLog = false;
|
||||
}
|
||||
} else if (copilotLog) {
|
||||
this.activeLog = true;
|
||||
copilotOutputLogTelemetry.handleOpen({ instantiationService: this.instantiationService });
|
||||
}
|
||||
};
|
||||
|
||||
get logVisible() {
|
||||
return this.activeLog;
|
||||
}
|
||||
|
||||
private isOutputLog = (editor: TextEditor | undefined) => {
|
||||
return (
|
||||
editor && editor.document.uri.scheme === 'output' && editor.document.uri.path.includes(citationsChannelName)
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vscode';
|
||||
import { IAuthenticationService } from '../../../../../../platform/authentication/common/authentication';
|
||||
import { IDisposable } from '../../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { CopilotToken } from '../../../lib/src/auth/copilotTokenManager';
|
||||
import { onCopilotToken } from '../../../lib/src/auth/copilotTokenNotifier';
|
||||
import { ICompletionsLogTargetService } from '../../../lib/src/logger';
|
||||
import { codeReferenceLogger } from '../../../lib/src/snippy/logger';
|
||||
import { ICompletionsRuntimeModeService } from '../../../lib/src/util/runtimeMode';
|
||||
import { CodeRefEngagementTracker } from './codeReferenceEngagementTracker';
|
||||
|
||||
export class CodeReference implements IDisposable {
|
||||
subscriptions: Disposable | undefined;
|
||||
event?: Disposable;
|
||||
enabled: boolean = false;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ICompletionsRuntimeModeService readonly _runtimeMode: ICompletionsRuntimeModeService,
|
||||
@ICompletionsLogTargetService private readonly _logTarget: ICompletionsLogTargetService,
|
||||
@IAuthenticationService private readonly _authenticationService: IAuthenticationService,
|
||||
) { }
|
||||
|
||||
dispose() {
|
||||
this.subscriptions?.dispose();
|
||||
this.event?.dispose();
|
||||
}
|
||||
|
||||
register() {
|
||||
if (!this._runtimeMode.isRunningInTest()) {
|
||||
this.event = onCopilotToken(this._authenticationService, (t) => this.onCopilotToken(t));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
addDisposable(disposable: Disposable) {
|
||||
if (!this.subscriptions) {
|
||||
this.subscriptions = Disposable.from(disposable);
|
||||
} else {
|
||||
this.subscriptions = Disposable.from(this.subscriptions, disposable);
|
||||
}
|
||||
}
|
||||
|
||||
onCopilotToken = (token: Omit<CopilotToken, 'token'>) => {
|
||||
this.enabled = token.codeQuoteEnabled || false;
|
||||
if (!token.codeQuoteEnabled) {
|
||||
this.subscriptions?.dispose();
|
||||
this.subscriptions = undefined;
|
||||
codeReferenceLogger.debug(this._logTarget, 'Public code references are disabled.');
|
||||
return;
|
||||
}
|
||||
|
||||
codeReferenceLogger.info(this._logTarget, 'Public code references are enabled.');
|
||||
this.addDisposable(this._instantiationService.createInstance(CodeRefEngagementTracker));
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { commands, env, Uri } from 'vscode';
|
||||
import { IVSCodeExtensionContext } from '../../../../../../platform/extContext/common/extensionContext';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { ICompletionsNotificationSender } from '../../../lib/src/notificationSender';
|
||||
import { OutputPaneShowCommand } from '../../../lib/src/snippy/constants';
|
||||
import { matchNotificationTelemetry, TelemetryActor } from '../../../lib/src/snippy/telemetryHandlers';
|
||||
|
||||
const matchCodeMessage =
|
||||
'We found a reference to public code in a recent suggestion. To learn more about public code references, review the [documentation](https://aka.ms/github-copilot-match-public-code).';
|
||||
const MatchAction = 'View reference';
|
||||
const SettingAction = 'Change setting';
|
||||
const CodeReferenceKey = 'codeReference.notified';
|
||||
|
||||
/**
|
||||
* Displays a toast notification when the first code reference is found.
|
||||
* The user will only ever see a single notification of this behavior.
|
||||
* Displays the output panel on notification ack.
|
||||
*/
|
||||
export function notify(accessor: ServicesAccessor) {
|
||||
const extension = accessor.get(IVSCodeExtensionContext);
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const didNotify = extension.globalState.get<boolean>(CodeReferenceKey);
|
||||
|
||||
if (didNotify) {
|
||||
return;
|
||||
}
|
||||
|
||||
const notificationSender = accessor.get(ICompletionsNotificationSender);
|
||||
|
||||
const messageItems = [{ title: MatchAction }, { title: SettingAction }];
|
||||
|
||||
void notificationSender.showWarningMessage(matchCodeMessage, ...messageItems).then(async action => {
|
||||
const event = { instantiationService, actor: 'user' as TelemetryActor };
|
||||
|
||||
switch (action?.title) {
|
||||
case MatchAction: {
|
||||
matchNotificationTelemetry.handleDoAction(event);
|
||||
await commands.executeCommand(OutputPaneShowCommand);
|
||||
break;
|
||||
}
|
||||
case SettingAction: {
|
||||
await env.openExternal(Uri.parse('https://aka.ms/github-copilot-settings'));
|
||||
break;
|
||||
}
|
||||
case undefined: {
|
||||
matchNotificationTelemetry.handleDismiss(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return extension.globalState.update(CodeReferenceKey, true);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { window, type OutputChannel } from 'vscode';
|
||||
import { IAuthenticationService } from '../../../../../../platform/authentication/common/authentication';
|
||||
import { Disposable, IDisposable, MutableDisposable } from '../../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { CopilotToken } from '../../../lib/src/auth/copilotTokenManager';
|
||||
import { onCopilotToken } from '../../../lib/src/auth/copilotTokenNotifier';
|
||||
|
||||
interface GitHubLogger extends Disposable {
|
||||
info(...messages: string[]): void;
|
||||
forceShow(): void;
|
||||
}
|
||||
|
||||
export const citationsChannelName = 'GitHub Copilot Log (Code References)';
|
||||
|
||||
// Literally taken from VS Code
|
||||
function getCurrentTimestamp() {
|
||||
const toTwoDigits = (v: number) => (v < 10 ? `0${v}` : v);
|
||||
const toThreeDigits = (v: number) => (v < 10 ? `00${v}` : v < 100 ? `0${v}` : v);
|
||||
const currentTime = new Date();
|
||||
return `${currentTime.getFullYear()}-${toTwoDigits(currentTime.getMonth() + 1)}-${toTwoDigits(
|
||||
currentTime.getDate()
|
||||
)} ${toTwoDigits(currentTime.getHours())}:${toTwoDigits(currentTime.getMinutes())}:${toTwoDigits(
|
||||
currentTime.getSeconds()
|
||||
)}.${toThreeDigits(currentTime.getMilliseconds())}`;
|
||||
}
|
||||
|
||||
class CodeReferenceOutputChannel implements IDisposable {
|
||||
constructor(private output: OutputChannel) { }
|
||||
|
||||
info(...messages: string[]) {
|
||||
this.output.appendLine(`${getCurrentTimestamp()} [info] ${messages.join(' ')}`);
|
||||
}
|
||||
|
||||
show(preserveFocus: boolean) {
|
||||
this.output.show(preserveFocus);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this.output.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class GitHubCopilotLogger extends Disposable implements GitHubLogger {
|
||||
|
||||
private output = this._register(new MutableDisposable<CodeReferenceOutputChannel>());
|
||||
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IAuthenticationService authenticationService: IAuthenticationService
|
||||
) {
|
||||
super();
|
||||
this._register(onCopilotToken(authenticationService, t => this.checkCopilotToken(t)));
|
||||
|
||||
this.createChannel();
|
||||
}
|
||||
|
||||
private checkCopilotToken = (token: Omit<CopilotToken, 'token'>) => {
|
||||
if (token.codeQuoteEnabled) {
|
||||
this.createChannel();
|
||||
} else {
|
||||
this.removeChannel();
|
||||
}
|
||||
};
|
||||
|
||||
private log(type: 'info', ...messages: string[]) {
|
||||
const output = this.createChannel();
|
||||
|
||||
const [base, ...rest] = messages;
|
||||
output[type](base, ...rest);
|
||||
}
|
||||
|
||||
info(...messages: string[]) {
|
||||
this.log('info', ...messages);
|
||||
}
|
||||
|
||||
forceShow() {
|
||||
// Preserve focus in the editor
|
||||
this.getChannel()?.show(true);
|
||||
}
|
||||
|
||||
private createChannel(): CodeReferenceOutputChannel {
|
||||
if (this.output.value) {
|
||||
return this.output.value;
|
||||
}
|
||||
|
||||
this.output.value = new CodeReferenceOutputChannel(window.createOutputChannel(citationsChannelName, 'code-referencing'));
|
||||
return this.output.value;
|
||||
}
|
||||
|
||||
private getChannel(): CodeReferenceOutputChannel | undefined {
|
||||
return this.output.value;
|
||||
}
|
||||
|
||||
private removeChannel() {
|
||||
this.output.value = undefined;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import { TextEditor } from 'vscode';
|
||||
import { DisposableStore } from '../../../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { withInMemoryTelemetry } from '../../../../lib/src/test/telemetry';
|
||||
import { createExtensionTestingContext } from '../../test/context';
|
||||
import { CodeRefEngagementTracker } from '../codeReferenceEngagementTracker';
|
||||
import { citationsChannelName } from '../outputChannel';
|
||||
|
||||
suite('CodeReferenceEngagementTracker', function () {
|
||||
let engagementTracker: CodeRefEngagementTracker;
|
||||
let accessor: ServicesAccessor;
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
setup(function () {
|
||||
accessor = createExtensionTestingContext().createTestingAccessor();
|
||||
engagementTracker = disposables.add(accessor.get(IInstantiationService).createInstance(CodeRefEngagementTracker));
|
||||
});
|
||||
|
||||
teardown(function () {
|
||||
disposables.clear();
|
||||
});
|
||||
|
||||
test('sends a telemetry event when the output channel is focused', async function () {
|
||||
const telemetry = await withInMemoryTelemetry(accessor, () => {
|
||||
engagementTracker.onActiveEditorChange({
|
||||
document: { uri: { scheme: 'output', path: citationsChannelName } },
|
||||
} as TextEditor);
|
||||
});
|
||||
|
||||
assert.ok(telemetry.reporter.events.length === 1);
|
||||
assert.strictEqual(telemetry.reporter.events[0].name, 'code_referencing.github_copilot_log.focus.count');
|
||||
});
|
||||
|
||||
test('sends a telemetry event when the output channel is focused2', async function () {
|
||||
const telemetry = await withInMemoryTelemetry(accessor, () => {
|
||||
engagementTracker.onActiveEditorChange({
|
||||
document: { uri: { scheme: 'output', path: citationsChannelName } },
|
||||
} as TextEditor);
|
||||
});
|
||||
|
||||
assert.ok(telemetry.reporter.events.length === 1);
|
||||
assert.strictEqual(telemetry.reporter.events[0].name, 'code_referencing.github_copilot_log.focus.count');
|
||||
});
|
||||
|
||||
|
||||
test('sends a telemetry event when the output channel is opened', async function () {
|
||||
const telemetry = await withInMemoryTelemetry(accessor, () => {
|
||||
engagementTracker.onVisibleEditorsChange([
|
||||
{
|
||||
document: { uri: { scheme: 'output', path: citationsChannelName } },
|
||||
},
|
||||
] as TextEditor[]);
|
||||
});
|
||||
|
||||
assert.ok(telemetry.reporter.events.length === 1);
|
||||
assert.strictEqual(telemetry.reporter.events[0].name, 'code_referencing.github_copilot_log.open.count');
|
||||
});
|
||||
|
||||
test('does not send a telemetry event when the output channel is already opened', async function () {
|
||||
const telemetry = await withInMemoryTelemetry(accessor, () => {
|
||||
engagementTracker.onVisibleEditorsChange([
|
||||
{
|
||||
document: { uri: { scheme: 'output', path: citationsChannelName } },
|
||||
},
|
||||
] as TextEditor[]);
|
||||
engagementTracker.onVisibleEditorsChange([
|
||||
{
|
||||
document: { uri: { scheme: 'output', path: citationsChannelName } },
|
||||
},
|
||||
{
|
||||
document: { uri: { scheme: 'file', path: 'some-other-file.js' } },
|
||||
},
|
||||
] as TextEditor[]);
|
||||
});
|
||||
|
||||
assert.ok(telemetry.reporter.events.length === 1);
|
||||
});
|
||||
|
||||
test('tracks when the log closes internally', async function () {
|
||||
const telemetry = await withInMemoryTelemetry(accessor, () => {
|
||||
engagementTracker.onVisibleEditorsChange([
|
||||
{
|
||||
document: { uri: { scheme: 'output', path: citationsChannelName } },
|
||||
},
|
||||
] as TextEditor[]);
|
||||
engagementTracker.onVisibleEditorsChange([
|
||||
{
|
||||
document: { uri: { scheme: 'file', path: 'some-other-file.js' } },
|
||||
},
|
||||
] as TextEditor[]);
|
||||
});
|
||||
|
||||
assert.ok(telemetry.reporter.events.length === 1);
|
||||
assert.ok(engagementTracker.logVisible === false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,70 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import * as Sinon from 'sinon';
|
||||
import { Disposable, ExtensionContext } from 'vscode';
|
||||
import { CodeReference } from '..';
|
||||
import { CopilotToken, createTestExtendedTokenInfo } from '../../../../../../../platform/authentication/common/copilotToken';
|
||||
import { generateUuid } from '../../../../../../../util/vs/base/common/uuid';
|
||||
import { IInstantiationService } from '../../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { ConnectionState } from '../../../../lib/src/snippy/connectionState';
|
||||
import { createExtensionTestingContext } from '../../test/context';
|
||||
|
||||
function testExtensionContext() {
|
||||
return {
|
||||
subscriptions: [],
|
||||
};
|
||||
}
|
||||
|
||||
suite('CodeReference', function () {
|
||||
let extensionContext: ExtensionContext;
|
||||
let instantiationService: IInstantiationService;
|
||||
let sub: Disposable | undefined;
|
||||
|
||||
setup(function () {
|
||||
const accessor = createExtensionTestingContext().createTestingAccessor();
|
||||
instantiationService = accessor.get(IInstantiationService);
|
||||
extensionContext = testExtensionContext() as unknown as ExtensionContext;
|
||||
});
|
||||
|
||||
teardown(function () {
|
||||
extensionContext.subscriptions.forEach(sub => {
|
||||
sub.dispose();
|
||||
});
|
||||
sub?.dispose();
|
||||
ConnectionState.setDisabled();
|
||||
});
|
||||
|
||||
suite('subscriptions', function () {
|
||||
test('should be undefined by default', function () {
|
||||
const result = instantiationService.createInstance(CodeReference);
|
||||
sub = result.subscriptions;
|
||||
assert.ok(!sub);
|
||||
});
|
||||
|
||||
test('should be updated correctly when token change events received', function () {
|
||||
const codeQuote = instantiationService.createInstance(CodeReference);
|
||||
const enabledToken = new CopilotToken(createTestExtendedTokenInfo({ token: `test token ${generateUuid()}`, username: 'fixedTokenManager', copilot_plan: 'unknown', code_quote_enabled: true }));
|
||||
const disabledToken = new CopilotToken(createTestExtendedTokenInfo({ token: `test token ${generateUuid()}`, username: 'fixedTokenManager', copilot_plan: 'unknown', code_quote_enabled: false }));
|
||||
|
||||
codeQuote.onCopilotToken(enabledToken);
|
||||
|
||||
assert.ok(codeQuote.enabled);
|
||||
assert.ok(codeQuote.subscriptions);
|
||||
assert.ok(codeQuote.subscriptions instanceof Disposable);
|
||||
|
||||
const subSpy = Sinon.spy(codeQuote.subscriptions, 'dispose');
|
||||
codeQuote.onCopilotToken(disabledToken);
|
||||
|
||||
assert.ok(!codeQuote.enabled);
|
||||
assert.strictEqual(codeQuote.subscriptions, undefined);
|
||||
assert.strictEqual(subSpy.calledOnce, true);
|
||||
|
||||
codeQuote.onCopilotToken(enabledToken);
|
||||
assert.ok(codeQuote.enabled);
|
||||
assert.notStrictEqual(codeQuote.subscriptions, undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,121 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import sinon from 'sinon';
|
||||
import { commands, env } from 'vscode';
|
||||
import { IVSCodeExtensionContext } from '../../../../../../../platform/extContext/common/extensionContext';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { ICompletionsNotificationSender } from '../../../../lib/src/notificationSender';
|
||||
import { OutputPaneShowCommand } from '../../../../lib/src/snippy/constants';
|
||||
import { withInMemoryTelemetry } from '../../../../lib/src/test/telemetry';
|
||||
import { TestNotificationSender } from '../../../../lib/src/test/testHelpers';
|
||||
import { createExtensionTestingContext } from '../../test/context';
|
||||
import { notify } from '../matchNotifier';
|
||||
|
||||
suite('.match', function () {
|
||||
let accessor: ServicesAccessor;
|
||||
|
||||
setup(function () {
|
||||
accessor = createExtensionTestingContext().createTestingAccessor();
|
||||
});
|
||||
|
||||
test('populates the globalState object', async function () {
|
||||
const extensionContext = accessor.get(IVSCodeExtensionContext);
|
||||
const globalState = extensionContext.globalState;
|
||||
|
||||
await notify(accessor);
|
||||
|
||||
assert.ok(globalState.get('codeReference.notified'));
|
||||
});
|
||||
|
||||
test('notifies the user', async function () {
|
||||
const testNotificationSender = accessor.get(ICompletionsNotificationSender) as TestNotificationSender;
|
||||
testNotificationSender.performAction('View reference');
|
||||
|
||||
await notify(accessor);
|
||||
|
||||
assert.strictEqual(testNotificationSender.sentMessages.length, 1);
|
||||
});
|
||||
|
||||
test('sends a telemetry event on view reference action', async function () {
|
||||
const testNotificationSender = accessor.get(ICompletionsNotificationSender) as TestNotificationSender;
|
||||
testNotificationSender.performAction('View reference');
|
||||
|
||||
const telemetry = await withInMemoryTelemetry(accessor, async accessor => {
|
||||
await notify(accessor);
|
||||
});
|
||||
|
||||
assert.strictEqual(telemetry.reporter.events.length, 1);
|
||||
assert.strictEqual(telemetry.reporter.events[0].name, 'code_referencing.match_notification.acknowledge.count');
|
||||
});
|
||||
|
||||
test('executes the output panel display command on view reference action', async function () {
|
||||
const spy = sinon.spy(commands, 'executeCommand');
|
||||
const testNotificationSender = accessor.get(ICompletionsNotificationSender) as TestNotificationSender;
|
||||
testNotificationSender.performAction('View reference');
|
||||
|
||||
await notify(accessor);
|
||||
|
||||
await testNotificationSender.waitForMessages();
|
||||
|
||||
assert.ok(spy.calledOnce);
|
||||
assert.ok(spy.calledWith(OutputPaneShowCommand));
|
||||
|
||||
spy.restore();
|
||||
});
|
||||
|
||||
test('opens the settings page on change setting action', async function () {
|
||||
const stub = sinon.stub(env, 'openExternal');
|
||||
const testNotificationSender = accessor.get(ICompletionsNotificationSender) as TestNotificationSender;
|
||||
testNotificationSender.performAction('Change setting');
|
||||
|
||||
await notify(accessor);
|
||||
|
||||
await testNotificationSender.waitForMessages();
|
||||
|
||||
assert.ok(stub.calledOnce);
|
||||
assert.ok(
|
||||
stub.calledWith(
|
||||
sinon.match({
|
||||
scheme: 'https',
|
||||
authority: 'aka.ms',
|
||||
path: '/github-copilot-settings',
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
test('sends a telemetry event on notification dismissal', async function () {
|
||||
const testNotificationSender = accessor.get(ICompletionsNotificationSender) as TestNotificationSender;
|
||||
testNotificationSender.performDismiss();
|
||||
|
||||
const telemetry = await withInMemoryTelemetry(accessor, async accessor => {
|
||||
await notify(accessor);
|
||||
});
|
||||
|
||||
await testNotificationSender.waitForMessages();
|
||||
|
||||
assert.strictEqual(telemetry.reporter.events.length, 1);
|
||||
assert.strictEqual(telemetry.reporter.events[0].name, 'code_referencing.match_notification.ignore.count');
|
||||
});
|
||||
|
||||
test('does not notify if already notified', async function () {
|
||||
const extensionContext = accessor.get(IVSCodeExtensionContext);
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const globalState = extensionContext.globalState;
|
||||
const testNotificationSender = accessor.get(ICompletionsNotificationSender) as TestNotificationSender;
|
||||
testNotificationSender.performAction('View reference');
|
||||
|
||||
await globalState.update('codeReference.notified', true);
|
||||
|
||||
await instantiationService.invokeFunction(notify);
|
||||
|
||||
await testNotificationSender.waitForMessages();
|
||||
|
||||
assert.strictEqual(testNotificationSender.sentMessages.length, 0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { VSCodeWorkspace } from '../../../../inlineEdits/vscode-node/parts/vscodeWorkspace';
|
||||
import { ICompletionsObservableWorkspace } from '../../lib/src/completionsObservableWorkspace';
|
||||
|
||||
export class CompletionsObservableWorkspace extends VSCodeWorkspace implements ICompletionsObservableWorkspace {
|
||||
declare _serviceBrand: undefined;
|
||||
}
|
||||
249
completions-sample-code/vscode-node/extension/src/config.ts
Normal file
249
completions-sample-code/vscode-node/extension/src/config.ts
Normal file
@@ -0,0 +1,249 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import type { WorkspaceConfiguration } from 'vscode';
|
||||
import * as vscode from 'vscode';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import {
|
||||
ConfigKey,
|
||||
ConfigKeyType,
|
||||
ConfigProvider, getConfigDefaultForKey,
|
||||
getConfigKeyRecursively,
|
||||
getOptionalConfigDefaultForKey,
|
||||
ICompletionsConfigProvider,
|
||||
ICompletionsEditorAndPluginInfo,
|
||||
packageJson
|
||||
} from '../../lib/src/config';
|
||||
import { CopilotConfigPrefix } from '../../lib/src/constants';
|
||||
import { Logger } from '../../lib/src/logger';
|
||||
import { transformEvent } from '../../lib/src/util/event';
|
||||
|
||||
const logger = new Logger('extensionConfig');
|
||||
|
||||
export class VSCodeConfigProvider extends ConfigProvider {
|
||||
private config: WorkspaceConfiguration;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.config = vscode.workspace.getConfiguration(CopilotConfigPrefix);
|
||||
|
||||
// Reload cached config if a workspace config change effects Copilot namespace
|
||||
vscode.workspace.onDidChangeConfiguration(changeEvent => {
|
||||
if (changeEvent.affectsConfiguration(CopilotConfigPrefix)) {
|
||||
this.config = vscode.workspace.getConfiguration(CopilotConfigPrefix);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
override getConfig<T>(key: ConfigKeyType): T {
|
||||
return getConfigKeyRecursively<T>(this.config, key) ?? getConfigDefaultForKey(key);
|
||||
}
|
||||
|
||||
override getOptionalConfig<T>(key: ConfigKeyType): T | undefined {
|
||||
return getConfigKeyRecursively<T>(this.config, key) ?? getOptionalConfigDefaultForKey(key);
|
||||
}
|
||||
|
||||
// Dumps config settings defined in the extension json
|
||||
override dumpForTelemetry(): { [key: string]: string } {
|
||||
return {};
|
||||
}
|
||||
|
||||
override onDidChangeCopilotSettings: ConfigProvider['onDidChangeCopilotSettings'] = transformEvent(
|
||||
vscode.workspace.onDidChangeConfiguration,
|
||||
event => {
|
||||
if (event.affectsConfiguration('github.copilot')) {
|
||||
return this;
|
||||
}
|
||||
if (event.affectsConfiguration('github.copilot-chat')) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// From vscode's src/vs/platform/telemetry/common/telemetryUtils.ts
|
||||
const telemetryAllowedAuthorities = new Set([
|
||||
'ssh-remote',
|
||||
'dev-container',
|
||||
'attached-container',
|
||||
'wsl',
|
||||
'tunnel',
|
||||
'codespaces',
|
||||
'amlext',
|
||||
]);
|
||||
|
||||
export class VSCodeEditorInfo implements ICompletionsEditorAndPluginInfo {
|
||||
declare _serviceBrand: undefined;
|
||||
getEditorInfo() {
|
||||
let devName = vscode.env.uriScheme;
|
||||
if (vscode.version.endsWith('-insider')) {
|
||||
devName = devName.replace(/-insiders$/, '');
|
||||
}
|
||||
const remoteName = vscode.env.remoteName;
|
||||
if (remoteName) {
|
||||
devName += `@${telemetryAllowedAuthorities.has(remoteName) ? remoteName : 'other'}`;
|
||||
}
|
||||
return {
|
||||
name: 'vscode',
|
||||
readableName: vscode.env.appName.replace(/ - Insiders$/, ''),
|
||||
devName: devName,
|
||||
version: vscode.version,
|
||||
root: vscode.env.appRoot,
|
||||
};
|
||||
}
|
||||
getEditorPluginInfo() {
|
||||
return { name: 'copilot-chat', readableName: 'GitHub Copilot for Visual Studio Code', version: packageJson.version };
|
||||
}
|
||||
getRelatedPluginInfo() {
|
||||
// Any additions to this list should also be added as a known filter in
|
||||
// lib/src/experiments/filters.ts
|
||||
return [
|
||||
'ms-vscode.cpptools',
|
||||
'ms-vscode.cmake-tools',
|
||||
'ms-vscode.makefile-tools',
|
||||
'ms-dotnettools.csdevkit',
|
||||
'ms-python.python',
|
||||
'ms-python.vscode-pylance',
|
||||
'vscjava.vscode-java-pack',
|
||||
'vscjava.vscode-java-dependency',
|
||||
'vscode.typescript-language-features',
|
||||
'ms-vscode.vscode-typescript-next',
|
||||
'ms-dotnettools.csharp',
|
||||
'github.copilot-chat',
|
||||
]
|
||||
.map(name => {
|
||||
const extpj = vscode.extensions.getExtension(name)?.packageJSON as unknown;
|
||||
if (extpj && typeof extpj === 'object' && 'version' in extpj && typeof extpj.version === 'string') {
|
||||
return { name, version: extpj.version };
|
||||
}
|
||||
})
|
||||
.filter(plugin => plugin !== undefined);
|
||||
}
|
||||
}
|
||||
|
||||
type EnabledConfigKeyType = { [key: string]: boolean };
|
||||
|
||||
function getEnabledConfigObject(accessor: ServicesAccessor): EnabledConfigKeyType {
|
||||
const configProvider = accessor.get(ICompletionsConfigProvider);
|
||||
return { '*': true, ...(configProvider.getConfig<EnabledConfigKeyType>(ConfigKey.Enable) ?? {}) };
|
||||
}
|
||||
|
||||
function getEnabledConfig(accessor: ServicesAccessor, languageId: string): boolean {
|
||||
const obj = getEnabledConfigObject(accessor);
|
||||
return obj[languageId] ?? obj['*'] ?? true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if automatic completions are enabled for the current document by all Copilot completion settings.
|
||||
* Excludes the `editor.inlineSuggest.enabled` setting.
|
||||
* Return undefined if there is no current document.
|
||||
*/
|
||||
export function isCompletionEnabled(accessor: ServicesAccessor): boolean | undefined {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return undefined;
|
||||
}
|
||||
return isCompletionEnabledForDocument(accessor, editor.document);
|
||||
}
|
||||
|
||||
export function isCompletionEnabledForDocument(accessor: ServicesAccessor, document: vscode.TextDocument): boolean {
|
||||
return getEnabledConfig(accessor, document.languageId);
|
||||
}
|
||||
|
||||
export function isInlineSuggestEnabled(): boolean | undefined {
|
||||
return vscode.workspace.getConfiguration('editor.inlineSuggest').get<boolean>('enabled');
|
||||
}
|
||||
|
||||
type ConfigurationInspect = Exclude<ReturnType<vscode.WorkspaceConfiguration['inspect']>, undefined>;
|
||||
const inspectKinds: [keyof ConfigurationInspect, vscode.ConfigurationTarget, boolean][] = [
|
||||
['workspaceFolderLanguageValue', vscode.ConfigurationTarget.WorkspaceFolder, true],
|
||||
['workspaceFolderValue', vscode.ConfigurationTarget.WorkspaceFolder, false],
|
||||
['workspaceLanguageValue', vscode.ConfigurationTarget.Workspace, true],
|
||||
['workspaceValue', vscode.ConfigurationTarget.Workspace, false],
|
||||
['globalLanguageValue', vscode.ConfigurationTarget.Global, true],
|
||||
['globalValue', vscode.ConfigurationTarget.Global, false],
|
||||
];
|
||||
|
||||
function getConfigurationTargetForEnabledConfig(): vscode.ConfigurationTarget {
|
||||
const inspect = vscode.workspace.getConfiguration(CopilotConfigPrefix).inspect(ConfigKey.Enable);
|
||||
if (inspect?.workspaceFolderValue !== undefined) {
|
||||
return vscode.ConfigurationTarget.WorkspaceFolder;
|
||||
} else if (inspect?.workspaceValue !== undefined) {
|
||||
return vscode.ConfigurationTarget.Workspace;
|
||||
} else {
|
||||
return vscode.ConfigurationTarget.Global;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable completions by every means possible.
|
||||
*/
|
||||
export async function enableCompletions(accessor: ServicesAccessor) {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const scope = vscode.window.activeTextEditor?.document;
|
||||
// Make sure both of these settings are enabled, because that's a precondition for the user seeing inline completions.
|
||||
for (const [section, option] of [['', 'editor.inlineSuggest.enabled']]) {
|
||||
const config = vscode.workspace.getConfiguration(section, scope);
|
||||
const inspect = config.inspect(option);
|
||||
// Start from the most specific setting and work our way up to the global default.
|
||||
for (const [key, target, overrideInLanguage] of inspectKinds) {
|
||||
// Exit condition: if VS Code thinks the setting is enabled, we're done.
|
||||
// This might be true from the start, or a call to .update() might flip it.
|
||||
if (vscode.workspace.getConfiguration(section, scope).get(option)) {
|
||||
break;
|
||||
}
|
||||
if (inspect?.[key] === false) {
|
||||
await config.update(option, true, target, overrideInLanguage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The rest of this function is the inverse of disableCompletions(), updating the github.copilot.enable setting.
|
||||
const languageId = vscode.window.activeTextEditor?.document.languageId;
|
||||
if (!languageId) { return; }
|
||||
const config = vscode.workspace.getConfiguration(CopilotConfigPrefix);
|
||||
const enabledConfig = { ...instantiationService.invokeFunction(getEnabledConfigObject) };
|
||||
if (!(languageId in enabledConfig)) {
|
||||
enabledConfig['*'] = true;
|
||||
} else {
|
||||
enabledConfig[languageId] = true;
|
||||
}
|
||||
await config.update(ConfigKey.Enable, enabledConfig, getConfigurationTargetForEnabledConfig());
|
||||
if (!instantiationService.invokeFunction(isCompletionEnabled)) {
|
||||
const inspect = vscode.workspace.getConfiguration(CopilotConfigPrefix).inspect(ConfigKey.Enable);
|
||||
const error = new Error(`Failed to enable completions for ${languageId}: ${JSON.stringify(inspect)}`);
|
||||
instantiationService.invokeFunction(acc => logger.exception(acc, error, '.enable'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable completions using the github.copilot.enable setting.
|
||||
*/
|
||||
export async function disableCompletions(accessor: ServicesAccessor) {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const languageId = vscode.window.activeTextEditor?.document.languageId;
|
||||
if (!languageId) { return; }
|
||||
const config = vscode.workspace.getConfiguration(CopilotConfigPrefix);
|
||||
const enabledConfig = { ...instantiationService.invokeFunction(getEnabledConfigObject) };
|
||||
if (!(languageId in enabledConfig)) {
|
||||
enabledConfig['*'] = false;
|
||||
} else if (enabledConfig[languageId]) {
|
||||
enabledConfig[languageId] = false;
|
||||
}
|
||||
await config.update(ConfigKey.Enable, enabledConfig, getConfigurationTargetForEnabledConfig());
|
||||
if (instantiationService.invokeFunction(isCompletionEnabled)) {
|
||||
const inspect = vscode.workspace.getConfiguration(CopilotConfigPrefix).inspect(ConfigKey.Enable);
|
||||
const error = new Error(`Failed to disable completions for ${languageId}: ${JSON.stringify(inspect)}`);
|
||||
instantiationService.invokeFunction(acc => logger.exception(acc, error, '.disable'));
|
||||
}
|
||||
}
|
||||
|
||||
export async function toggleCompletions(accessor: ServicesAccessor) {
|
||||
if (isCompletionEnabled(accessor) && isInlineSuggestEnabled()) {
|
||||
await disableCompletions(accessor);
|
||||
} else {
|
||||
await enableCompletions(accessor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// Commands ending with "Client" refer to the command ID used in the legacy Copilot extension.
|
||||
// - These IDs should not appear in the package.json file
|
||||
// - These IDs should be registered to support all functionality (except if this command needs to be supported when both extensions are loaded/active).
|
||||
// Commands ending with "Chat" refer to the command ID used in the Copilot Chat extension.
|
||||
// - These IDs should be used in package.json
|
||||
// - These IDs should only be registered if they appear in the package.json (meaning the command palette) or if the command needs to be supported when both extensions are loaded/active.
|
||||
|
||||
export const CMDOpenPanelClient = 'github.copilot.generate';
|
||||
export const CMDOpenPanelChat = 'github.copilot.chat.openSuggestionsPanel'; // "github.copilot.chat.generate" is already being used
|
||||
|
||||
export const CMDAcceptCursorPanelSolutionClient = 'github.copilot.acceptCursorPanelSolution';
|
||||
export const CMDNavigatePreviousPanelSolutionClient = 'github.copilot.previousPanelSolution';
|
||||
export const CMDNavigateNextPanelSolutionClient = 'github.copilot.nextPanelSolution';
|
||||
|
||||
export const CMDToggleStatusMenuClient = 'github.copilot.toggleStatusMenu';
|
||||
export const CMDToggleStatusMenuChat = 'github.copilot.chat.toggleStatusMenu';
|
||||
|
||||
// Needs to be supported in both extensions when they are loaded/active. Requires a different ID.
|
||||
export const CMDSendCompletionsFeedbackChat = 'github.copilot.chat.sendCompletionFeedback';
|
||||
|
||||
export const CMDEnableCompletionsChat = 'github.copilot.chat.completions.enable';
|
||||
export const CMDDisableCompletionsChat = 'github.copilot.chat.completions.disable';
|
||||
export const CMDToggleCompletionsChat = 'github.copilot.chat.completions.toggle';
|
||||
export const CMDEnableCompletionsClient = 'github.copilot.completions.enable';
|
||||
export const CMDDisableCompletionsClient = 'github.copilot.completions.disable';
|
||||
export const CMDToggleCompletionsClient = 'github.copilot.completions.toggle';
|
||||
|
||||
export const CMDOpenLogsClient = 'github.copilot.openLogs';
|
||||
export const CMDOpenDocumentationClient = 'github.copilot.openDocs';
|
||||
|
||||
// Existing chat command reused for diagnostics
|
||||
export const CMDCollectDiagnosticsChat = 'github.copilot.debug.collectDiagnostics';
|
||||
|
||||
// Context variable that enable/disable panel-specific commands
|
||||
export const CopilotPanelVisible = 'github.copilot.panelVisible';
|
||||
export const ComparisonPanelVisible = 'github.copilot.comparisonPanelVisible';
|
||||
|
||||
export const CMDOpenModelPickerClient = 'github.copilot.openModelPicker';
|
||||
export const CMDOpenModelPickerChat = 'github.copilot.chat.openModelPicker';
|
||||
@@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { languages, workspace } from 'vscode';
|
||||
import { DocumentSelector } from 'vscode-languageserver-protocol';
|
||||
import { IInstantiationService } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { isDocumentValid } from '../../lib/src/util/documentEvaluation';
|
||||
import { DocumentContext } from '../../types/src';
|
||||
|
||||
export async function contextProviderMatch(
|
||||
instantiationService: IInstantiationService,
|
||||
documentSelector: DocumentSelector,
|
||||
documentContext: DocumentContext
|
||||
): Promise<number> {
|
||||
const vscDoc = workspace.textDocuments.find(td => td.uri.toString() === documentContext.uri);
|
||||
if (!vscDoc) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const result = await instantiationService.invokeFunction(isDocumentValid, documentContext);
|
||||
if (result.status !== 'valid') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return languages.match(documentSelector, vscDoc);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Command, commands, InlineCompletionItem, Uri } from 'vscode';
|
||||
import { Disposable } from '../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { collectCompletionDiagnostics, formatDiagnosticsAsMarkdown } from '../../lib/src/diagnostics';
|
||||
import { telemetry, TelemetryData } from '../../lib/src/telemetry';
|
||||
import { CMDSendCompletionsFeedbackChat } from './constants';
|
||||
|
||||
export const sendCompletionFeedbackCommand: Command = {
|
||||
command: CMDSendCompletionsFeedbackChat,
|
||||
title: 'Send Copilot Completion Feedback',
|
||||
tooltip: 'Send feedback about the last shown Copilot completion item',
|
||||
};
|
||||
|
||||
export class CopilotCompletionFeedbackTracker extends Disposable {
|
||||
private lastShownCopilotCompletionItem: InlineCompletionItem | undefined;
|
||||
|
||||
constructor(@IInstantiationService private readonly instantiationService: IInstantiationService) {
|
||||
super();
|
||||
this._register(commands.registerCommand(sendCompletionFeedbackCommand.command, async () => {
|
||||
const commandArg: unknown = this.lastShownCopilotCompletionItem?.command?.arguments?.[0];
|
||||
let telemetryArg: TelemetryData | undefined;
|
||||
if (commandArg && typeof commandArg === 'object' && 'telemetry' in commandArg) {
|
||||
if (commandArg.telemetry instanceof TelemetryData) {
|
||||
telemetryArg = commandArg.telemetry;
|
||||
}
|
||||
}
|
||||
this.instantiationService.invokeFunction(telemetry, 'ghostText.sentFeedback', telemetryArg);
|
||||
|
||||
await this.instantiationService.invokeFunction(openGitHubIssue, this.lastShownCopilotCompletionItem, telemetryArg);
|
||||
}));
|
||||
}
|
||||
|
||||
trackItem(item: InlineCompletionItem) {
|
||||
this.lastShownCopilotCompletionItem = item;
|
||||
}
|
||||
}
|
||||
|
||||
async function openGitHubIssue(
|
||||
accessor: ServicesAccessor,
|
||||
item: InlineCompletionItem | undefined,
|
||||
telemetry: TelemetryData | undefined
|
||||
) {
|
||||
const body = generateGitHubIssueBody(accessor, item, telemetry);
|
||||
await commands.executeCommand('workbench.action.openIssueReporter', {
|
||||
extensionId: 'github.copilot',
|
||||
uri: Uri.parse('https://github.com/microsoft/vscode'),
|
||||
data: body,
|
||||
});
|
||||
}
|
||||
|
||||
function generateGitHubIssueBody(
|
||||
accessor: ServicesAccessor,
|
||||
item: InlineCompletionItem | undefined,
|
||||
telemetry: TelemetryData | undefined
|
||||
) {
|
||||
const diagnostics = collectCompletionDiagnostics(accessor, telemetry);
|
||||
const formattedDiagnostics = formatDiagnosticsAsMarkdown(diagnostics);
|
||||
if (typeof item?.insertText !== 'string') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return `## Copilot Completion Feedback
|
||||
### Describe the issue, feedback, or steps to reproduce it:
|
||||
|
||||
|
||||
### Completion text:
|
||||
\`\`\`
|
||||
${item.insertText}
|
||||
\`\`\`
|
||||
|
||||
<details>
|
||||
<summary>Diagnostics</summary>
|
||||
|
||||
${formattedDiagnostics}
|
||||
|
||||
</details>
|
||||
`;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Range, commands, window, type Disposable } from 'vscode';
|
||||
import { CopilotNamedAnnotationList } from '../../../../../../platform/completions-core/common/openai/copilotAnnotations';
|
||||
import { DisposableStore, IDisposable } from '../../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService, type ServicesAccessor } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import * as constants from '../constants';
|
||||
import { registerCommand } from '../telemetry';
|
||||
import { wrapDoc } from '../textDocumentManager';
|
||||
import { CopilotSuggestionsPanelManager } from './copilotSuggestionsPanelManager';
|
||||
|
||||
// Exported for testing
|
||||
export enum PanelNavigationType {
|
||||
Previous = 'previous',
|
||||
Next = 'next',
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface contains data associated to a completion displayed in the panel.
|
||||
*/
|
||||
export interface PanelCompletion {
|
||||
insertText: string;
|
||||
range: Range;
|
||||
copilotAnnotations?: CopilotNamedAnnotationList;
|
||||
postInsertionCallback: () => PromiseLike<void> | void;
|
||||
}
|
||||
|
||||
export function registerPanelSupport(accessor: ServicesAccessor): Disposable {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const suggestionsPanelManager = instantiationService.createInstance(CopilotSuggestionsPanelManager);
|
||||
|
||||
const disposableStore = new DisposableStore();
|
||||
|
||||
function registerOpenPanelCommand(id: string): IDisposable {
|
||||
return registerCommand(accessor, id, async () => {
|
||||
// hide ghost text while opening the generation ui
|
||||
await commands.executeCommand('editor.action.inlineSuggest.hide');
|
||||
await instantiationService.invokeFunction(commandOpenPanel, suggestionsPanelManager);
|
||||
});
|
||||
}
|
||||
|
||||
// Register both commands to also support command palette
|
||||
disposableStore.add(registerOpenPanelCommand(constants.CMDOpenPanelChat));
|
||||
disposableStore.add(registerOpenPanelCommand(constants.CMDOpenPanelClient));
|
||||
|
||||
// No command palette support needed for these commands
|
||||
disposableStore.add(suggestionsPanelManager.registerCommands());
|
||||
|
||||
return disposableStore;
|
||||
}
|
||||
|
||||
function commandOpenPanel(accessor: ServicesAccessor, suggestionsPanelManager: CopilotSuggestionsPanelManager) {
|
||||
const editor = window.activeTextEditor;
|
||||
if (!editor) { return; }
|
||||
const wrapped = wrapDoc(editor.document);
|
||||
if (!wrapped) { return; }
|
||||
|
||||
const { line, character } = editor.selection.active;
|
||||
|
||||
suggestionsPanelManager.renderPanel(editor.document, { line, character }, wrapped);
|
||||
return commands.executeCommand('setContext', constants.CopilotPanelVisible, true);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { IPosition, ITextDocument } from '../../../lib/src/textDocument';
|
||||
import { solutionCountTarget } from '../lib/copilotPanel/common';
|
||||
import { runSolutions } from '../lib/copilotPanel/panel';
|
||||
import { UnformattedSolution } from '../lib/panelShared/panelTypes';
|
||||
import { BaseListDocument } from '../panelShared/baseListDocument';
|
||||
import { BasePanelCompletion, ISuggestionsPanel } from '../panelShared/basePanelTypes';
|
||||
import { PanelCompletion } from './common';
|
||||
|
||||
/**
|
||||
* Class representing a Open Copilot list using a ITextDocument as a way of displaying results.
|
||||
* Currently only used in the VSCode extension.
|
||||
*/
|
||||
export class CopilotListDocument extends BaseListDocument<PanelCompletion> {
|
||||
constructor(
|
||||
textDocument: ITextDocument,
|
||||
position: IPosition,
|
||||
panel: ISuggestionsPanel,
|
||||
countTarget = solutionCountTarget,
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
) {
|
||||
super(textDocument, position, panel, countTarget, instantiationService);
|
||||
}
|
||||
|
||||
protected createPanelCompletion(
|
||||
unformatted: UnformattedSolution,
|
||||
baseCompletion: BasePanelCompletion
|
||||
): PanelCompletion {
|
||||
return {
|
||||
insertText: baseCompletion.insertText,
|
||||
range: baseCompletion.range,
|
||||
copilotAnnotations: baseCompletion.copilotAnnotations,
|
||||
postInsertionCallback: baseCompletion.postInsertionCallback,
|
||||
};
|
||||
}
|
||||
|
||||
protected shouldAddSolution(newItem: PanelCompletion): boolean {
|
||||
return !this.findDuplicateSolution(newItem);
|
||||
}
|
||||
|
||||
protected runSolutionsImpl(): Promise<void> {
|
||||
return this.instantiationService.invokeFunction(runSolutions, this, this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument, WebviewPanel } from 'vscode';
|
||||
import { IVSCodeExtensionContext } from '../../../../../../platform/extContext/common/extensionContext';
|
||||
import { BaseSuggestionsPanel, SolutionContent, WebviewMessage } from '../panelShared/baseSuggestionsPanel';
|
||||
import { PanelCompletion } from './common';
|
||||
import { CopilotSuggestionsPanelManager } from './copilotSuggestionsPanelManager';
|
||||
import { copilotPanelConfig } from './panelConfig';
|
||||
|
||||
export interface CopilotSolutionsMessage {
|
||||
command: 'solutionsUpdated';
|
||||
solutions: SolutionContent[];
|
||||
percentage: number;
|
||||
}
|
||||
|
||||
export class CopilotSuggestionsPanel extends BaseSuggestionsPanel<PanelCompletion> {
|
||||
constructor(
|
||||
webviewPanel: WebviewPanel,
|
||||
document: TextDocument,
|
||||
suggestionsPanelManager: CopilotSuggestionsPanelManager,
|
||||
@IVSCodeExtensionContext contextService: IVSCodeExtensionContext,
|
||||
) {
|
||||
super(webviewPanel, document, suggestionsPanelManager, copilotPanelConfig, contextService);
|
||||
}
|
||||
|
||||
protected renderSolutionContent(item: PanelCompletion, baseContent: SolutionContent): SolutionContent {
|
||||
// Copilot panel just returns the base content without modifications
|
||||
return baseContent;
|
||||
}
|
||||
|
||||
protected createSolutionsMessage(content: SolutionContent[], percentage: number): CopilotSolutionsMessage {
|
||||
return {
|
||||
command: 'solutionsUpdated',
|
||||
solutions: content,
|
||||
percentage,
|
||||
};
|
||||
}
|
||||
|
||||
protected override async handleCustomMessage(message: WebviewMessage): Promise<boolean> {
|
||||
switch (message.command) {
|
||||
case 'acceptSolution': {
|
||||
const solution = this.items()[message.solutionIndex];
|
||||
await this.acceptSolution(solution, true);
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
default:
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument, WebviewPanel } from 'vscode';
|
||||
import { IVSCodeExtensionContext } from '../../../../../../platform/extContext/common/extensionContext';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { IPosition, ITextDocument } from '../../../lib/src/textDocument';
|
||||
import { solutionCountTarget } from '../lib/copilotPanel/common';
|
||||
import { BaseSuggestionsPanelManager, ListDocumentInterface } from '../panelShared/baseSuggestionsPanelManager';
|
||||
import { PanelCompletion } from './common';
|
||||
import { CopilotListDocument } from './copilotListDocument';
|
||||
import { CopilotSuggestionsPanel } from './copilotSuggestionsPanel';
|
||||
import { copilotPanelConfig } from './panelConfig';
|
||||
|
||||
export class CopilotSuggestionsPanelManager extends BaseSuggestionsPanelManager<PanelCompletion> {
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IVSCodeExtensionContext extensionContext: IVSCodeExtensionContext,
|
||||
) {
|
||||
super(copilotPanelConfig, instantiationService, extensionContext);
|
||||
}
|
||||
|
||||
protected createListDocument(
|
||||
wrapped: ITextDocument,
|
||||
position: IPosition,
|
||||
panel: CopilotSuggestionsPanel
|
||||
): ListDocumentInterface {
|
||||
return this._instantiationService.createInstance(CopilotListDocument, wrapped, position, panel, solutionCountTarget);
|
||||
}
|
||||
|
||||
protected createSuggestionsPanel(
|
||||
panel: WebviewPanel,
|
||||
document: TextDocument,
|
||||
manager: this
|
||||
): CopilotSuggestionsPanel {
|
||||
return this._instantiationService.createInstance(CopilotSuggestionsPanel, panel, document, manager);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as constants from '../constants';
|
||||
import { CopilotPanelVisible } from '../constants';
|
||||
import { PanelConfig } from '../panelShared/basePanelTypes';
|
||||
|
||||
// Configuration for the GitHub Copilot Suggestions Panel
|
||||
export const copilotPanelConfig: PanelConfig = {
|
||||
panelTitle: 'GitHub Copilot Suggestions',
|
||||
webviewId: 'GitHub Copilot Suggestions',
|
||||
webviewScriptName: 'suggestionsPanelWebview.js',
|
||||
contextVariable: CopilotPanelVisible,
|
||||
commands: {
|
||||
accept: constants.CMDAcceptCursorPanelSolutionClient,
|
||||
navigatePrevious: constants.CMDNavigatePreviousPanelSolutionClient,
|
||||
navigateNext: constants.CMDNavigateNextPanelSolutionClient,
|
||||
},
|
||||
renderingMode: 'streaming',
|
||||
shuffleSolutions: false,
|
||||
};
|
||||
@@ -0,0 +1,166 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { provideVSCodeDesignSystem, vsCodeButton } from '@vscode/webview-ui-toolkit';
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
const solutionsContainer = document.getElementById('solutionsContainer');
|
||||
const vscode = acquireVsCodeApi();
|
||||
let currentFocusIndex: number = 0;
|
||||
let solutionEventHandlersInitialized = false;
|
||||
|
||||
provideVSCodeDesignSystem().register(vsCodeButton());
|
||||
|
||||
type Message = {
|
||||
command: string;
|
||||
solutions: {
|
||||
htmlSnippet: string;
|
||||
citation?: {
|
||||
message: string;
|
||||
url: string;
|
||||
};
|
||||
}[];
|
||||
percentage: number;
|
||||
};
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
// Notify the extension that the webview is ready
|
||||
vscode.postMessage({ command: 'webviewReady' });
|
||||
initializeSolutionEventHandlers();
|
||||
});
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
const message = event.data as Message; // The JSON data our extension sent
|
||||
|
||||
switch (message.command) {
|
||||
case 'solutionsUpdated':
|
||||
handleSolutionUpdate(message);
|
||||
break;
|
||||
case 'navigatePreviousSolution':
|
||||
navigatePreviousSolution();
|
||||
break;
|
||||
case 'navigateNextSolution':
|
||||
navigateNextSolution();
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
function handleSolutionUpdate(message: Message) {
|
||||
updateLoadingContainer(message);
|
||||
|
||||
if (solutionsContainer) {
|
||||
solutionsContainer.innerHTML = message.solutions
|
||||
.map((solution, index) => {
|
||||
const renderedCitation = solution.citation
|
||||
? `<p>
|
||||
<span style="vertical-align: text-bottom" aria-hidden="true">Warning</span>
|
||||
${DOMPurify.sanitize(solution.citation.message)}
|
||||
<a href="${DOMPurify.sanitize(solution.citation.url)}" target="_blank">Inspect source code</a>
|
||||
</p>`
|
||||
: '';
|
||||
const sanitizedSnippet = DOMPurify.sanitize(solution.htmlSnippet);
|
||||
|
||||
return `<h3 class='solutionHeading' id="solution-${index + 1}-heading">Suggestion ${index + 1}</h3>
|
||||
<div class='snippetContainer' aria-labelledby="solution-${index + 1}-heading" role="group" data-solution-index="${index}">${sanitizedSnippet
|
||||
}</div>
|
||||
${DOMPurify.sanitize(renderedCitation)}
|
||||
<vscode-button role="button" class="acceptButton" id="acceptButton${index}" appearance="secondary" data-solution-index="${index}">Accept suggestion ${index + 1
|
||||
}</vscode-button>`;
|
||||
})
|
||||
.join('');
|
||||
}
|
||||
}
|
||||
|
||||
function navigatePreviousSolution() {
|
||||
const snippets = document.querySelectorAll<HTMLElement>('.snippetContainer pre');
|
||||
const prevIndex = currentFocusIndex - 1;
|
||||
|
||||
snippets[prevIndex]?.focus();
|
||||
}
|
||||
|
||||
function navigateNextSolution() {
|
||||
const snippets = document.querySelectorAll<HTMLElement>('.snippetContainer pre');
|
||||
const nextIndex = (currentFocusIndex ?? -1) + 1;
|
||||
|
||||
if (snippets[nextIndex]) {
|
||||
snippets[nextIndex].focus();
|
||||
} else if (snippets[0]) {
|
||||
snippets[0].focus();
|
||||
}
|
||||
}
|
||||
|
||||
function updateLoadingContainer(message: Message) {
|
||||
const progressBar = document.getElementById('progress-bar') as HTMLProgressElement;
|
||||
const loadingContainer = document.getElementById('loadingContainer') as HTMLDivElement;
|
||||
if (!progressBar || !loadingContainer) {
|
||||
return;
|
||||
}
|
||||
if (message.percentage >= 100) {
|
||||
loadingContainer.innerHTML = `${message.solutions.length} Suggestions`;
|
||||
} else {
|
||||
const loadingLabelElement = loadingContainer.querySelector('label') as HTMLLabelElement;
|
||||
if (loadingLabelElement.textContent !== 'Loading suggestions:\u00A0') {
|
||||
loadingLabelElement.textContent = 'Loading suggestions:\u00A0';
|
||||
}
|
||||
progressBar.value = message.percentage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function initializeSolutionEventHandlers(): void {
|
||||
if (solutionEventHandlersInitialized || solutionsContainer === null) {
|
||||
return;
|
||||
}
|
||||
solutionsContainer.addEventListener('focusin', (event) => {
|
||||
const target = event.target as HTMLElement | null;
|
||||
const index = extractSolutionIndex(target);
|
||||
if (index === undefined) {
|
||||
return;
|
||||
}
|
||||
handleFocus(index);
|
||||
});
|
||||
solutionsContainer.addEventListener('click', (event) => {
|
||||
const target = event.target as HTMLElement | null;
|
||||
const button = target?.closest('vscode-button[data-solution-index]');
|
||||
if (!(button instanceof HTMLElement)) {
|
||||
return;
|
||||
}
|
||||
const index = extractSolutionIndex(button);
|
||||
if (index === undefined) {
|
||||
return;
|
||||
}
|
||||
handleClick(index);
|
||||
});
|
||||
solutionEventHandlersInitialized = true;
|
||||
}
|
||||
|
||||
function extractSolutionIndex(element: HTMLElement | null): number | undefined {
|
||||
const solutionElement = element?.closest('[data-solution-index]');
|
||||
if (!(solutionElement instanceof HTMLElement)) {
|
||||
return undefined;
|
||||
}
|
||||
const attributeValue = solutionElement.getAttribute('data-solution-index');
|
||||
if (attributeValue === null) {
|
||||
return undefined;
|
||||
}
|
||||
const index = Number.parseInt(attributeValue, 10);
|
||||
return Number.isNaN(index) ? undefined : index;
|
||||
}
|
||||
|
||||
function handleFocus(index: number) {
|
||||
currentFocusIndex = index;
|
||||
vscode.postMessage({
|
||||
command: 'focusSolution',
|
||||
solutionIndex: index,
|
||||
});
|
||||
}
|
||||
|
||||
function handleClick(index: number) {
|
||||
vscode.postMessage({
|
||||
command: 'acceptSolution',
|
||||
solutionIndex: index,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es2022",
|
||||
"skipLibCheck": true, // https://github.com/DataDog/datadog-ci/issues/1059
|
||||
"sourceMap": true,
|
||||
"rootDir": ".",
|
||||
"lib": ["ES2021", "dom"],
|
||||
// Reset values set in the parent tsconfig
|
||||
"strict": true, /* enable all strict type-checking options */
|
||||
/* Additional Checks */
|
||||
"noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
"noImplicitOverride": true, /* Force use of `override` keyword. */
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"useDefineForClassFields": false,
|
||||
"resolveJsonModule": true,
|
||||
"experimentalDecorators": true,
|
||||
"isolatedModules": false,
|
||||
},
|
||||
"exclude": [],
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createServiceIdentifier } from '../../../../../util/common/services';
|
||||
import { Command, StatusKind } from '../../types/src';
|
||||
|
||||
export const ICompletionsExtensionStatus = createServiceIdentifier<ICompletionsExtensionStatus>('ICompletionsExtensionStatus');
|
||||
export interface ICompletionsExtensionStatus {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
kind: StatusKind;
|
||||
message?: string;
|
||||
busy: boolean;
|
||||
command?: Command;
|
||||
}
|
||||
|
||||
export class CopilotExtensionStatus implements ICompletionsExtensionStatus {
|
||||
declare _serviceBrand: undefined;
|
||||
constructor(
|
||||
public kind: StatusKind = 'Normal',
|
||||
public message?: string,
|
||||
public busy = false,
|
||||
public command?: Command
|
||||
) { }
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { FileType, Uri, workspace } from 'vscode';
|
||||
import { FileIdentifier, FileStat, ICompletionsFileSystemService } from '../../lib/src/fileSystem';
|
||||
|
||||
class ExtensionFileSystem implements ICompletionsFileSystemService {
|
||||
declare _serviceBrand: undefined;
|
||||
|
||||
async readFileString(uri: FileIdentifier): Promise<string> {
|
||||
if (typeof uri !== 'string') {
|
||||
uri = uri.uri;
|
||||
}
|
||||
return new TextDecoder().decode(await workspace.fs.readFile(Uri.parse(uri, true)));
|
||||
}
|
||||
async stat(uri: FileIdentifier): Promise<FileStat> {
|
||||
if (typeof uri !== 'string') {
|
||||
uri = uri.uri;
|
||||
}
|
||||
return await workspace.fs.stat(Uri.parse(uri, true));
|
||||
}
|
||||
async readDirectory(uri: FileIdentifier): Promise<[string, FileType][]> {
|
||||
if (typeof uri !== 'string') {
|
||||
uri = uri.uri;
|
||||
}
|
||||
return await workspace.fs.readDirectory(Uri.parse(uri, true));
|
||||
}
|
||||
}
|
||||
|
||||
export const extensionFileSystem = new ExtensionFileSystem();
|
||||
@@ -0,0 +1,127 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
CancellationToken,
|
||||
InlineCompletionContext,
|
||||
InlineCompletionEndOfLifeReason,
|
||||
InlineCompletionEndOfLifeReasonKind,
|
||||
InlineCompletionItem,
|
||||
InlineCompletionList,
|
||||
InlineCompletionTriggerKind,
|
||||
PartialAcceptInfo,
|
||||
Position,
|
||||
Range,
|
||||
TextDocument,
|
||||
window
|
||||
} from 'vscode';
|
||||
import { ISurveyService } from '../../../../../../platform/survey/common/surveyService';
|
||||
import { assertNever } from '../../../../../../util/vs/base/common/assert';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { createCorrelationId } from '../../../../../inlineEdits/common/correlationId';
|
||||
import { CopilotCompletion } from '../../../lib/src/ghostText/copilotCompletion';
|
||||
import { handleGhostTextPostInsert, handleGhostTextShown, handlePartialGhostTextPostInsert } from '../../../lib/src/ghostText/last';
|
||||
import { GhostText } from '../../../lib/src/inlineCompletion';
|
||||
import { telemetry } from '../../../lib/src/telemetry';
|
||||
import { wrapDoc } from '../textDocumentManager';
|
||||
|
||||
export interface GhostTextCompletionList extends InlineCompletionList {
|
||||
items: GhostTextCompletionItem[];
|
||||
}
|
||||
|
||||
export interface GhostTextCompletionItem extends InlineCompletionItem {
|
||||
copilotCompletion: CopilotCompletion;
|
||||
}
|
||||
|
||||
export class GhostTextProvider {
|
||||
|
||||
private readonly ghostText: GhostText;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@ISurveyService private readonly _surveyService: ISurveyService,
|
||||
) {
|
||||
this.ghostText = this.instantiationService.createInstance(GhostText);
|
||||
}
|
||||
|
||||
async provideInlineCompletionItems(
|
||||
vscodeDoc: TextDocument,
|
||||
position: Position,
|
||||
context: InlineCompletionContext,
|
||||
token: CancellationToken
|
||||
): Promise<GhostTextCompletionList | undefined> {
|
||||
const textDocument = wrapDoc(vscodeDoc);
|
||||
if (!textDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Opportunity ID is a unique ID generated by the client relating to a single "opportunity"
|
||||
// to provide some kind of suggestion to the user. Multiple requests might be made for a single
|
||||
// opportunity, for example requesting a completion as well as an edit suggestion. The single ID
|
||||
// allows us to correlate the different requests.
|
||||
const opportunityId = context.requestUuid;
|
||||
|
||||
const formattingOptions = window.visibleTextEditors.find(e => e.document.uri === vscodeDoc.uri)?.options;
|
||||
|
||||
const rawCompletions = await this.ghostText.getInlineCompletions(textDocument, position, token, {
|
||||
isCycling: context.triggerKind === InlineCompletionTriggerKind.Invoke,
|
||||
selectedCompletionInfo: context.selectedCompletionInfo,
|
||||
formattingOptions,
|
||||
opportunityId,
|
||||
});
|
||||
|
||||
if (!rawCompletions) {
|
||||
return;
|
||||
}
|
||||
|
||||
const items: GhostTextCompletionItem[] = rawCompletions.map(completion => {
|
||||
const { start, end } = completion.range;
|
||||
const newRange = new Range(start.line, start.character, end.line, end.character);
|
||||
return {
|
||||
insertText: completion.insertText,
|
||||
range: newRange,
|
||||
copilotCompletion: completion,
|
||||
correlationId: createCorrelationId('completions', {}),
|
||||
} satisfies GhostTextCompletionItem;
|
||||
});
|
||||
|
||||
return { items };
|
||||
}
|
||||
|
||||
handleDidShowCompletionItem(item: GhostTextCompletionItem) {
|
||||
this.instantiationService.invokeFunction(handleGhostTextShown, item.copilotCompletion);
|
||||
}
|
||||
|
||||
handleDidPartiallyAcceptCompletionItem(item: GhostTextCompletionItem, info: number | PartialAcceptInfo) {
|
||||
if (typeof info === 'number') {
|
||||
return; // deprecated API
|
||||
}
|
||||
this.instantiationService.invokeFunction(handlePartialGhostTextPostInsert, item.copilotCompletion, info.acceptedLength);
|
||||
}
|
||||
|
||||
async handleEndOfLifetime(completionItem: GhostTextCompletionItem, reason: InlineCompletionEndOfLifeReason) {
|
||||
const copilotCompletion = completionItem.copilotCompletion;
|
||||
switch (reason.kind) {
|
||||
case InlineCompletionEndOfLifeReasonKind.Accepted: {
|
||||
this.instantiationService.invokeFunction(handleGhostTextPostInsert, copilotCompletion);
|
||||
this._surveyService.signalUsage('completions').catch(() => {
|
||||
// Ignore errors from the survey command execution
|
||||
});
|
||||
return;
|
||||
}
|
||||
case InlineCompletionEndOfLifeReasonKind.Rejected: {
|
||||
this.instantiationService.invokeFunction(telemetry, 'ghostText.dismissed', copilotCompletion.telemetry);
|
||||
return;
|
||||
}
|
||||
case InlineCompletionEndOfLifeReasonKind.Ignored: {
|
||||
// @ulugbekna: no-op ?
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
assertNever(reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
completions-sample-code/vscode-node/extension/src/icon.ts
Normal file
11
completions-sample-code/vscode-node/extension/src/icon.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export enum Icon {
|
||||
Logo = '$(copilot)',
|
||||
Warning = '$(copilot-warning)',
|
||||
NotConnected = '$(copilot-not-connected)',
|
||||
Blocked = '$(copilot-blocked)',
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const solutionCountTarget = 10;
|
||||
@@ -0,0 +1,137 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IInstantiationService, type ServicesAccessor } from '../../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { asyncIterableMapFilter } from '../../../../lib/src/helpers/iterableHelpers';
|
||||
import { ICompletionsLogTargetService, Logger } from '../../../../lib/src/logger';
|
||||
import { CopilotUiKind, ICompletionsOpenAIFetcherService } from '../../../../lib/src/openai/fetch';
|
||||
import { APIChoice } from '../../../../lib/src/openai/openai';
|
||||
import { ICompletionsStatusReporter } from '../../../../lib/src/progress';
|
||||
import { getNodeStartUtil } from '../../../../lib/src/prompt/parseBlock';
|
||||
import { trimLastLine } from '../../../../lib/src/prompt/prompt';
|
||||
import { postProcessChoiceInContext } from '../../../../lib/src/suggestions/suggestions';
|
||||
import { LocationFactory } from '../../../../lib/src/textDocument';
|
||||
import {
|
||||
generateSolutionsStream,
|
||||
reportSolutions,
|
||||
setupCompletionParams,
|
||||
setupPromptAndTelemetry,
|
||||
SolutionManager,
|
||||
trimChoices,
|
||||
} from '../panelShared/common';
|
||||
import { ISolutionHandler, SolutionsStream, UnformattedSolution } from '../panelShared/panelTypes';
|
||||
|
||||
const solutionsLogger = new Logger('solutions');
|
||||
|
||||
/**
|
||||
* Given an `ISolutionManager` with the context of a specific "Open Copilot" request,
|
||||
* initiate the generation of a stream of solutions for that request.
|
||||
*/
|
||||
export async function launchSolutions(accessor: ServicesAccessor, solutionManager: SolutionManager): Promise<SolutionsStream> {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const fetcherService = accessor.get(ICompletionsOpenAIFetcherService);
|
||||
const logTarget = accessor.get(ICompletionsLogTargetService);
|
||||
const position = solutionManager.targetPosition;
|
||||
const document = solutionManager.textDocument;
|
||||
|
||||
// Setup prompt and telemetry using shared function
|
||||
const promptSetup = await setupPromptAndTelemetry(accessor, solutionManager, 'open copilot', solutionsLogger);
|
||||
if ('status' in promptSetup) {
|
||||
// This is a SolutionsStream indicating an error occurred
|
||||
return promptSetup;
|
||||
}
|
||||
|
||||
const { prompt, trailingWs, telemetryData, repoInfo, ourRequestId } = promptSetup;
|
||||
|
||||
// Setup completion parameters using shared function
|
||||
const { extra, postOptions, finishedCb, engineInfo } = instantiationService.invokeFunction(setupCompletionParams,
|
||||
document,
|
||||
position,
|
||||
prompt,
|
||||
solutionManager,
|
||||
telemetryData
|
||||
);
|
||||
|
||||
const cancellationToken = solutionManager.cancellationToken;
|
||||
|
||||
const completionParams = {
|
||||
prompt,
|
||||
languageId: document.detectedLanguageId,
|
||||
repoInfo,
|
||||
ourRequestId,
|
||||
engineModelId: engineInfo.modelId,
|
||||
count: solutionManager.solutionCountTarget,
|
||||
uiKind: CopilotUiKind.Panel,
|
||||
postOptions,
|
||||
headers: engineInfo.headers,
|
||||
extra,
|
||||
};
|
||||
|
||||
const res = await fetcherService.fetchAndStreamCompletions(completionParams, telemetryData.extendedBy(), finishedCb, cancellationToken);
|
||||
|
||||
if (res.type === 'failed' || res.type === 'canceled') {
|
||||
return { status: 'FinishedWithError', error: `${res.type}: ${res.reason}` };
|
||||
}
|
||||
|
||||
let choices: AsyncIterable<APIChoice> = res.choices;
|
||||
choices = trimChoices(choices);
|
||||
choices = asyncIterableMapFilter(choices, choice => instantiationService.invokeFunction(postProcessChoiceInContext, document, position, choice, false, solutionsLogger));
|
||||
|
||||
const solutions = asyncIterableMapFilter(choices, async (apiChoice: APIChoice) => {
|
||||
let display = apiChoice.completionText;
|
||||
solutionsLogger.info(logTarget, `Open Copilot completion: [${apiChoice.completionText}]`);
|
||||
|
||||
// For completions that can happen in any location in the middle of the code we try to find the existing code
|
||||
// that should be displayed in the OpenCopilot panel so the code is nicely formatted/highlighted.
|
||||
// This is not needed for implement unknown function quick fix, as it will be
|
||||
// always "complete" standalone function in the location suggested by TS' extension.
|
||||
const displayStartPos =
|
||||
(await getNodeStartUtil(document, position, apiChoice.completionText)) ??
|
||||
LocationFactory.position(position.line, 0);
|
||||
const [displayBefore] = trimLastLine(document.getText(LocationFactory.range(displayStartPos, position)));
|
||||
|
||||
display = displayBefore + display;
|
||||
let completionText = apiChoice.completionText;
|
||||
|
||||
if (trailingWs.length > 0 && completionText.startsWith(trailingWs)) {
|
||||
completionText = completionText.substring(trailingWs.length);
|
||||
}
|
||||
|
||||
const meanLogProb = apiChoice.meanLogProb;
|
||||
const meanProb: number = meanLogProb !== undefined ? Math.exp(meanLogProb) : 0;
|
||||
|
||||
const solutionTelemetryData = telemetryData.extendedBy({
|
||||
choiceIndex: apiChoice.choiceIndex.toString(),
|
||||
});
|
||||
const solution: UnformattedSolution = {
|
||||
completionText,
|
||||
insertText: display,
|
||||
range: LocationFactory.range(displayStartPos, position),
|
||||
meanProb: meanProb,
|
||||
meanLogProb: meanLogProb || 0,
|
||||
requestId: apiChoice.requestId,
|
||||
choiceIndex: apiChoice.choiceIndex,
|
||||
telemetryData: solutionTelemetryData,
|
||||
copilotAnnotations: apiChoice.copilotAnnotations,
|
||||
};
|
||||
return solution;
|
||||
});
|
||||
// deliberately not awaiting so that we can return quickly
|
||||
const solutionsStream = generateSolutionsStream(cancellationToken, solutions[Symbol.asyncIterator]());
|
||||
return solutionsStream;
|
||||
}
|
||||
|
||||
export async function runSolutions(
|
||||
accessor: ServicesAccessor,
|
||||
solutionManager: SolutionManager,
|
||||
solutionHandler: ISolutionHandler
|
||||
): Promise<void> {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const statusReporter = accessor.get(ICompletionsStatusReporter);
|
||||
return statusReporter.withProgress(async () => {
|
||||
const nextSolution = instantiationService.invokeFunction(launchSolutions, solutionManager);
|
||||
return await reportSolutions(nextSolution, solutionHandler);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken } from 'vscode';
|
||||
import { generateUuid } from '../../../../../../../util/vs/base/common/uuid';
|
||||
import { IInstantiationService, type ServicesAccessor } from '../../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { createCompletionState } from '../../../../lib/src/completionState';
|
||||
import { BlockMode } from '../../../../lib/src/config';
|
||||
import { ICompletionsFeaturesService } from '../../../../lib/src/experiments/featuresService';
|
||||
import { ICompletionsBlockModeConfig } from '../../../../lib/src/ghostText/configBlockMode';
|
||||
import { ICompletionsLogTargetService, type Logger } from '../../../../lib/src/logger';
|
||||
import { getEngineRequestInfo } from '../../../../lib/src/openai/config';
|
||||
import { CompletionHeaders, CompletionRequestExtra, PostOptions } from '../../../../lib/src/openai/fetch';
|
||||
import { APIChoice, FinishedCallback } from '../../../../lib/src/openai/openai';
|
||||
import { contextIndentation, parsingBlockFinished } from '../../../../lib/src/prompt/parseBlock';
|
||||
import { extractPrompt, Prompt } from '../../../../lib/src/prompt/prompt';
|
||||
import { extractRepoInfoInBackground, MaybeRepoInfo } from '../../../../lib/src/prompt/repository';
|
||||
import { telemetrizePromptLength, telemetry, TelemetryData, TelemetryWithExp } from '../../../../lib/src/telemetry';
|
||||
import { IPosition, ITextDocument, LocationFactory, TextDocumentContents } from '../../../../lib/src/textDocument';
|
||||
import { isSupportedLanguageId } from '../../../../prompt/src/parse';
|
||||
import { Position } from '../../../../types/src';
|
||||
import { ISolutionHandler, SolutionsStream, UnformattedSolution } from './panelTypes';
|
||||
|
||||
export const solutionCountTarget = 10;
|
||||
|
||||
export function panelPositionForDocument(document: TextDocumentContents, position: Position): IPosition {
|
||||
let returnPosition = position;
|
||||
const line = document.lineAt(position.line);
|
||||
if (!line.isEmptyOrWhitespace) {
|
||||
returnPosition = line.range.end;
|
||||
}
|
||||
return returnPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim trailing whitespace.
|
||||
*/
|
||||
export async function* trimChoices(choices: AsyncIterable<APIChoice>): AsyncIterable<APIChoice> {
|
||||
for await (const choice of choices) {
|
||||
const choiceCopy = { ...choice };
|
||||
choiceCopy.completionText = choiceCopy.completionText.trimEnd();
|
||||
yield choiceCopy;
|
||||
}
|
||||
}
|
||||
|
||||
export class SolutionManager {
|
||||
private _savedTelemetryData?: TelemetryWithExp | undefined;
|
||||
readonly targetPosition = panelPositionForDocument(this.textDocument, this.startPosition);
|
||||
|
||||
constructor(
|
||||
readonly textDocument: ITextDocument,
|
||||
public startPosition: IPosition,
|
||||
readonly cancellationToken: CancellationToken,
|
||||
readonly solutionCountTarget: number
|
||||
) { }
|
||||
|
||||
get savedTelemetryData(): TelemetryWithExp | undefined {
|
||||
return this._savedTelemetryData;
|
||||
}
|
||||
|
||||
set savedTelemetryData(data: TelemetryWithExp | undefined) {
|
||||
this._savedTelemetryData = data;
|
||||
}
|
||||
}
|
||||
|
||||
export async function reportSolutions(
|
||||
nextSolutionPromise: Promise<SolutionsStream>,
|
||||
solutionHandler: ISolutionHandler
|
||||
): Promise<void> {
|
||||
const nextSolution = await nextSolutionPromise;
|
||||
switch (nextSolution.status) {
|
||||
case 'Solution':
|
||||
await solutionHandler.onSolution(nextSolution.solution);
|
||||
await reportSolutions(nextSolution.next, solutionHandler);
|
||||
break;
|
||||
case 'FinishedNormally':
|
||||
await solutionHandler.onFinishedNormally();
|
||||
break;
|
||||
case 'FinishedWithError':
|
||||
await solutionHandler.onFinishedWithError(nextSolution.error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export async function generateSolutionsStream(
|
||||
cancellationToken: CancellationToken,
|
||||
solutions: AsyncIterator<UnformattedSolution>
|
||||
): Promise<SolutionsStream> {
|
||||
if (cancellationToken.isCancellationRequested) {
|
||||
return { status: 'FinishedWithError', error: 'Cancelled' };
|
||||
}
|
||||
const nextResult = await solutions.next();
|
||||
if (nextResult.done === true) {
|
||||
return { status: 'FinishedNormally' };
|
||||
}
|
||||
return {
|
||||
status: 'Solution',
|
||||
solution: nextResult.value,
|
||||
next: generateSolutionsStream(cancellationToken, solutions),
|
||||
};
|
||||
}
|
||||
|
||||
export function normalizeCompletionText(text: string): string {
|
||||
return text.replace(/\s+/g, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of prompt processing setup
|
||||
*/
|
||||
export interface PromptSetupResult {
|
||||
prompt: Prompt;
|
||||
trailingWs: string;
|
||||
telemetryData: TelemetryWithExp;
|
||||
repoInfo: MaybeRepoInfo;
|
||||
ourRequestId: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up prompt extraction, telemetry, and handles common error cases.
|
||||
* Returns null if an error occurred that should terminate processing.
|
||||
*/
|
||||
export async function setupPromptAndTelemetry(
|
||||
accessor: ServicesAccessor,
|
||||
solutionManager: SolutionManager,
|
||||
source: 'open copilot' | 'open comparison',
|
||||
solutionsLogger: Logger,
|
||||
engineName?: string,
|
||||
comparisonRequestId?: string
|
||||
): Promise<PromptSetupResult | SolutionsStream> {
|
||||
const position = solutionManager.targetPosition;
|
||||
const document = solutionManager.textDocument;
|
||||
|
||||
const repoInfo = extractRepoInfoInBackground(accessor, document.uri);
|
||||
|
||||
// Telemetry setup
|
||||
const ourRequestId = generateUuid();
|
||||
const tempTelemetry = TelemetryData.createAndMarkAsIssued(
|
||||
{
|
||||
headerRequestId: ourRequestId,
|
||||
languageId: document.detectedLanguageId,
|
||||
source,
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
const featuresService = accessor.get(ICompletionsFeaturesService);
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const logTarget = accessor.get(ICompletionsLogTargetService);
|
||||
// Update telemetry with experiment values
|
||||
solutionManager.savedTelemetryData = await featuresService
|
||||
.fetchTokenAndUpdateExPValuesAndAssignments(
|
||||
{ uri: document.uri, languageId: document.detectedLanguageId },
|
||||
tempTelemetry
|
||||
);
|
||||
|
||||
// Add in comparison panel specific info
|
||||
if (engineName) {
|
||||
solutionManager.savedTelemetryData = solutionManager.savedTelemetryData!.extendedBy({
|
||||
engineName,
|
||||
});
|
||||
}
|
||||
if (comparisonRequestId) {
|
||||
solutionManager.savedTelemetryData = solutionManager.savedTelemetryData!.extendedBy({
|
||||
comparisonRequestId,
|
||||
});
|
||||
}
|
||||
|
||||
// Extract prompt
|
||||
const promptResponse = await instantiationService.invokeFunction(extractPrompt,
|
||||
ourRequestId,
|
||||
createCompletionState(document, position),
|
||||
solutionManager.savedTelemetryData!
|
||||
);
|
||||
|
||||
// Handle prompt extraction errors
|
||||
if (promptResponse.type === 'copilotContentExclusion') {
|
||||
return { status: 'FinishedNormally' };
|
||||
}
|
||||
if (promptResponse.type === 'contextTooShort') {
|
||||
return { status: 'FinishedWithError', error: 'Context too short' };
|
||||
}
|
||||
if (promptResponse.type === 'promptCancelled') {
|
||||
return { status: 'FinishedWithError', error: 'Prompt cancelled' };
|
||||
}
|
||||
if (promptResponse.type === 'promptTimeout') {
|
||||
return { status: 'FinishedWithError', error: 'Prompt timeout' };
|
||||
}
|
||||
if (promptResponse.type === 'promptError') {
|
||||
return { status: 'FinishedWithError', error: 'Prompt error' };
|
||||
}
|
||||
|
||||
const prompt = promptResponse.prompt;
|
||||
const trailingWs = promptResponse.trailingWs;
|
||||
|
||||
// Handle trailing whitespace adjustment
|
||||
if (trailingWs.length > 0) {
|
||||
solutionManager.startPosition = LocationFactory.position(
|
||||
solutionManager.startPosition.line,
|
||||
solutionManager.startPosition.character - trailingWs.length
|
||||
);
|
||||
}
|
||||
|
||||
// Update telemetry with prompt information
|
||||
solutionManager.savedTelemetryData = solutionManager.savedTelemetryData!.extendedBy(
|
||||
{},
|
||||
{
|
||||
...telemetrizePromptLength(prompt),
|
||||
solutionCount: solutionManager.solutionCountTarget,
|
||||
promptEndPos: document.offsetAt(position),
|
||||
}
|
||||
);
|
||||
|
||||
solutionsLogger.debug(logTarget, 'prompt:', prompt);
|
||||
instantiationService.invokeFunction(telemetry, 'solution.requested', solutionManager.savedTelemetryData);
|
||||
|
||||
return {
|
||||
prompt,
|
||||
trailingWs,
|
||||
telemetryData: solutionManager.savedTelemetryData,
|
||||
repoInfo,
|
||||
ourRequestId,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of completion parameters setup
|
||||
*/
|
||||
export interface CompletionSetupResult {
|
||||
extra: CompletionRequestExtra;
|
||||
postOptions: PostOptions;
|
||||
finishedCb: FinishedCallback;
|
||||
engineInfo: { modelId: string; headers: CompletionHeaders };
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up block mode, completion parameters, and finished callback.
|
||||
*/
|
||||
export function setupCompletionParams(
|
||||
accessor: ServicesAccessor,
|
||||
document: ITextDocument,
|
||||
position: IPosition,
|
||||
prompt: Prompt,
|
||||
solutionManager: SolutionManager,
|
||||
telemetryData: TelemetryWithExp
|
||||
): CompletionSetupResult {
|
||||
// Compute block mode
|
||||
const blockMode = accessor.get(ICompletionsBlockModeConfig).forLanguage(document.detectedLanguageId, telemetryData);
|
||||
const isSupportedLanguage = isSupportedLanguageId(document.detectedLanguageId);
|
||||
|
||||
const contextIndent = contextIndentation(document, position);
|
||||
const extra: CompletionRequestExtra = {
|
||||
language: document.detectedLanguageId,
|
||||
next_indent: contextIndent.next ?? 0,
|
||||
prompt_tokens: prompt.prefixTokens ?? 0,
|
||||
suffix_tokens: prompt.suffixTokens ?? 0,
|
||||
};
|
||||
|
||||
const postOptions: PostOptions = {};
|
||||
if (blockMode === BlockMode.Parsing && !isSupportedLanguage) {
|
||||
postOptions['stop'] = ['\n\n', '\r\n\r\n'];
|
||||
}
|
||||
|
||||
const engineInfo = getEngineRequestInfo(accessor, telemetryData);
|
||||
|
||||
let finishedCb: FinishedCallback;
|
||||
|
||||
switch (blockMode) {
|
||||
case BlockMode.Server:
|
||||
// Client knows the block is done when the completion is.
|
||||
finishedCb = () => undefined;
|
||||
// If requested at the top-level, don't trim at all.
|
||||
extra.force_indent = contextIndent.prev ?? -1;
|
||||
extra.trim_by_indentation = true;
|
||||
break;
|
||||
case BlockMode.ParsingAndServer:
|
||||
finishedCb = isSupportedLanguage
|
||||
? parsingBlockFinished(document, solutionManager.startPosition)
|
||||
: () => undefined;
|
||||
// If requested at the top-level, don't trim at all.
|
||||
extra.force_indent = contextIndent.prev ?? -1;
|
||||
extra.trim_by_indentation = true;
|
||||
break;
|
||||
case BlockMode.Parsing:
|
||||
default:
|
||||
finishedCb = isSupportedLanguage
|
||||
? parsingBlockFinished(document, solutionManager.startPosition)
|
||||
: () => undefined;
|
||||
break;
|
||||
}
|
||||
|
||||
return {
|
||||
extra,
|
||||
postOptions,
|
||||
finishedCb,
|
||||
engineInfo,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CopilotNamedAnnotationList } from '../../../../../../../platform/completions-core/common/openai/copilotAnnotations';
|
||||
import { RequestId } from '../../../../../../../platform/networking/common/fetch';
|
||||
import { TelemetryWithExp } from '../../../../lib/src/telemetry';
|
||||
import { IRange } from '../../../../lib/src/textDocument';
|
||||
|
||||
export interface UnformattedSolution {
|
||||
/** Raw text returned by model */
|
||||
completionText: string;
|
||||
/** Text that should be inserted into the document, replacing the text at .range */
|
||||
insertText: string;
|
||||
range: IRange;
|
||||
meanProb: number;
|
||||
meanLogProb: number;
|
||||
requestId: RequestId;
|
||||
choiceIndex: number;
|
||||
telemetryData: TelemetryWithExp;
|
||||
copilotAnnotations?: CopilotNamedAnnotationList;
|
||||
/** Optional Model ID when fetching from multiple models */
|
||||
modelId?: string;
|
||||
}
|
||||
|
||||
export interface ISolutionHandler {
|
||||
onSolution(solution: UnformattedSolution): Promise<void> | void;
|
||||
onFinishedNormally(): Promise<void> | void;
|
||||
onFinishedWithError(error: string): Promise<void> | void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A stream of solutions, ending either with 'FinishedNormally' or 'FinishedWithError'.
|
||||
* This structure allows for errors to occur part way through the stream, as well as
|
||||
* at the beginning.
|
||||
*
|
||||
* The stream is similar to an async generator, but with more information when the stream
|
||||
* ends: instead of just `done` we can have `FinishedNormally` or `FinishedWithError`.
|
||||
*/
|
||||
export type SolutionsStream =
|
||||
| { status: 'FinishedNormally' }
|
||||
| { status: 'FinishedWithError'; error: string }
|
||||
| { status: 'Solution'; solution: UnformattedSolution; next: Promise<SolutionsStream> };
|
||||
148
completions-sample-code/vscode-node/extension/src/modelPicker.ts
Normal file
148
completions-sample-code/vscode-node/extension/src/modelPicker.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { env, QuickPick, QuickPickItem, QuickPickItemKind, Uri, window, workspace } from 'vscode';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { ConfigKey, getConfig } from '../../lib/src/config';
|
||||
import { CopilotConfigPrefix } from '../../lib/src/constants';
|
||||
import { AsyncCompletionManager, ICompletionsAsyncManagerService } from '../../lib/src/ghostText/asyncCompletions';
|
||||
import { CompletionsCache, ICompletionsCacheService } from '../../lib/src/ghostText/completionsCache';
|
||||
import { ICompletionsLogTargetService, Logger } from '../../lib/src/logger';
|
||||
import { AvailableModelsManager, ICompletionsModelManagerService, ModelItem } from '../../lib/src/openai/model';
|
||||
import { telemetry, TelemetryData } from '../../lib/src/telemetry';
|
||||
const logger = new Logger('modelPicker');
|
||||
|
||||
interface ModelPickerItem extends Omit<ModelItem, 'preview' | 'tokenizer'>, QuickPickItem {
|
||||
// Distinguish between items in the quick pick
|
||||
type: 'model' | 'separator' | 'learn-more';
|
||||
}
|
||||
|
||||
// Separator and learn-more links are always shown in the quick pick
|
||||
const defaultModelPickerItems: ModelPickerItem[] = [
|
||||
// Add separator after the models
|
||||
{
|
||||
label: '',
|
||||
kind: QuickPickItemKind.Separator,
|
||||
modelId: 'separator',
|
||||
type: 'separator' as const,
|
||||
alwaysShow: true,
|
||||
},
|
||||
// Add "Learn more" item at the end
|
||||
{
|
||||
modelId: 'learn-more',
|
||||
label: 'Learn more $(link-external)',
|
||||
description: '',
|
||||
alwaysShow: true,
|
||||
type: 'learn-more' as const,
|
||||
},
|
||||
];
|
||||
|
||||
export class ModelPickerManager {
|
||||
// URL for information about Copilot models
|
||||
private readonly MODELS_INFO_URL = 'https://aka.ms/CopilotCompletionsModelPickerLearnMore';
|
||||
|
||||
get models(): ModelItem[] {
|
||||
return this._modelManager.getGenericCompletionModels();
|
||||
}
|
||||
|
||||
private getDefaultModelId(): string {
|
||||
return this._modelManager.getDefaultModelId();
|
||||
}
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ICompletionsAsyncManagerService private readonly _asyncCompletionManager: AsyncCompletionManager,
|
||||
@ICompletionsModelManagerService private readonly _modelManager: AvailableModelsManager,
|
||||
@ICompletionsLogTargetService private readonly _logTarget: ICompletionsLogTargetService,
|
||||
@ICompletionsCacheService private readonly _completionsCache: CompletionsCache
|
||||
) { }
|
||||
|
||||
async setUserSelectedCompletionModel(modelId: string | null) {
|
||||
return workspace
|
||||
.getConfiguration(CopilotConfigPrefix)
|
||||
.update(ConfigKey.UserSelectedCompletionModel, modelId ?? '', true);
|
||||
}
|
||||
|
||||
async handleModelSelection(quickpickList: QuickPick<ModelPickerItem>) {
|
||||
const model = quickpickList.activeItems[0];
|
||||
if (model === undefined) {
|
||||
return;
|
||||
}
|
||||
quickpickList.hide();
|
||||
|
||||
// Open up the link
|
||||
if (model.type === 'learn-more') {
|
||||
await env.openExternal(Uri.parse(this.MODELS_INFO_URL));
|
||||
this._instantiationService.invokeFunction(telemetry, 'modelPicker.learnMoreClicked');
|
||||
return;
|
||||
}
|
||||
|
||||
await this.selectModel(model);
|
||||
}
|
||||
|
||||
async selectModel(model: ModelPickerItem) {
|
||||
const currentModel = this._instantiationService.invokeFunction(getUserSelectedModelConfiguration);
|
||||
|
||||
if (currentModel !== model.modelId) {
|
||||
this._completionsCache.clear();
|
||||
this._asyncCompletionManager.clear();
|
||||
}
|
||||
|
||||
const modelSelection = model.modelId === this.getDefaultModelId() ? null : model.modelId;
|
||||
await this.setUserSelectedCompletionModel(modelSelection);
|
||||
if (modelSelection === null) {
|
||||
logger.info(this._logTarget, `User selected default model; setting null`);
|
||||
} else {
|
||||
logger.info(this._logTarget, `Selected model: ${model.modelId}`);
|
||||
}
|
||||
|
||||
this._instantiationService.invokeFunction(
|
||||
telemetry,
|
||||
'modelPicker.modelSelected',
|
||||
TelemetryData.createAndMarkAsIssued({
|
||||
engineName: modelSelection ?? 'default',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private modelsForModelPicker(): [string | null, ModelPickerItem[]] {
|
||||
const currentModelSelection = this._instantiationService.invokeFunction(getUserSelectedModelConfiguration);
|
||||
const items: ModelPickerItem[] = this.models.map(model => {
|
||||
return {
|
||||
modelId: model.modelId,
|
||||
label: `${model.label}${model.preview ? ' (Preview)' : ''}`,
|
||||
description: `(${model.modelId})`,
|
||||
alwaysShow: model.modelId === this.getDefaultModelId(),
|
||||
type: 'model' as const,
|
||||
};
|
||||
});
|
||||
|
||||
return [currentModelSelection, items];
|
||||
}
|
||||
|
||||
showModelPicker(): QuickPick<ModelPickerItem> {
|
||||
const [currentModelSelection, items] = this.modelsForModelPicker();
|
||||
|
||||
const quickPick = window.createQuickPick<ModelPickerItem>();
|
||||
quickPick.title = 'Change Completions Model';
|
||||
quickPick.items = [...items, ...defaultModelPickerItems];
|
||||
quickPick.onDidAccept(() => this.handleModelSelection(quickPick));
|
||||
|
||||
const currentModelOrDefault = currentModelSelection ?? this.getDefaultModelId();
|
||||
|
||||
// set the currently selected model as active
|
||||
const selectedItem = quickPick.items.find(item => item.modelId === currentModelOrDefault);
|
||||
if (selectedItem) {
|
||||
quickPick.activeItems = [selectedItem];
|
||||
}
|
||||
|
||||
quickPick.show();
|
||||
return quickPick;
|
||||
}
|
||||
}
|
||||
|
||||
function getUserSelectedModelConfiguration(accessor: ServicesAccessor): string | null {
|
||||
const value = getConfig<string | null>(accessor, ConfigKey.UserSelectedCompletionModel);
|
||||
return typeof value === 'string' && value.length > 0 ? value : null;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Position, Range } from 'vscode';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { postInsertionTasks } from '../../../lib/src/postInsertion';
|
||||
import { countLines } from '../../../lib/src/suggestions/partialSuggestions';
|
||||
import { IPosition, ITextDocument } from '../../../lib/src/textDocument';
|
||||
import { normalizeCompletionText, solutionCountTarget, SolutionManager } from '../lib/panelShared/common';
|
||||
import { UnformattedSolution } from '../lib/panelShared/panelTypes';
|
||||
import { BasePanelCompletion, ISuggestionsPanel } from './basePanelTypes';
|
||||
|
||||
// BaseListDocument to be shared with both the copilot and comparison completion panels.
|
||||
export abstract class BaseListDocument<TPanelCompletion extends BasePanelCompletion> extends SolutionManager {
|
||||
private _solutionCount = 0;
|
||||
protected readonly _solutions: TPanelCompletion[] = [];
|
||||
|
||||
constructor(
|
||||
textDocument: ITextDocument,
|
||||
position: IPosition,
|
||||
readonly panel: ISuggestionsPanel,
|
||||
countTarget = solutionCountTarget,
|
||||
@IInstantiationService protected readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super(textDocument, position, panel.cancellationToken, countTarget);
|
||||
}
|
||||
|
||||
protected abstract createPanelCompletion(
|
||||
unformatted: UnformattedSolution,
|
||||
baseCompletion: BasePanelCompletion
|
||||
): TPanelCompletion;
|
||||
protected abstract shouldAddSolution(newItem: TPanelCompletion): boolean;
|
||||
protected abstract runSolutionsImpl(): Promise<void>;
|
||||
|
||||
// Find if two solutions are duplicates by comparing their normalized text content.
|
||||
protected areSolutionsDuplicates(solutionA: TPanelCompletion, solutionB: TPanelCompletion): boolean {
|
||||
const stripA = normalizeCompletionText(solutionA.insertText);
|
||||
const stripB = normalizeCompletionText(solutionB.insertText);
|
||||
return stripA === stripB;
|
||||
}
|
||||
|
||||
protected findDuplicateSolution(newItem: TPanelCompletion): TPanelCompletion | undefined {
|
||||
return this._solutions.find(item => this.areSolutionsDuplicates(item, newItem));
|
||||
}
|
||||
|
||||
onSolution(unformatted: UnformattedSolution) {
|
||||
const offset = this.textDocument.offsetAt(this.targetPosition);
|
||||
const rank = this._solutions.length;
|
||||
|
||||
const postInsertionCallback = () => {
|
||||
const telemetryData = this.savedTelemetryData!.extendedBy(
|
||||
{
|
||||
choiceIndex: unformatted.choiceIndex.toString(),
|
||||
engineName: unformatted.modelId || '',
|
||||
},
|
||||
{
|
||||
compCharLen: unformatted.insertText.length,
|
||||
meanProb: unformatted.meanProb,
|
||||
rank,
|
||||
}
|
||||
);
|
||||
return this.instantiationService.invokeFunction(postInsertionTasks,
|
||||
'solution',
|
||||
unformatted.insertText,
|
||||
offset,
|
||||
this.textDocument.uri,
|
||||
telemetryData,
|
||||
{
|
||||
compType: 'full',
|
||||
acceptedLength: unformatted.insertText.length,
|
||||
acceptedLines: countLines(unformatted.insertText),
|
||||
},
|
||||
unformatted.copilotAnnotations
|
||||
);
|
||||
};
|
||||
|
||||
const baseCompletion: BasePanelCompletion = {
|
||||
insertText: unformatted.insertText,
|
||||
range: new Range(
|
||||
new Position(unformatted.range.start.line, unformatted.range.start.character),
|
||||
new Position(unformatted.range.end.line, unformatted.range.end.character)
|
||||
),
|
||||
copilotAnnotations: unformatted.copilotAnnotations,
|
||||
postInsertionCallback,
|
||||
};
|
||||
|
||||
const newItem = this.createPanelCompletion(unformatted, baseCompletion);
|
||||
|
||||
if (this.shouldAddSolution(newItem)) {
|
||||
this.panel.onItem(newItem);
|
||||
this._solutions.push(newItem);
|
||||
}
|
||||
this._solutionCount++;
|
||||
this.panel.onWorkDone({ percentage: (100 * this._solutionCount) / this.solutionCountTarget });
|
||||
}
|
||||
|
||||
onFinishedNormally() {
|
||||
return this.panel.onFinished();
|
||||
}
|
||||
|
||||
onFinishedWithError(_: string) {
|
||||
return this.onFinishedNormally();
|
||||
}
|
||||
|
||||
runQuery() {
|
||||
return this.runSolutionsImpl();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken, Range } from 'vscode';
|
||||
import { CopilotNamedAnnotationList } from '../../../../../../platform/completions-core/common/openai/copilotAnnotations';
|
||||
|
||||
// Base interface for a completion displayed in the panel.
|
||||
export interface BasePanelCompletion {
|
||||
insertText: string;
|
||||
range: Range;
|
||||
copilotAnnotations?: CopilotNamedAnnotationList;
|
||||
postInsertionCallback: () => PromiseLike<void> | void;
|
||||
}
|
||||
|
||||
// Interface for the suggestions panel, which handles work done notifications and item selections.
|
||||
export interface ISuggestionsPanel {
|
||||
cancellationToken: CancellationToken;
|
||||
onWorkDone(_: { percentage: number }): void;
|
||||
onItem(_: BasePanelCompletion): void;
|
||||
onFinished(): void;
|
||||
}
|
||||
|
||||
// Configuration for webview panels for completions.
|
||||
export interface PanelConfig {
|
||||
panelTitle: string;
|
||||
webviewId: string;
|
||||
webviewScriptName: string;
|
||||
contextVariable: string;
|
||||
commands: {
|
||||
accept: string;
|
||||
navigatePrevious: string;
|
||||
navigateNext: string;
|
||||
};
|
||||
renderingMode: 'streaming' | 'batch';
|
||||
shuffleSolutions: boolean;
|
||||
}
|
||||
|
||||
// Configuration for webview panels, used to pass settings to the webview.
|
||||
export interface WebviewConfig {
|
||||
renderingMode: 'batch' | 'streaming';
|
||||
shuffleSolutions: boolean;
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
CancellationTokenSource,
|
||||
Disposable,
|
||||
Event,
|
||||
EventEmitter,
|
||||
TextDocument,
|
||||
Uri,
|
||||
WebviewPanel,
|
||||
WorkspaceEdit,
|
||||
commands,
|
||||
workspace,
|
||||
} from 'vscode';
|
||||
import { IVSCodeExtensionContext } from '../../../../../../platform/extContext/common/extensionContext';
|
||||
import { debounce } from '../../../../../../util/common/debounce';
|
||||
import { BasePanelCompletion, ISuggestionsPanel, PanelConfig } from './basePanelTypes';
|
||||
import { Highlighter } from './highlighter';
|
||||
import { getNonce, pluralize } from './utils';
|
||||
|
||||
//import { IPCitationDetail } from '#lib/citationManager';
|
||||
interface IPCitationDetail {
|
||||
license: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface SuggestionsPanelManagerInterface {
|
||||
activeWebviewPanel: BaseSuggestionsPanel<BasePanelCompletion> | undefined;
|
||||
decrementPanelCount(): void;
|
||||
}
|
||||
|
||||
export interface SolutionContent {
|
||||
htmlSnippet: string;
|
||||
citation?: { message: string; url: string };
|
||||
[key: string]: unknown; // Allow additional properties for panel-specific content
|
||||
}
|
||||
|
||||
export interface BaseWebviewMessage {
|
||||
command: string;
|
||||
}
|
||||
|
||||
interface AcceptSolutionMessage extends BaseWebviewMessage {
|
||||
command: 'acceptSolution';
|
||||
solutionIndex: number;
|
||||
}
|
||||
|
||||
interface FocusSolutionMessage extends BaseWebviewMessage {
|
||||
command: 'focusSolution';
|
||||
solutionIndex: number;
|
||||
}
|
||||
|
||||
interface SubmitFeedbackMessage extends BaseWebviewMessage {
|
||||
command: 'submitFeedback';
|
||||
solutionIndex: number;
|
||||
feedback: string;
|
||||
}
|
||||
|
||||
interface RefreshMessage extends BaseWebviewMessage {
|
||||
command: 'refresh';
|
||||
}
|
||||
|
||||
interface WebviewReadyMessage extends BaseWebviewMessage {
|
||||
command: 'webviewReady';
|
||||
}
|
||||
|
||||
export type WebviewMessage =
|
||||
| AcceptSolutionMessage
|
||||
| FocusSolutionMessage
|
||||
| SubmitFeedbackMessage
|
||||
| RefreshMessage
|
||||
| WebviewReadyMessage;
|
||||
|
||||
export abstract class BaseSuggestionsPanel<TPanelCompletion extends BasePanelCompletion> implements ISuggestionsPanel {
|
||||
private _disposables: Disposable[] = [];
|
||||
#items: TPanelCompletion[] = [];
|
||||
#batchItems: TPanelCompletion[] = [];
|
||||
#percentage = 0;
|
||||
#highlighter: Thenable<Highlighter>;
|
||||
private _focusedSolution: TPanelCompletion | undefined;
|
||||
private _isDisposed: boolean = false;
|
||||
#documentUri: Uri;
|
||||
#cts = new CancellationTokenSource();
|
||||
|
||||
private _onDidDispose = new EventEmitter<void>();
|
||||
readonly onDidDispose: Event<void> = this._onDidDispose.event;
|
||||
|
||||
get cancellationToken() {
|
||||
return this.#cts.token;
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly webviewPanel: WebviewPanel,
|
||||
document: TextDocument,
|
||||
protected suggestionsPanelManager: SuggestionsPanelManagerInterface,
|
||||
protected readonly config: PanelConfig,
|
||||
@IVSCodeExtensionContext protected readonly contextService: IVSCodeExtensionContext,
|
||||
) {
|
||||
webviewPanel.onDidDispose(() => this._dispose(), null, this._disposables);
|
||||
webviewPanel.webview.html = this._getWebviewContent();
|
||||
this.#documentUri = document.uri;
|
||||
|
||||
this.#highlighter = Highlighter.create(document.languageId);
|
||||
|
||||
workspace.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('workbench.colorTheme')) {
|
||||
return this.render();
|
||||
}
|
||||
});
|
||||
|
||||
webviewPanel.webview.onDidReceiveMessage(async (message: WebviewMessage) => {
|
||||
// First lest the subclass handle custom messages
|
||||
if ((await this.handleCustomMessage(message)) === true) {
|
||||
return;
|
||||
}
|
||||
switch (message.command) {
|
||||
case 'focusSolution':
|
||||
this._focusedSolution = this.#items[message.solutionIndex];
|
||||
return;
|
||||
case 'webviewReady':
|
||||
// Send the config to the webview
|
||||
void this.postMessage({
|
||||
command: 'updateConfig',
|
||||
config: {
|
||||
renderingMode: this.config.renderingMode,
|
||||
shuffleSolutions: this.config.shuffleSolutions,
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, undefined);
|
||||
|
||||
webviewPanel.onDidChangeViewState(e => {
|
||||
if (e.webviewPanel?.visible) {
|
||||
this.suggestionsPanelManager.activeWebviewPanel = this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected async handleCustomMessage(message: BaseWebviewMessage): Promise<boolean> {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
protected abstract renderSolutionContent(item: TPanelCompletion, baseContent: SolutionContent): SolutionContent;
|
||||
|
||||
private _buildExtensionUri(...path: string[]): Uri {
|
||||
const extensionPath = Uri.joinPath(this.contextService.extensionUri, ...path);
|
||||
return this.webviewPanel.webview.asWebviewUri(extensionPath);
|
||||
}
|
||||
|
||||
private _getWebviewContent() {
|
||||
const nonce = getNonce();
|
||||
const scriptUri = this._buildExtensionUri('dist', this.config.webviewScriptName);
|
||||
|
||||
return `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'none'; font-src ${this.webviewPanel.webview.cspSource}; style-src 'unsafe-inline' ${this.webviewPanel.webview.cspSource}; script-src 'nonce-${nonce}';"
|
||||
/>
|
||||
<title>${this.config.panelTitle}</title>
|
||||
<style>
|
||||
.solutionHeading {
|
||||
margin-top: 40px;
|
||||
}
|
||||
pre:focus-visible {
|
||||
border: 1px solid var(--vscode-focusBorder);
|
||||
outline: none;
|
||||
}
|
||||
pre {
|
||||
margin-bottom: 6px;
|
||||
display: block;
|
||||
padding: 9.5px;
|
||||
line-height: 1.42857143;
|
||||
word-break: break-all;
|
||||
word-wrap: break-word;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--vscode-notebook-cellBorderColor);
|
||||
white-space: pre-wrap;
|
||||
font-size: var(--vscode-editor-font-size);
|
||||
}
|
||||
pre.shiki {
|
||||
padding: 0.5em 0.7em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
border-radius: 4px;
|
||||
}
|
||||
code {
|
||||
background-color: transparent;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>${this.config.panelTitle}</h2>
|
||||
<div id="loadingContainer" aria-live="assertive" aria-atomic="true">
|
||||
<label for="progress-bar">Loading suggestions:</label>
|
||||
<progress id="progress-bar" max="100" value="0"></progress>
|
||||
</div>
|
||||
<div id="solutionsContainer" aria-busy="true" aria-describedby="progress-bar"></div>
|
||||
<script nonce="${nonce}" type="module" src="${scriptUri.toString()}"></script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
}
|
||||
|
||||
onWorkDone({ percentage }: { percentage: number }) {
|
||||
this.#percentage = percentage;
|
||||
void this.render();
|
||||
}
|
||||
|
||||
onItem(item: TPanelCompletion) {
|
||||
// If rendering mode is 'batch', we collect items and render them later
|
||||
// Otherwise, we render immediately
|
||||
if (this.config.renderingMode === 'batch') {
|
||||
this.#batchItems.push(item);
|
||||
} else {
|
||||
this.#items.push(item);
|
||||
void this.render();
|
||||
}
|
||||
}
|
||||
|
||||
clearSolutions() {
|
||||
// Cancel any ongoing operations
|
||||
this.#cts.cancel();
|
||||
// Create a new cancellation token source for the next operation
|
||||
this.#cts = new CancellationTokenSource();
|
||||
|
||||
// Clear all solutions and reset state
|
||||
this.#items = [];
|
||||
this.#batchItems = [];
|
||||
this._focusedSolution = undefined;
|
||||
this.#percentage = 0;
|
||||
void this.render();
|
||||
}
|
||||
|
||||
onFinished() {
|
||||
this.#percentage = 100;
|
||||
|
||||
// If we have batch items, add them to the main items list, shuffle if needed, and render
|
||||
if (this.#batchItems.length > 0) {
|
||||
this.#items.push(...this.#batchItems);
|
||||
|
||||
if (this.config.shuffleSolutions) {
|
||||
this.#items = this.#items.sort(() => Math.random() - 0.5);
|
||||
}
|
||||
|
||||
this.#batchItems = [];
|
||||
}
|
||||
|
||||
void this.render();
|
||||
}
|
||||
|
||||
protected async acceptSolution(solution: TPanelCompletion, closePanel: boolean = true) {
|
||||
if (this._isDisposed === false && solution?.range) {
|
||||
const edit = new WorkspaceEdit();
|
||||
edit.replace(this.#documentUri, solution.range, solution.insertText);
|
||||
await workspace.applyEdit(edit);
|
||||
this.#cts.cancel();
|
||||
if (closePanel) {
|
||||
await commands.executeCommand('workbench.action.closeActiveEditor');
|
||||
}
|
||||
await solution.postInsertionCallback();
|
||||
}
|
||||
}
|
||||
|
||||
protected items(): TPanelCompletion[] {
|
||||
return this.#items;
|
||||
}
|
||||
|
||||
async acceptFocusedSolution() {
|
||||
const solution = this._focusedSolution;
|
||||
if (solution) {
|
||||
return this.acceptSolution(solution);
|
||||
}
|
||||
}
|
||||
|
||||
protected async renderSolutions() {
|
||||
const highlighter = await this.#highlighter;
|
||||
const content = this.#items.map(item => {
|
||||
const firstCitation = item.copilotAnnotations?.ip_code_citations?.[0];
|
||||
const details = firstCitation?.details.citations as IPCitationDetail[] | undefined;
|
||||
let renderedCitatation: { message: string; url: string } | undefined;
|
||||
if (details && details.length > 0) {
|
||||
const licensesSet = new Set(details.map(d => d.license));
|
||||
if (licensesSet.has('NOASSERTION')) {
|
||||
licensesSet.delete('NOASSERTION');
|
||||
licensesSet.add('unknown');
|
||||
}
|
||||
const allLicenses = Array.from(licensesSet).sort();
|
||||
const licenseString = allLicenses.length === 1 ? allLicenses[0] : `[${allLicenses.join(', ')}]`;
|
||||
renderedCitatation = {
|
||||
message: `Similar code with ${pluralize(allLicenses.length, 'license type')} ${licenseString} detected.`,
|
||||
url: details[0].url,
|
||||
};
|
||||
}
|
||||
|
||||
const baseContent = {
|
||||
htmlSnippet: highlighter.createSnippet(item.insertText.trim()),
|
||||
citation: renderedCitatation,
|
||||
};
|
||||
|
||||
return this.renderSolutionContent(item, baseContent);
|
||||
});
|
||||
|
||||
const message = this.createSolutionsMessage(content, this.#percentage);
|
||||
await this.postMessage(message);
|
||||
}
|
||||
|
||||
// Subclasses must implement this to create their specific message format
|
||||
protected abstract createSolutionsMessage(content: SolutionContent[], percentage: number): unknown;
|
||||
|
||||
render = debounce(10, () => this.renderSolutions());
|
||||
|
||||
postMessage(message: unknown) {
|
||||
if (this._isDisposed === false) {
|
||||
return this.webviewPanel.webview.postMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private _dispose() {
|
||||
this._isDisposed = true;
|
||||
this._onDidDispose.fire();
|
||||
this.suggestionsPanelManager.decrementPanelCount();
|
||||
while (this._disposables.length) {
|
||||
const disposable = this._disposables.pop();
|
||||
if (disposable) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
this._onDidDispose.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument, Uri, ViewColumn, WebviewPanel, commands, window } from 'vscode';
|
||||
import { IVSCodeExtensionContext } from '../../../../../../platform/extContext/common/extensionContext';
|
||||
import { DisposableStore, IDisposable } from '../../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { IPosition, ITextDocument } from '../../../lib/src/textDocument';
|
||||
import { basename } from '../../../lib/src/util/uri';
|
||||
import { registerCommandWrapper } from '../telemetry';
|
||||
import { BasePanelCompletion, PanelConfig } from './basePanelTypes';
|
||||
import { BaseSuggestionsPanel, SuggestionsPanelManagerInterface } from './baseSuggestionsPanel';
|
||||
|
||||
export interface ListDocumentInterface {
|
||||
runQuery(): Promise<void>;
|
||||
}
|
||||
|
||||
export abstract class BaseSuggestionsPanelManager<TPanelCompletion extends BasePanelCompletion>
|
||||
implements SuggestionsPanelManagerInterface {
|
||||
activeWebviewPanel: BaseSuggestionsPanel<TPanelCompletion> | undefined;
|
||||
private _panelCount: number = 0;
|
||||
|
||||
constructor(
|
||||
protected readonly config: PanelConfig,
|
||||
@IInstantiationService protected readonly _instantiationService: IInstantiationService,
|
||||
@IVSCodeExtensionContext protected readonly _extensionContext: IVSCodeExtensionContext,
|
||||
) { }
|
||||
|
||||
protected abstract createListDocument(
|
||||
wrapped: ITextDocument,
|
||||
position: IPosition,
|
||||
panel: BaseSuggestionsPanel<TPanelCompletion>
|
||||
): ListDocumentInterface;
|
||||
|
||||
protected abstract createSuggestionsPanel(
|
||||
panel: WebviewPanel,
|
||||
document: TextDocument,
|
||||
manager: this
|
||||
): BaseSuggestionsPanel<TPanelCompletion>;
|
||||
|
||||
renderPanel(
|
||||
document: TextDocument,
|
||||
position: IPosition,
|
||||
wrapped: ITextDocument
|
||||
): BaseSuggestionsPanel<TPanelCompletion> {
|
||||
const title = `${this.config.panelTitle} for ${basename(document.uri.toString()) || document.uri.toString()}`;
|
||||
const panel = window.createWebviewPanel(this.config.webviewId, title, ViewColumn.Two, {
|
||||
enableScripts: true,
|
||||
localResourceRoots: [Uri.joinPath(this._extensionContext.extensionUri, 'dist')],
|
||||
retainContextWhenHidden: true,
|
||||
});
|
||||
|
||||
const suggestionPanel = this.createSuggestionsPanel(panel, document, this);
|
||||
// Listen for the panel disposal event to clear our reference
|
||||
suggestionPanel.onDidDispose(() => {
|
||||
if (this.activeWebviewPanel === suggestionPanel) {
|
||||
this.activeWebviewPanel = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
void this.createListDocument(wrapped, position, suggestionPanel).runQuery();
|
||||
|
||||
this.activeWebviewPanel = suggestionPanel;
|
||||
this._panelCount = this._panelCount + 1;
|
||||
return suggestionPanel;
|
||||
}
|
||||
|
||||
registerCommands(): IDisposable {
|
||||
const disposableStore = new DisposableStore();
|
||||
|
||||
disposableStore.add(this._instantiationService.invokeFunction(registerCommandWrapper, this.config.commands.accept, () => {
|
||||
return this.activeWebviewPanel?.acceptFocusedSolution();
|
||||
}));
|
||||
|
||||
disposableStore.add(this._instantiationService.invokeFunction(registerCommandWrapper, this.config.commands.navigatePrevious, () => {
|
||||
return this.activeWebviewPanel?.postMessage({
|
||||
command: 'navigatePreviousSolution',
|
||||
});
|
||||
}));
|
||||
|
||||
disposableStore.add(this._instantiationService.invokeFunction(registerCommandWrapper, this.config.commands.navigateNext, () => {
|
||||
return this.activeWebviewPanel?.postMessage({
|
||||
command: 'navigateNextSolution',
|
||||
});
|
||||
}));
|
||||
|
||||
return disposableStore;
|
||||
}
|
||||
|
||||
decrementPanelCount() {
|
||||
this._panelCount = this._panelCount - 1;
|
||||
if (this._panelCount === 0) {
|
||||
void commands.executeCommand('setContext', this.config.contextVariable, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getSingletonHighlighterCore, HighlighterCore, ThemeRegistration, ThemeRegistrationAny } from 'shiki/core';
|
||||
import * as langs from 'shiki/langs';
|
||||
import { BundledLanguage } from 'shiki/langs';
|
||||
import getWasmInlined from 'shiki/wasm';
|
||||
import { ColorThemeKind, window, workspace } from 'vscode';
|
||||
import * as languages from './languages';
|
||||
import * as themes from './themes';
|
||||
|
||||
export class Highlighter {
|
||||
private constructor(
|
||||
private languageId: string | undefined,
|
||||
private highlighter: HighlighterCore | undefined
|
||||
) { }
|
||||
|
||||
static async create(languageId = window.activeTextEditor?.document.languageId): Promise<Highlighter> {
|
||||
if (!languageId) {
|
||||
return new Highlighter(undefined, undefined);
|
||||
}
|
||||
|
||||
const highlighter = await getSingletonHighlighterCore({
|
||||
langs: Object.values(langs.bundledLanguages),
|
||||
loadWasm: getWasmInlined,
|
||||
});
|
||||
|
||||
// Load additional language if not out of the box for shiki
|
||||
if (!langs.bundledLanguages[languageId as BundledLanguage]) {
|
||||
const additionalLang = vscLanguageMap[languageId as keyof typeof vscLanguageMap];
|
||||
if (additionalLang) {
|
||||
await highlighter.loadLanguage(additionalLang);
|
||||
}
|
||||
}
|
||||
|
||||
return new Highlighter(languageId, highlighter);
|
||||
}
|
||||
|
||||
createSnippet(text: string): string {
|
||||
if (!this.highlighter || !this.languageId || !this.languageSupported()) {
|
||||
return `<pre>${text}</pre>`;
|
||||
}
|
||||
|
||||
return this.highlighter.codeToHtml(text, { lang: this.languageId, theme: getCurrentTheme() });
|
||||
}
|
||||
|
||||
private languageSupported() {
|
||||
if (!this.languageId) { return false; }
|
||||
|
||||
if (this.highlighter?.getLoadedLanguages().includes(this.languageId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function getCurrentTheme(): ThemeRegistration {
|
||||
const workbenchConfig = workspace.getConfiguration('workbench');
|
||||
if (workbenchConfig) {
|
||||
const vsCodeTheme = workbenchConfig.get<string>('colorTheme');
|
||||
if (vsCodeTheme && isSupportedTheme(vsCodeTheme)) {
|
||||
return vscThemeMap[vsCodeTheme];
|
||||
}
|
||||
const themeType = window.activeColorTheme;
|
||||
const defaultTheme = vscDefaultMap[themeType.kind]; // fall back to default themes if we don't have a match
|
||||
|
||||
return defaultTheme;
|
||||
} else {
|
||||
return vscThemeMap['Default Dark Modern'];
|
||||
}
|
||||
}
|
||||
|
||||
const vscDefaultMap: { [key in ColorThemeKind]: ThemeRegistrationAny } = {
|
||||
[ColorThemeKind.Dark]: themes.darkModern,
|
||||
[ColorThemeKind.Light]: themes.lightModern,
|
||||
[ColorThemeKind.HighContrast]: themes.darkHC,
|
||||
[ColorThemeKind.HighContrastLight]: themes.lightHC,
|
||||
};
|
||||
|
||||
// These are vs code themes that aren't out of the box in shiki but come standard with vs code
|
||||
const vscThemeMap: { [key: string]: ThemeRegistrationAny } = {
|
||||
Abyss: themes.abyss,
|
||||
'Dark High Contrast': themes.darkHC,
|
||||
'Light High Constrast': themes.lightHC,
|
||||
'Default Dark Modern': themes.darkModern,
|
||||
'Kimbie Dark': themes.kimbieDark,
|
||||
'Default Light Modern': themes.lightModern,
|
||||
'Monokai Dimmed': themes.monokaiDim,
|
||||
'Quiet Light': themes.quietLight,
|
||||
Red: themes.red,
|
||||
'Tomorrow Night Blue': themes.tomorrowNightBlue,
|
||||
'Visual Studio Dark': themes.vsDark,
|
||||
'Visual Studio Light': themes.vsLight,
|
||||
'Default Dark+': themes.darkPlus,
|
||||
'Default Light+': themes.lightPlus,
|
||||
Monokai: themes.monokai,
|
||||
'Solarized Dark': themes.solarizedDark,
|
||||
'Solarized Light': themes.solarizedLight,
|
||||
} as const;
|
||||
|
||||
function isSupportedTheme(theme: keyof typeof vscThemeMap): theme is keyof typeof vscThemeMap {
|
||||
return theme in vscThemeMap;
|
||||
}
|
||||
|
||||
// These are vs code themes that aren't out of the box in shiki but come standard with vs code
|
||||
const vscLanguageMap = {
|
||||
'cuda-cpp': languages.cudaCpp,
|
||||
javascriptreact: languages.javascriptreact,
|
||||
markdown_latex_combined: languages.markdownLatexCombined,
|
||||
'markdown-math': languages.markdownMath,
|
||||
restructuredtext: languages.restructuredtext,
|
||||
'search-result': languages.searchResult,
|
||||
typescriptreact: languages.typescriptreact,
|
||||
} as const;
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export { cudaCpp } from './cuda-cpp.tmLanguage';
|
||||
export { javascriptreact } from './javaScriptReact.tmLanguage';
|
||||
export { markdownLatexCombined } from './markdown-latex-combined.tmLanguage';
|
||||
export { markdownMath } from './md-math.tmLanguage';
|
||||
export { restructuredtext } from './rst.tmLanguage';
|
||||
export { searchResult } from './searchResult.tmLanguage';
|
||||
export { typescriptreact } from './typeScriptReact.tmLanguage';
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,113 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { LanguageInput } from 'shiki/core';
|
||||
|
||||
// This file includes some grammar rules copied from https://github.com/James-Yu/LaTeX-Workshop/blob/master/syntax/TeX.tmLanguage.json',
|
||||
export const markdownMath: LanguageInput = {
|
||||
name: 'markdown-math',
|
||||
scopeName: 'text.html.markdown.math',
|
||||
patterns: [
|
||||
{
|
||||
include: '#math',
|
||||
},
|
||||
],
|
||||
repository: {
|
||||
$self: {},
|
||||
$base: {},
|
||||
math: {
|
||||
patterns: [
|
||||
{
|
||||
name: 'comment.line.math.tex',
|
||||
match: '((?<!\\\\)%)(.+)$',
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'punctuation.definition.comment.math.tex',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'line.separator.math.tex',
|
||||
match: '(\\\\\\\\)$',
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'punctuation.line.separator.math.tex',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'meta.function.math.tex',
|
||||
begin: '((\\\\)([a-zA-Z_]+))\\s*(\\{)',
|
||||
beginCaptures: {
|
||||
'1': {
|
||||
name: 'storage.type.function.math.tex',
|
||||
},
|
||||
'2': {
|
||||
name: 'punctuation.definition.function.math.tex',
|
||||
},
|
||||
'3': {
|
||||
name: 'entity.name.function.math.tex',
|
||||
},
|
||||
'4': {
|
||||
name: 'punctuation.definition.arguments.begin.math.tex',
|
||||
},
|
||||
},
|
||||
end: '\\}',
|
||||
endCaptures: {
|
||||
'0': {
|
||||
name: 'punctuation.definition.arguments.end.math.tex',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '$self',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'punctuation.definition.constant.math.tex',
|
||||
},
|
||||
},
|
||||
match: '(\\\\)([a-zA-Z_]+)\\b',
|
||||
name: 'constant.character.math.tex',
|
||||
},
|
||||
{
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'punctuation.definition.constant.math.tex',
|
||||
},
|
||||
},
|
||||
match: '(\\\\)(?!begin\\*\\{|verb)([A-Za-z]+)',
|
||||
name: 'constant.other.general.math.tex',
|
||||
},
|
||||
{
|
||||
match: '(?<!\\\\)\\{',
|
||||
name: 'punctuation.math.begin.bracket.curly',
|
||||
},
|
||||
{
|
||||
match: '(?<!\\\\)\\}',
|
||||
name: 'punctuation.math.end.bracket.curly',
|
||||
},
|
||||
{
|
||||
match: '\\(',
|
||||
name: 'punctuation.math.begin.bracket.round',
|
||||
},
|
||||
{
|
||||
match: '\\)',
|
||||
name: 'punctuation.math.end.bracket.round',
|
||||
},
|
||||
{
|
||||
match: '(([0-9]*[\\.][0-9]+)|[0-9]+)',
|
||||
name: 'constant.numeric.math.tex',
|
||||
},
|
||||
{
|
||||
match: '[\\+\\*/_\\^-]',
|
||||
name: 'punctuation.math.operator.latex',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,740 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/* eslint-disable local/no-unexternalized-strings */
|
||||
import { LanguageInput } from 'shiki/core';
|
||||
|
||||
// This file has been converted from https://github.com/trond-snekvik/vscode-rst/blob/master/syntaxes/rst.tmLanguage.json
|
||||
// If you want to provide a fix or improvement, please create a pull request against the original repository.
|
||||
// Once accepted there, we are happy to receive an update request.
|
||||
// version: https://github.com/trond-snekvik/vscode-rst/commit/f0fe19ffde6509be52ad9267a57e1b3df665f072
|
||||
export const restructuredtext: LanguageInput = {
|
||||
scopeName: 'source.rst',
|
||||
name: 'restructuredtext',
|
||||
patterns: [
|
||||
{
|
||||
include: '#body',
|
||||
},
|
||||
],
|
||||
repository: {
|
||||
$self: {},
|
||||
$base: {},
|
||||
body: {
|
||||
patterns: [
|
||||
{
|
||||
include: '#title',
|
||||
},
|
||||
{
|
||||
include: '#inline-markup',
|
||||
},
|
||||
{
|
||||
include: '#anchor',
|
||||
},
|
||||
{
|
||||
include: '#line-block',
|
||||
},
|
||||
{
|
||||
include: '#replace-include',
|
||||
},
|
||||
{
|
||||
include: '#footnote',
|
||||
},
|
||||
{
|
||||
include: '#substitution',
|
||||
},
|
||||
{
|
||||
include: '#blocks',
|
||||
},
|
||||
{
|
||||
include: '#table',
|
||||
},
|
||||
{
|
||||
include: '#simple-table',
|
||||
},
|
||||
{
|
||||
include: '#options-list',
|
||||
},
|
||||
],
|
||||
},
|
||||
title: {
|
||||
match: '^(\\*{3,}|#{3,}|\\={3,}|~{3,}|\\+{3,}|-{3,}|`{3,}|\\^{3,}|:{3,}|"{3,}|_{3,}|\'{3,})$',
|
||||
name: 'markup.heading',
|
||||
},
|
||||
'inline-markup': {
|
||||
patterns: [
|
||||
{
|
||||
include: '#escaped',
|
||||
},
|
||||
{
|
||||
include: '#ignore',
|
||||
},
|
||||
{
|
||||
include: '#ref',
|
||||
},
|
||||
{
|
||||
include: '#literal',
|
||||
},
|
||||
{
|
||||
include: '#monospaced',
|
||||
},
|
||||
{
|
||||
include: '#citation',
|
||||
},
|
||||
{
|
||||
include: '#bold',
|
||||
},
|
||||
{
|
||||
include: '#italic',
|
||||
},
|
||||
{
|
||||
include: '#list',
|
||||
},
|
||||
{
|
||||
include: '#macro',
|
||||
},
|
||||
{
|
||||
include: '#reference',
|
||||
},
|
||||
{
|
||||
include: '#footnote-ref',
|
||||
},
|
||||
],
|
||||
},
|
||||
ignore: {
|
||||
patterns: [
|
||||
{
|
||||
match: "'[`*]+'",
|
||||
},
|
||||
{
|
||||
match: '<[`*]+>',
|
||||
},
|
||||
{
|
||||
match: '{[`*]+}',
|
||||
},
|
||||
{
|
||||
match: '\\([`*]+\\)',
|
||||
},
|
||||
{
|
||||
match: '\\[[`*]+\\]',
|
||||
},
|
||||
{
|
||||
match: '"[`*]+"',
|
||||
},
|
||||
],
|
||||
},
|
||||
table: {
|
||||
begin: '^\\s*\\+[=+-]+\\+\\s*$',
|
||||
end: '^(?![+|])',
|
||||
beginCaptures: {
|
||||
'0': {
|
||||
name: 'keyword.control.table',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
match: '[=+|-]',
|
||||
name: 'keyword.control.table',
|
||||
},
|
||||
],
|
||||
},
|
||||
'simple-table': {
|
||||
match: '^[=\\s]+$',
|
||||
name: 'keyword.control.table',
|
||||
},
|
||||
ref: {
|
||||
begin: '(:ref:)`',
|
||||
end: '`|^\\s*$',
|
||||
name: 'entity.name.tag',
|
||||
beginCaptures: {
|
||||
'1': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
match: '<.*?>',
|
||||
name: 'markup.underline.link',
|
||||
},
|
||||
],
|
||||
},
|
||||
reference: {
|
||||
match: '[\\w-]*[a-zA-Z\\d-]__?\\b',
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
macro: {
|
||||
match: '\\|[^\\|]+\\|',
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
literal: {
|
||||
match: '(:\\S+:)(`.*?`\\\\?)',
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'2': {
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
},
|
||||
},
|
||||
monospaced: {
|
||||
begin: '(?<=[\\s"\'(\\[{<]|^)``[^\\s`]',
|
||||
end: '``|^\\s*$',
|
||||
name: 'string.interpolated',
|
||||
},
|
||||
citation: {
|
||||
begin: '(?<=[\\s"\'(\\[{<]|^)`[^\\s`]',
|
||||
end: '`_{,2}|^\\s*$',
|
||||
name: 'entity.name.tag',
|
||||
applyEndPatternLast: false,
|
||||
},
|
||||
bold: {
|
||||
begin: '(?<=[\\s"\'(\\[{<]|^)\\*{2}[^\\s*]',
|
||||
end: '\\*{2}|^\\s*$',
|
||||
name: 'markup.bold',
|
||||
},
|
||||
italic: {
|
||||
begin: '(?<=[\\s"\'(\\[{<]|^)\\*[^\\s*]',
|
||||
end: '\\*|^\\s*$',
|
||||
name: 'markup.italic',
|
||||
},
|
||||
escaped: {
|
||||
match: '\\\\.',
|
||||
name: 'constant.character.escape',
|
||||
},
|
||||
list: {
|
||||
match: '^\\s*(\\d+\\.|\\* -|[a-zA-Z#]\\.|[iIvVxXmMcC]+\\.|\\(\\d+\\)|\\d+\\)|[*+-])\\s+',
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'line-block': {
|
||||
match: '^\\|\\s+',
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'raw-html': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+raw\\s*::)\\s+(html)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'3': {
|
||||
name: 'variable.parameter.html',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'text.html.derivative',
|
||||
},
|
||||
],
|
||||
},
|
||||
anchor: {
|
||||
match: '^\\.{2}\\s+(_[^:]+:)\\s*',
|
||||
name: 'entity.name.tag.anchor',
|
||||
},
|
||||
'replace-include': {
|
||||
match: '^\\s*(\\.{2})\\s+(\\|[^\\|]+\\|)\\s+(replace::)',
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'2': {
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
'3': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
},
|
||||
},
|
||||
footnote: {
|
||||
match: '^\\s*\\.{2}\\s+\\[(?:[\\w\\.-]+|[#*]|#\\w+)\\]\\s+',
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
'footnote-ref': {
|
||||
match: '\\[(?:[\\w\\.-]+|[#*])\\]_',
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
substitution: {
|
||||
match: '^\\.{2}\\s*\\|([^|]+)\\|',
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
'options-list': {
|
||||
match: '^((?:-\\w|--[\\w-]+|/\\w+)(?:,? ?[\\w-]+)*)(?: |\\t|$)',
|
||||
name: 'variable.parameter',
|
||||
},
|
||||
blocks: {
|
||||
patterns: [
|
||||
{
|
||||
include: '#domains',
|
||||
},
|
||||
{
|
||||
include: '#doctest',
|
||||
},
|
||||
{
|
||||
include: '#code-block-cpp',
|
||||
},
|
||||
{
|
||||
include: '#code-block-py',
|
||||
},
|
||||
{
|
||||
include: '#code-block-console',
|
||||
},
|
||||
{
|
||||
include: '#code-block-javascript',
|
||||
},
|
||||
{
|
||||
include: '#code-block-yaml',
|
||||
},
|
||||
{
|
||||
include: '#code-block-cmake',
|
||||
},
|
||||
{
|
||||
include: '#code-block-kconfig',
|
||||
},
|
||||
{
|
||||
include: '#code-block-ruby',
|
||||
},
|
||||
{
|
||||
include: '#code-block-dts',
|
||||
},
|
||||
{
|
||||
include: '#code-block',
|
||||
},
|
||||
{
|
||||
include: '#doctest-block',
|
||||
},
|
||||
{
|
||||
include: '#raw-html',
|
||||
},
|
||||
{
|
||||
include: '#block',
|
||||
},
|
||||
{
|
||||
include: '#literal-block',
|
||||
},
|
||||
{
|
||||
include: '#block-comment',
|
||||
},
|
||||
],
|
||||
},
|
||||
'block-comment': {
|
||||
begin: '^(\\s*)\\.{2}',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
name: 'comment.block',
|
||||
},
|
||||
'literal-block': {
|
||||
begin: '^(\\s*)(.*)(::)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
patterns: [
|
||||
{
|
||||
include: '#inline-markup',
|
||||
},
|
||||
],
|
||||
},
|
||||
'3': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
},
|
||||
},
|
||||
block: {
|
||||
begin: '^(\\s*)(\\.{2}\\s+\\S+::)(.*)',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'3': {
|
||||
name: 'variable',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: '#body',
|
||||
},
|
||||
],
|
||||
},
|
||||
'block-param': {
|
||||
patterns: [
|
||||
{
|
||||
match: '(:param\\s+(.+?):)(?:\\s|$)',
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'2': {
|
||||
name: 'variable.parameter',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
match: '(:.+?:)(?:$|\\s+(.*))',
|
||||
captures: {
|
||||
'1': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'2': {
|
||||
patterns: [
|
||||
{
|
||||
match: '\\b(0x[a-fA-F\\d]+|\\d+)\\b',
|
||||
name: 'constant.numeric',
|
||||
},
|
||||
{
|
||||
include: '#inline-markup',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
domains: {
|
||||
patterns: [
|
||||
{
|
||||
include: '#domain-cpp',
|
||||
},
|
||||
{
|
||||
include: '#domain-py',
|
||||
},
|
||||
{
|
||||
include: '#domain-auto',
|
||||
},
|
||||
{
|
||||
include: '#domain-js',
|
||||
},
|
||||
],
|
||||
},
|
||||
'domain-cpp': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(?:cpp|c):(?:class|struct|function|member|var|type|enum|enum-struct|enum-class|enumerator|union|concept)::)\\s*(?:(@\\w+)|(.*))',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'3': {
|
||||
name: 'entity.name.tag',
|
||||
},
|
||||
'4': {
|
||||
patterns: [
|
||||
{
|
||||
include: 'source.cpp',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: '#body',
|
||||
},
|
||||
],
|
||||
},
|
||||
'domain-py': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+py:(?:module|function|data|exception|class|attribute|property|method|staticmethod|classmethod|decorator|decoratormethod)::)\\s*(.*)',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'3': {
|
||||
patterns: [
|
||||
{
|
||||
include: 'source.python',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: '#body',
|
||||
},
|
||||
],
|
||||
},
|
||||
'domain-auto': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+auto(?:class|module|exception|function|decorator|data|method|attribute|property)::)\\s*(.*)',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control.py',
|
||||
},
|
||||
'3': {
|
||||
patterns: [
|
||||
{
|
||||
include: 'source.python',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: '#body',
|
||||
},
|
||||
],
|
||||
},
|
||||
'domain-js': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+js:\\w+::)\\s*(.*)',
|
||||
end: '^(?!\\1[ \\t]|$)',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'3': {
|
||||
patterns: [
|
||||
{
|
||||
include: 'source.js',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: '#body',
|
||||
},
|
||||
],
|
||||
},
|
||||
doctest: {
|
||||
begin: '^(>>>)\\s*(.*)',
|
||||
end: '^\\s*$',
|
||||
beginCaptures: {
|
||||
'1': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'2': {
|
||||
patterns: [
|
||||
{
|
||||
include: 'source.python',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'code-block-cpp': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(c|c\\+\\+|cpp|C|C\\+\\+|CPP|Cpp)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.cpp',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.cpp',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-console': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(console|shell|bash)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.console',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.shell',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-py': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(python)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.py',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.python',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-javascript': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(javascript)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.js',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.js',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-yaml': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(ya?ml)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.yaml',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.yaml',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-cmake': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(cmake)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.cmake',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.cmake',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-kconfig': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*([kK]config)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.kconfig',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.kconfig',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-ruby': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(ruby)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.ruby',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.ruby',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block-dts': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)\\s*(dts|DTS|devicetree)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
'4': {
|
||||
name: 'variable.parameter.codeblock.dts',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.dts',
|
||||
},
|
||||
],
|
||||
},
|
||||
'code-block': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+(code|code-block)::)',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
],
|
||||
},
|
||||
'doctest-block': {
|
||||
begin: '^(\\s*)(\\.{2}\\s+doctest::)\\s*$',
|
||||
while: '^\\1(?=\\s)|^\\s*$',
|
||||
beginCaptures: {
|
||||
'2': {
|
||||
name: 'keyword.control',
|
||||
},
|
||||
},
|
||||
patterns: [
|
||||
{
|
||||
include: '#block-param',
|
||||
},
|
||||
{
|
||||
include: 'source.python',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,343 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const abyss: ThemeRegistrationAny = {
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'activityBar.background': '#051336',
|
||||
'badge.background': '#0063a5',
|
||||
'button.background': '#2b3c5d',
|
||||
'debugExceptionWidget.background': '#051336',
|
||||
'debugExceptionWidget.border': '#ab395b',
|
||||
'debugToolBar.background': '#051336',
|
||||
'diffEditor.insertedTextBackground': '#31958a55',
|
||||
'diffEditor.removedTextBackground': '#892f4688',
|
||||
'dropdown.background': '#181f2f',
|
||||
'editor.background': '#000c18',
|
||||
'editor.findMatchHighlightBackground': '#eeeeee44',
|
||||
'editor.foreground': '#6688cc',
|
||||
'editor.lineHighlightBackground': '#082050',
|
||||
'editor.selectionBackground': '#770811',
|
||||
'editorCursor.foreground': '#ddbb88',
|
||||
'editorGroup.border': '#2b2b4a',
|
||||
'editorGroup.dropBackground': '#25375daa',
|
||||
'editorGroupHeader.tabsBackground': '#1c1c2a',
|
||||
'editorHoverWidget.background': '#000c38',
|
||||
'editorHoverWidget.border': '#004c18',
|
||||
'editorIndentGuide.activeBackground': '#204972',
|
||||
'editorIndentGuide.background': '#002952',
|
||||
'editorLineNumber.activeForeground': '#80a2c2',
|
||||
'editorLineNumber.foreground': '#406385',
|
||||
'editorLink.activeForeground': '#0063a5',
|
||||
'editorMarkerNavigation.background': '#060621',
|
||||
'editorMarkerNavigationError.background': '#ab395b',
|
||||
'editorMarkerNavigationWarning.background': '#5b7e7a',
|
||||
'editorWhitespace.foreground': '#103050',
|
||||
'editorWidget.background': '#262641',
|
||||
'extensionButton.prominentBackground': '#5f8b3b',
|
||||
'extensionButton.prominentHoverBackground': '#5f8b3bbb',
|
||||
focusBorder: '#596f99',
|
||||
'input.background': '#181f2f',
|
||||
'inputOption.activeBorder': '#1d4a87',
|
||||
'inputValidation.errorBackground': '#a22d44',
|
||||
'inputValidation.errorBorder': '#ab395b',
|
||||
'inputValidation.infoBackground': '#051336',
|
||||
'inputValidation.infoBorder': '#384078',
|
||||
'inputValidation.warningBackground': '#5b7e7a',
|
||||
'inputValidation.warningBorder': '#5b7e7a',
|
||||
'list.activeSelectionBackground': '#08286b',
|
||||
'list.dropBackground': '#041d52',
|
||||
'list.highlightForeground': '#0063a5',
|
||||
'list.hoverBackground': '#061940',
|
||||
'list.inactiveSelectionBackground': '#152037',
|
||||
'minimap.selectionHighlight': '#750000',
|
||||
'panel.border': '#2b2b4a',
|
||||
'peekView.border': '#2b2b4a',
|
||||
'peekViewEditor.background': '#10192c',
|
||||
'peekViewEditor.matchHighlightBackground': '#eeeeee33',
|
||||
'peekViewResult.background': '#060621',
|
||||
'peekViewResult.matchHighlightBackground': '#eeeeee44',
|
||||
'peekViewTitle.background': '#10192c',
|
||||
'pickerGroup.border': '#596f99',
|
||||
'pickerGroup.foreground': '#596f99',
|
||||
'ports.iconRunningProcessForeground': '#80a2c2',
|
||||
'progressBar.background': '#0063a5',
|
||||
'quickInputList.focusBackground': '#08286b',
|
||||
'scrollbar.shadow': '#515e91aa',
|
||||
'scrollbarSlider.activeBackground': '#3b3f5188',
|
||||
'scrollbarSlider.background': '#1f2230aa',
|
||||
'scrollbarSlider.hoverBackground': '#3b3f5188',
|
||||
'sideBar.background': '#060621',
|
||||
'sideBarSectionHeader.background': '#10192c',
|
||||
'statusBar.background': '#10192c',
|
||||
'statusBar.debuggingBackground': '#10192c',
|
||||
'statusBar.noFolderBackground': '#10192c',
|
||||
'statusBarItem.prominentBackground': '#0063a5',
|
||||
'statusBarItem.prominentHoverBackground': '#0063a5dd',
|
||||
'statusBarItem.remoteBackground': '#0063a5',
|
||||
'tab.border': '#2b2b4a',
|
||||
'tab.inactiveBackground': '#10192c',
|
||||
'tab.lastPinnedBorder': '#2b3c5d',
|
||||
'terminal.ansiBlack': '#111111',
|
||||
'terminal.ansiBlue': '#bbdaff',
|
||||
'terminal.ansiBrightBlack': '#333333',
|
||||
'terminal.ansiBrightBlue': '#80baff',
|
||||
'terminal.ansiBrightCyan': '#78ffff',
|
||||
'terminal.ansiBrightGreen': '#b8f171',
|
||||
'terminal.ansiBrightMagenta': '#d778ff',
|
||||
'terminal.ansiBrightRed': '#ff7882',
|
||||
'terminal.ansiBrightWhite': '#ffffff',
|
||||
'terminal.ansiBrightYellow': '#ffe580',
|
||||
'terminal.ansiCyan': '#99ffff',
|
||||
'terminal.ansiGreen': '#d1f1a9',
|
||||
'terminal.ansiMagenta': '#ebbbff',
|
||||
'terminal.ansiRed': '#ff9da4',
|
||||
'terminal.ansiWhite': '#cccccc',
|
||||
'terminal.ansiYellow': '#ffeead',
|
||||
'titleBar.activeBackground': '#10192c',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: ['meta.embedded', 'source.groovy.embedded', 'string meta.image.inline.markdown'],
|
||||
settings: {
|
||||
foreground: '#6688CC',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#384887',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string',
|
||||
settings: {
|
||||
foreground: '#22AA44',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.numeric',
|
||||
settings: {
|
||||
foreground: '#F280D0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#F280D0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['constant.character', 'constant.other'],
|
||||
settings: {
|
||||
foreground: '#F280D0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable',
|
||||
settings: {
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#225588',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#225588',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.type',
|
||||
settings: {
|
||||
foreground: '#9966B8',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['entity.name.class', 'entity.name.type', 'entity.name.namespace', 'entity.name.scope-resolution'],
|
||||
settings: {
|
||||
foreground: '#FFEEBB',
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.inherited-class',
|
||||
settings: {
|
||||
foreground: '#DDBB88',
|
||||
fontStyle: 'italic underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.function',
|
||||
settings: {
|
||||
foreground: '#DDBB88',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.parameter',
|
||||
settings: {
|
||||
foreground: '#2277FF',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#225588',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#DDBB88',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function',
|
||||
settings: {
|
||||
foreground: '#9966B8',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.constant',
|
||||
settings: {
|
||||
foreground: '#9966B8',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['support.type', 'support.class'],
|
||||
settings: {
|
||||
foreground: '#9966B8',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.other.variable',
|
||||
settings: {
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#A22D44',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid.deprecated',
|
||||
settings: {
|
||||
foreground: '#A22D44',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.diff', 'meta.diff.header'],
|
||||
settings: {
|
||||
foreground: '#E0EDDD',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#DC322F',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#CB4B16',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#219186',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.quote',
|
||||
settings: {
|
||||
foreground: '#22AA44',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.bold', 'markup.italic'],
|
||||
settings: {
|
||||
foreground: '#22AA44',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#9966B8',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.heading', 'markup.heading.setext'],
|
||||
settings: {
|
||||
foreground: '#6688CC',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,462 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const darkHC: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'actionBar.toggledBackground': '#383a49',
|
||||
'editor.background': '#000000',
|
||||
'editor.foreground': '#ffffff',
|
||||
'editor.selectionBackground': '#ffffff',
|
||||
'editorIndentGuide.activeBackground1': '#ffffff',
|
||||
'editorIndentGuide.background1': '#ffffff',
|
||||
'editorWhitespace.foreground': '#7c7c7c',
|
||||
'ports.iconRunningProcessForeground': '#ffffff',
|
||||
'selection.background': '#008000',
|
||||
'sideBarTitle.foreground': '#ffffff',
|
||||
'statusBarItem.remoteBackground': '#00000000',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'emphasis',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'strong',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.header',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#7CA668',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.numeric',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.regexp',
|
||||
settings: {
|
||||
foreground: '#B46695',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag.css',
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.other.attribute-name.class.css',
|
||||
'entity.other.attribute-name.class.mixin.css',
|
||||
'entity.other.attribute-name.id.css',
|
||||
'entity.other.attribute-name.parent-selector.css',
|
||||
'entity.other.attribute-name.pseudo-class.css',
|
||||
'entity.other.attribute-name.pseudo-element.css',
|
||||
'source.css.less entity.other.attribute-name.id',
|
||||
'entity.other.attribute-name.scss',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline',
|
||||
settings: {
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.definition.tag'],
|
||||
settings: {
|
||||
foreground: '#808080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.string',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.numeric',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.structure.dictionary.key.python',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.type',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.modifier',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.tag',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.value',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#D16969',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.template-expression.begin',
|
||||
'punctuation.definition.template-expression.end',
|
||||
'punctuation.section.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.template.expression'],
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.type.vendored.property-name',
|
||||
'support.type.property-name',
|
||||
'variable.css',
|
||||
'variable.scss',
|
||||
'variable.other.less',
|
||||
'source.coffee.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.control',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.operator.new',
|
||||
'keyword.operator.expression',
|
||||
'keyword.operator.cast',
|
||||
'keyword.operator.sizeof',
|
||||
'keyword.operator.logical.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function.git-rebase',
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.sha.git-rebase',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier.import.java', 'variable.language.wildcard.java', 'storage.modifier.package.java'],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language.this',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.name.function',
|
||||
'support.function',
|
||||
'support.constant.handlebars',
|
||||
'source.powershell variable.other.member',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#DCDCAA',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.class',
|
||||
'support.type',
|
||||
'entity.name.type',
|
||||
'entity.name.namespace',
|
||||
'entity.name.scope-resolution',
|
||||
'entity.name.class',
|
||||
'storage.type.cs',
|
||||
'storage.type.generic.cs',
|
||||
'storage.type.modifier.cs',
|
||||
'storage.type.variable.cs',
|
||||
'storage.type.annotation.java',
|
||||
'storage.type.generic.java',
|
||||
'storage.type.java',
|
||||
'storage.type.object.array.java',
|
||||
'storage.type.primitive.array.java',
|
||||
'storage.type.primitive.java',
|
||||
'storage.type.token.java',
|
||||
'storage.type.groovy',
|
||||
'storage.type.annotation.groovy',
|
||||
'storage.type.parameters.groovy',
|
||||
'storage.type.generic.groovy',
|
||||
'storage.type.object.array.groovy',
|
||||
'storage.type.primitive.array.groovy',
|
||||
'storage.type.primitive.groovy',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#4EC9B0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'meta.type.cast.expr',
|
||||
'meta.type.new.expr',
|
||||
'support.constant.math',
|
||||
'support.constant.dom',
|
||||
'support.constant.json',
|
||||
'entity.other.inherited-class',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#4EC9B0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.control',
|
||||
'source.cpp keyword.operator.new',
|
||||
'source.cpp keyword.operator.delete',
|
||||
'keyword.other.using',
|
||||
'keyword.other.directive.using',
|
||||
'keyword.other.operator',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#C586C0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['variable', 'meta.definition.variable.name', 'support.variable'],
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.object-literal.key'],
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.constant.property-value',
|
||||
'support.constant.font-name',
|
||||
'support.constant.media-type',
|
||||
'support.constant.media',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.resultLinePrefix.contextLinePrefix.search',
|
||||
settings: {
|
||||
foreground: '#CBEDCB',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#008000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#FF0000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,692 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const darkModern: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'actionBar.toggledBackground': '#383a49',
|
||||
'activityBar.activeBorder': '#0078d4',
|
||||
'activityBar.background': '#181818',
|
||||
'activityBar.border': '#2b2b2b',
|
||||
'activityBar.foreground': '#d7d7d7',
|
||||
'activityBar.inactiveForeground': '#868686',
|
||||
'activityBarBadge.background': '#0078d4',
|
||||
'activityBarBadge.foreground': '#ffffff',
|
||||
'badge.background': '#616161',
|
||||
'badge.foreground': '#f8f8f8',
|
||||
'button.background': '#0078d4',
|
||||
'button.border': '#ffffff12',
|
||||
'button.foreground': '#ffffff',
|
||||
'button.hoverBackground': '#026ec1',
|
||||
'button.secondaryBackground': '#313131',
|
||||
'button.secondaryForeground': '#cccccc',
|
||||
'button.secondaryHoverBackground': '#3c3c3c',
|
||||
'chat.slashCommandBackground': '#34414b',
|
||||
'chat.slashCommandForeground': '#40a6ff',
|
||||
'checkbox.background': '#313131',
|
||||
'checkbox.border': '#3c3c3c',
|
||||
'debugToolBar.background': '#181818',
|
||||
descriptionForeground: '#9d9d9d',
|
||||
'dropdown.background': '#313131',
|
||||
'dropdown.border': '#3c3c3c',
|
||||
'dropdown.foreground': '#cccccc',
|
||||
'dropdown.listBackground': '#1f1f1f',
|
||||
'editor.background': '#1f1f1f',
|
||||
'editor.findMatchBackground': '#9e6a03',
|
||||
'editor.foreground': '#cccccc',
|
||||
'editor.inactiveSelectionBackground': '#3a3d41',
|
||||
'editor.selectionHighlightBackground': '#add6ff26',
|
||||
'editorGroup.border': '#ffffff17',
|
||||
'editorGroupHeader.tabsBackground': '#181818',
|
||||
'editorGroupHeader.tabsBorder': '#2b2b2b',
|
||||
'editorGutter.addedBackground': '#2ea043',
|
||||
'editorGutter.deletedBackground': '#f85149',
|
||||
'editorGutter.modifiedBackground': '#0078d4',
|
||||
'editorIndentGuide.activeBackground1': '#707070',
|
||||
'editorIndentGuide.background1': '#404040',
|
||||
'editorLineNumber.activeForeground': '#cccccc',
|
||||
'editorLineNumber.foreground': '#6e7681',
|
||||
'editorOverviewRuler.border': '#010409',
|
||||
'editorWidget.background': '#202020',
|
||||
errorForeground: '#f85149',
|
||||
focusBorder: '#0078d4',
|
||||
foreground: '#cccccc',
|
||||
'icon.foreground': '#cccccc',
|
||||
'input.background': '#313131',
|
||||
'input.border': '#3c3c3c',
|
||||
'input.foreground': '#cccccc',
|
||||
'input.placeholderForeground': '#818181',
|
||||
'inputOption.activeBackground': '#2489db82',
|
||||
'inputOption.activeBorder': '#2488db',
|
||||
'keybindingLabel.foreground': '#cccccc',
|
||||
'list.activeSelectionIconForeground': '#ffffff',
|
||||
'list.dropBackground': '#383b3d',
|
||||
'menu.background': '#1f1f1f',
|
||||
'menu.border': '#454545',
|
||||
'menu.foreground': '#cccccc',
|
||||
'menu.separatorBackground': '#454545',
|
||||
'notificationCenterHeader.background': '#1f1f1f',
|
||||
'notificationCenterHeader.foreground': '#cccccc',
|
||||
'notifications.background': '#1f1f1f',
|
||||
'notifications.border': '#2b2b2b',
|
||||
'notifications.foreground': '#cccccc',
|
||||
'panel.background': '#181818',
|
||||
'panel.border': '#2b2b2b',
|
||||
'panelInput.border': '#2b2b2b',
|
||||
'panelTitle.activeBorder': '#0078d4',
|
||||
'panelTitle.activeForeground': '#cccccc',
|
||||
'panelTitle.inactiveForeground': '#9d9d9d',
|
||||
'peekViewEditor.background': '#1f1f1f',
|
||||
'peekViewEditor.matchHighlightBackground': '#bb800966',
|
||||
'peekViewResult.background': '#1f1f1f',
|
||||
'peekViewResult.matchHighlightBackground': '#bb800966',
|
||||
'pickerGroup.border': '#3c3c3c',
|
||||
'ports.iconRunningProcessForeground': '#369432',
|
||||
'progressBar.background': '#0078d4',
|
||||
'quickInput.background': '#222222',
|
||||
'quickInput.foreground': '#cccccc',
|
||||
'settings.dropdownBackground': '#313131',
|
||||
'settings.dropdownBorder': '#3c3c3c',
|
||||
'settings.headerForeground': '#ffffff',
|
||||
'settings.modifiedItemIndicator': '#bb800966',
|
||||
'sideBar.background': '#181818',
|
||||
'sideBar.border': '#2b2b2b',
|
||||
'sideBar.foreground': '#cccccc',
|
||||
'sideBarSectionHeader.background': '#181818',
|
||||
'sideBarSectionHeader.border': '#2b2b2b',
|
||||
'sideBarSectionHeader.foreground': '#cccccc',
|
||||
'sideBarTitle.foreground': '#cccccc',
|
||||
'statusBar.background': '#181818',
|
||||
'statusBar.border': '#2b2b2b',
|
||||
'statusBar.debuggingBackground': '#0078d4',
|
||||
'statusBar.debuggingForeground': '#ffffff',
|
||||
'statusBar.focusBorder': '#0078d4',
|
||||
'statusBar.foreground': '#cccccc',
|
||||
'statusBar.noFolderBackground': '#1f1f1f',
|
||||
'statusBarItem.focusBorder': '#0078d4',
|
||||
'statusBarItem.prominentBackground': '#6e768166',
|
||||
'statusBarItem.remoteBackground': '#0078d4',
|
||||
'statusBarItem.remoteForeground': '#ffffff',
|
||||
'tab.activeBackground': '#1f1f1f',
|
||||
'tab.activeBorder': '#1f1f1f',
|
||||
'tab.activeBorderTop': '#0078d4',
|
||||
'tab.activeForeground': '#ffffff',
|
||||
'tab.border': '#2b2b2b',
|
||||
'tab.hoverBackground': '#1f1f1f',
|
||||
'tab.inactiveBackground': '#181818',
|
||||
'tab.inactiveForeground': '#9d9d9d',
|
||||
'tab.lastPinnedBorder': '#cccccc33',
|
||||
'tab.unfocusedActiveBorder': '#1f1f1f',
|
||||
'tab.unfocusedActiveBorderTop': '#2b2b2b',
|
||||
'tab.unfocusedHoverBackground': '#1f1f1f',
|
||||
'terminal.foreground': '#cccccc',
|
||||
'terminal.inactiveSelectionBackground': '#3a3d41',
|
||||
'terminal.tab.activeBorder': '#0078d4',
|
||||
'textBlockQuote.background': '#2b2b2b',
|
||||
'textBlockQuote.border': '#616161',
|
||||
'textCodeBlock.background': '#2b2b2b',
|
||||
'textLink.activeForeground': '#4daafc',
|
||||
'textLink.foreground': '#4daafc',
|
||||
'textPreformat.background': '#3c3c3c',
|
||||
'textPreformat.foreground': '#d0d0d0',
|
||||
'textSeparator.foreground': '#21262d',
|
||||
'titleBar.activeBackground': '#181818',
|
||||
'titleBar.activeForeground': '#cccccc',
|
||||
'titleBar.border': '#2b2b2b',
|
||||
'titleBar.inactiveBackground': '#1f1f1f',
|
||||
'titleBar.inactiveForeground': '#9d9d9d',
|
||||
'welcomePage.progress.foreground': '#0078d4',
|
||||
'welcomePage.tileBackground': '#2b2b2b',
|
||||
'widget.border': '#313131',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'emphasis',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'strong',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'header',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#6A9955',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.numeric',
|
||||
'variable.other.enummember',
|
||||
'keyword.operator.plus.exponent',
|
||||
'keyword.operator.minus.exponent',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.regexp',
|
||||
settings: {
|
||||
foreground: '#646695',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag.css',
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.other.attribute-name.class.css',
|
||||
'entity.other.attribute-name.class.mixin.css',
|
||||
'entity.other.attribute-name.id.css',
|
||||
'entity.other.attribute-name.parent-selector.css',
|
||||
'entity.other.attribute-name.pseudo-class.css',
|
||||
'entity.other.attribute-name.pseudo-element.css',
|
||||
'source.css.less entity.other.attribute-name.id',
|
||||
'entity.other.attribute-name.scss',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline',
|
||||
settings: {
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.quote.begin.markdown',
|
||||
settings: {
|
||||
foreground: '#6A9955',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.list.begin.markdown',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.tag',
|
||||
settings: {
|
||||
foreground: '#808080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.preprocessor', 'entity.name.function.preprocessor'],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.string',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.numeric',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.structure.dictionary.key.python',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.header',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.type',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier', 'keyword.operator.noexcept'],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['string', 'meta.embedded.assembly'],
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.tag',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.value',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#D16969',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.template-expression.begin',
|
||||
'punctuation.definition.template-expression.end',
|
||||
'punctuation.section.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.template.expression'],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.type.vendored.property-name',
|
||||
'support.type.property-name',
|
||||
'variable.css',
|
||||
'variable.scss',
|
||||
'variable.other.less',
|
||||
'source.coffee.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.control',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.operator.new',
|
||||
'keyword.operator.expression',
|
||||
'keyword.operator.cast',
|
||||
'keyword.operator.sizeof',
|
||||
'keyword.operator.alignof',
|
||||
'keyword.operator.typeid',
|
||||
'keyword.operator.alignas',
|
||||
'keyword.operator.instanceof',
|
||||
'keyword.operator.logical.python',
|
||||
'keyword.operator.wordlike',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.section.embedded.begin.php', 'punctuation.section.embedded.end.php'],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function.git-rebase',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.sha.git-rebase',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier.import.java', 'variable.language.wildcard.java', 'storage.modifier.package.java'],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.name.function',
|
||||
'support.function',
|
||||
'support.constant.handlebars',
|
||||
'source.powershell variable.other.member',
|
||||
'entity.name.operator.custom-literal',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#DCDCAA',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.class',
|
||||
'support.type',
|
||||
'entity.name.type',
|
||||
'entity.name.namespace',
|
||||
'entity.other.attribute',
|
||||
'entity.name.scope-resolution',
|
||||
'entity.name.class',
|
||||
'storage.type.numeric.go',
|
||||
'storage.type.byte.go',
|
||||
'storage.type.boolean.go',
|
||||
'storage.type.string.go',
|
||||
'storage.type.uintptr.go',
|
||||
'storage.type.error.go',
|
||||
'storage.type.rune.go',
|
||||
'storage.type.cs',
|
||||
'storage.type.generic.cs',
|
||||
'storage.type.modifier.cs',
|
||||
'storage.type.variable.cs',
|
||||
'storage.type.annotation.java',
|
||||
'storage.type.generic.java',
|
||||
'storage.type.java',
|
||||
'storage.type.object.array.java',
|
||||
'storage.type.primitive.array.java',
|
||||
'storage.type.primitive.java',
|
||||
'storage.type.token.java',
|
||||
'storage.type.groovy',
|
||||
'storage.type.annotation.groovy',
|
||||
'storage.type.parameters.groovy',
|
||||
'storage.type.generic.groovy',
|
||||
'storage.type.object.array.groovy',
|
||||
'storage.type.primitive.array.groovy',
|
||||
'storage.type.primitive.groovy',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#4EC9B0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'meta.type.cast.expr',
|
||||
'meta.type.new.expr',
|
||||
'support.constant.math',
|
||||
'support.constant.dom',
|
||||
'support.constant.json',
|
||||
'entity.other.inherited-class',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#4EC9B0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.control',
|
||||
'source.cpp keyword.operator.new',
|
||||
'keyword.operator.delete',
|
||||
'keyword.other.using',
|
||||
'keyword.other.directive.using',
|
||||
'keyword.other.operator',
|
||||
'entity.name.operator',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#C586C0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'variable',
|
||||
'meta.definition.variable.name',
|
||||
'support.variable',
|
||||
'entity.name.variable',
|
||||
'constant.other.placeholder',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['variable.other.constant', 'variable.other.enummember'],
|
||||
settings: {
|
||||
foreground: '#4FC1FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.object-literal.key'],
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.constant.property-value',
|
||||
'support.constant.font-name',
|
||||
'support.constant.media-type',
|
||||
'support.constant.media',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.group.regexp',
|
||||
'punctuation.definition.group.assertion.regexp',
|
||||
'punctuation.definition.character-class.regexp',
|
||||
'punctuation.character.set.begin.regexp',
|
||||
'punctuation.character.set.end.regexp',
|
||||
'keyword.operator.negation.regexp',
|
||||
'support.other.parenthesis.regexp',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.character.character-class.regexp',
|
||||
'constant.other.character-class.set.regexp',
|
||||
'constant.other.character-class.regexp',
|
||||
'constant.character.set.regexp',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D16969',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['keyword.operator.or.regexp', 'keyword.control.anchor.regexp'],
|
||||
settings: {
|
||||
foreground: '#DCDCAA',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator.quantifier.regexp',
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['constant.character', 'constant.other.option'],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character.escape',
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.label',
|
||||
settings: {
|
||||
foreground: '#C8C8C8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'ref.matchtext',
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
export { default as darkPlus } from 'shiki/themes/dark-plus.mjs';
|
||||
export { default as lightPlus } from 'shiki/themes/light-plus.mjs';
|
||||
export { default as monokai } from 'shiki/themes/monokai.mjs';
|
||||
export { default as solarizedDark } from 'shiki/themes/solarized-dark.mjs';
|
||||
export { default as solarizedLight } from 'shiki/themes/solarized-light.mjs';
|
||||
export { abyss } from './abyss';
|
||||
export { darkHC } from './dark-hc';
|
||||
export { darkModern } from './dark-modern';
|
||||
export { kimbieDark } from './kimbie-dark';
|
||||
export { lightHC } from './light-hc';
|
||||
export { lightModern } from './light-modern';
|
||||
export { monokaiDim } from './monokai-dim';
|
||||
export { quietLight } from './quiet-light';
|
||||
export { red } from './red';
|
||||
export { tomorrowNightBlue } from './tomorrow-night-blue';
|
||||
export { vsDark } from './vs-dark';
|
||||
export { vsLight } from './vs-light';
|
||||
@@ -0,0 +1,374 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const kimbieDark: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'activityBar.background': '#221a0f',
|
||||
'activityBar.foreground': '#d3af86',
|
||||
'badge.background': '#7f5d38',
|
||||
'button.background': '#6e583b',
|
||||
'dropdown.background': '#51412c',
|
||||
'editor.background': '#221a0f',
|
||||
'editor.foreground': '#d3af86',
|
||||
'editor.lineHighlightBackground': '#5e452b',
|
||||
'editor.selectionBackground': '#84613daa',
|
||||
'editorCursor.foreground': '#d3af86',
|
||||
'editorGroupHeader.tabsBackground': '#131510',
|
||||
'editorHoverWidget.background': '#221a14',
|
||||
'editorLineNumber.activeForeground': '#adadad',
|
||||
'editorWhitespace.foreground': '#a57a4c',
|
||||
'editorWidget.background': '#131510',
|
||||
focusBorder: '#a57a4c',
|
||||
'input.background': '#51412c',
|
||||
'inputOption.activeBorder': '#a57a4c',
|
||||
'inputValidation.errorBackground': '#5f0d0d',
|
||||
'inputValidation.errorBorder': '#9d2f23',
|
||||
'inputValidation.infoBackground': '#2b2a42',
|
||||
'inputValidation.infoBorder': '#1b60a5',
|
||||
'inputValidation.warningBackground': '#51412c',
|
||||
'list.activeSelectionBackground': '#7c5021',
|
||||
'list.highlightForeground': '#e3b583',
|
||||
'list.hoverBackground': '#7c502166',
|
||||
'list.inactiveSelectionBackground': '#645342',
|
||||
'menu.background': '#362712',
|
||||
'menu.foreground': '#cccccc',
|
||||
'minimap.selectionHighlight': '#84613daa',
|
||||
'peekView.border': '#5e452b',
|
||||
'peekViewEditor.background': '#221a14',
|
||||
'peekViewEditor.matchHighlightBackground': '#84613daa',
|
||||
'peekViewResult.background': '#362712',
|
||||
'peekViewTitle.background': '#362712',
|
||||
'pickerGroup.border': '#e3b583',
|
||||
'pickerGroup.foreground': '#e3b583',
|
||||
'ports.iconRunningProcessForeground': '#369432',
|
||||
'progressBar.background': '#7f5d38',
|
||||
'quickInputList.focusBackground': '#7c5021aa',
|
||||
'selection.background': '#84613daa',
|
||||
'sideBar.background': '#362712',
|
||||
'statusBar.background': '#423523',
|
||||
'statusBar.debuggingBackground': '#423523',
|
||||
'statusBar.noFolderBackground': '#423523',
|
||||
'statusBarItem.remoteBackground': '#6e583b',
|
||||
'tab.inactiveBackground': '#131510',
|
||||
'tab.lastPinnedBorder': '#51412c',
|
||||
'titleBar.activeBackground': '#423523',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D3AF86',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.parameter.function',
|
||||
settings: {
|
||||
foreground: '#D3AF86',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['comment', 'punctuation.definition.comment'],
|
||||
settings: {
|
||||
foreground: '#A57A4C',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.string',
|
||||
'punctuation.definition.variable',
|
||||
'punctuation.definition.string',
|
||||
'punctuation.definition.parameters',
|
||||
'punctuation.definition.string',
|
||||
'punctuation.definition.array',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D3AF86',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'none',
|
||||
settings: {
|
||||
foreground: '#D3AF86',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#D3AF86',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword',
|
||||
'keyword.control',
|
||||
'keyword.operator.new.cpp',
|
||||
'keyword.operator.delete.cpp',
|
||||
'keyword.other.using',
|
||||
'keyword.other.directive.using',
|
||||
'keyword.other.operator',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#98676A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable',
|
||||
settings: {
|
||||
foreground: '#DC3958',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['entity.name.function', 'meta.require', 'support.function.any-method'],
|
||||
settings: {
|
||||
foreground: '#8AB1B0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.class',
|
||||
'entity.name.class',
|
||||
'entity.name.type',
|
||||
'entity.name.namespace',
|
||||
'entity.name.scope-resolution',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#F06431',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.special-method',
|
||||
settings: {
|
||||
foreground: '#8AB1B0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#98676A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function',
|
||||
settings: {
|
||||
foreground: '#7E602C',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['string', 'constant.other.symbol', 'entity.other.inherited-class'],
|
||||
settings: {
|
||||
foreground: '#889B4A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.numeric',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'none',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'none',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#DC3958',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['entity.other.attribute-name.id', 'punctuation.definition.entity'],
|
||||
settings: {
|
||||
foreground: '#8AB1B0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.selector',
|
||||
settings: {
|
||||
foreground: '#98676A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'none',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.heading', 'markup.heading.setext', 'punctuation.definition.heading', 'entity.name.section'],
|
||||
settings: {
|
||||
foreground: '#8AB1B0',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.bold', 'punctuation.definition.bold'],
|
||||
settings: {
|
||||
foreground: '#F06431',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.italic', 'punctuation.definition.italic'],
|
||||
settings: {
|
||||
foreground: '#98676A',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#889B4A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.other.link',
|
||||
settings: {
|
||||
foreground: '#DC3958',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.link',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.list',
|
||||
settings: {
|
||||
foreground: '#DC3958',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.quote',
|
||||
settings: {
|
||||
foreground: '#F79A32',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.separator',
|
||||
settings: {
|
||||
foreground: '#D3AF86',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#889B4A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#DC3958',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#98676A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.other.color',
|
||||
settings: {
|
||||
foreground: '#7E602C',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#7E602C',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character.escape',
|
||||
settings: {
|
||||
foreground: '#7E602C',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.section.embedded', 'variable.interpolation'],
|
||||
settings: {
|
||||
foreground: '#088649',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#DC3958',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'ref.matchtext',
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,572 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const lightHC: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'light',
|
||||
colors: {
|
||||
'actionBar.toggledBackground': '#dddddd',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: ['meta.embedded', 'source.groovy.embedded', 'variable.legacy.builtin.python'],
|
||||
settings: {
|
||||
foreground: '#292929',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'emphasis',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'strong',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.header',
|
||||
settings: {
|
||||
foreground: '#062F4A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#515151',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.numeric',
|
||||
'variable.other.enummember',
|
||||
'keyword.operator.plus.exponent',
|
||||
'keyword.operator.minus.exponent',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#096D48',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.regexp',
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.selector',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#264F78',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.other.attribute-name.class.css',
|
||||
'entity.other.attribute-name.class.mixin.css',
|
||||
'entity.other.attribute-name.id.css',
|
||||
'entity.other.attribute-name.parent-selector.css',
|
||||
'entity.other.attribute-name.pseudo-class.css',
|
||||
'entity.other.attribute-name.pseudo-element.css',
|
||||
'source.css.less entity.other.attribute-name.id',
|
||||
'entity.other.attribute-name.scss',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#B5200D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline',
|
||||
settings: {
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#096D48',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#5A5A5A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.definition.quote.begin.markdown', 'punctuation.definition.list.begin.markdown'],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.tag',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.preprocessor', 'entity.name.function.preprocessor'],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.string',
|
||||
settings: {
|
||||
foreground: '#B5200D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.numeric',
|
||||
settings: {
|
||||
foreground: '#096D48',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.structure.dictionary.key.python',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.type',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier', 'keyword.operator.noexcept'],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['string', 'meta.embedded.assembly'],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'string.comment.buffered.block.pug',
|
||||
'string.quoted.pug',
|
||||
'string.interpolated.pug',
|
||||
'string.unquoted.plain.in.yaml',
|
||||
'string.unquoted.plain.out.yaml',
|
||||
'string.unquoted.block.yaml',
|
||||
'string.quoted.single.yaml',
|
||||
'string.quoted.double.xml',
|
||||
'string.quoted.single.xml',
|
||||
'string.unquoted.cdata.xml',
|
||||
'string.quoted.double.html',
|
||||
'string.quoted.single.html',
|
||||
'string.unquoted.html',
|
||||
'string.quoted.single.handlebars',
|
||||
'string.quoted.double.handlebars',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.template-expression.begin',
|
||||
'punctuation.definition.template-expression.end',
|
||||
'punctuation.section.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.template.expression'],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.constant.property-value',
|
||||
'support.constant.font-name',
|
||||
'support.constant.media-type',
|
||||
'support.constant.media',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.type.vendored.property-name',
|
||||
'support.type.property-name',
|
||||
'variable.css',
|
||||
'variable.scss',
|
||||
'variable.other.less',
|
||||
'source.coffee.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#264F78',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['support.type.property-name.json'],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.control',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.operator.new',
|
||||
'keyword.operator.expression',
|
||||
'keyword.operator.cast',
|
||||
'keyword.operator.sizeof',
|
||||
'keyword.operator.alignof',
|
||||
'keyword.operator.typeid',
|
||||
'keyword.operator.alignas',
|
||||
'keyword.operator.instanceof',
|
||||
'keyword.operator.logical.python',
|
||||
'keyword.operator.wordlike',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#096D48',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.section.embedded.begin.php', 'punctuation.section.embedded.end.php'],
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function.git-rebase',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.sha.git-rebase',
|
||||
settings: {
|
||||
foreground: '#096D48',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier.import.java', 'variable.language.wildcard.java', 'storage.modifier.package.java'],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.name.function',
|
||||
'support.function',
|
||||
'support.constant.handlebars',
|
||||
'source.powershell variable.other.member',
|
||||
'entity.name.operator.custom-literal',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#5E2CBC',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.class',
|
||||
'support.type',
|
||||
'entity.name.type',
|
||||
'entity.name.namespace',
|
||||
'entity.other.attribute',
|
||||
'entity.name.scope-resolution',
|
||||
'entity.name.class',
|
||||
'storage.type.numeric.go',
|
||||
'storage.type.byte.go',
|
||||
'storage.type.boolean.go',
|
||||
'storage.type.string.go',
|
||||
'storage.type.uintptr.go',
|
||||
'storage.type.error.go',
|
||||
'storage.type.rune.go',
|
||||
'storage.type.cs',
|
||||
'storage.type.generic.cs',
|
||||
'storage.type.modifier.cs',
|
||||
'storage.type.variable.cs',
|
||||
'storage.type.annotation.java',
|
||||
'storage.type.generic.java',
|
||||
'storage.type.java',
|
||||
'storage.type.object.array.java',
|
||||
'storage.type.primitive.array.java',
|
||||
'storage.type.primitive.java',
|
||||
'storage.type.token.java',
|
||||
'storage.type.groovy',
|
||||
'storage.type.annotation.groovy',
|
||||
'storage.type.parameters.groovy',
|
||||
'storage.type.generic.groovy',
|
||||
'storage.type.object.array.groovy',
|
||||
'storage.type.primitive.array.groovy',
|
||||
'storage.type.primitive.groovy',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#185E73',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'meta.type.cast.expr',
|
||||
'meta.type.new.expr',
|
||||
'support.constant.math',
|
||||
'support.constant.dom',
|
||||
'support.constant.json',
|
||||
'entity.other.inherited-class',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#185E73',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.control',
|
||||
'source.cpp keyword.operator.new',
|
||||
'source.cpp keyword.operator.delete',
|
||||
'keyword.other.using',
|
||||
'keyword.other.directive.using',
|
||||
'keyword.other.operator',
|
||||
'entity.name.operator',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#B5200D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'variable',
|
||||
'meta.definition.variable.name',
|
||||
'support.variable',
|
||||
'entity.name.variable',
|
||||
'constant.other.placeholder',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#001080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['variable.other.constant', 'variable.other.enummember'],
|
||||
settings: {
|
||||
foreground: '#02715D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.object-literal.key'],
|
||||
settings: {
|
||||
foreground: '#001080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.constant.property-value',
|
||||
'support.constant.font-name',
|
||||
'support.constant.media-type',
|
||||
'support.constant.media',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.group.regexp',
|
||||
'punctuation.definition.group.assertion.regexp',
|
||||
'punctuation.definition.character-class.regexp',
|
||||
'punctuation.character.set.begin.regexp',
|
||||
'punctuation.character.set.end.regexp',
|
||||
'keyword.operator.negation.regexp',
|
||||
'support.other.parenthesis.regexp',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D16969',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.character.character-class.regexp',
|
||||
'constant.other.character-class.set.regexp',
|
||||
'constant.other.character-class.regexp',
|
||||
'constant.character.set.regexp',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator.quantifier.regexp',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['keyword.operator.or.regexp', 'keyword.control.anchor.regexp'],
|
||||
settings: {
|
||||
foreground: '#EE0000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character',
|
||||
settings: {
|
||||
foreground: '#0F4A85',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character.escape',
|
||||
settings: {
|
||||
foreground: '#EE0000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.label',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#316BCD',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#CD3131',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#800080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'ref.matchtext',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,716 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const lightModern: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'light',
|
||||
colors: {
|
||||
'actionBar.toggledBackground': '#dddddd',
|
||||
'activityBar.activeBorder': '#005fb8',
|
||||
'activityBar.background': '#f8f8f8',
|
||||
'activityBar.border': '#e5e5e5',
|
||||
'activityBar.foreground': '#1f1f1f',
|
||||
'activityBar.inactiveForeground': '#616161',
|
||||
'activityBarBadge.background': '#005fb8',
|
||||
'activityBarBadge.foreground': '#ffffff',
|
||||
'badge.background': '#cccccc',
|
||||
'badge.foreground': '#3b3b3b',
|
||||
'button.background': '#005fb8',
|
||||
'button.border': '#0000001a',
|
||||
'button.foreground': '#ffffff',
|
||||
'button.hoverBackground': '#0258a8',
|
||||
'button.secondaryBackground': '#e5e5e5',
|
||||
'button.secondaryForeground': '#3b3b3b',
|
||||
'button.secondaryHoverBackground': '#cccccc',
|
||||
'chat.slashCommandBackground': '#d2ecff',
|
||||
'chat.slashCommandForeground': '#306ca2',
|
||||
'checkbox.background': '#f8f8f8',
|
||||
'checkbox.border': '#cecece',
|
||||
descriptionForeground: '#3b3b3b',
|
||||
'dropdown.background': '#ffffff',
|
||||
'dropdown.border': '#cecece',
|
||||
'dropdown.foreground': '#3b3b3b',
|
||||
'dropdown.listBackground': '#ffffff',
|
||||
'editor.background': '#ffffff',
|
||||
'editor.foreground': '#3b3b3b',
|
||||
'editor.inactiveSelectionBackground': '#e5ebf1',
|
||||
'editor.selectionHighlightBackground': '#add6ff80',
|
||||
'editorGroup.border': '#e5e5e5',
|
||||
'editorGroupHeader.tabsBackground': '#f8f8f8',
|
||||
'editorGroupHeader.tabsBorder': '#e5e5e5',
|
||||
'editorGutter.addedBackground': '#2ea043',
|
||||
'editorGutter.deletedBackground': '#f85149',
|
||||
'editorGutter.modifiedBackground': '#005fb8',
|
||||
'editorIndentGuide.activeBackground1': '#939393',
|
||||
'editorIndentGuide.background1': '#d3d3d3',
|
||||
'editorLineNumber.activeForeground': '#171184',
|
||||
'editorLineNumber.foreground': '#6e7681',
|
||||
'editorOverviewRuler.border': '#e5e5e5',
|
||||
'editorSuggestWidget.background': '#f8f8f8',
|
||||
'editorWidget.background': '#f8f8f8',
|
||||
errorForeground: '#f85149',
|
||||
focusBorder: '#005fb8',
|
||||
foreground: '#3b3b3b',
|
||||
'icon.foreground': '#3b3b3b',
|
||||
'input.background': '#ffffff',
|
||||
'input.border': '#cecece',
|
||||
'input.foreground': '#3b3b3b',
|
||||
'input.placeholderForeground': '#868686',
|
||||
'inputOption.activeBackground': '#bed6ed',
|
||||
'inputOption.activeBorder': '#005fb8',
|
||||
'inputOption.activeForeground': '#000000',
|
||||
'keybindingLabel.foreground': '#3b3b3b',
|
||||
'list.activeSelectionBackground': '#e8e8e8',
|
||||
'list.activeSelectionForeground': '#000000',
|
||||
'list.activeSelectionIconForeground': '#000000',
|
||||
'list.focusAndSelectionOutline': '#005fb8',
|
||||
'list.hoverBackground': '#f2f2f2',
|
||||
'menu.border': '#cecece',
|
||||
'notebook.cellBorderColor': '#e5e5e5',
|
||||
'notebook.selectedCellBackground': '#c8ddf150',
|
||||
'notificationCenterHeader.background': '#ffffff',
|
||||
'notificationCenterHeader.foreground': '#3b3b3b',
|
||||
'notifications.background': '#ffffff',
|
||||
'notifications.border': '#e5e5e5',
|
||||
'notifications.foreground': '#3b3b3b',
|
||||
'panel.background': '#f8f8f8',
|
||||
'panel.border': '#e5e5e5',
|
||||
'panelInput.border': '#e5e5e5',
|
||||
'panelTitle.activeBorder': '#005fb8',
|
||||
'panelTitle.activeForeground': '#3b3b3b',
|
||||
'panelTitle.inactiveForeground': '#3b3b3b',
|
||||
'peekViewEditor.matchHighlightBackground': '#bb800966',
|
||||
'peekViewResult.background': '#ffffff',
|
||||
'peekViewResult.matchHighlightBackground': '#bb800966',
|
||||
'pickerGroup.border': '#e5e5e5',
|
||||
'pickerGroup.foreground': '#8b949e',
|
||||
'ports.iconRunningProcessForeground': '#369432',
|
||||
'progressBar.background': '#005fb8',
|
||||
'quickInput.background': '#f8f8f8',
|
||||
'quickInput.foreground': '#3b3b3b',
|
||||
'searchEditor.textInputBorder': '#cecece',
|
||||
'settings.dropdownBackground': '#ffffff',
|
||||
'settings.dropdownBorder': '#cecece',
|
||||
'settings.headerForeground': '#1f1f1f',
|
||||
'settings.modifiedItemIndicator': '#bb800966',
|
||||
'settings.numberInputBorder': '#cecece',
|
||||
'settings.textInputBorder': '#cecece',
|
||||
'sideBar.background': '#f8f8f8',
|
||||
'sideBar.border': '#e5e5e5',
|
||||
'sideBar.foreground': '#3b3b3b',
|
||||
'sideBarSectionHeader.background': '#f8f8f8',
|
||||
'sideBarSectionHeader.border': '#e5e5e5',
|
||||
'sideBarSectionHeader.foreground': '#3b3b3b',
|
||||
'sideBarTitle.foreground': '#3b3b3b',
|
||||
'statusBar.background': '#f8f8f8',
|
||||
'statusBar.border': '#e5e5e5',
|
||||
'statusBar.debuggingBackground': '#fd716c',
|
||||
'statusBar.debuggingForeground': '#000000',
|
||||
'statusBar.focusBorder': '#005fb8',
|
||||
'statusBar.foreground': '#3b3b3b',
|
||||
'statusBar.noFolderBackground': '#f8f8f8',
|
||||
'statusBarItem.errorBackground': '#c72e0f',
|
||||
'statusBarItem.focusBorder': '#005fb8',
|
||||
'statusBarItem.prominentBackground': '#6e768166',
|
||||
'statusBarItem.remoteBackground': '#005fb8',
|
||||
'statusBarItem.remoteForeground': '#ffffff',
|
||||
'tab.activeBackground': '#ffffff',
|
||||
'tab.activeBorder': '#f8f8f8',
|
||||
'tab.activeBorderTop': '#005fb8',
|
||||
'tab.activeForeground': '#3b3b3b',
|
||||
'tab.border': '#e5e5e5',
|
||||
'tab.hoverBackground': '#ffffff',
|
||||
'tab.inactiveBackground': '#f8f8f8',
|
||||
'tab.inactiveForeground': '#868686',
|
||||
'tab.lastPinnedBorder': '#d4d4d4',
|
||||
'tab.unfocusedActiveBorder': '#f8f8f8',
|
||||
'tab.unfocusedActiveBorderTop': '#e5e5e5',
|
||||
'tab.unfocusedHoverBackground': '#f8f8f8',
|
||||
'terminal.foreground': '#3b3b3b',
|
||||
'terminal.inactiveSelectionBackground': '#e5ebf1',
|
||||
'terminal.tab.activeBorder': '#005fb8',
|
||||
'terminalCursor.foreground': '#005fb8',
|
||||
'textBlockQuote.background': '#f8f8f8',
|
||||
'textBlockQuote.border': '#e5e5e5',
|
||||
'textCodeBlock.background': '#f8f8f8',
|
||||
'textLink.activeForeground': '#005fb8',
|
||||
'textLink.foreground': '#005fb8',
|
||||
'textPreformat.background': '#0000001f',
|
||||
'textPreformat.foreground': '#3b3b3b',
|
||||
'textSeparator.foreground': '#21262d',
|
||||
'titleBar.activeBackground': '#f8f8f8',
|
||||
'titleBar.activeForeground': '#1e1e1e',
|
||||
'titleBar.border': '#e5e5e5',
|
||||
'titleBar.inactiveBackground': '#f8f8f8',
|
||||
'titleBar.inactiveForeground': '#8b949e',
|
||||
'welcomePage.tileBackground': '#f3f3f3',
|
||||
'widget.border': '#e5e5e5',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'emphasis',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'strong',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.header',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#008000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.numeric',
|
||||
'variable.other.enummember',
|
||||
'keyword.operator.plus.exponent',
|
||||
'keyword.operator.minus.exponent',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.regexp',
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.selector',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#E50000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.other.attribute-name.class.css',
|
||||
'entity.other.attribute-name.class.mixin.css',
|
||||
'entity.other.attribute-name.id.css',
|
||||
'entity.other.attribute-name.parent-selector.css',
|
||||
'entity.other.attribute-name.pseudo-class.css',
|
||||
'entity.other.attribute-name.pseudo-element.css',
|
||||
'source.css.less entity.other.attribute-name.id',
|
||||
'entity.other.attribute-name.scss',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#CD3131',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline',
|
||||
settings: {
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#A31515',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.definition.quote.begin.markdown', 'punctuation.definition.list.begin.markdown'],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.tag',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.preprocessor', 'entity.name.function.preprocessor'],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.string',
|
||||
settings: {
|
||||
foreground: '#A31515',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.numeric',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.structure.dictionary.key.python',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.type',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier', 'keyword.operator.noexcept'],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['string', 'meta.embedded.assembly'],
|
||||
settings: {
|
||||
foreground: '#A31515',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'string.comment.buffered.block.pug',
|
||||
'string.quoted.pug',
|
||||
'string.interpolated.pug',
|
||||
'string.unquoted.plain.in.yaml',
|
||||
'string.unquoted.plain.out.yaml',
|
||||
'string.unquoted.block.yaml',
|
||||
'string.quoted.single.yaml',
|
||||
'string.quoted.double.xml',
|
||||
'string.quoted.single.xml',
|
||||
'string.unquoted.cdata.xml',
|
||||
'string.quoted.double.html',
|
||||
'string.quoted.single.html',
|
||||
'string.unquoted.html',
|
||||
'string.quoted.single.handlebars',
|
||||
'string.quoted.double.handlebars',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.template-expression.begin',
|
||||
'punctuation.definition.template-expression.end',
|
||||
'punctuation.section.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.template.expression'],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.constant.property-value',
|
||||
'support.constant.font-name',
|
||||
'support.constant.media-type',
|
||||
'support.constant.media',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.type.vendored.property-name',
|
||||
'support.type.property-name',
|
||||
'variable.css',
|
||||
'variable.scss',
|
||||
'variable.other.less',
|
||||
'source.coffee.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#E50000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['support.type.property-name.json'],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.control',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.operator.new',
|
||||
'keyword.operator.expression',
|
||||
'keyword.operator.cast',
|
||||
'keyword.operator.sizeof',
|
||||
'keyword.operator.alignof',
|
||||
'keyword.operator.typeid',
|
||||
'keyword.operator.alignas',
|
||||
'keyword.operator.instanceof',
|
||||
'keyword.operator.logical.python',
|
||||
'keyword.operator.wordlike',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.section.embedded.begin.php', 'punctuation.section.embedded.end.php'],
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function.git-rebase',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.sha.git-rebase',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier.import.java', 'variable.language.wildcard.java', 'storage.modifier.package.java'],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.name.function',
|
||||
'support.function',
|
||||
'support.constant.handlebars',
|
||||
'source.powershell variable.other.member',
|
||||
'entity.name.operator.custom-literal',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#795E26',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.class',
|
||||
'support.type',
|
||||
'entity.name.type',
|
||||
'entity.name.namespace',
|
||||
'entity.other.attribute',
|
||||
'entity.name.scope-resolution',
|
||||
'entity.name.class',
|
||||
'storage.type.numeric.go',
|
||||
'storage.type.byte.go',
|
||||
'storage.type.boolean.go',
|
||||
'storage.type.string.go',
|
||||
'storage.type.uintptr.go',
|
||||
'storage.type.error.go',
|
||||
'storage.type.rune.go',
|
||||
'storage.type.cs',
|
||||
'storage.type.generic.cs',
|
||||
'storage.type.modifier.cs',
|
||||
'storage.type.variable.cs',
|
||||
'storage.type.annotation.java',
|
||||
'storage.type.generic.java',
|
||||
'storage.type.java',
|
||||
'storage.type.object.array.java',
|
||||
'storage.type.primitive.array.java',
|
||||
'storage.type.primitive.java',
|
||||
'storage.type.token.java',
|
||||
'storage.type.groovy',
|
||||
'storage.type.annotation.groovy',
|
||||
'storage.type.parameters.groovy',
|
||||
'storage.type.generic.groovy',
|
||||
'storage.type.object.array.groovy',
|
||||
'storage.type.primitive.array.groovy',
|
||||
'storage.type.primitive.groovy',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#267F99',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'meta.type.cast.expr',
|
||||
'meta.type.new.expr',
|
||||
'support.constant.math',
|
||||
'support.constant.dom',
|
||||
'support.constant.json',
|
||||
'entity.other.inherited-class',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#267F99',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.control',
|
||||
'source.cpp keyword.operator.new',
|
||||
'source.cpp keyword.operator.delete',
|
||||
'keyword.other.using',
|
||||
'keyword.other.directive.using',
|
||||
'keyword.other.operator',
|
||||
'entity.name.operator',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#AF00DB',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'variable',
|
||||
'meta.definition.variable.name',
|
||||
'support.variable',
|
||||
'entity.name.variable',
|
||||
'constant.other.placeholder',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#001080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['variable.other.constant', 'variable.other.enummember'],
|
||||
settings: {
|
||||
foreground: '#0070C1',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.object-literal.key'],
|
||||
settings: {
|
||||
foreground: '#001080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.constant.property-value',
|
||||
'support.constant.font-name',
|
||||
'support.constant.media-type',
|
||||
'support.constant.media',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.group.regexp',
|
||||
'punctuation.definition.group.assertion.regexp',
|
||||
'punctuation.definition.character-class.regexp',
|
||||
'punctuation.character.set.begin.regexp',
|
||||
'punctuation.character.set.end.regexp',
|
||||
'keyword.operator.negation.regexp',
|
||||
'support.other.parenthesis.regexp',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D16969',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.character.character-class.regexp',
|
||||
'constant.other.character-class.set.regexp',
|
||||
'constant.other.character-class.regexp',
|
||||
'constant.character.set.regexp',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator.quantifier.regexp',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['keyword.operator.or.regexp', 'keyword.control.anchor.regexp'],
|
||||
settings: {
|
||||
foreground: '#EE0000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['constant.character', 'constant.other.option'],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character.escape',
|
||||
settings: {
|
||||
foreground: '#EE0000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.label',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'ref.matchtext',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#316BCD',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#CD3131',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#800080',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,573 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const monokaiDim: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'activityBar.background': '#353535',
|
||||
'activityBar.foreground': '#ffffff',
|
||||
'activityBarBadge.background': '#3655b5',
|
||||
'button.background': '#565656',
|
||||
'dropdown.background': '#525252',
|
||||
'editor.background': '#1e1e1e',
|
||||
'editor.foreground': '#c5c8c6',
|
||||
'editor.lineHighlightBackground': '#303030',
|
||||
'editor.selectionBackground': '#676b7180',
|
||||
'editor.selectionHighlightBackground': '#575b6180',
|
||||
'editor.wordHighlightBackground': '#4747a180',
|
||||
'editor.wordHighlightStrongBackground': '#6767ce80',
|
||||
'editorCursor.foreground': '#c07020',
|
||||
'editorGroupHeader.tabsBackground': '#282828',
|
||||
'editorIndentGuide.activeBackground': '#707057',
|
||||
'editorIndentGuide.background': '#505037',
|
||||
'editorLineNumber.activeForeground': '#949494',
|
||||
'editorWhitespace.foreground': '#505037',
|
||||
focusBorder: '#3655b5',
|
||||
'inputOption.activeBorder': '#3655b5',
|
||||
'list.activeSelectionBackground': '#707070',
|
||||
'list.highlightForeground': '#e58520',
|
||||
'list.hoverBackground': '#444444',
|
||||
'list.inactiveSelectionBackground': '#4e4e4e',
|
||||
'menu.background': '#272727',
|
||||
'menu.foreground': '#cccccc',
|
||||
'minimap.selectionHighlight': '#676b7180',
|
||||
'panelTitle.activeForeground': '#ffffff',
|
||||
'peekView.border': '#3655b5',
|
||||
'pickerGroup.foreground': '#b0b0b0',
|
||||
'ports.iconRunningProcessForeground': '#cccccc',
|
||||
'quickInputList.focusBackground': '#707070',
|
||||
'sideBar.background': '#272727',
|
||||
'sideBarSectionHeader.background': '#505050',
|
||||
'statusBar.background': '#505050',
|
||||
'statusBar.debuggingBackground': '#505050',
|
||||
'statusBar.noFolderBackground': '#505050',
|
||||
'statusBarItem.remoteBackground': '#3655b5',
|
||||
'tab.border': '#303030',
|
||||
'tab.inactiveBackground': '#404040',
|
||||
'tab.inactiveForeground': '#d8d8d8',
|
||||
'tab.lastPinnedBorder': '#505050',
|
||||
'terminal.ansiBlack': '#1e1e1e',
|
||||
'terminal.ansiBlue': '#6a7ec8',
|
||||
'terminal.ansiBrightBlack': '#666666',
|
||||
'terminal.ansiBrightBlue': '#819aff',
|
||||
'terminal.ansiBrightCyan': '#66d9ef',
|
||||
'terminal.ansiBrightGreen': '#a6e22e',
|
||||
'terminal.ansiBrightMagenta': '#ae81ff',
|
||||
'terminal.ansiBrightRed': '#f92672',
|
||||
'terminal.ansiBrightWhite': '#f8f8f2',
|
||||
'terminal.ansiBrightYellow': '#e2e22e',
|
||||
'terminal.ansiCyan': '#56adbc',
|
||||
'terminal.ansiGreen': '#86b42b',
|
||||
'terminal.ansiMagenta': '#8c6bc8',
|
||||
'terminal.ansiRed': '#c4265e',
|
||||
'terminal.ansiWhite': '#e3e3dd',
|
||||
'terminal.ansiYellow': '#b3b42b',
|
||||
'terminal.inactiveSelectionBackground': '#676b7140',
|
||||
'titleBar.activeBackground': '#505050',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: ['meta.embedded', 'source.groovy.embedded', 'variable.legacy.builtin.python'],
|
||||
settings: {
|
||||
foreground: '#C5C8C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#9A9B99',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string source',
|
||||
settings: {
|
||||
foreground: '#D08442',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.numeric',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#408080',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character, constant.other',
|
||||
settings: {
|
||||
foreground: '#8080FF',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support',
|
||||
settings: {
|
||||
foreground: '#C7444A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.class, entity.name.type, entity.name.namespace, entity.name.scope-resolution',
|
||||
settings: {
|
||||
foreground: '#9B0000',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.inherited-class',
|
||||
settings: {
|
||||
foreground: '#C7444A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.function',
|
||||
settings: {
|
||||
foreground: '#CE6700',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.parameter',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#676867',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.other, variable.js, punctuation.separator.variable',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.section.embedded -(source string source punctuation.section.embedded), meta.brace.erb.html',
|
||||
settings: {
|
||||
foreground: '#008200',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#FF0B00',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.other.php, variable.other.normal',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.function-call.object',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.other.property',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.control',
|
||||
'keyword.operator.new.cpp',
|
||||
'keyword.operator.delete.cpp',
|
||||
'keyword.other.using',
|
||||
'keyword.other.directive.using',
|
||||
'keyword.other.operator',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.tag',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.doctype, meta.tag.sgml-declaration.doctype, meta.tag.sgml.doctype',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.tag.inline source, text.html.php.source',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.tag.other, entity.name.tag.style, entity.name.tag.script, meta.tag.block.script, source.js.embedded punctuation.definition.tag.html, source.css.embedded punctuation.definition.tag.html',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name, meta.tag punctuation.definition.string',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.tag string -source -punctuation, text source text meta.tag string -punctuation',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.section.embedded -(source string source punctuation.section.embedded), meta.brace.erb.html',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.toc-list.id',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.quoted.double.html, punctuation.definition.string.begin.html, punctuation.definition.string.end.html, punctuation.definition.string.end.html source, string.quoted.double.html source',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.tag.html, punctuation.definition.tag.begin, punctuation.definition.tag.end',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.selector.css entity.other.attribute-name.id',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.type.property-name.css',
|
||||
settings: {
|
||||
foreground: '#676867',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css',
|
||||
settings: {
|
||||
foreground: '#C7444A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language.js',
|
||||
settings: {
|
||||
foreground: '#CC555A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.definition.template-expression', 'punctuation.section.embedded.coffee'],
|
||||
settings: {
|
||||
foreground: '#D08442',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.template.expression'],
|
||||
settings: {
|
||||
foreground: '#C5C8C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.function-call.object.php',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.string.end.php, punctuation.definition.string.begin.php',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'source.php.embedded.line.html',
|
||||
settings: {
|
||||
foreground: '#676867',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.section.embedded.begin.php, punctuation.section.embedded.end.php',
|
||||
settings: {
|
||||
foreground: '#D08442',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.other.symbol.ruby',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language.ruby',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.special-method.ruby',
|
||||
settings: {
|
||||
foreground: '#D9B700',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.section.embedded.begin.ruby', 'punctuation.section.embedded.end.ruby'],
|
||||
settings: {
|
||||
foreground: '#D08442',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.DML.sql',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff, meta.diff.header',
|
||||
settings: {
|
||||
foreground: '#E0EDDD',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#DC322F',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#CB4B16',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#219186',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.quote',
|
||||
settings: {
|
||||
foreground: '#9872A2',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.list',
|
||||
settings: {
|
||||
foreground: '#9AA83A',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold, markup.italic',
|
||||
settings: {
|
||||
foreground: '#6089B4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#FF0080',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading.setext',
|
||||
settings: {
|
||||
foreground: '#D0B344',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading.markdown',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.quote.markdown',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold.markdown',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.other.link.title.markdown,string.other.link.description.markdown',
|
||||
settings: {
|
||||
foreground: '#AE81FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline.link.markdown,markup.underline.link.image.markdown',
|
||||
settings: {},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic.markdown',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.list.unnumbered.markdown, markup.list.numbered.markdown',
|
||||
settings: {},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.definition.list.begin.markdown'],
|
||||
settings: {},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language',
|
||||
settings: {
|
||||
foreground: '#C7444A',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,465 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const quietLight: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'light',
|
||||
colors: {
|
||||
'activityBar.background': '#ededf5',
|
||||
'activityBar.foreground': '#705697',
|
||||
'activityBarBadge.background': '#705697',
|
||||
'badge.background': '#705697aa',
|
||||
'button.background': '#705697',
|
||||
'dropdown.background': '#f5f5f5',
|
||||
'editor.background': '#f5f5f5',
|
||||
'editor.findMatchBackground': '#bf9cac',
|
||||
'editor.findMatchHighlightBackground': '#edc9d899',
|
||||
'editor.lineHighlightBackground': '#e4f6d4',
|
||||
'editor.selectionBackground': '#c9d0d9',
|
||||
'editorCursor.foreground': '#54494b',
|
||||
'editorGroup.dropBackground': '#c9d0d988',
|
||||
'editorIndentGuide.activeBackground': '#777777b0',
|
||||
'editorIndentGuide.background': '#aaaaaa60',
|
||||
'editorLineNumber.activeForeground': '#9769dc',
|
||||
'editorLineNumber.foreground': '#6d705b',
|
||||
'editorWhitespace.foreground': '#aaaaaa',
|
||||
errorForeground: '#f1897f',
|
||||
focusBorder: '#9769dc',
|
||||
'inputOption.activeBorder': '#adafb7',
|
||||
'inputValidation.errorBackground': '#ffeaea',
|
||||
'inputValidation.errorBorder': '#f1897f',
|
||||
'inputValidation.infoBackground': '#f2fcff',
|
||||
'inputValidation.infoBorder': '#4ec1e5',
|
||||
'inputValidation.warningBackground': '#fffee2',
|
||||
'inputValidation.warningBorder': '#ffe055',
|
||||
'list.activeSelectionBackground': '#c4d9b1',
|
||||
'list.activeSelectionForeground': '#6c6c6c',
|
||||
'list.highlightForeground': '#9769dc',
|
||||
'list.hoverBackground': '#e0e0e0',
|
||||
'list.inactiveSelectionBackground': '#d3dbcd',
|
||||
'minimap.selectionHighlight': '#c9d0d9',
|
||||
'panel.background': '#f5f5f5',
|
||||
'peekView.border': '#705697',
|
||||
'peekViewEditor.background': '#f2f8fc',
|
||||
'peekViewEditor.matchHighlightBackground': '#c2dfe3',
|
||||
'peekViewResult.background': '#f2f8fc',
|
||||
'peekViewResult.matchHighlightBackground': '#93c6d6',
|
||||
'peekViewTitle.background': '#f2f8fc',
|
||||
'pickerGroup.border': '#749351',
|
||||
'pickerGroup.foreground': '#a6b39b',
|
||||
'ports.iconRunningProcessForeground': '#749351',
|
||||
'progressBar.background': '#705697',
|
||||
'quickInputList.focusBackground': '#cadeb9',
|
||||
'selection.background': '#c9d0d9',
|
||||
'sideBar.background': '#f2f2f2',
|
||||
'sideBarSectionHeader.background': '#ede8ef',
|
||||
'statusBar.background': '#705697',
|
||||
'statusBar.debuggingBackground': '#705697',
|
||||
'statusBar.noFolderBackground': '#705697',
|
||||
'statusBarItem.remoteBackground': '#4e3c69',
|
||||
'tab.lastPinnedBorder': '#c9d0d9',
|
||||
'titleBar.activeBackground': '#c4b7d7',
|
||||
'walkThrough.embeddedEditorBackground': '#00000014',
|
||||
'welcomePage.tileBackground': '#f0f0f7',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#333333',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['comment', 'punctuation.definition.comment'],
|
||||
settings: {
|
||||
foreground: '#AAAAAA',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment.block.preprocessor',
|
||||
settings: {
|
||||
foreground: '#AAAAAA',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'comment.documentation',
|
||||
'comment.block.documentation',
|
||||
'comment.block.documentation punctuation.definition.comment ',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#448C27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#CD3131',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid.illegal',
|
||||
settings: {
|
||||
foreground: '#660000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#777777',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['keyword', 'storage'],
|
||||
settings: {
|
||||
foreground: '#4B69C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.type', 'support.type'],
|
||||
settings: {
|
||||
foreground: '#7A3E9D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['constant.language', 'support.constant', 'variable.language'],
|
||||
settings: {
|
||||
foreground: '#9C5D27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['variable', 'support.variable'],
|
||||
settings: {
|
||||
foreground: '#7A3E9D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['entity.name.function', 'support.function'],
|
||||
settings: {
|
||||
foreground: '#AA3731',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.name.type',
|
||||
'entity.name.namespace',
|
||||
'entity.name.scope-resolution',
|
||||
'entity.other.inherited-class',
|
||||
'support.class',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#7A3E9D',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.exception',
|
||||
settings: {
|
||||
foreground: '#660000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.section',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['constant.numeric', 'constant.character', 'constant'],
|
||||
settings: {
|
||||
foreground: '#9C5D27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string',
|
||||
settings: {
|
||||
foreground: '#448C27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character.escape',
|
||||
settings: {
|
||||
foreground: '#777777',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#4B69C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.other.symbol',
|
||||
settings: {
|
||||
foreground: '#9C5D27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation',
|
||||
settings: {
|
||||
foreground: '#777777',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'meta.tag.sgml.doctype',
|
||||
'meta.tag.sgml.doctype string',
|
||||
'meta.tag.sgml.doctype entity.name.tag',
|
||||
'meta.tag.sgml punctuation.definition.tag.html',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#AAAAAA',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'meta.tag',
|
||||
'punctuation.definition.tag.html',
|
||||
'punctuation.definition.tag.begin.html',
|
||||
'punctuation.definition.tag.end.html',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#91B3E0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#4B69C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.tag entity.other.attribute-name', 'entity.other.attribute-name.html'],
|
||||
settings: {
|
||||
foreground: '#8190A0',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['constant.character.entity', 'punctuation.definition.entity'],
|
||||
settings: {
|
||||
foreground: '#9C5D27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.selector', 'meta.selector entity', 'meta.selector entity punctuation', 'entity.name.tag.css'],
|
||||
settings: {
|
||||
foreground: '#7A3E9D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.property-name', 'support.type.property-name'],
|
||||
settings: {
|
||||
foreground: '#9C5D27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.property-value', 'meta.property-value constant.other', 'support.constant.property-value'],
|
||||
settings: {
|
||||
foreground: '#448C27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.important',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.error',
|
||||
settings: {
|
||||
foreground: '#660000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.link',
|
||||
settings: {
|
||||
foreground: '#4B69C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.output', 'markup.raw'],
|
||||
settings: {
|
||||
foreground: '#777777',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.prompt',
|
||||
settings: {
|
||||
foreground: '#777777',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#AA3731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.traceback',
|
||||
settings: {
|
||||
foreground: '#660000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline',
|
||||
settings: {
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.quote',
|
||||
settings: {
|
||||
foreground: '#7A3E9D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.list',
|
||||
settings: {
|
||||
foreground: '#4B69C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.bold', 'markup.italic'],
|
||||
settings: {
|
||||
foreground: '#448C27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#9C5D27',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.diff.range', 'meta.diff.index', 'meta.separator'],
|
||||
settings: {
|
||||
foreground: '#434343',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.diff.header.from-file', 'punctuation.definition.from-file.diff'],
|
||||
settings: {
|
||||
foreground: '#4B69C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.diff.header.to-file', 'punctuation.definition.to-file.diff'],
|
||||
settings: {
|
||||
foreground: '#4B69C6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted.diff',
|
||||
settings: {
|
||||
foreground: '#C73D20',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed.diff',
|
||||
settings: {
|
||||
foreground: '#9C5D27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted.diff',
|
||||
settings: {
|
||||
foreground: '#448C27',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.tag.js',
|
||||
'punctuation.definition.tag.begin.js',
|
||||
'punctuation.definition.tag.end.js',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#91B3E0',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.jsx.children.js',
|
||||
settings: {
|
||||
foreground: '#333333',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'ref.matchtext',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#316BCD',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#CD3131',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#800080',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,376 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const red: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'activityBar.background': '#580000',
|
||||
'badge.background': '#cc3333',
|
||||
'button.background': '#883333',
|
||||
'debugToolBar.background': '#660000',
|
||||
'dropdown.background': '#580000',
|
||||
'editor.background': '#390000',
|
||||
'editor.foreground': '#f8f8f8',
|
||||
'editor.hoverHighlightBackground': '#ff000044',
|
||||
'editor.lineHighlightBackground': '#ff000033',
|
||||
'editor.selectionBackground': '#750000',
|
||||
'editor.selectionHighlightBackground': '#f5500039',
|
||||
'editorCursor.foreground': '#970000',
|
||||
'editorGroup.border': '#ff666633',
|
||||
'editorGroupHeader.tabsBackground': '#330000',
|
||||
'editorHoverWidget.background': '#300000',
|
||||
'editorLineNumber.activeForeground': '#ffbbbb88',
|
||||
'editorLineNumber.foreground': '#ff777788',
|
||||
'editorLink.activeForeground': '#ffd0aa',
|
||||
'editorSuggestWidget.background': '#300000',
|
||||
'editorSuggestWidget.border': '#220000',
|
||||
'editorWhitespace.foreground': '#c10000',
|
||||
'editorWidget.background': '#300000',
|
||||
errorForeground: '#ffeaea',
|
||||
'extensionButton.prominentBackground': '#cc3333',
|
||||
'extensionButton.prominentHoverBackground': '#cc333388',
|
||||
focusBorder: '#ff6666aa',
|
||||
'input.background': '#580000',
|
||||
'inputOption.activeBorder': '#cc0000',
|
||||
'inputValidation.infoBackground': '#550000',
|
||||
'inputValidation.infoBorder': '#db7e58',
|
||||
'list.activeSelectionBackground': '#880000',
|
||||
'list.dropBackground': '#662222',
|
||||
'list.highlightForeground': '#ff4444',
|
||||
'list.hoverBackground': '#800000',
|
||||
'list.inactiveSelectionBackground': '#770000',
|
||||
'minimap.selectionHighlight': '#750000',
|
||||
'peekView.border': '#ff000044',
|
||||
'peekViewEditor.background': '#300000',
|
||||
'peekViewResult.background': '#400000',
|
||||
'peekViewTitle.background': '#550000',
|
||||
'pickerGroup.border': '#ff000033',
|
||||
'pickerGroup.foreground': '#cc9999',
|
||||
'ports.iconRunningProcessForeground': '#db7e58',
|
||||
'progressBar.background': '#cc3333',
|
||||
'quickInputList.focusBackground': '#660000',
|
||||
'selection.background': '#ff777788',
|
||||
'sideBar.background': '#330000',
|
||||
'statusBar.background': '#700000',
|
||||
'statusBar.noFolderBackground': '#700000',
|
||||
'statusBarItem.remoteBackground': '#cc3333',
|
||||
'tab.activeBackground': '#490000',
|
||||
'tab.inactiveBackground': '#300a0a',
|
||||
'tab.lastPinnedBorder': '#ff000044',
|
||||
'titleBar.activeBackground': '#770000',
|
||||
'titleBar.inactiveBackground': '#772222',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#F8F8F8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#E7C0C0',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant',
|
||||
settings: {
|
||||
foreground: '#994646',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#F12727',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity',
|
||||
settings: {
|
||||
foreground: '#FEC758',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#FF6262',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string',
|
||||
settings: {
|
||||
foreground: '#CD8D8D',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support',
|
||||
settings: {
|
||||
foreground: '#9DF39F',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable',
|
||||
settings: {
|
||||
foreground: '#FB9A4B',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.inherited-class',
|
||||
settings: {
|
||||
foreground: '#AA5507',
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.character',
|
||||
settings: {
|
||||
foreground: '#EC0D1E',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['string constant', 'constant.character.escape'],
|
||||
settings: {
|
||||
foreground: '#FFE862',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#FFB454',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string variable',
|
||||
settings: {
|
||||
foreground: '#EDEF7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function',
|
||||
settings: {
|
||||
foreground: '#FFB454',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['support.constant', 'support.variable'],
|
||||
settings: {
|
||||
foreground: '#EB939A',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'declaration.sgml.html declaration.doctype',
|
||||
'declaration.sgml.html declaration.doctype entity',
|
||||
'declaration.sgml.html declaration.doctype string',
|
||||
'declaration.xml-processing',
|
||||
'declaration.xml-processing entity',
|
||||
'declaration.xml-processing string',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#73817D',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['declaration.tag', 'declaration.tag entity', 'meta.tag', 'meta.tag entity'],
|
||||
settings: {
|
||||
foreground: '#EC0D1E',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.selector.css entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#AA5507',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.selector.css entity.other.attribute-name.id',
|
||||
settings: {
|
||||
foreground: '#FEC758',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.selector.css entity.other.attribute-name.class',
|
||||
settings: {
|
||||
foreground: '#41A83E',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.type.property-name.css',
|
||||
settings: {
|
||||
foreground: '#96DD3B',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'meta.property-group support.constant.property-value.css',
|
||||
'meta.property-value support.constant.property-value.css',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#FFE862',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.property-value support.constant.named-color.css', 'meta.property-value constant'],
|
||||
settings: {
|
||||
foreground: '#FFE862',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.at-rule keyword.control.at-rule',
|
||||
settings: {
|
||||
foreground: '#FD6209',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.constructor.argument.css',
|
||||
settings: {
|
||||
foreground: '#EC9799',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.diff', 'meta.diff.header'],
|
||||
settings: {
|
||||
foreground: '#F8F8F8',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#EC9799',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#F8F8F8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#41A83E',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.quote',
|
||||
settings: {
|
||||
foreground: '#F12727',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.list',
|
||||
settings: {
|
||||
foreground: '#FF6262',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.bold', 'markup.italic'],
|
||||
settings: {
|
||||
foreground: '#FB9A4B',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#CD8D8D',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['markup.heading', 'markup.heading.setext', 'punctuation.definition.heading', 'entity.name.section'],
|
||||
settings: {
|
||||
foreground: '#FEC758',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.template-expression.begin',
|
||||
'punctuation.definition.template-expression.end',
|
||||
'punctuation.section.embedded',
|
||||
'.format.placeholder',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#EC0D1E',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,265 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const tomorrowNightBlue: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'activityBar.background': '#001733',
|
||||
'badge.background': '#bbdaffcc',
|
||||
'badge.foreground': '#001733',
|
||||
'debugToolBar.background': '#001c40',
|
||||
'dropdown.background': '#001733',
|
||||
'editor.background': '#002451',
|
||||
'editor.foreground': '#ffffff',
|
||||
'editor.lineHighlightBackground': '#00346e',
|
||||
'editor.selectionBackground': '#003f8e',
|
||||
'editorCursor.foreground': '#ffffff',
|
||||
'editorGroup.border': '#404f7d',
|
||||
'editorGroup.dropBackground': '#25375daa',
|
||||
'editorGroupHeader.tabsBackground': '#001733',
|
||||
'editorHoverWidget.background': '#001c40',
|
||||
'editorHoverWidget.border': '#ffffff44',
|
||||
'editorLineNumber.activeForeground': '#949494',
|
||||
'editorWhitespace.foreground': '#404f7d',
|
||||
'editorWidget.background': '#001c40',
|
||||
errorForeground: '#a92049',
|
||||
focusBorder: '#bbdaff',
|
||||
'input.background': '#001733',
|
||||
'list.activeSelectionBackground': '#ffffff60',
|
||||
'list.highlightForeground': '#bbdaff',
|
||||
'list.hoverBackground': '#ffffff30',
|
||||
'list.inactiveSelectionBackground': '#ffffff40',
|
||||
'minimap.selectionHighlight': '#003f8e',
|
||||
'peekViewResult.background': '#001c40',
|
||||
'pickerGroup.foreground': '#bbdaff',
|
||||
'ports.iconRunningProcessForeground': '#bbdaff',
|
||||
'progressBar.background': '#bbdaffcc',
|
||||
'quickInputList.focusBackground': '#ffffff60',
|
||||
'sideBar.background': '#001c40',
|
||||
'statusBar.background': '#001126',
|
||||
'statusBar.debuggingBackground': '#001126',
|
||||
'statusBar.noFolderBackground': '#001126',
|
||||
'statusBarItem.remoteBackground': '#0e639c',
|
||||
'tab.inactiveBackground': '#001c40',
|
||||
'tab.lastPinnedBorder': '#007acc80',
|
||||
'terminal.ansiBlack': '#111111',
|
||||
'terminal.ansiBlue': '#bbdaff',
|
||||
'terminal.ansiBrightBlack': '#333333',
|
||||
'terminal.ansiBrightBlue': '#80baff',
|
||||
'terminal.ansiBrightCyan': '#78ffff',
|
||||
'terminal.ansiBrightGreen': '#b8f171',
|
||||
'terminal.ansiBrightMagenta': '#d778ff',
|
||||
'terminal.ansiBrightRed': '#ff7882',
|
||||
'terminal.ansiBrightWhite': '#ffffff',
|
||||
'terminal.ansiBrightYellow': '#ffe580',
|
||||
'terminal.ansiCyan': '#99ffff',
|
||||
'terminal.ansiGreen': '#d1f1a9',
|
||||
'terminal.ansiMagenta': '#ebbbff',
|
||||
'terminal.ansiRed': '#ff9da4',
|
||||
'terminal.ansiWhite': '#cccccc',
|
||||
'terminal.ansiYellow': '#ffeead',
|
||||
'titleBar.activeBackground': '#001126',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'meta.jsx.children',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#7285B7',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator.class, keyword.operator, constant.other, source.php.embedded.line',
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable, support.other.variable, string.other.link, string.regexp, entity.name.tag, entity.other.attribute-name, meta.tag, declaration.tag, markup.deleted.git_gutter',
|
||||
settings: {
|
||||
foreground: '#FF9DA4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.numeric, constant.language, support.constant, constant.character, variable.parameter, punctuation.section.embedded, keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#FFC58F',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.class, entity.name.type, entity.name.namespace, entity.name.scope-resolution, support.type, support.class',
|
||||
settings: {
|
||||
foreground: '#FFEEAD',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string, constant.other.symbol, entity.other.inherited-class, markup.heading, markup.inserted.git_gutter',
|
||||
settings: {
|
||||
foreground: '#D1F1A9',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator, constant.other.color',
|
||||
settings: {
|
||||
foreground: '#99FFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.function, meta.function-call, support.function, keyword.other.special-method, meta.block-level, markup.changed.git_gutter',
|
||||
settings: {
|
||||
foreground: '#BBDAFF',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword, storage, storage.type, entity.name.tag.css',
|
||||
settings: {
|
||||
foreground: '#EBBBFF',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#A92049',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.separator',
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid.deprecated',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted.diff, markup.deleted.diff, meta.diff.header.to-file, meta.diff.header.from-file',
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted.diff, meta.diff.header.to-file',
|
||||
settings: {
|
||||
foreground: '#718C00',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted.diff, meta.diff.header.from-file',
|
||||
settings: {
|
||||
foreground: '#C82829',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.header.from-file, meta.diff.header.to-file',
|
||||
settings: {
|
||||
foreground: '#4271AE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.range',
|
||||
settings: {
|
||||
foreground: '#3E999F',
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.quote',
|
||||
settings: {
|
||||
foreground: '#FFC58F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.list',
|
||||
settings: {
|
||||
foreground: '#BBDAFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold, markup.italic',
|
||||
settings: {
|
||||
foreground: '#FFC58F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#FF9DA4',
|
||||
fontStyle: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,412 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const vsDark: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'dark',
|
||||
colors: {
|
||||
'actionBar.toggledBackground': '#383a49',
|
||||
'activityBarBadge.background': '#007acc',
|
||||
'checkbox.border': '#6b6b6b',
|
||||
'editor.background': '#1e1e1e',
|
||||
'editor.foreground': '#d4d4d4',
|
||||
'editor.inactiveSelectionBackground': '#3a3d41',
|
||||
'editor.selectionHighlightBackground': '#add6ff26',
|
||||
'editorIndentGuide.activeBackground1': '#707070',
|
||||
'editorIndentGuide.background1': '#404040',
|
||||
'input.placeholderForeground': '#a6a6a6',
|
||||
'list.activeSelectionIconForeground': '#ffffff',
|
||||
'list.dropBackground': '#383b3d',
|
||||
'menu.background': '#252526',
|
||||
'menu.border': '#454545',
|
||||
'menu.foreground': '#cccccc',
|
||||
'menu.separatorBackground': '#454545',
|
||||
'ports.iconRunningProcessForeground': '#369432',
|
||||
'sideBarSectionHeader.background': '#00000000',
|
||||
'sideBarSectionHeader.border': '#cccccc33',
|
||||
'sideBarTitle.foreground': '#bbbbbb',
|
||||
'statusBarItem.remoteBackground': '#16825d',
|
||||
'statusBarItem.remoteForeground': '#ffffff',
|
||||
'tab.lastPinnedBorder': '#cccccc33',
|
||||
'terminal.inactiveSelectionBackground': '#3a3d41',
|
||||
'widget.border': '#303031',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'emphasis',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'strong',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'header',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#6A9955',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.numeric',
|
||||
'variable.other.enummember',
|
||||
'keyword.operator.plus.exponent',
|
||||
'keyword.operator.minus.exponent',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.regexp',
|
||||
settings: {
|
||||
foreground: '#646695',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag.css',
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.other.attribute-name.class.css',
|
||||
'entity.other.attribute-name.class.mixin.css',
|
||||
'entity.other.attribute-name.id.css',
|
||||
'entity.other.attribute-name.parent-selector.css',
|
||||
'entity.other.attribute-name.pseudo-class.css',
|
||||
'entity.other.attribute-name.pseudo-element.css',
|
||||
'source.css.less entity.other.attribute-name.id',
|
||||
'entity.other.attribute-name.scss',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#D7BA7D',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline',
|
||||
settings: {
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.quote.begin.markdown',
|
||||
settings: {
|
||||
foreground: '#6A9955',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.list.begin.markdown',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.tag',
|
||||
settings: {
|
||||
foreground: '#808080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.preprocessor', 'entity.name.function.preprocessor'],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.string',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.numeric',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.structure.dictionary.key.python',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.header',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.type',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier', 'keyword.operator.noexcept'],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['string', 'meta.embedded.assembly'],
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.tag',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.value',
|
||||
settings: {
|
||||
foreground: '#CE9178',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#D16969',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.template-expression.begin',
|
||||
'punctuation.definition.template-expression.end',
|
||||
'punctuation.section.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.template.expression'],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.type.vendored.property-name',
|
||||
'support.type.property-name',
|
||||
'variable.css',
|
||||
'variable.scss',
|
||||
'variable.other.less',
|
||||
'source.coffee.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.control',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.operator.new',
|
||||
'keyword.operator.expression',
|
||||
'keyword.operator.cast',
|
||||
'keyword.operator.sizeof',
|
||||
'keyword.operator.alignof',
|
||||
'keyword.operator.typeid',
|
||||
'keyword.operator.alignas',
|
||||
'keyword.operator.instanceof',
|
||||
'keyword.operator.logical.python',
|
||||
'keyword.operator.wordlike',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.section.embedded.begin.php', 'punctuation.section.embedded.end.php'],
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function.git-rebase',
|
||||
settings: {
|
||||
foreground: '#9CDCFE',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.sha.git-rebase',
|
||||
settings: {
|
||||
foreground: '#B5CEA8',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier.import.java', 'variable.language.wildcard.java', 'storage.modifier.package.java'],
|
||||
settings: {
|
||||
foreground: '#D4D4D4',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language',
|
||||
settings: {
|
||||
foreground: '#569CD6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'ref.matchtext',
|
||||
settings: {
|
||||
foreground: '#FFFFFF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#6796E6',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#F44747',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#B267E6',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,435 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ThemeRegistrationAny } from 'shiki';
|
||||
|
||||
export const vsLight: ThemeRegistrationAny = {
|
||||
$schema: 'vscode://schemas/color-theme',
|
||||
type: 'light',
|
||||
colors: {
|
||||
'actionBar.toggledBackground': '#dddddd',
|
||||
'activityBarBadge.background': '#007acc',
|
||||
'checkbox.border': '#919191',
|
||||
'editor.background': '#ffffff',
|
||||
'editor.foreground': '#000000',
|
||||
'editor.inactiveSelectionBackground': '#e5ebf1',
|
||||
'editor.selectionHighlightBackground': '#add6ff80',
|
||||
'editorIndentGuide.activeBackground1': '#939393',
|
||||
'editorIndentGuide.background1': '#d3d3d3',
|
||||
'editorSuggestWidget.background': '#f3f3f3',
|
||||
'input.placeholderForeground': '#767676',
|
||||
'list.activeSelectionIconForeground': '#ffffff',
|
||||
'list.focusAndSelectionOutline': '#90c2f9',
|
||||
'list.hoverBackground': '#e8e8e8',
|
||||
'menu.border': '#d4d4d4',
|
||||
'notebook.cellBorderColor': '#e8e8e8',
|
||||
'notebook.selectedCellBackground': '#c8ddf150',
|
||||
'ports.iconRunningProcessForeground': '#369432',
|
||||
'searchEditor.textInputBorder': '#cecece',
|
||||
'settings.numberInputBorder': '#cecece',
|
||||
'settings.textInputBorder': '#cecece',
|
||||
'sideBarSectionHeader.background': '#00000000',
|
||||
'sideBarSectionHeader.border': '#61616130',
|
||||
'sideBarTitle.foreground': '#6f6f6f',
|
||||
'statusBarItem.errorBackground': '#c72e0f',
|
||||
'statusBarItem.remoteBackground': '#16825d',
|
||||
'statusBarItem.remoteForeground': '#ffffff',
|
||||
'tab.lastPinnedBorder': '#61616130',
|
||||
'terminal.inactiveSelectionBackground': '#e5ebf1',
|
||||
'widget.border': '#d4d4d4',
|
||||
},
|
||||
tokenColors: [
|
||||
{
|
||||
scope: [
|
||||
'meta.embedded',
|
||||
'source.groovy.embedded',
|
||||
'string meta.image.inline.markdown',
|
||||
'variable.legacy.builtin.python',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'emphasis',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'strong',
|
||||
settings: {
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.diff.header',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'comment',
|
||||
settings: {
|
||||
foreground: '#008000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.language',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'constant.numeric',
|
||||
'variable.other.enummember',
|
||||
'keyword.operator.plus.exponent',
|
||||
'keyword.operator.minus.exponent',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.regexp',
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.tag',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.name.selector',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'entity.other.attribute-name',
|
||||
settings: {
|
||||
foreground: '#E50000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'entity.other.attribute-name.class.css',
|
||||
'entity.other.attribute-name.class.mixin.css',
|
||||
'entity.other.attribute-name.id.css',
|
||||
'entity.other.attribute-name.parent-selector.css',
|
||||
'entity.other.attribute-name.pseudo-class.css',
|
||||
'entity.other.attribute-name.pseudo-element.css',
|
||||
'source.css.less entity.other.attribute-name.id',
|
||||
'entity.other.attribute-name.scss',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'invalid',
|
||||
settings: {
|
||||
foreground: '#CD3131',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.underline',
|
||||
settings: {
|
||||
fontStyle: 'underline',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.bold',
|
||||
settings: {
|
||||
foreground: '#000080',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.heading',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
fontStyle: 'bold',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.italic',
|
||||
settings: {
|
||||
fontStyle: 'italic',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.strikethrough',
|
||||
settings: {
|
||||
fontStyle: 'strikethrough',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inserted',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.deleted',
|
||||
settings: {
|
||||
foreground: '#A31515',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.changed',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.definition.quote.begin.markdown', 'punctuation.definition.list.begin.markdown'],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'markup.inline.raw',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'punctuation.definition.tag',
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.preprocessor', 'entity.name.function.preprocessor'],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.string',
|
||||
settings: {
|
||||
foreground: '#A31515',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.preprocessor.numeric',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'meta.structure.dictionary.key.python',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'storage.type',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier', 'keyword.operator.noexcept'],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['string', 'meta.embedded.assembly'],
|
||||
settings: {
|
||||
foreground: '#A31515',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'string.comment.buffered.block.pug',
|
||||
'string.quoted.pug',
|
||||
'string.interpolated.pug',
|
||||
'string.unquoted.plain.in.yaml',
|
||||
'string.unquoted.plain.out.yaml',
|
||||
'string.unquoted.block.yaml',
|
||||
'string.quoted.single.yaml',
|
||||
'string.quoted.double.xml',
|
||||
'string.quoted.single.xml',
|
||||
'string.unquoted.cdata.xml',
|
||||
'string.quoted.double.html',
|
||||
'string.quoted.single.html',
|
||||
'string.unquoted.html',
|
||||
'string.quoted.single.handlebars',
|
||||
'string.quoted.double.handlebars',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'string.regexp',
|
||||
settings: {
|
||||
foreground: '#811F3F',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'punctuation.definition.template-expression.begin',
|
||||
'punctuation.definition.template-expression.end',
|
||||
'punctuation.section.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['meta.template.expression'],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.constant.property-value',
|
||||
'support.constant.font-name',
|
||||
'support.constant.media-type',
|
||||
'support.constant.media',
|
||||
'constant.other.color.rgb-value',
|
||||
'constant.other.rgb-value',
|
||||
'support.constant.color',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'support.type.vendored.property-name',
|
||||
'support.type.property-name',
|
||||
'variable.css',
|
||||
'variable.scss',
|
||||
'variable.other.less',
|
||||
'source.coffee.embedded',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#E50000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['support.type.property-name.json'],
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.control',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.operator',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: [
|
||||
'keyword.operator.new',
|
||||
'keyword.operator.expression',
|
||||
'keyword.operator.cast',
|
||||
'keyword.operator.sizeof',
|
||||
'keyword.operator.alignof',
|
||||
'keyword.operator.typeid',
|
||||
'keyword.operator.alignas',
|
||||
'keyword.operator.instanceof',
|
||||
'keyword.operator.logical.python',
|
||||
'keyword.operator.wordlike',
|
||||
],
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'keyword.other.unit',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['punctuation.section.embedded.begin.php', 'punctuation.section.embedded.end.php'],
|
||||
settings: {
|
||||
foreground: '#800000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'support.function.git-rebase',
|
||||
settings: {
|
||||
foreground: '#0451A5',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'constant.sha.git-rebase',
|
||||
settings: {
|
||||
foreground: '#098658',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: ['storage.modifier.import.java', 'variable.language.wildcard.java', 'storage.modifier.package.java'],
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'variable.language',
|
||||
settings: {
|
||||
foreground: '#0000FF',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'ref.matchtext',
|
||||
settings: {
|
||||
foreground: '#000000',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.info-token',
|
||||
settings: {
|
||||
foreground: '#316BCD',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.warn-token',
|
||||
settings: {
|
||||
foreground: '#CD9731',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.error-token',
|
||||
settings: {
|
||||
foreground: '#CD3131',
|
||||
},
|
||||
},
|
||||
{
|
||||
scope: 'token.debug-token',
|
||||
settings: {
|
||||
foreground: '#800080',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export function getNonce() {
|
||||
let text = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
export function pluralize(count: number, noun: string, suffix = 's') {
|
||||
return `${count} ${noun}${count !== 1 ? suffix : ''}`;
|
||||
}
|
||||
134
completions-sample-code/vscode-node/extension/src/statusBar.ts
Normal file
134
completions-sample-code/vscode-node/extension/src/statusBar.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { commands, Disposable, languages, LanguageStatusItem, LanguageStatusSeverity, window, workspace } from 'vscode';
|
||||
import { IDisposable } from '../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { CopilotConfigPrefix } from '../../lib/src/constants';
|
||||
import { CMDQuotaExceeded } from '../../lib/src/openai/fetch';
|
||||
import { StatusChangedEvent, StatusReporter } from '../../lib/src/progress';
|
||||
import { isCompletionEnabled, isInlineSuggestEnabled } from './config';
|
||||
import { CMDToggleStatusMenuChat } from './constants';
|
||||
import { ICompletionsExtensionStatus } from './extensionStatus';
|
||||
import { Icon } from './icon';
|
||||
|
||||
export class CopilotStatusBar extends StatusReporter implements IDisposable {
|
||||
readonly item!: LanguageStatusItem;
|
||||
showingMessage = false;
|
||||
private disposables: Disposable[] = [];
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
@ICompletionsExtensionStatus readonly extensionStatusService: ICompletionsExtensionStatus,
|
||||
@IInstantiationService readonly instantiationService: IInstantiationService,
|
||||
|
||||
) {
|
||||
super();
|
||||
|
||||
this.item = languages.createLanguageStatusItem(id, '*');
|
||||
this.disposables.push(this.item);
|
||||
|
||||
this.updateStatusBarIndicator();
|
||||
|
||||
this.disposables.push(
|
||||
window.onDidChangeActiveTextEditor(() => {
|
||||
this.updateStatusBarIndicator();
|
||||
})
|
||||
);
|
||||
|
||||
this.disposables.push(
|
||||
workspace.onDidCloseTextDocument(() => {
|
||||
this.updateStatusBarIndicator();
|
||||
})
|
||||
);
|
||||
|
||||
this.disposables.push(
|
||||
workspace.onDidOpenTextDocument(() => {
|
||||
this.updateStatusBarIndicator();
|
||||
})
|
||||
);
|
||||
|
||||
this.disposables.push(
|
||||
workspace.onDidChangeConfiguration(e => {
|
||||
if (!e.affectsConfiguration(CopilotConfigPrefix)) { return; }
|
||||
this.updateStatusBarIndicator();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
override didChange(event: StatusChangedEvent): void {
|
||||
this.extensionStatusService.kind = event.kind;
|
||||
this.extensionStatusService.message = event.message;
|
||||
this.extensionStatusService.command = event.command;
|
||||
this.updateStatusBarIndicator();
|
||||
}
|
||||
|
||||
private checkEnabledForLanguage(): boolean {
|
||||
return this.instantiationService.invokeFunction(isCompletionEnabled) ?? true;
|
||||
}
|
||||
|
||||
protected updateStatusBarIndicator() {
|
||||
if (this.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
void commands.executeCommand(
|
||||
'setContext',
|
||||
'github.copilot.completions.quotaExceeded',
|
||||
this.extensionStatusService.command?.command === CMDQuotaExceeded
|
||||
);
|
||||
const enabled = this.checkEnabledForLanguage();
|
||||
void commands.executeCommand('setContext', 'github.copilot.completions.enabled', enabled);
|
||||
this.item.command = { command: CMDToggleStatusMenuChat, title: 'View Details' };
|
||||
switch (this.extensionStatusService.kind) {
|
||||
case 'Error':
|
||||
this.item.severity = LanguageStatusSeverity.Error;
|
||||
this.item.text = `${Icon.Warning} Completions`;
|
||||
this.item.detail = 'Error';
|
||||
break;
|
||||
case 'Warning':
|
||||
this.item.severity = LanguageStatusSeverity.Warning;
|
||||
this.item.text = `${Icon.Warning} Completions`;
|
||||
this.item.detail = 'Temporary issues';
|
||||
break;
|
||||
case 'Inactive':
|
||||
this.item.severity = LanguageStatusSeverity.Information;
|
||||
this.item.text = `${Icon.Blocked} Completions`;
|
||||
this.item.detail = 'Inactive';
|
||||
break;
|
||||
case 'Normal':
|
||||
this.item.severity = LanguageStatusSeverity.Information;
|
||||
if (!isInlineSuggestEnabled()) {
|
||||
this.item.text = `${Icon.NotConnected} Completions`;
|
||||
this.item.detail = 'VS Code inline suggestions disabled';
|
||||
} else if (!enabled) {
|
||||
this.item.text = `${Icon.NotConnected} Completions`;
|
||||
this.item.detail = 'Disabled';
|
||||
} else {
|
||||
this.item.text = `${Icon.Logo} Completions`;
|
||||
this.item.detail = '';
|
||||
}
|
||||
this.item.command.title = 'Open Menu';
|
||||
break;
|
||||
}
|
||||
this.item.accessibilityInformation = {
|
||||
label: 'Inline Suggestions',
|
||||
};
|
||||
if (this.extensionStatusService.command) {
|
||||
this.item.command = this.extensionStatusService.command;
|
||||
this.item.detail = this.extensionStatusService.message;
|
||||
}
|
||||
}
|
||||
|
||||
dispose() {
|
||||
for (const d of this.disposables) {
|
||||
d.dispose();
|
||||
}
|
||||
this.disposables = [];
|
||||
}
|
||||
|
||||
private isDisposed() {
|
||||
return this.disposables.length === 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { QuickPick, QuickPickItem, QuickPickItemKind, commands, l10n, window } from 'vscode';
|
||||
import { isWeb } from '../../../../../util/vs/base/common/platform';
|
||||
import { IInstantiationService } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { isCompletionEnabled, isInlineSuggestEnabled } from './config';
|
||||
import { CMDCollectDiagnosticsChat, CMDDisableCompletionsChat, CMDEnableCompletionsChat, CMDOpenDocumentationClient, CMDOpenLogsClient, CMDOpenModelPickerClient, CMDOpenPanelClient } from './constants';
|
||||
import { ICompletionsExtensionStatus } from './extensionStatus';
|
||||
import { Icon } from './icon';
|
||||
|
||||
export class CopilotStatusBarPickMenu {
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@ICompletionsExtensionStatus private readonly extensionStatusService: ICompletionsExtensionStatus,
|
||||
) { }
|
||||
|
||||
showStatusMenu() {
|
||||
const quickpickList = window.createQuickPick();
|
||||
quickpickList.placeholder = l10n.t('Select an option');
|
||||
quickpickList.title = l10n.t('Configure Inline Suggestions');
|
||||
quickpickList.items = this.collectQuickPickItems();
|
||||
quickpickList.onDidAccept(() => this.handleItemSelection(quickpickList));
|
||||
quickpickList.show();
|
||||
return quickpickList;
|
||||
}
|
||||
|
||||
async handleItemSelection(quickpickList: QuickPick<QuickPickItem>): Promise<void> {
|
||||
const selection = quickpickList.selectedItems[0];
|
||||
if (selection === undefined) { return; }
|
||||
|
||||
if ('command' in selection) {
|
||||
const commandSelection = selection as CommandQuickItem;
|
||||
await commands.executeCommand(commandSelection.command, ...commandSelection.commandArgs);
|
||||
quickpickList.hide();
|
||||
} else {
|
||||
throw new Error('Unexpected Copilot quick picker selection');
|
||||
}
|
||||
}
|
||||
|
||||
private collectQuickPickItems() {
|
||||
return [
|
||||
this.newStatusItem(),
|
||||
this.newSeparator(),
|
||||
...this.collectLanguageSpecificItems(),
|
||||
this.newKeyboardItem(),
|
||||
this.newSettingsItem(),
|
||||
...this.collectDiagnosticsItems(),
|
||||
this.newOpenLogsItem(),
|
||||
this.newSeparator(),
|
||||
this.newDocsItem(),
|
||||
//this.newForumItem(),
|
||||
];
|
||||
}
|
||||
|
||||
private collectLanguageSpecificItems() {
|
||||
const items: QuickPickItem[] = [];
|
||||
if (!this.hasActiveStatus()) { return items; }
|
||||
|
||||
const editor = window.activeTextEditor;
|
||||
if (!isWeb && editor) { items.push(this.newPanelItem()); }
|
||||
// Always show the model picker even if only one model is available
|
||||
if (!isWeb) { items.push(this.newChangeModelItem()); }
|
||||
if (editor) { items.push(...this.newEnableLanguageItem()); }
|
||||
if (items.length) { items.push(this.newSeparator()); }
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
private hasActiveStatus() {
|
||||
return ['Normal'].includes(this.extensionStatusService.kind);
|
||||
}
|
||||
|
||||
private isCompletionEnabled() {
|
||||
return isInlineSuggestEnabled() && this.instantiationService.invokeFunction(isCompletionEnabled);
|
||||
}
|
||||
|
||||
private newEnableLanguageItem() {
|
||||
const isEnabled = this.isCompletionEnabled();
|
||||
if (isEnabled) {
|
||||
return [this.newCommandItem(l10n.t('Disable Inline Suggestions'), CMDDisableCompletionsChat)];
|
||||
} else if (isEnabled === false) {
|
||||
return [this.newCommandItem(l10n.t('Enable Inline Suggestions'), CMDEnableCompletionsChat)];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private newStatusItem() {
|
||||
let statusText;
|
||||
let statusIcon = Icon.Logo;
|
||||
switch (this.extensionStatusService.kind) {
|
||||
case 'Normal':
|
||||
statusText = l10n.t('Ready');
|
||||
if (isInlineSuggestEnabled() === false) {
|
||||
statusText += ` (${l10n.t('VS Code inline suggestions disabled')})`;
|
||||
} else if (this.instantiationService.invokeFunction(isCompletionEnabled) === false) {
|
||||
statusText += ` (${l10n.t('Disabled')})`;
|
||||
}
|
||||
break;
|
||||
case 'Inactive':
|
||||
statusText = this.extensionStatusService.message || l10n.t('Copilot is currently inactive');
|
||||
statusIcon = Icon.Blocked;
|
||||
break;
|
||||
default:
|
||||
statusText = this.extensionStatusService.message || l10n.t('Copilot has encountered an error');
|
||||
statusIcon = Icon.NotConnected;
|
||||
break;
|
||||
}
|
||||
return this.newCommandItem(`${statusIcon} ${l10n.t('Status')}: ${statusText}`, CMDOpenLogsClient);
|
||||
}
|
||||
|
||||
private newOpenLogsItem() {
|
||||
return this.newCommandItem(l10n.t('Open Logs...'), CMDOpenLogsClient);
|
||||
}
|
||||
|
||||
private collectDiagnosticsItems() {
|
||||
if (isWeb) { return []; }
|
||||
return [this.newCommandItem(l10n.t('Show Diagnostics...'), CMDCollectDiagnosticsChat)];
|
||||
}
|
||||
|
||||
private newKeyboardItem() {
|
||||
return this.newCommandItem(l10n.t('$(keyboard) Edit Keyboard Shortcuts...'), 'workbench.action.openGlobalKeybindings', [
|
||||
'copilot',
|
||||
]);
|
||||
}
|
||||
|
||||
private newSettingsItem() {
|
||||
return this.newCommandItem(l10n.t('$(settings-gear) Edit Settings...'), 'workbench.action.openSettings', [
|
||||
'GitHub Copilot',
|
||||
]);
|
||||
}
|
||||
|
||||
private newPanelItem() {
|
||||
return this.newCommandItem(l10n.t('Open Completions Panel...'), CMDOpenPanelClient);
|
||||
}
|
||||
|
||||
private newChangeModelItem() {
|
||||
return this.newCommandItem(l10n.t('Change Completions Model...'), CMDOpenModelPickerClient);
|
||||
}
|
||||
|
||||
private newDocsItem() {
|
||||
return this.newCommandItem(
|
||||
l10n.t('$(remote-explorer-documentation) View Copilot Documentation...'),
|
||||
CMDOpenDocumentationClient
|
||||
);
|
||||
}
|
||||
|
||||
private newCommandItem(label: string, command: string, commandArgs?: string[]): CommandQuickItem {
|
||||
return new CommandQuickItem(label, command, commandArgs || []);
|
||||
}
|
||||
|
||||
private newSeparator(): QuickPickItem {
|
||||
return {
|
||||
label: '',
|
||||
kind: QuickPickItemKind.Separator,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class CommandQuickItem implements QuickPickItem {
|
||||
constructor(
|
||||
readonly label: string,
|
||||
readonly command: string,
|
||||
readonly commandArgs: string[]
|
||||
) { }
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { commands, Disposable } from 'vscode';
|
||||
import { IDisposable } from '../../../../../util/vs/base/common/lifecycle';
|
||||
import { IInstantiationService, type ServicesAccessor } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { handleException } from '../../lib/src/defaultHandlers';
|
||||
import { Logger } from '../../lib/src/logger';
|
||||
|
||||
function exception(accessor: ServicesAccessor, error: unknown, origin: string, logger?: Logger) {
|
||||
if (error instanceof Error && error.name === 'Canceled') {
|
||||
// these are VS Code cancellations
|
||||
return;
|
||||
}
|
||||
if (error instanceof Error && error.name === 'CodeExpectedError') {
|
||||
// expected errors from VS Code
|
||||
return;
|
||||
}
|
||||
handleException(accessor, error, origin, logger);
|
||||
}
|
||||
|
||||
export function registerCommand(accessor: ServicesAccessor, command: string, fn: (...args: unknown[]) => unknown): Disposable {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
try {
|
||||
const disposable = commands.registerCommand(command, async (...args: unknown[]) => {
|
||||
try {
|
||||
await fn(...args);
|
||||
} catch (error) {
|
||||
// Pass in the command string as the origin
|
||||
instantiationService.invokeFunction(exception, error, command);
|
||||
}
|
||||
});
|
||||
return disposable;
|
||||
} catch (error) {
|
||||
console.error(`Error registering command ${command}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrapper that handles errors and cleans up the command on extension deactivation
|
||||
export function registerCommandWrapper(accessor: ServicesAccessor, command: string, fn: (...args: unknown[]) => unknown): IDisposable {
|
||||
return registerCommand(accessor, command, fn);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { ConfigKey, ConfigKeyType, DefaultsOnlyConfigProvider, InMemoryConfigProvider } from '../../../lib/src/config';
|
||||
import { VSCodeConfigProvider } from '../config';
|
||||
|
||||
/**
|
||||
* Provides the default configurations, except lets through the configured value
|
||||
* of test-only settings like the proxy override URL.
|
||||
*/
|
||||
export class ExtensionTestConfigProvider extends InMemoryConfigProvider {
|
||||
private readonly vscConfigProvider = new VSCodeConfigProvider();
|
||||
|
||||
constructor() {
|
||||
super(new DefaultsOnlyConfigProvider());
|
||||
}
|
||||
|
||||
override getConfig<T>(key: ConfigKeyType): T {
|
||||
if (key === ConfigKey.DebugTestOverrideProxyUrl) {
|
||||
return this.vscConfigProvider.getConfig<T>(key);
|
||||
}
|
||||
return super.getConfig(key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import { SyncDescriptor } from '../../../../../../util/vs/platform/instantiation/common/descriptors';
|
||||
import { createExtensionTestingServices } from '../../../../../test/vscode-node/services';
|
||||
import { ICompletionsEditorAndPluginInfo } from '../../../lib/src/config';
|
||||
import { ICompletionsFileSystemService } from '../../../lib/src/fileSystem';
|
||||
import { ICompletionsFetcherService } from '../../../lib/src/networking';
|
||||
import { _createBaselineContext } from '../../../lib/src/test/context';
|
||||
import { StaticFetcher } from '../../../lib/src/test/fetcher';
|
||||
import { ICompletionsTextDocumentManagerService } from '../../../lib/src/textDocumentManager';
|
||||
import { VSCodeEditorInfo } from '../config';
|
||||
import { CopilotExtensionStatus, ICompletionsExtensionStatus } from '../extensionStatus';
|
||||
import { extensionFileSystem } from '../fileSystem';
|
||||
import { ExtensionTextDocumentManager } from '../textDocumentManager';
|
||||
import { ExtensionTestConfigProvider } from './config';
|
||||
|
||||
/**
|
||||
* A default context for VSCode extension testing, building on general one in `lib`.
|
||||
* Only includes items that are needed for almost all extension tests.
|
||||
*/
|
||||
export function createExtensionTestingContext() {
|
||||
let serviceCollection = createExtensionTestingServices();
|
||||
serviceCollection = _createBaselineContext(serviceCollection, new ExtensionTestConfigProvider());
|
||||
|
||||
serviceCollection.define(ICompletionsFetcherService, new StaticFetcher());
|
||||
serviceCollection.define(ICompletionsEditorAndPluginInfo, new VSCodeEditorInfo());
|
||||
serviceCollection.define(ICompletionsTextDocumentManagerService, new SyncDescriptor(ExtensionTextDocumentManager));
|
||||
serviceCollection.define(ICompletionsFileSystemService, extensionFileSystem);
|
||||
serviceCollection.define(ICompletionsExtensionStatus, new CopilotExtensionStatus());
|
||||
|
||||
return serviceCollection;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import assert from 'assert';
|
||||
import sinon from 'sinon';
|
||||
import { commands, env } from 'vscode';
|
||||
import { SyncDescriptor } from '../../../../../../util/vs/platform/instantiation/common/descriptors';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { AvailableModelsManager, ICompletionsModelManagerService } from '../../../lib/src/openai/model';
|
||||
import { ModelPickerManager } from './../modelPicker';
|
||||
import { createExtensionTestingContext } from './context';
|
||||
|
||||
suite('ModelPickerManager unit tests', function () {
|
||||
let accessor: ServicesAccessor;
|
||||
let modelPicker: ModelPickerManager;
|
||||
let availableModelsManager: ICompletionsModelManagerService;
|
||||
let sandbox: sinon.SinonSandbox;
|
||||
|
||||
// Couple of fake models to use in our tests.
|
||||
const fakeModels = [
|
||||
{
|
||||
modelId: 'model-a',
|
||||
label: 'Model A',
|
||||
type: 'model',
|
||||
alwaysShow: true,
|
||||
preview: false,
|
||||
tokenizer: 'o200k_base',
|
||||
},
|
||||
{
|
||||
modelId: 'model-b',
|
||||
label: 'Model B',
|
||||
type: 'model',
|
||||
alwaysShow: true,
|
||||
preview: false,
|
||||
tokenizer: 'cl100k_base',
|
||||
},
|
||||
];
|
||||
|
||||
setup(function () {
|
||||
sandbox = sinon.createSandbox();
|
||||
// Create our test context, and stub the AvailableModelsManager to return our fake models.
|
||||
const serviceCollection = createExtensionTestingContext();
|
||||
serviceCollection.define(ICompletionsModelManagerService, new SyncDescriptor(AvailableModelsManager, [true]));
|
||||
accessor = serviceCollection.createTestingAccessor();
|
||||
|
||||
availableModelsManager = accessor.get(ICompletionsModelManagerService);
|
||||
sandbox.stub(availableModelsManager, 'getGenericCompletionModels').returns(fakeModels);
|
||||
modelPicker = accessor.get(IInstantiationService).createInstance(ModelPickerManager);
|
||||
});
|
||||
|
||||
teardown(async function () {
|
||||
// Make sure to close any open quick pick dialogs after each test.
|
||||
await commands.executeCommand('workbench.action.closeQuickOpen');
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
test('showModelPicker returns correct items', function () {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
|
||||
modelPicker = instantiationService.createInstance(ModelPickerManager);
|
||||
|
||||
const quickPick = modelPicker.showModelPicker();
|
||||
|
||||
// Check that we have the correct number of items
|
||||
// The items should include the two fake models, a separator, and a learn more item.
|
||||
assert(quickPick.items.length === 4, quickPick.items.length.toString());
|
||||
assert.strictEqual(quickPick.items[0].modelId, 'model-a');
|
||||
assert.strictEqual(quickPick.items[1].modelId, 'model-b');
|
||||
assert.strictEqual(quickPick.items[2].type, 'separator');
|
||||
assert.strictEqual(quickPick.items[3].type, 'learn-more');
|
||||
});
|
||||
|
||||
test('selecting a model updates user selection', async function () {
|
||||
// Stub out setting model
|
||||
const setModelStub = sandbox.stub(modelPicker, 'setUserSelectedCompletionModel').resolves();
|
||||
|
||||
const quickPick = modelPicker.showModelPicker();
|
||||
|
||||
const secondItem = quickPick.items[1];
|
||||
assert(secondItem !== undefined, 'model picker should have a model-b second item.');
|
||||
|
||||
// Fake selecting the second item
|
||||
quickPick.activeItems = [secondItem];
|
||||
await modelPicker.handleModelSelection(quickPick);
|
||||
|
||||
// Test that we updated the user configuration with the selected model
|
||||
assert(setModelStub.calledOnce, 'setUserSelectedCompletionModel should be called once');
|
||||
assert.strictEqual(setModelStub.firstCall.args[0], secondItem.modelId);
|
||||
});
|
||||
|
||||
test('selecting the learn more link tries to open the learn more url', async function () {
|
||||
// Stub openExternal
|
||||
const openUrlStub = sandbox.stub(env, 'openExternal').resolves();
|
||||
|
||||
const quickPick = modelPicker.showModelPicker();
|
||||
|
||||
const learnMoreItem = quickPick.items[3];
|
||||
assert(learnMoreItem !== undefined, 'model picker should have a learn more item.');
|
||||
|
||||
// Fake selecting the learn more item
|
||||
quickPick.activeItems = [learnMoreItem];
|
||||
await modelPicker.handleModelSelection(quickPick);
|
||||
|
||||
// Test that we opened the learn more URL
|
||||
assert(openUrlStub.calledOnce, 'openUrl should be called once');
|
||||
assert.strictEqual(
|
||||
openUrlStub.firstCall.args[0].toString(),
|
||||
'https://aka.ms/CopilotCompletionsModelPickerLearnMore'
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,123 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { window, workspace } from 'vscode';
|
||||
import { detectLanguage } from '../../lib/src/language/languageDetection';
|
||||
import { CopilotTextDocument, INotebookCell, INotebookDocument, ITextDocument } from '../../lib/src/textDocument';
|
||||
import { TextDocumentManager, WorkspaceFoldersChangeEvent } from '../../lib/src/textDocumentManager';
|
||||
import { transformEvent } from '../../lib/src/util/event';
|
||||
import { normalizeUri } from '../../lib/src/util/uri';
|
||||
|
||||
// List of document URI schemes that avoid ghost text suggestions
|
||||
const ignoreUriSchemes = new Set([
|
||||
'output', // vscode output pane (important: avoids infinite log loop)
|
||||
'search-editor', // search results virtual document
|
||||
'comment', // very little context available and suggestions are often bad
|
||||
'git', // virtual file tracked by git
|
||||
'chat-editing-snapshot-text-model', // VS Code Chat temporary editing snapshot
|
||||
]);
|
||||
|
||||
export function wrapDoc(doc: vscode.TextDocument): ITextDocument | undefined {
|
||||
if (ignoreUriSchemes.has(doc.uri.scheme)) {
|
||||
return;
|
||||
}
|
||||
let text: string;
|
||||
try {
|
||||
text = doc.getText();
|
||||
} catch (e) {
|
||||
// "Invalid string length", it's too big to fit in a string
|
||||
if (e instanceof RangeError) {
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
const languageId = detectLanguage({ uri: doc.uri.toString(), languageId: doc.languageId });
|
||||
return CopilotTextDocument.create(doc.uri.toString(), doc.languageId, doc.version, text, languageId);
|
||||
}
|
||||
|
||||
export class ExtensionTextDocumentManager extends TextDocumentManager {
|
||||
override onDidFocusTextDocument = transformEvent(window.onDidChangeActiveTextEditor, event => {
|
||||
return { document: event && { uri: event.document.uri.toString() } };
|
||||
});
|
||||
|
||||
override onDidChangeTextDocument = transformEvent(workspace.onDidChangeTextDocument, e => {
|
||||
const document = wrapDoc(e.document);
|
||||
return document && { document, contentChanges: e.contentChanges };
|
||||
});
|
||||
|
||||
override onDidOpenTextDocument = transformEvent(workspace.onDidOpenTextDocument, e => {
|
||||
// use wrapDoc() to handle the "Invalid string length" case
|
||||
const text = wrapDoc(e)?.getText();
|
||||
if (text === undefined) {
|
||||
return;
|
||||
}
|
||||
return { document: { uri: e.uri.toString(), languageId: e.languageId, version: e.version, text } };
|
||||
});
|
||||
|
||||
override onDidCloseTextDocument = transformEvent(workspace.onDidCloseTextDocument, e => {
|
||||
return { document: { uri: normalizeUri(e.uri.toString()) } };
|
||||
});
|
||||
|
||||
override onDidChangeWorkspaceFolders = transformEvent(
|
||||
workspace.onDidChangeWorkspaceFolders,
|
||||
(e): WorkspaceFoldersChangeEvent => {
|
||||
return {
|
||||
workspaceFolders: this.getWorkspaceFolders(),
|
||||
added: e.added.map(f => ({ uri: f.uri.toString(), name: f.name })),
|
||||
removed: e.removed.map(f => ({ uri: f.uri.toString(), name: f.name })),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
getTextDocumentsUnsafe(): ITextDocument[] {
|
||||
const docs: ITextDocument[] = [];
|
||||
for (const vscodeDoc of workspace.textDocuments) {
|
||||
const doc = wrapDoc(vscodeDoc);
|
||||
if (doc) {
|
||||
docs.push(doc);
|
||||
}
|
||||
}
|
||||
return docs;
|
||||
}
|
||||
|
||||
findNotebook(doc: { uri: string }): INotebookDocument | undefined {
|
||||
for (const notebook of workspace.notebookDocuments) {
|
||||
if (notebook.getCells().some(cell => cell.document.uri.toString() === doc.uri.toString())) {
|
||||
return {
|
||||
getCells: () => notebook.getCells().map(cell => this.wrapCell(cell)),
|
||||
getCellFor: ({ uri }: { uri: string }) => {
|
||||
const cell = notebook.getCells().find(cell => cell.document.uri.toString() === uri.toString());
|
||||
return cell ? this.wrapCell(cell) : undefined;
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wrapCell(cell: vscode.NotebookCell): INotebookCell {
|
||||
return {
|
||||
...cell,
|
||||
get document(): ITextDocument {
|
||||
return CopilotTextDocument.create(
|
||||
cell.document.uri.toString(),
|
||||
cell.document.languageId,
|
||||
cell.document.version,
|
||||
cell.document.getText(),
|
||||
// use the original language id as cells have no metadata to leverage for language detection
|
||||
cell.document.languageId
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
getWorkspaceFolders() {
|
||||
return (
|
||||
workspace.workspaceFolders?.map(f => {
|
||||
return { uri: f.uri.toString(), name: f.name };
|
||||
}) ?? []
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
CancellationToken,
|
||||
InlineCompletionContext,
|
||||
InlineCompletionEndOfLifeReason,
|
||||
InlineCompletionItemProvider,
|
||||
InlineCompletionList,
|
||||
InlineCompletionTriggerKind,
|
||||
PartialAcceptInfo,
|
||||
Position,
|
||||
TextDocument,
|
||||
workspace
|
||||
} from 'vscode';
|
||||
import { Disposable } from '../../../../../util/vs/base/common/lifecycle';
|
||||
import { LineEdit } from '../../../../../util/vs/editor/common/core/edits/lineEdit';
|
||||
import { TextEdit, TextReplacement } from '../../../../../util/vs/editor/common/core/edits/textEdit';
|
||||
import { Range } from '../../../../../util/vs/editor/common/core/range';
|
||||
import { LineBasedText } from '../../../../../util/vs/editor/common/core/text/abstractText';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../../util/vs/platform/instantiation/common/instantiation';
|
||||
import { InlineEditLogger } from '../../../../inlineEdits/vscode-node/parts/inlineEditLogger';
|
||||
import { GhostTextContext } from '../../../common/ghostTextContext';
|
||||
import { ICompletionsTelemetryService } from '../../bridge/src/completionsTelemetryServiceBridge';
|
||||
import { BuildInfo } from '../../lib/src/config';
|
||||
import { CopilotConfigPrefix } from '../../lib/src/constants';
|
||||
import { handleException } from '../../lib/src/defaultHandlers';
|
||||
import { Logger } from '../../lib/src/logger';
|
||||
import { isCompletionEnabledForDocument } from './config';
|
||||
import { CopilotCompletionFeedbackTracker, sendCompletionFeedbackCommand } from './copilotCompletionFeedbackTracker';
|
||||
import { ICompletionsExtensionStatus } from './extensionStatus';
|
||||
import { GhostTextCompletionItem, GhostTextCompletionList, GhostTextProvider } from './ghostText/ghostTextProvider';
|
||||
|
||||
const logger = new Logger('inlineCompletionItemProvider');
|
||||
|
||||
function quickSuggestionsDisabled() {
|
||||
const qs = workspace.getConfiguration('editor.quickSuggestions');
|
||||
return qs.get('other') !== 'on' && qs.get('comments') !== 'on' && qs.get('strings') !== 'on';
|
||||
}
|
||||
|
||||
export function exception(accessor: ServicesAccessor, error: unknown, origin: string, logger?: Logger) {
|
||||
if (error instanceof Error && error.name === 'Canceled') {
|
||||
// these are VS Code cancellations
|
||||
return;
|
||||
}
|
||||
if (error instanceof Error && error.name === 'CodeExpectedError') {
|
||||
// expected errors from VS Code
|
||||
return;
|
||||
}
|
||||
const telemetryService = accessor.get(ICompletionsTelemetryService);
|
||||
telemetryService.sendGHTelemetryException(error, 'codeUnification.completions.exception');
|
||||
handleException(accessor, error, origin, logger);
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export class CopilotInlineCompletionItemProvider extends Disposable implements InlineCompletionItemProvider {
|
||||
private readonly copilotCompletionFeedbackTracker: CopilotCompletionFeedbackTracker;
|
||||
private readonly ghostTextProvider: GhostTextProvider;
|
||||
private readonly inlineEditLogger: InlineEditLogger;
|
||||
|
||||
public onDidChange = undefined;
|
||||
public handleListEndOfLifetime: InlineCompletionItemProvider['handleListEndOfLifetime'] = undefined;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@ICompletionsTelemetryService private readonly telemetryService: ICompletionsTelemetryService,
|
||||
@ICompletionsExtensionStatus private readonly extensionStatusService: ICompletionsExtensionStatus,
|
||||
) {
|
||||
super();
|
||||
this.copilotCompletionFeedbackTracker = this._register(this.instantiationService.createInstance(CopilotCompletionFeedbackTracker));
|
||||
this.ghostTextProvider = this.instantiationService.createInstance(GhostTextProvider);
|
||||
this.inlineEditLogger = this.instantiationService.createInstance(InlineEditLogger);
|
||||
}
|
||||
|
||||
async provideInlineCompletionItems(
|
||||
doc: TextDocument,
|
||||
position: Position,
|
||||
context: InlineCompletionContext,
|
||||
token: CancellationToken
|
||||
): Promise<GhostTextCompletionList | undefined> {
|
||||
const logContext = new GhostTextContext(doc.uri.toString(), doc.version, context);
|
||||
try {
|
||||
return await this._provideInlineCompletionItems(doc, position, context, logContext, token);
|
||||
} catch (e) {
|
||||
logContext.setError(e);
|
||||
this.telemetryService.sendGHTelemetryException(e, 'codeUnification.completions.exception');
|
||||
} finally {
|
||||
this.inlineEditLogger.add(logContext);
|
||||
}
|
||||
}
|
||||
|
||||
private async _provideInlineCompletionItems(
|
||||
doc: TextDocument,
|
||||
position: Position,
|
||||
context: InlineCompletionContext,
|
||||
logContext: GhostTextContext,
|
||||
token: CancellationToken
|
||||
): Promise<GhostTextCompletionList | undefined> {
|
||||
if (context.triggerKind === InlineCompletionTriggerKind.Automatic) {
|
||||
if (!this.instantiationService.invokeFunction(isCompletionEnabledForDocument, doc)) {
|
||||
return;
|
||||
}
|
||||
if (this.extensionStatusService.kind === 'Error') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const copilotConfig = workspace.getConfiguration(CopilotConfigPrefix);
|
||||
// Constraining the generated inline completion to match selectedCompletionInfo sandbags Copilot pretty hard, as
|
||||
// typically it's just the first entry in the list alphabetically. But if we generate a result that doesn't
|
||||
// match it, VS Code won't show it to the user unless the completion dropdown is dismissed. Historically we've
|
||||
// chosen to favor completion quality, but this option allows opting into or out of generating a completion that
|
||||
// VS Code will actually show.
|
||||
if (!copilotConfig.get('respectSelectedCompletionInfo', quickSuggestionsDisabled() || BuildInfo.isPreRelease())) {
|
||||
context = { ...context, selectedCompletionInfo: undefined };
|
||||
}
|
||||
|
||||
try {
|
||||
let items = await this.ghostTextProvider.provideInlineCompletionItems(doc, position, context, token);
|
||||
|
||||
if (!items) {
|
||||
if (token.isCancellationRequested) {
|
||||
logContext.setIsSkipped();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If the language client provides a list of items, we want to add the send feedback command to it.
|
||||
if (Array.isArray(items)) {
|
||||
items = { items };
|
||||
}
|
||||
|
||||
this.logSuggestion(logContext, doc, items);
|
||||
|
||||
return {
|
||||
...items,
|
||||
commands: [sendCompletionFeedbackCommand],
|
||||
};
|
||||
} catch (e) {
|
||||
this.instantiationService.invokeFunction(exception, e, '._provideInlineCompletionItems', logger);
|
||||
logContext.setError(e);
|
||||
}
|
||||
}
|
||||
|
||||
handleDidShowCompletionItem(item: GhostTextCompletionItem) {
|
||||
try {
|
||||
this.copilotCompletionFeedbackTracker.trackItem(item);
|
||||
return this.ghostTextProvider.handleDidShowCompletionItem(item);
|
||||
} catch (e) {
|
||||
this.instantiationService.invokeFunction(exception, e, '.handleDidShowCompletionItem', logger);
|
||||
}
|
||||
}
|
||||
|
||||
handleDidPartiallyAcceptCompletionItem(
|
||||
item: GhostTextCompletionItem,
|
||||
acceptedLengthOrInfo: number | PartialAcceptInfo
|
||||
) {
|
||||
try {
|
||||
return this.ghostTextProvider.handleDidPartiallyAcceptCompletionItem(item, acceptedLengthOrInfo);
|
||||
} catch (e) {
|
||||
this.instantiationService.invokeFunction(exception, e, '.handleDidPartiallyAcceptCompletionItem', logger);
|
||||
}
|
||||
}
|
||||
|
||||
handleEndOfLifetime(completionItem: GhostTextCompletionItem, reason: InlineCompletionEndOfLifeReason) {
|
||||
try {
|
||||
return this.ghostTextProvider.handleEndOfLifetime(completionItem, reason);
|
||||
} catch (e) {
|
||||
this.instantiationService.invokeFunction(exception, e, '.handleEndOfLifetime', logger);
|
||||
}
|
||||
}
|
||||
|
||||
private logSuggestion(
|
||||
logContext: GhostTextContext,
|
||||
doc: TextDocument,
|
||||
items: InlineCompletionList
|
||||
) {
|
||||
if (items.items.length === 0) {
|
||||
logContext.markAsNoSuggestions();
|
||||
logContext.addLog('No inline completion items provided');
|
||||
return;
|
||||
}
|
||||
const firstItem = items.items[0];
|
||||
if (!firstItem.range) {
|
||||
logContext.addLog('Inline completion item has no range');
|
||||
return;
|
||||
}
|
||||
if (typeof firstItem.insertText !== 'string') {
|
||||
logContext.addLog('Inline completion item has non-string insertText');
|
||||
return;
|
||||
}
|
||||
|
||||
const text = new LineBasedText(lineNumber => doc.lineAt(lineNumber - 1).text, doc.lineCount);
|
||||
|
||||
const lineEdit = LineEdit.fromTextEdit(
|
||||
new TextEdit(
|
||||
[new TextReplacement(
|
||||
new Range(firstItem.range.start.line + 1, firstItem.range.start.character + 1, firstItem.range.end.line + 1, firstItem.range.end.character + 1),
|
||||
firstItem.insertText,
|
||||
)],
|
||||
),
|
||||
text
|
||||
);
|
||||
|
||||
const patch = lineEdit.humanReadablePatch(text.getLines());
|
||||
|
||||
logContext.setResult(patch);
|
||||
}
|
||||
}
|
||||
75
completions-sample-code/vscode-node/extension/test/run.js
Normal file
75
completions-sample-code/vscode-node/extension/test/run.js
Normal file
@@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
require('tsx/cjs');
|
||||
|
||||
const { globSync } = require('glob');
|
||||
const Mocha = require('mocha');
|
||||
const path = require('path');
|
||||
const dotenv = require('dotenv');
|
||||
const envfile = path.join(__dirname, '../../../../../../.env');
|
||||
dotenv.config({ path: envfile });
|
||||
|
||||
function run() {
|
||||
const projectRoot = path.resolve(__dirname, '../..');
|
||||
const mochaOptions = {
|
||||
ui: 'tdd',
|
||||
color: !process.env.NO_COLOR && process.env.TERM !== 'dumb',
|
||||
reporter: 'mocha-multi-reporters',
|
||||
reporterOptions: {
|
||||
reporterEnabled: 'spec',
|
||||
},
|
||||
};
|
||||
if (process.env.MOCHA_GREP) {
|
||||
mochaOptions.grep = process.env.MOCHA_GREP;
|
||||
}
|
||||
if (process.env.CI) {
|
||||
mochaOptions.forbidOnly = true;
|
||||
mochaOptions.retries = 2;
|
||||
mochaOptions.reporterOptions.reporterEnabled += ', mocha-junit-reporter';
|
||||
mochaOptions.reporterOptions.mochaJunitReporterReporterOptions = {
|
||||
testCaseSwitchClassnameAndName: true,
|
||||
testsuitesTitle: 'Copilot VS Code Extension Tests',
|
||||
mochaFile: path.resolve(projectRoot, 'test-results-Extension.xml'),
|
||||
};
|
||||
}
|
||||
if (process.env.GITHUB_EVENT_NAME === 'merge_group') {
|
||||
mochaOptions.retries = 3;
|
||||
}
|
||||
|
||||
// Create the mocha test
|
||||
const mocha = new Mocha(mochaOptions);
|
||||
|
||||
let fileCount = 0;
|
||||
(process.env.MOCHA_FILES || [
|
||||
path.resolve(projectRoot, 'lib/src/**/*.test.{ts,tsx}'),
|
||||
path.resolve(projectRoot, 'extension/src/**/*.test.{ts,tsx}')
|
||||
].join('\n')).split('\n').forEach(f => {
|
||||
globSync(f, { windowsPathsNoEscape: true }).forEach(f => {
|
||||
fileCount++;
|
||||
mocha.addFile(f);
|
||||
});
|
||||
});
|
||||
if (!fileCount) {
|
||||
throw new Error('No tests to run');
|
||||
}
|
||||
|
||||
return new Promise((c, e) => {
|
||||
try {
|
||||
// Run the mocha test
|
||||
mocha.run(failures => {
|
||||
if (failures > 0) {
|
||||
e(new Error(`${failures} tests failed.`));
|
||||
} else {
|
||||
c();
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
e(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { run };
|
||||
@@ -0,0 +1,79 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { promises as fs } from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import yargs from 'yargs';
|
||||
import { hideBin } from 'yargs/helpers';
|
||||
|
||||
import { runTests } from '@vscode/test-electron';
|
||||
|
||||
async function main() {
|
||||
const tempdir = await fs.mkdtemp(os.tmpdir() + '/copilot-extension-test-');
|
||||
|
||||
let exitCode;
|
||||
try {
|
||||
// The folder containing the Extension Manifest package.json
|
||||
// Passed to `--extensionDevelopmentPath`
|
||||
const extensionDevelopmentPath = path.resolve(__dirname, '../..');
|
||||
|
||||
// The path to the extension test script (must be javascript)
|
||||
// Passed to --extensionTestsPath
|
||||
const extensionTestsPath = path.resolve(__dirname, './run');
|
||||
|
||||
const launchArgs = [];
|
||||
// Disable other extensions while testing,
|
||||
launchArgs.push('--disable-extensions');
|
||||
|
||||
// use a temporary folder so we can run multiple instances of the same VS Code together
|
||||
// see https://github.com/microsoft/vscode/issues/137678
|
||||
launchArgs.push('--user-data-dir', tempdir);
|
||||
|
||||
const argv = await yargs(hideBin(process.argv))
|
||||
.options({
|
||||
stable: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
grep: {
|
||||
alias: 'g',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
.parse();
|
||||
const version = argv.stable ? 'stable' : 'insiders';
|
||||
|
||||
const extensionTestsEnv: typeof process.env = {};
|
||||
// Pass arguments to mocha by environment variables
|
||||
if (argv.grep) { extensionTestsEnv.MOCHA_GREP = argv.grep; }
|
||||
if (argv._.length > 0) { extensionTestsEnv.MOCHA_FILES = argv._.join('\n'); }
|
||||
if (!process.stdout.isTTY) { extensionTestsEnv.NO_COLOR = 'true'; }
|
||||
const workspaceFolder = await fs.mkdtemp(path.join(os.tmpdir(), 'copilot-extension-test-'));
|
||||
launchArgs.push(workspaceFolder);
|
||||
|
||||
extensionTestsEnv.CORETEST = 'true';
|
||||
//@dbaeumer This can be removed as soon as we have the cache handle CORETEST
|
||||
extensionTestsEnv.VITEST = 'true';
|
||||
|
||||
// Download VS Code, unzip it and run the integration test
|
||||
exitCode = await runTests({
|
||||
version,
|
||||
extensionDevelopmentPath,
|
||||
extensionTestsPath,
|
||||
launchArgs,
|
||||
extensionTestsEnv,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Failed to run tests', err);
|
||||
exitCode = 1;
|
||||
} finally {
|
||||
await fs.rm(tempdir, { recursive: true });
|
||||
}
|
||||
process.exit(exitCode);
|
||||
}
|
||||
|
||||
void main();
|
||||
Reference in New Issue
Block a user