Merge branch 'main' into tyriar/34103_241101

This commit is contained in:
Daniel Imms
2024-11-04 09:16:33 -08:00
committed by GitHub
13 changed files with 118 additions and 67 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "$REPO=repo:microsoft/vscode\n$MILESTONE=milestone:\"October 2024\""
"value": "$REPO=repo:microsoft/vscode\n$MILESTONE=milestone:\"November 2024\""
},
{
"kind": 1,
+1 -1
View File
@@ -7,7 +7,7 @@
{
"kind": 2,
"language": "github-issues",
"value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n// current milestone name\n$MILESTONE=milestone:\"October 2024\"\n"
"value": "// list of repos we work in\n$REPOS=repo:microsoft/lsprotocol repo:microsoft/monaco-editor repo:microsoft/vscode repo:microsoft/vscode-anycode repo:microsoft/vscode-autopep8 repo:microsoft/vscode-black-formatter repo:microsoft/vscode-copilot repo:microsoft/vscode-copilot-release repo:microsoft/vscode-dev repo:microsoft/vscode-dev-chrome-launcher repo:microsoft/vscode-emmet-helper repo:microsoft/vscode-extension-telemetry repo:microsoft/vscode-flake8 repo:microsoft/vscode-github-issue-notebooks repo:microsoft/vscode-hexeditor repo:microsoft/vscode-internalbacklog repo:microsoft/vscode-isort repo:microsoft/vscode-js-debug repo:microsoft/vscode-jupyter repo:microsoft/vscode-jupyter-internal repo:microsoft/vscode-l10n repo:microsoft/vscode-livepreview repo:microsoft/vscode-markdown-languageservice repo:microsoft/vscode-markdown-tm-grammar repo:microsoft/vscode-mypy repo:microsoft/vscode-pull-request-github repo:microsoft/vscode-pylint repo:microsoft/vscode-python repo:microsoft/vscode-python-debugger repo:microsoft/vscode-python-tools-extension-template repo:microsoft/vscode-references-view repo:microsoft/vscode-remote-release repo:microsoft/vscode-remote-repositories-github repo:microsoft/vscode-remote-tunnels repo:microsoft/vscode-remotehub repo:microsoft/vscode-settings-sync-server repo:microsoft/vscode-unpkg repo:microsoft/vscode-vsce\n\n// current milestone name\n$MILESTONE=milestone:\"November 2024\"\n"
},
{
"kind": 1,
@@ -5,6 +5,7 @@
import { getActiveWindow } from '../../../../base/browser/dom.js';
import { CharCode } from '../../../../base/common/charCode.js';
import { BugIndicatingError } from '../../../../base/common/errors.js';
import { Emitter, Event } from '../../../../base/common/event.js';
import { Disposable, dispose, MutableDisposable, toDisposable } from '../../../../base/common/lifecycle.js';
import { ThreeKeyMap } from '../../../../base/common/map.js';
@@ -22,7 +23,7 @@ export interface ITextureAtlasOptions {
}
export class TextureAtlas extends Disposable {
private _colorMap!: string[];
private _colorMap?: string[];
private readonly _warmUpTask: MutableDisposable<IdleTaskQueue> = this._register(new MutableDisposable());
private readonly _warmedUpRasterizers = new Set<number>();
private readonly _allocatorType: AllocatorType;
@@ -60,7 +61,9 @@ export class TextureAtlas extends Disposable {
this._allocatorType = options?.allocatorType ?? 'slab';
this._register(Event.runAndSubscribe(this._themeService.onDidColorThemeChange, () => {
// TODO: Clear entire atlas on theme change
if (this._colorMap) {
this.clear();
}
this._colorMap = this._themeService.getColorTheme().tokenColorMap;
}));
@@ -147,13 +150,17 @@ export class TextureAtlas extends Disposable {
* is distrubuted over multiple idle callbacks to avoid blocking the main thread.
*/
private _warmUpAtlas(rasterizer: IGlyphRasterizer): void {
const colorMap = this._colorMap;
if (!colorMap) {
throw new BugIndicatingError('Cannot warm atlas without color map');
}
this._warmUpTask.value?.clear();
const taskQueue = this._warmUpTask.value = new IdleTaskQueue();
// Warm up using roughly the larger glyphs first to help optimize atlas allocation
// A-Z
for (let code = CharCode.A; code <= CharCode.Z; code++) {
taskQueue.enqueue(() => {
for (const fgColor of this._colorMap.keys()) {
for (const fgColor of colorMap.keys()) {
this.getGlyph(rasterizer, String.fromCharCode(code), (fgColor << MetadataConsts.FOREGROUND_OFFSET) & MetadataConsts.FOREGROUND_MASK);
}
});
@@ -161,7 +168,7 @@ export class TextureAtlas extends Disposable {
// a-z
for (let code = CharCode.a; code <= CharCode.z; code++) {
taskQueue.enqueue(() => {
for (const fgColor of this._colorMap.keys()) {
for (const fgColor of colorMap.keys()) {
this.getGlyph(rasterizer, String.fromCharCode(code), (fgColor << MetadataConsts.FOREGROUND_OFFSET) & MetadataConsts.FOREGROUND_MASK);
}
});
@@ -169,7 +176,7 @@ export class TextureAtlas extends Disposable {
// Remaining ascii
for (let code = CharCode.ExclamationMark; code <= CharCode.Tilde; code++) {
taskQueue.enqueue(() => {
for (const fgColor of this._colorMap.keys()) {
for (const fgColor of colorMap.keys()) {
this.getGlyph(rasterizer, String.fromCharCode(code), (fgColor << MetadataConsts.FOREGROUND_OFFSET) & MetadataConsts.FOREGROUND_MASK);
}
});
@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from '../../../../base/common/event.js';
import { Disposable, toDisposable } from '../../../../base/common/lifecycle.js';
import { ThreeKeyMap } from '../../../../base/common/map.js';
import { ILogService, LogLevel } from '../../../../platform/log/common/log.js';
@@ -46,11 +45,12 @@ export class TextureAtlasPage extends Disposable implements IReadableTextureAtla
pageSize: number,
allocatorType: AllocatorType,
@ILogService private readonly _logService: ILogService,
@IThemeService private readonly _themeService: IThemeService,
@IThemeService themeService: IThemeService,
) {
super();
this._canvas = new OffscreenCanvas(pageSize, pageSize);
this._colorMap = themeService.getColorTheme().tokenColorMap;
switch (allocatorType) {
case 'shelf': this._allocator = new TextureAtlasShelfAllocator(this._canvas, textureIndex); break;
@@ -58,11 +58,6 @@ export class TextureAtlasPage extends Disposable implements IReadableTextureAtla
default: this._allocator = allocatorType(this._canvas, textureIndex); break;
}
this._register(Event.runAndSubscribe(this._themeService.onDidColorThemeChange, () => {
// TODO: Clear entire atlas on theme change
this._colorMap = this._themeService.getColorTheme().tokenColorMap;
}));
// Reduce impact of a memory leak if this object is not released
this._register(toDisposable(() => {
this._canvas.width = 1;
@@ -40,6 +40,7 @@ export class ViewLinesGpu extends ViewPart implements IViewLines {
private readonly canvas: HTMLCanvasElement;
private _initViewportData?: ViewportData[];
private _lastViewportData?: ViewportData;
private _lastViewLineOptions?: ViewLineOptions;
@@ -285,6 +286,16 @@ export class ViewLinesGpu extends ViewPart implements IViewLines {
// endregion Bind group
this._initialized = true;
// Render the initial viewport immediately after initialization
if (this._initViewportData) {
// HACK: Rendering multiple times in the same frame like this isn't ideal, but there
// isn't an easy way to merge viewport data
for (const viewportData of this._initViewportData) {
this.renderText(viewportData);
}
this._initViewportData = undefined;
}
}
private _updateAtlasStorageBufferAndTexture() {
@@ -361,6 +372,9 @@ export class ViewLinesGpu extends ViewPart implements IViewLines {
public renderText(viewportData: ViewportData): void {
if (this._initialized) {
return this._renderText(viewportData);
} else {
this._initViewportData = this._initViewportData ?? [];
this._initViewportData.push(viewportData);
}
}
@@ -85,7 +85,10 @@ class SubmitWithoutDispatchingAction extends Action2 {
precondition: ContextKeyExpr.and(
ChatContextKeys.inputHasText,
ChatContextKeys.requestInProgress.negate(),
ContextKeyExpr.and(ChatContextKeys.location.isEqualTo(ChatAgentLocation.Panel))),
ContextKeyExpr.and(ContextKeyExpr.or(
ChatContextKeys.location.isEqualTo(ChatAgentLocation.Panel),
ChatContextKeys.location.isEqualTo(ChatAgentLocation.Editor),
))),
keybinding: {
when: ChatContextKeys.inChatInput,
primary: KeyMod.Alt | KeyMod.Shift | KeyCode.Enter,
@@ -140,7 +143,8 @@ export class ChatSubmitSecondaryAgentAction extends Action2 {
menu: {
id: MenuId.ChatExecuteSecondary,
group: 'group_1',
order: 3
order: 3,
when: ContextKeyExpr.equals(ChatContextKeys.location.key, ChatAgentLocation.Panel)
},
keybinding: {
when: ChatContextKeys.inChatInput,
@@ -185,12 +189,22 @@ class SendToChatEditingAction extends Action2 {
id: MenuId.ChatExecuteSecondary,
group: 'group_1',
order: 4,
when: ContextKeyExpr.and(ChatContextKeys.enabled, ChatContextKeys.editingParticipantRegistered, ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession))
when: ContextKeyExpr.and(
ChatContextKeys.enabled,
ChatContextKeys.editingParticipantRegistered,
ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession),
ChatContextKeys.location.notEqualsTo(ChatAgentLocation.Editor)
)
},
keybinding: {
weight: KeybindingWeight.WorkbenchContrib,
primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.Enter,
when: ContextKeyExpr.and(ChatContextKeys.enabled, ChatContextKeys.editingParticipantRegistered, ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession))
when: ContextKeyExpr.and(
ChatContextKeys.enabled,
ChatContextKeys.editingParticipantRegistered,
ChatContextKeys.location.notEqualsTo(ChatAgentLocation.EditingSession),
ChatContextKeys.location.notEqualsTo(ChatAgentLocation.Editor),
)
}
});
}
@@ -258,7 +272,9 @@ class SendToNewChatAction extends Action2 {
f1: false,
menu: {
id: MenuId.ChatExecuteSecondary,
group: 'group_2'
group: 'group_2',
when: ContextKeyExpr.equals(ChatContextKeys.location.key, ChatAgentLocation.Panel)
},
keybinding: {
weight: KeybindingWeight.WorkbenchContrib,
@@ -57,6 +57,27 @@ abstract class WorkingSetAction extends Action2 {
abstract runWorkingSetAction(accessor: ServicesAccessor, currentEditingSession: IChatEditingSession, chatWidget: IChatWidget | undefined, ...uris: URI[]): any;
}
registerAction2(class AddFileToWorkingSet extends WorkingSetAction {
constructor() {
super({
id: 'chatEditing.addFileToWorkingSet',
title: localize2('addFileToWorkingSet', 'Add File'),
icon: Codicon.plus,
menu: [{
id: MenuId.ChatEditingWidgetModifiedFilesToolbar,
when: ContextKeyExpr.equals(chatEditingWidgetFileStateContextKey.key, WorkingSetEntryState.Transient),
order: 0,
group: 'navigation'
}],
});
}
async runWorkingSetAction(_accessor: ServicesAccessor, currentEditingSession: IChatEditingSession, _chatWidget: IChatWidget, ...uris: URI[]): Promise<void> {
for (const uri of uris) {
currentEditingSession.addFileToWorkingSet(uri);
}
}
});
registerAction2(class RemoveFileFromWorkingSet extends WorkingSetAction {
constructor() {
@@ -467,7 +467,8 @@ export class ChatEditingSession extends Disposable implements IChatEditingSessio
}
addFileToWorkingSet(resource: URI) {
if (!this._workingSet.has(resource)) {
const state = this._workingSet.get(resource);
if (state === undefined || state === WorkingSetEntryState.Transient) {
this._workingSet.set(resource, WorkingSetEntryState.Attached);
// Convert all transient entries to attachments
@@ -6,7 +6,7 @@ import { isCodeEditor } from '../../../../editor/browser/editorBrowser.js';
import { localize2 } from '../../../../nls.js';
import { ServicesAccessor } from '../../../../editor/browser/editorExtensions.js';
import { Codicon } from '../../../../base/common/codicons.js';
import { Action2, MenuId, registerAction2 } from '../../../../platform/actions/common/actions.js';
import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js';
import { KeybindingWeight } from '../../../../platform/keybinding/common/keybindingsRegistry.js';
import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';
import { CHAT_CATEGORY } from './actions/chatActions.js';
@@ -35,13 +35,7 @@ abstract class NavigateAction extends Action2 {
weight: KeybindingWeight.EditorContrib,
when: ContextKeyExpr.and(ctxHasEditorModification, EditorContextKeys.focus),
},
f1: true,
menu: {
id: MenuId.EditorTitle,
group: 'navigation',
order: next ? -100 : -101,
when: ctxHasEditorModification
}
f1: true
});
}
@@ -75,12 +69,7 @@ abstract class AcceptDiscardAction extends Action2 {
icon: accept
? Codicon.check
: Codicon.discard,
menu: {
id: MenuId.EditorTitle,
group: 'navigation',
order: accept ? -103 : -102,
when: ctxHasEditorModification
}
f1: true,
});
}
@@ -19,6 +19,9 @@ import { Range } from '../../../../editor/common/core/range.js';
import { Codicon } from '../../../../base/common/codicons.js';
import { ThemeIcon } from '../../../../base/common/themables.js';
import { ChatEditorController } from './chatEditorController.js';
import { IViewsService } from '../../../services/views/common/viewsService.js';
import { EDITS_VIEW_ID } from './chat.js';
import { ActionViewItem } from '../../../../base/browser/ui/actionbar/actionViewItems.js';
class ChatEditorOverlayWidget implements IOverlayWidget {
@@ -33,20 +36,21 @@ class ChatEditorOverlayWidget implements IOverlayWidget {
constructor(
private readonly _editor: ICodeEditor,
@IEditorService private readonly _editorService: IEditorService,
@IViewsService private readonly _viewsService: IViewsService,
@IInstantiationService instaService: IInstantiationService,
) {
this._domNode = document.createElement('div');
this._domNode.classList.add('chat-editor-overlay-widget');
const progressNode = document.createElement('div');
progressNode.classList.add('progress-container');
progressNode.classList.add(...ThemeIcon.asClassNameArray(ThemeIcon.modify(Codicon.loading, 'spin')));
this._domNode.appendChild(progressNode);
const toolbarContainer = document.createElement('div');
toolbarContainer.classList.add('toolbar-container');
this._domNode.appendChild(toolbarContainer);
this._toolbar = instaService.createInstance(WorkbenchToolBar, toolbarContainer, {});
this._toolbar = instaService.createInstance(WorkbenchToolBar, this._domNode, {
telemetrySource: 'chatEditor.overlayToolbar',
actionViewItemProvider: (action, options) => {
if (action.id === 'accept' || action.id === 'discard') {
return new ActionViewItem(undefined, action, { ...options, label: true, icon: false });
}
return undefined;
}
});
}
dispose() {
@@ -104,9 +108,20 @@ class ChatEditorOverlayWidget implements IOverlayWidget {
this._domNode.classList.toggle('busy', busy);
const groups = [[
toAction({
id: 'open',
label: localize('open', 'Open Chat Edit'),
class: ThemeIcon.asClassName(busy
? ThemeIcon.modify(Codicon.loading, 'spin')
: Codicon.goToEditingSession),
run: async () => {
await this._viewsService.openView(EDITS_VIEW_ID);
}
}),
toAction({
id: 'accept',
label: localize('accept', 'Accept Chat Edits'),
label: localize('accept', 'Accept'),
tooltip: localize('acceptTooltip', 'Accept Chat Edits'),
class: ThemeIcon.asClassName(Codicon.check),
enabled: !busy && modified,
run: () => {
@@ -116,7 +131,8 @@ class ChatEditorOverlayWidget implements IOverlayWidget {
}),
toAction({
id: 'discard',
label: localize('discard', 'Discard Chat Edits'),
label: localize('discard', 'Discard'),
tooltip: localize('discardTooltip', 'Discard Chat Edits'),
class: ThemeIcon.asClassName(Codicon.discard),
enabled: !busy && modified,
run: () => {
@@ -629,7 +629,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
hoverDelegate,
hiddenItemStrategy: HiddenItemStrategy.Ignore, // keep it lean when hiding items and avoid a "..." overflow menu
actionViewItemProvider: (action, options) => {
if (this.location === ChatAgentLocation.Panel) {
if (this.location === ChatAgentLocation.Panel || this.location === ChatAgentLocation.Editor) {
if ((action.id === SubmitAction.ID || action.id === CancelAction.ID) && action instanceof MenuItemAction) {
const dropdownAction = this.instantiationService.createInstance(MenuItemAction, { id: 'chat.moreExecuteActions', title: localize('notebook.moreExecuteActionsLabel', "More..."), icon: Codicon.chevronDown }, undefined, undefined, undefined, undefined);
return this.instantiationService.createInstance(ChatSubmitDropdownActionItem, action, dropdownAction, options);
@@ -4,35 +4,26 @@
*--------------------------------------------------------------------------------------------*/
.chat-editor-overlay-widget {
padding: 4px;
padding: 0px;
color: var(--vscode-button-foreground);
background-color: var(--vscode-button-background);
border-radius: 2px;
border-radius: 5px;
border: 1px solid var(--vscode-contrastBorder);
display: flex;
align-items: center
}
.chat-editor-overlay-widget .progress-container {
display: none;
padding: 0 4px;
.chat-editor-overlay-widget .action-item > .action-label {
padding: 5px;
}
.chat-editor-overlay-widget.busy .progress-container {
display: inherit;
}
.chat-editor-overlay-widget .progress-container.codicon {
.chat-editor-overlay-widget .action-item > .action-label.codicon {
color: var(--vscode-button-foreground);
}
.chat-editor-overlay-widget .toolbar-container .action-item > .action-label.codicon {
color: var(--vscode-button-foreground);
}
.chat-editor-overlay-widget .toolbar-container .action-item.disabled > .action-label.codicon::before,
.chat-editor-overlay-widget .toolbar-container .action-item.disabled > .action-label.codicon {
.chat-editor-overlay-widget .action-item.disabled > .action-label.codicon::before,
.chat-editor-overlay-widget .action-item.disabled > .action-label.codicon,
.chat-editor-overlay-widget .action-item.disabled > .action-label {
color: var(--vscode-button-foreground);
opacity: 0.7;
}
@@ -60,7 +60,10 @@ registerActiveXtermAction({
keybinding: {
primary: KeyCode.Escape,
secondary: [KeyMod.Shift | KeyCode.Escape],
when: ContextKeyExpr.and(TerminalChatContextKeys.focused, TerminalChatContextKeys.visible),
when: ContextKeyExpr.and(
ContextKeyExpr.or(TerminalContextKeys.focus, TerminalChatContextKeys.focused),
TerminalChatContextKeys.visible
),
weight: KeybindingWeight.WorkbenchContrib,
},
icon: Codicon.close,
@@ -70,9 +73,7 @@ registerActiveXtermAction({
order: 2
},
f1: true,
precondition: ContextKeyExpr.and(
ContextKeyExpr.and(TerminalChatContextKeys.focused, TerminalChatContextKeys.visible)
),
precondition: TerminalChatContextKeys.visible,
run: (_xterm, _accessor, activeInstance) => {
if (isDetachedTerminalInstance(activeInstance)) {
return;