Skip to content

Commit 0231286

Browse files
authored
Handle arrow key conflicts (microsoft#181981)
* Handle arrow key conflicts * Fix arrow keys for livepreview mode. * fix merge issues
1 parent dc897c6 commit 0231286

File tree

5 files changed

+85
-11
lines changed

5 files changed

+85
-11
lines changed

src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorActions.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ export class ArrowOutUpAction extends AbstractInteractiveEditorAction {
157157
super({
158158
id: 'interactiveEditor.arrowOutUp',
159159
title: localize('arrowUp', 'Cursor Up'),
160-
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_FIRST, CTX_INTERACTIVE_EDITOR_EDIT_MODE.notEqualsTo(EditMode.LivePreview)),
160+
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_FIRST, EditorContextKeys.isEmbeddedDiffEditor.negate()),
161161
keybinding: {
162162
weight: KeybindingWeight.EditorCore,
163163
primary: KeyCode.UpArrow
@@ -175,7 +175,7 @@ export class ArrowOutDownAction extends AbstractInteractiveEditorAction {
175175
super({
176176
id: 'interactiveEditor.arrowOutDown',
177177
title: localize('arrowDown', 'Cursor Down'),
178-
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST, CTX_INTERACTIVE_EDITOR_EDIT_MODE.notEqualsTo(EditMode.LivePreview)),
178+
precondition: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST, EditorContextKeys.isEmbeddedDiffEditor.negate()),
179179
keybinding: {
180180
weight: KeybindingWeight.EditorCore,
181181
primary: KeyCode.DownArrow
@@ -198,11 +198,11 @@ export class FocusInteractiveEditor extends EditorAction2 {
198198
precondition: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, CTX_INTERACTIVE_EDITOR_VISIBLE, CTX_INTERACTIVE_EDITOR_FOCUSED.negate()),
199199
keybinding: [{
200200
weight: KeybindingWeight.EditorCore + 10, // win against core_command
201-
when: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION.isEqualTo('above'), CTX_INTERACTIVE_EDITOR_EDIT_MODE.notEqualsTo(EditMode.LivePreview)),
201+
when: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION.isEqualTo('above'), EditorContextKeys.isEmbeddedDiffEditor.negate()),
202202
primary: KeyCode.DownArrow,
203203
}, {
204204
weight: KeybindingWeight.EditorCore + 10, // win against core_command
205-
when: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION.isEqualTo('below'), CTX_INTERACTIVE_EDITOR_EDIT_MODE.notEqualsTo(EditMode.LivePreview)),
205+
when: ContextKeyExpr.and(CTX_INTERACTIVE_EDITOR_OUTER_CURSOR_POSITION.isEqualTo('below'), EditorContextKeys.isEmbeddedDiffEditor.negate()),
206206
primary: KeyCode.UpArrow,
207207
}]
208208
});

src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorController.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { assertType } from 'vs/base/common/types';
1313
import 'vs/css!./interactiveEditor';
1414
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
1515
import { EditOperation } from 'vs/editor/common/core/editOperation';
16+
import { Position } from 'vs/editor/common/core/position';
1617
import { IRange, Range } from 'vs/editor/common/core/range';
1718
import { IEditorContribution, IEditorDecorationsCollection } from 'vs/editor/common/editorCommon';
1819
import { ModelDecorationOptions, createTextBufferFactoryFromSnapshot } from 'vs/editor/common/model/textModel';
@@ -119,6 +120,10 @@ export class InteractiveEditorController implements IEditorContribution {
119120
return INTERACTIVE_EDITOR_ID;
120121
}
121122

123+
getWidgetPosition(): Position | undefined {
124+
return this._zone.position;
125+
}
126+
122127
async run(options: InteractiveEditorRunOptions | undefined): Promise<void> {
123128
this._nextState(SessionState.CREATE_SESSION, { ...options });
124129
}

src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorLivePreviewWidget.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export class InteractiveEditorLivePreviewWidget extends ZoneWidget {
7474
diffCodeLens: false,
7575
stickyScroll: { enabled: false },
7676
minimap: { enabled: false },
77+
isInEmbeddedEditor: true
7778
}, {
7879
originalEditor: { contributions: diffContributions },
7980
modifiedEditor: { contributions: diffContributions }

src/vs/workbench/contrib/interactiveEditor/browser/interactiveEditorWidget.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ const _previewEditorEditorOptions: IDiffEditorConstructionOptions = {
9999
modifiedAriaLabel: localize('original', 'Original'),
100100
diffAlgorithm: 'advanced',
101101
readOnly: true,
102+
isInEmbeddedEditor: true
102103
};
103104

104105
export interface InteractiveEditorWidgetViewState {

src/vs/workbench/contrib/notebook/browser/contrib/navigation/arrow.ts

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import { timeout } from 'vs/base/common/async';
77
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
8+
import { isEqual } from 'vs/base/common/resources';
9+
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
810
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
911
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
1012
import { localize } from 'vs/nls';
@@ -16,8 +18,10 @@ import { InputFocusedContextKey } from 'vs/platform/contextkey/common/contextkey
1618
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
1719
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
1820
import { Registry } from 'vs/platform/registry/common/platform';
21+
import { InteractiveEditorController } from 'vs/workbench/contrib/interactiveEditor/browser/interactiveEditorController';
22+
import { CTX_INTERACTIVE_EDITOR_FOCUSED, CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST } from 'vs/workbench/contrib/interactiveEditor/common/interactiveEditor';
1923
import { INotebookActionContext, INotebookCellActionContext, NotebookAction, NotebookCellAction, NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT } from 'vs/workbench/contrib/notebook/browser/controller/coreActions';
20-
import { CellEditState } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
24+
import { CellEditState, ICellViewModel } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
2125
import { CellKind, NOTEBOOK_EDITOR_CURSOR_BOUNDARY } from 'vs/workbench/contrib/notebook/common/notebookCommon';
2226
import { NOTEBOOK_CELL_HAS_OUTPUTS, NOTEBOOK_CELL_MARKDOWN_EDIT_MODE, NOTEBOOK_CELL_TYPE, NOTEBOOK_CURSOR_NAVIGATION_MODE, NOTEBOOK_EDITOR_FOCUSED, NOTEBOOK_OUTPUT_FOCUSED } from 'vs/workbench/contrib/notebook/common/notebookContextKeys';
2327

@@ -33,6 +37,17 @@ const NOTEBOOK_CURSOR_PAGEUP_SELECT_COMMAND_ID = 'notebook.cell.cursorPageUpSele
3337
const NOTEBOOK_CURSOR_PAGEDOWN_COMMAND_ID = 'notebook.cell.cursorPageDown';
3438
const NOTEBOOK_CURSOR_PAGEDOWN_SELECT_COMMAND_ID = 'notebook.cell.cursorPageDownSelect';
3539

40+
function findTargetCellEditor(context: INotebookCellActionContext, targetCell: ICellViewModel) {
41+
let foundEditor: ICodeEditor | undefined = undefined;
42+
for (const [, codeEditor] of context.notebookEditor.codeEditors) {
43+
if (isEqual(codeEditor.getModel()?.uri, targetCell.uri)) {
44+
foundEditor = codeEditor;
45+
break;
46+
}
47+
}
48+
49+
return foundEditor;
50+
}
3651

3752
registerAction2(class FocusNextCellAction extends NotebookCellAction {
3853
constructor() {
@@ -51,6 +66,7 @@ registerAction2(class FocusNextCellAction extends NotebookCellAction {
5166
NOTEBOOK_EDITOR_CURSOR_BOUNDARY.notEqualsTo('top'),
5267
NOTEBOOK_EDITOR_CURSOR_BOUNDARY.notEqualsTo('none'),
5368
),
69+
EditorContextKeys.isEmbeddedDiffEditor.negate()
5470
),
5571
primary: KeyCode.DownArrow,
5672
weight: NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT, // code cell keybinding, focus inside editor: lower weight to not override suggest widget
@@ -63,7 +79,8 @@ registerAction2(class FocusNextCellAction extends NotebookCellAction {
6379
ContextKeyExpr.and(
6480
NOTEBOOK_CELL_TYPE.isEqualTo('markup'),
6581
NOTEBOOK_CELL_MARKDOWN_EDIT_MODE.isEqualTo(false),
66-
NOTEBOOK_CURSOR_NAVIGATION_MODE)
82+
NOTEBOOK_CURSOR_NAVIGATION_MODE),
83+
EditorContextKeys.isEmbeddedDiffEditor.negate()
6784
),
6885
primary: KeyCode.DownArrow,
6986
weight: KeybindingWeight.WorkbenchContrib, // markdown keybinding, focus on list: higher weight to override list.focusDown
@@ -73,6 +90,39 @@ registerAction2(class FocusNextCellAction extends NotebookCellAction {
7390
primary: KeyMod.CtrlCmd | KeyCode.DownArrow,
7491
mac: { primary: KeyMod.WinCtrl | KeyMod.CtrlCmd | KeyCode.DownArrow, },
7592
weight: KeybindingWeight.WorkbenchContrib
93+
},
94+
{
95+
when: ContextKeyExpr.and(
96+
NOTEBOOK_EDITOR_FOCUSED,
97+
CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate(),
98+
ContextKeyExpr.equals('config.notebook.navigation.allowNavigateToSurroundingCells', true),
99+
ContextKeyExpr.and(
100+
ContextKeyExpr.has(InputFocusedContextKey),
101+
NOTEBOOK_EDITOR_CURSOR_BOUNDARY.notEqualsTo('top'),
102+
NOTEBOOK_EDITOR_CURSOR_BOUNDARY.notEqualsTo('none'),
103+
),
104+
CTX_INTERACTIVE_EDITOR_FOCUSED,
105+
CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST,
106+
EditorContextKeys.isEmbeddedDiffEditor.negate()
107+
),
108+
primary: KeyCode.DownArrow,
109+
weight: KeybindingWeight.EditorCore
110+
},
111+
{
112+
when: ContextKeyExpr.and(
113+
NOTEBOOK_EDITOR_FOCUSED,
114+
CONTEXT_ACCESSIBILITY_MODE_ENABLED.negate(),
115+
ContextKeyExpr.equals('config.notebook.navigation.allowNavigateToSurroundingCells', true),
116+
ContextKeyExpr.and(
117+
NOTEBOOK_CELL_TYPE.isEqualTo('markup'),
118+
NOTEBOOK_CELL_MARKDOWN_EDIT_MODE.isEqualTo(false),
119+
NOTEBOOK_CURSOR_NAVIGATION_MODE),
120+
CTX_INTERACTIVE_EDITOR_FOCUSED,
121+
CTX_INTERACTIVE_EDITOR_INNER_CURSOR_LAST,
122+
EditorContextKeys.isEmbeddedDiffEditor.negate()
123+
),
124+
primary: KeyCode.DownArrow,
125+
weight: KeybindingWeight.EditorCore
76126
}
77127
]
78128
});
@@ -92,9 +142,17 @@ registerAction2(class FocusNextCellAction extends NotebookCellAction {
92142
return;
93143
}
94144

95-
const newCell = editor.cellAt(idx + 1);
96-
const newFocusMode = newCell.cellKind === CellKind.Markup && newCell.getEditState() === CellEditState.Preview ? 'container' : 'editor';
97-
await editor.focusNotebookCell(newCell, newFocusMode, { focusEditorLine: 1 });
145+
const focusEditorLine = activeCell.textBuffer.getLineCount();
146+
const targetCell = (context.cell ?? context.selectedCells?.[0]);
147+
const foundEditor: ICodeEditor | undefined = targetCell ? findTargetCellEditor(context, targetCell) : undefined;
148+
149+
if (foundEditor && foundEditor.hasTextFocus() && InteractiveEditorController.get(foundEditor)?.getWidgetPosition()?.lineNumber === focusEditorLine) {
150+
InteractiveEditorController.get(foundEditor)?.focus();
151+
} else {
152+
const newCell = editor.cellAt(idx + 1);
153+
const newFocusMode = newCell.cellKind === CellKind.Markup && newCell.getEditState() === CellEditState.Preview ? 'container' : 'editor';
154+
await editor.focusNotebookCell(newCell, newFocusMode, { focusEditorLine: 1 });
155+
}
98156
}
99157
});
100158

@@ -117,6 +175,7 @@ registerAction2(class FocusPreviousCellAction extends NotebookCellAction {
117175
NOTEBOOK_EDITOR_CURSOR_BOUNDARY.notEqualsTo('bottom'),
118176
NOTEBOOK_EDITOR_CURSOR_BOUNDARY.notEqualsTo('none'),
119177
),
178+
EditorContextKeys.isEmbeddedDiffEditor.negate()
120179
),
121180
primary: KeyCode.UpArrow,
122181
weight: NOTEBOOK_EDITOR_WIDGET_ACTION_WEIGHT, // code cell keybinding, focus inside editor: lower weight to not override suggest widget
@@ -130,7 +189,8 @@ registerAction2(class FocusPreviousCellAction extends NotebookCellAction {
130189
NOTEBOOK_CELL_TYPE.isEqualTo('markup'),
131190
NOTEBOOK_CELL_MARKDOWN_EDIT_MODE.isEqualTo(false),
132191
NOTEBOOK_CURSOR_NAVIGATION_MODE
133-
)
192+
),
193+
EditorContextKeys.isEmbeddedDiffEditor.negate()
134194
),
135195
primary: KeyCode.UpArrow,
136196
weight: KeybindingWeight.WorkbenchContrib, // markdown keybinding, focus on list: higher weight to override list.focusDown
@@ -155,7 +215,14 @@ registerAction2(class FocusPreviousCellAction extends NotebookCellAction {
155215

156216
const newCell = editor.cellAt(idx - 1);
157217
const newFocusMode = newCell.cellKind === CellKind.Markup && newCell.getEditState() === CellEditState.Preview ? 'container' : 'editor';
158-
await editor.focusNotebookCell(newCell, newFocusMode, { focusEditorLine: newCell.textBuffer.getLineCount() });
218+
const focusEditorLine = newCell.textBuffer.getLineCount();
219+
await editor.focusNotebookCell(newCell, newFocusMode, { focusEditorLine: focusEditorLine });
220+
221+
const foundEditor: ICodeEditor | undefined = findTargetCellEditor(context, newCell);
222+
223+
if (foundEditor && InteractiveEditorController.get(foundEditor)?.getWidgetPosition()?.lineNumber === focusEditorLine) {
224+
InteractiveEditorController.get(foundEditor)?.focus();
225+
}
159226
}
160227
});
161228

0 commit comments

Comments
 (0)