Skip to content

Commit 3a0fa48

Browse files
authored
Allow escape and ctrl+U to clear the interactive window (#10513)
* Support escaping code in the input box * Make sure shift+tab doesn't go to another window * Add test for escape/ctrl+u * Actual correct news entry
1 parent aec070b commit 3a0fa48

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

news/1 Enhancements/10198.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Support using 'esc' or 'ctrl+u' to clear the contents of the interactive window input box.

src/datascience-ui/history-react/interactiveCell.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,20 @@ export class InteractiveCell extends React.Component<IInteractiveCellProps> {
349349
};
350350

351351
private onEditCellKeyDown = (_cellId: string, e: IKeyboardEvent) => {
352-
if (e.code === 'Escape') {
353-
this.editCellEscape(e);
352+
if (e.code === 'Tab' && e.shiftKey) {
353+
this.editCellShiftTab(e);
354354
} else if (e.code === 'Enter' && e.shiftKey) {
355355
this.editCellSubmit(e);
356356
} else if (e.code === 'NumpadEnter' && e.shiftKey) {
357357
this.editCellSubmit(e);
358+
} else if (e.code === 'KeyU' && e.ctrlKey && e.editorInfo && !e.editorInfo.isSuggesting) {
359+
e.editorInfo.clear();
360+
e.stopPropagation();
361+
e.preventDefault();
362+
} else if (e.code === 'Escape' && e.editorInfo && !e.editorInfo.isSuggesting) {
363+
e.editorInfo.clear();
364+
e.stopPropagation();
365+
e.preventDefault();
358366
}
359367
};
360368

@@ -395,11 +403,13 @@ export class InteractiveCell extends React.Component<IInteractiveCellProps> {
395403
}
396404
}
397405

398-
private editCellEscape = (e: IKeyboardEvent) => {
406+
private editCellShiftTab = (e: IKeyboardEvent) => {
399407
const focusedElement = document.activeElement;
400408
if (focusedElement !== null && e.editorInfo && !e.editorInfo.isSuggesting) {
401409
const nextTabStop = this.findTabStop(1, focusedElement);
402410
if (nextTabStop) {
411+
e.stopPropagation();
412+
e.preventDefault();
403413
nextTabStop.focus();
404414
}
405415
}

src/test/datascience/interactiveWindow.functional.test.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import * as path from 'path';
99
import * as TypeMoq from 'typemoq';
1010
import { Disposable, Selection, TextDocument, TextEditor, Uri } from 'vscode';
1111

12+
import { ReactWrapper } from 'enzyme';
1213
import { IApplicationShell, IDocumentManager } from '../../client/common/application/types';
1314
import { IDataScienceSettings } from '../../client/common/types';
1415
import { createDeferred, waitForPromise } from '../../client/common/utils/async';
@@ -19,7 +20,9 @@ import { InteractiveWindowMessages } from '../../client/datascience/interactive-
1920
import { InteractiveWindow } from '../../client/datascience/interactive-window/interactiveWindow';
2021
import { concatMultilineStringInput } from '../../datascience-ui/common';
2122
import { InteractivePanel } from '../../datascience-ui/history-react/interactivePanel';
23+
import { IKeyboardEvent } from '../../datascience-ui/react-common/event';
2224
import { ImageButton } from '../../datascience-ui/react-common/imageButton';
25+
import { MonacoEditor } from '../../datascience-ui/react-common/monacoEditor';
2326
import { DataScienceIocContainer } from './dataScienceIocContainer';
2427
import { createDocument } from './editor-integration/helpers';
2528
import { defaultDataScienceSettings } from './helpers';
@@ -38,6 +41,7 @@ import {
3841
addMockData,
3942
CellInputState,
4043
CellPosition,
44+
enterEditorKey,
4145
enterInput,
4246
escapePath,
4347
findButton,
@@ -87,6 +91,13 @@ suite('DataScience Interactive Window output tests', () => {
8791
return update;
8892
}
8993

94+
function simulateKeyPressOnEditor(
95+
editorControl: ReactWrapper<any, Readonly<{}>, React.Component> | undefined,
96+
keyboardEvent: Partial<IKeyboardEvent> & { code: string }
97+
) {
98+
enterEditorKey(editorControl, keyboardEvent);
99+
}
100+
90101
// Uncomment this to debug hangs on exit
91102
// suiteTeardown(() => {
92103
// asyncDump();
@@ -217,6 +228,36 @@ for i in range(10):
217228
}
218229
);
219230

231+
runMountedTest(
232+
'Escape/Ctrl+U',
233+
async wrapper => {
234+
// Create an interactive window so that it listens to the results.
235+
const interactiveWindow = await getOrCreateInteractiveWindow(ioc);
236+
await interactiveWindow.show();
237+
238+
// Type in the input box
239+
const editor = getInteractiveEditor(wrapper);
240+
typeCode(editor, 'a=1\na');
241+
242+
// Check code is what we think it is
243+
const reactEditor = editor.instance() as MonacoEditor;
244+
assert.equal(reactEditor.state.model?.getValue().replace(/\r/g, ''), 'a=1\na');
245+
246+
// Send escape
247+
simulateKeyPressOnEditor(editor, { code: 'Escape' });
248+
assert.equal(reactEditor.state.model?.getValue().replace(/\r/g, ''), '');
249+
250+
typeCode(editor, 'a=1\na');
251+
assert.equal(reactEditor.state.model?.getValue().replace(/\r/g, ''), 'a=1\na');
252+
253+
simulateKeyPressOnEditor(editor, { code: 'KeyU', ctrlKey: true });
254+
assert.equal(reactEditor.state.model?.getValue().replace(/\r/g, ''), '');
255+
},
256+
() => {
257+
return ioc;
258+
}
259+
);
260+
220261
runMountedTest(
221262
'Click outside cells sets focus to input box',
222263
async wrapper => {

0 commit comments

Comments
 (0)