Skip to content

Commit b0d975f

Browse files
authored
Add secondary chat execute button (microsoft#208495)
* Set up secondary chat execute button * Add "send to new chat" * Fix build
1 parent 3c1fdd4 commit b0d975f

File tree

7 files changed

+159
-78
lines changed

7 files changed

+159
-78
lines changed

src/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ export class DropdownWithPrimaryActionViewItem extends BaseActionViewItem {
134134
this._dropdown = new DropdownMenuActionViewItem(dropdownAction, dropdownMenuActions, this._contextMenuProvider, {
135135
menuAsChild: true,
136136
classNames: ['codicon', dropdownIcon || 'codicon-chevron-down'],
137-
hoverDelegate: this._options?.hoverDelegate
137+
actionRunner: this._options?.actionRunner,
138+
hoverDelegate: this._options?.hoverDelegate,
139+
keybindingProvider: this._options?.getKeyBinding
138140
});
139141
if (this._dropdownContainer) {
140142
this._dropdown.render(this._dropdownContainer);

src/vs/platform/actions/common/actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ export class MenuId {
218218
static readonly ChatCodeBlock = new MenuId('ChatCodeblock');
219219
static readonly ChatMessageTitle = new MenuId('ChatMessageTitle');
220220
static readonly ChatExecute = new MenuId('ChatExecute');
221+
static readonly ChatExecuteSecondary = new MenuId('ChatExecuteSecondary');
221222
static readonly ChatInputSide = new MenuId('ChatInputSide');
222223
static readonly AccessibleView = new MenuId('AccessibleView');
223224
static readonly MultiDiffEditorFileToolbar = new MenuId('MultiDiffEditorFileToolbar');

src/vs/workbench/contrib/chat/browser/actions/chatActions.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,30 @@ import { ThemeIcon } from 'vs/base/common/themables';
1010
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
1111
import { EditorAction2, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
1212
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
13-
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
1413
import { localize, localize2 } from 'vs/nls';
1514
import { Action2, IAction2Options, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
1615
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
16+
import { IsLinuxContext, IsWindowsContext } from 'vs/platform/contextkey/common/contextkeys';
1717
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
1818
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
1919
import { Registry } from 'vs/platform/registry/common/platform';
2020
import { ViewAction } from 'vs/workbench/browser/parts/views/viewPane';
2121
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
22-
import { IViewsService } from 'vs/workbench/services/views/common/viewsService';
2322
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
2423
import { runAccessibilityHelpAction } from 'vs/workbench/contrib/chat/browser/actions/chatAccessibilityHelp';
2524
import { IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat';
2625
import { IChatEditorOptions } from 'vs/workbench/contrib/chat/browser/chatEditor';
2726
import { ChatEditorInput } from 'vs/workbench/contrib/chat/browser/chatEditorInput';
2827
import { ChatViewPane } from 'vs/workbench/contrib/chat/browser/chatViewPane';
2928
import { IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
30-
import { CONTEXT_CHAT_INPUT_CURSOR_AT_TOP, CONTEXT_IN_CHAT_INPUT, CONTEXT_IN_CHAT_SESSION, CONTEXT_PROVIDER_EXISTS, CONTEXT_REQUEST, CONTEXT_RESPONSE } from 'vs/workbench/contrib/chat/common/chatContextKeys';
29+
import { CONTEXT_CHAT_INPUT_CURSOR_AT_TOP, CONTEXT_CHAT_INPUT_HAS_AGENT, CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_INPUT, CONTEXT_IN_CHAT_SESSION, CONTEXT_PROVIDER_EXISTS, CONTEXT_REQUEST, CONTEXT_RESPONSE } from 'vs/workbench/contrib/chat/common/chatContextKeys';
3130
import { IChatContributionService } from 'vs/workbench/contrib/chat/common/chatContributionService';
3231
import { chatAgentLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes';
3332
import { IChatDetail, IChatService } from 'vs/workbench/contrib/chat/common/chatService';
3433
import { IChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chatWidgetHistoryService';
3534
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
3635
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
37-
import { IsLinuxContext, IsWindowsContext } from 'vs/platform/contextkey/common/contextkeys';
36+
import { IViewsService } from 'vs/workbench/services/views/common/viewsService';
3837

3938
export const CHAT_CATEGORY = localize2('chat.category', 'Chat');
4039
export const CHAT_OPEN_ACTION_ID = 'workbench.action.chat.open';
@@ -101,11 +100,16 @@ export class ChatSubmitSecondaryAgentEditorAction extends EditorAction2 {
101100
super({
102101
id: ChatSubmitSecondaryAgentEditorAction.ID,
103102
title: localize2({ key: 'actions.chat.submitSecondaryAgent', comment: ['Send input from the chat input box to the secondary agent'] }, "Submit to Secondary Agent"),
104-
precondition: CONTEXT_IN_CHAT_INPUT,
103+
precondition: ContextKeyExpr.and(CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_INPUT_HAS_AGENT.negate(), CONTEXT_CHAT_REQUEST_IN_PROGRESS.negate()),
105104
keybinding: {
106-
when: EditorContextKeys.textInputFocus,
105+
when: CONTEXT_IN_CHAT_INPUT,
107106
primary: KeyMod.CtrlCmd | KeyCode.Enter,
108107
weight: KeybindingWeight.EditorContrib
108+
},
109+
menu: {
110+
id: MenuId.ChatExecuteSecondary,
111+
group: 'group_1',
112+
when: CONTEXT_CHAT_INPUT_HAS_AGENT.negate(),
109113
}
110114
});
111115
}
@@ -141,12 +145,17 @@ export class ChatSubmitEditorAction extends EditorAction2 {
141145
super({
142146
id: ChatSubmitEditorAction.ID,
143147
title: localize2({ key: 'actions.chat.submit', comment: ['Apply input from the chat input box'] }, "Submit"),
144-
precondition: CONTEXT_IN_CHAT_INPUT,
148+
precondition: CONTEXT_CHAT_INPUT_HAS_TEXT,
145149
keybinding: {
146-
when: EditorContextKeys.textInputFocus,
150+
when: CONTEXT_IN_CHAT_INPUT,
147151
primary: KeyCode.Enter,
148152
weight: KeybindingWeight.EditorContrib
149-
}
153+
},
154+
menu: {
155+
id: MenuId.ChatExecuteSecondary,
156+
when: CONTEXT_CHAT_REQUEST_IN_PROGRESS.negate(),
157+
group: 'group_1',
158+
},
150159
});
151160
}
152161

src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { Codicon } from 'vs/base/common/codicons';
7+
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
78
import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
89
import { localize2 } from 'vs/nls';
910
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
11+
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
12+
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
1013
import { CHAT_CATEGORY } from 'vs/workbench/contrib/chat/browser/actions/chatActions';
1114
import { IChatWidget, IChatWidgetService } from 'vs/workbench/contrib/chat/browser/chat';
12-
import { CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_REQUEST_IN_PROGRESS } from 'vs/workbench/contrib/chat/common/chatContextKeys';
15+
import { CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_REQUEST_IN_PROGRESS, CONTEXT_IN_CHAT_INPUT } from 'vs/workbench/contrib/chat/common/chatContextKeys';
1316
import { IChatService } from 'vs/workbench/contrib/chat/common/chatService';
1417

1518
export interface IVoiceChatExecuteActionContext {
@@ -32,7 +35,7 @@ export class SubmitAction extends Action2 {
3235
f1: false,
3336
category: CHAT_CATEGORY,
3437
icon: Codicon.send,
35-
precondition: CONTEXT_CHAT_INPUT_HAS_TEXT,
38+
precondition: ContextKeyExpr.and(CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_CHAT_REQUEST_IN_PROGRESS.negate()),
3639
menu: {
3740
id: MenuId.ChatExecute,
3841
when: CONTEXT_CHAT_REQUEST_IN_PROGRESS.negate(),
@@ -50,34 +53,72 @@ export class SubmitAction extends Action2 {
5053
}
5154
}
5255

53-
export function registerChatExecuteActions() {
54-
registerAction2(SubmitAction);
55-
registerAction2(class CancelAction extends Action2 {
56-
constructor() {
57-
super({
58-
id: 'workbench.action.chat.cancel',
59-
title: localize2('interactive.cancel.label', "Cancel"),
60-
f1: false,
61-
category: CHAT_CATEGORY,
62-
icon: Codicon.debugStop,
63-
menu: {
64-
id: MenuId.ChatExecute,
65-
when: CONTEXT_CHAT_REQUEST_IN_PROGRESS,
66-
group: 'navigation',
67-
}
68-
});
56+
class SendToNewChatAction extends Action2 {
57+
constructor() {
58+
super({
59+
id: 'workbench.action.chat.sendToNewChat',
60+
title: localize2('chat.newChat.label', "Send to New Chat"),
61+
precondition: ContextKeyExpr.and(CONTEXT_CHAT_REQUEST_IN_PROGRESS.negate(), CONTEXT_CHAT_INPUT_HAS_TEXT),
62+
category: CHAT_CATEGORY,
63+
f1: false,
64+
menu: {
65+
id: MenuId.ChatExecuteSecondary,
66+
group: 'group_2'
67+
},
68+
keybinding: {
69+
weight: KeybindingWeight.WorkbenchContrib,
70+
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.Enter,
71+
when: CONTEXT_IN_CHAT_INPUT,
72+
}
73+
});
74+
}
75+
76+
async run(accessor: ServicesAccessor, ...args: any[]) {
77+
const context: IChatExecuteActionContext | undefined = args[0];
78+
79+
const widgetService = accessor.get(IChatWidgetService);
80+
const widget = context?.widget ?? widgetService.lastFocusedWidget;
81+
if (!widget) {
82+
return;
6983
}
7084

71-
run(accessor: ServicesAccessor, ...args: any[]) {
72-
const context: IChatExecuteActionContext = args[0];
73-
if (!context.widget) {
74-
return;
75-
}
85+
widget.clear();
86+
widget.acceptInput(context?.inputValue);
87+
}
88+
}
7689

77-
const chatService = accessor.get(IChatService);
78-
if (context.widget.viewModel) {
79-
chatService.cancelCurrentRequestForSession(context.widget.viewModel.sessionId);
90+
export class CancelAction extends Action2 {
91+
static readonly ID = 'workbench.action.chat.cancel';
92+
constructor() {
93+
super({
94+
id: CancelAction.ID,
95+
title: localize2('interactive.cancel.label', "Cancel"),
96+
f1: false,
97+
category: CHAT_CATEGORY,
98+
icon: Codicon.debugStop,
99+
menu: {
100+
id: MenuId.ChatExecute,
101+
when: CONTEXT_CHAT_REQUEST_IN_PROGRESS,
102+
group: 'navigation',
80103
}
104+
});
105+
}
106+
107+
run(accessor: ServicesAccessor, ...args: any[]) {
108+
const context: IChatExecuteActionContext = args[0];
109+
if (!context.widget) {
110+
return;
81111
}
82-
});
112+
113+
const chatService = accessor.get(IChatService);
114+
if (context.widget.viewModel) {
115+
chatService.cancelCurrentRequestForSession(context.widget.viewModel.sessionId);
116+
}
117+
}
118+
}
119+
120+
export function registerChatExecuteActions() {
121+
registerAction2(SubmitAction);
122+
registerAction2(CancelAction);
123+
registerAction2(SendToNewChatAction);
83124
}

src/vs/workbench/contrib/chat/browser/chatInputPart.ts

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as dom from 'vs/base/browser/dom';
7+
import { DEFAULT_FONT_FAMILY } from 'vs/base/browser/fonts';
78
import { IHistoryNavigationWidget } from 'vs/base/browser/history';
8-
import { ActionViewItem, IActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
99
import * as aria from 'vs/base/browser/ui/aria/aria';
1010
import { Checkbox } from 'vs/base/browser/ui/toggle/toggle';
1111
import { IAction } from 'vs/base/common/actions';
12+
import { Codicon } from 'vs/base/common/codicons';
1213
import { Emitter } from 'vs/base/common/event';
1314
import { HistoryNavigator } from 'vs/base/common/history';
1415
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
1516
import { isMacintosh } from 'vs/base/common/platform';
1617
import { URI } from 'vs/base/common/uri';
18+
import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration';
1719
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
1820
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditor/codeEditorWidget';
1921
import { IDimension } from 'vs/editor/common/core/dimension';
@@ -23,31 +25,33 @@ import { IModelService } from 'vs/editor/common/services/model';
2325
import { HoverController } from 'vs/editor/contrib/hover/browser/hover';
2426
import { localize } from 'vs/nls';
2527
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
28+
import { DropdownWithPrimaryActionViewItem } from 'vs/platform/actions/browser/dropdownWithPrimaryActionViewItem';
29+
import { createAndFillInActionBarActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
2630
import { HiddenItemStrategy, MenuWorkbenchToolBar } from 'vs/platform/actions/browser/toolbar';
27-
import { MenuId } from 'vs/platform/actions/common/actions';
31+
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
2832
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
2933
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
34+
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
3035
import { registerAndCreateHistoryNavigationContext } from 'vs/platform/history/browser/contextScopedHistoryWidget';
3136
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
3237
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
3338
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
39+
import { INotificationService } from 'vs/platform/notification/common/notification';
3440
import { defaultCheckboxStyles } from 'vs/platform/theme/browser/defaultStyles';
3541
import { asCssVariableWithDefault, checkboxBorder, inputBackground } from 'vs/platform/theme/common/colorRegistry';
36-
import { DEFAULT_FONT_FAMILY } from 'vs/base/browser/fonts';
42+
import { IThemeService } from 'vs/platform/theme/common/themeService';
3743
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
3844
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
39-
import { ChatSubmitEditorAction, ChatSubmitSecondaryAgentEditorAction } from 'vs/workbench/contrib/chat/browser/actions/chatActions';
40-
import { IChatExecuteActionContext, SubmitAction } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
45+
import { ChatSubmitSecondaryAgentEditorAction } from 'vs/workbench/contrib/chat/browser/actions/chatActions';
46+
import { CancelAction, IChatExecuteActionContext, SubmitAction } from 'vs/workbench/contrib/chat/browser/actions/chatExecuteActions';
4147
import { IChatWidget } from 'vs/workbench/contrib/chat/browser/chat';
4248
import { ChatFollowups } from 'vs/workbench/contrib/chat/browser/chatFollowups';
4349
import { ChatAgentLocation, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
4450
import { CONTEXT_CHAT_INPUT_CURSOR_AT_TOP, CONTEXT_CHAT_INPUT_HAS_FOCUS, CONTEXT_CHAT_INPUT_HAS_TEXT, CONTEXT_IN_CHAT_INPUT } from 'vs/workbench/contrib/chat/common/chatContextKeys';
45-
import { chatAgentLeader } from 'vs/workbench/contrib/chat/common/chatParserTypes';
4651
import { IChatFollowup } from 'vs/workbench/contrib/chat/common/chatService';
4752
import { IChatResponseViewModel } from 'vs/workbench/contrib/chat/common/chatViewModel';
4853
import { IChatHistoryEntry, IChatWidgetHistoryService } from 'vs/workbench/contrib/chat/common/chatWidgetHistoryService';
4954
import { getSimpleCodeEditorWidgetOptions, getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions';
50-
import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration';
5155

5256
const $ = dom.$;
5357

@@ -139,7 +143,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
139143
@IContextKeyService private readonly contextKeyService: IContextKeyService,
140144
@IConfigurationService private readonly configurationService: IConfigurationService,
141145
@IKeybindingService private readonly keybindingService: IKeybindingService,
142-
@IAccessibilityService private readonly accessibilityService: IAccessibilityService
146+
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
143147
) {
144148
super();
145149

@@ -368,8 +372,9 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
368372
},
369373
hiddenItemStrategy: HiddenItemStrategy.Ignore, // keep it lean when hiding items and avoid a "..." overflow menu
370374
actionViewItemProvider: (action, options) => {
371-
if (action.id === SubmitAction.ID) {
372-
return this.instantiationService.createInstance(SubmitButtonActionViewItem, { widget } satisfies IChatExecuteActionContext, action, options);
375+
if ((action.id === SubmitAction.ID || action.id === CancelAction.ID) && action instanceof MenuItemAction) {
376+
const dropdownAction = this.instantiationService.createInstance(MenuItemAction, { id: 'chat.moreExecuteActions', title: localize('notebook.moreExecuteActionsLabel', "More..."), icon: Codicon.chevronDown }, undefined, undefined, undefined);
377+
return this.instantiationService.createInstance(ChatSubmitDropdownActionItem, action, dropdownAction);
373378
}
374379

375380
return undefined;
@@ -482,40 +487,57 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
482487
}
483488
}
484489

485-
class SubmitButtonActionViewItem extends ActionViewItem {
486-
private readonly _tooltip: string;
490+
function getLastPosition(model: ITextModel): IPosition {
491+
return { lineNumber: model.getLineCount(), column: model.getLineLength(model.getLineCount()) + 1 };
492+
}
487493

494+
// This does seems like a lot just to customize an item with dropdown. This whole class exists just because we need an
495+
// onDidChange listener on the submenu, which is apparently not needed in other cases.
496+
class ChatSubmitDropdownActionItem extends DropdownWithPrimaryActionViewItem {
488497
constructor(
489-
context: unknown,
490-
action: IAction,
491-
options: IActionViewItemOptions,
492-
@IKeybindingService keybindingService: IKeybindingService,
498+
action: MenuItemAction,
499+
dropdownAction: IAction,
500+
@IMenuService menuService: IMenuService,
501+
@IContextMenuService contextMenuService: IContextMenuService,
493502
@IChatAgentService chatAgentService: IChatAgentService,
503+
@IContextKeyService contextKeyService: IContextKeyService,
504+
@IKeybindingService keybindingService: IKeybindingService,
505+
@INotificationService notificationService: INotificationService,
506+
@IThemeService themeService: IThemeService,
507+
@IAccessibilityService accessibilityService: IAccessibilityService
494508
) {
495-
super(context, action, options);
496-
497-
const primaryKeybinding = keybindingService.lookupKeybinding(ChatSubmitEditorAction.ID)?.getLabel();
498-
let tooltip = action.label;
499-
if (primaryKeybinding) {
500-
tooltip += ` (${primaryKeybinding})`;
501-
}
502-
503-
const secondaryAgent = chatAgentService.getSecondaryAgent();
504-
if (secondaryAgent) {
505-
const secondaryKeybinding = keybindingService.lookupKeybinding(ChatSubmitSecondaryAgentEditorAction.ID)?.getLabel();
506-
if (secondaryKeybinding) {
507-
tooltip += `\n${chatAgentLeader}${secondaryAgent.name} (${secondaryKeybinding})`;
509+
super(
510+
action,
511+
dropdownAction,
512+
[],
513+
'',
514+
contextMenuService,
515+
{
516+
getKeyBinding: (action: IAction) => keybindingService.lookupKeybinding(action.id, contextKeyService)
517+
},
518+
keybindingService,
519+
notificationService,
520+
contextKeyService,
521+
themeService,
522+
accessibilityService);
523+
const menu = menuService.createMenu(MenuId.ChatExecuteSecondary, contextKeyService);
524+
const setActions = () => {
525+
const secondary: IAction[] = [];
526+
createAndFillInActionBarActions(menu, { shouldForwardArgs: true }, secondary);
527+
const secondaryAgent = chatAgentService.getSecondaryAgent();
528+
if (secondaryAgent) {
529+
secondary.forEach(a => {
530+
if (a.id === ChatSubmitSecondaryAgentEditorAction.ID) {
531+
a.label = localize('chat.submitToSecondaryAgent', "Send to @{0}", secondaryAgent.name);
532+
}
533+
534+
return a;
535+
});
508536
}
509-
}
510-
511-
this._tooltip = tooltip;
512-
}
513537

514-
protected override getTooltip(): string | undefined {
515-
return this._tooltip;
538+
this.update(dropdownAction, secondary);
539+
};
540+
setActions();
541+
this._register(menu.onDidChange(() => setActions()));
516542
}
517543
}
518-
519-
function getLastPosition(model: ITextModel): IPosition {
520-
return { lineNumber: model.getLineCount(), column: model.getLineLength(model.getLineCount()) + 1 };
521-
}

0 commit comments

Comments
 (0)