Skip to content

Issue 12414 python interactive cell editing shortcuts #12529

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8f1fd7b
refactored ICellRange definition to type.ts since it's now used acros…
Jun 19, 2020
fd5e865
add command insertCellBelowPosition
Jun 20, 2020
127e2df
add command insertCellBelow
Jun 20, 2020
38fad86
add command insertCellAbove
Jun 20, 2020
5afe4cc
add deleteCells command
Jun 21, 2020
dd846c1
add selectCell command
Jun 21, 2020
cfeccbb
add selectCellContents command
Jun 21, 2020
500fe5a
modify selectCell to maintain previous orientation of selection ancho…
Jun 21, 2020
cf5e404
fix detection of anchor and active position direction
Jun 21, 2020
aa39444
add extendSelectionByCellAbove
Jun 21, 2020
9a073aa
add extendSelectionByCellBelow
Jun 22, 2020
4a95409
add moveCellsUp
Jun 23, 2020
95fc70d
add moveCellsDown
Jun 23, 2020
cc37494
added news file for enhancement changes being added
Jun 24, 2020
1f73555
add changeCellToMarkdown
Jun 28, 2020
e62137a
add changeCellToCode
Jul 10, 2020
f624692
Remove cell edit commands from context menu
Jul 10, 2020
9a17d5f
Use the insertCell method to insert a cell when RunCellAndAdvance rea…
Jul 10, 2020
0ae48a6
Use the insertCell method to insert cell within addEmptyCellToBottom
Jul 10, 2020
8842cde
Add telemetry for cell edit commands in interactive python
Jul 10, 2020
8d1ae3f
Add codeLensFactory.getCodeLensCacheData and abstracted the cell rang…
Jul 10, 2020
db47d3a
clean up async and promises within codewatcher.ts
Jul 13, 2020
4fdd64c
clean up unnecessary Promise.resolve()
Jul 14, 2020
9876718
refactor unnecessary async functions to sync functions
Jul 31, 2020
0b83e38
added unit tests for move cells down
Jul 31, 2020
6ac5741
Merge branch 'master' into issue-12414-python-interactive-cell-shortcuts
Jul 31, 2020
716200b
change the when for commands to display when the python file has cells
Aug 1, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/1 Enhancements/12414.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add cell editing shortcuts for python interactive cells. Thanks [@earthastronaut](https://github.com/earthastronaut/)!
132 changes: 132 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,66 @@
"title": "%python.command.python.datascience.debugcontinue.title%",
"category": "Python"
},
{
"command": "python.datascience.insertCellBelowPosition",
"title": "%python.command.python.datascience.insertCellBelowPosition.title%",
"category": "Python"
},
{
"command": "python.datascience.insertCellBelow",
"title": "%python.command.python.datascience.insertCellBelow.title%",
"category": "Python"
},
{
"command": "python.datascience.insertCellAbove",
"title": "%python.command.python.datascience.insertCellAbove.title%",
"category": "Python"
},
{
"command": "python.datascience.deleteCells",
"title": "%python.command.python.datascience.deleteCells.title%",
"category": "Python"
},
{
"command": "python.datascience.selectCell",
"title": "%python.command.python.datascience.selectCell.title%",
"category": "Python"
},
{
"command": "python.datascience.selectCellContents",
"title": "%python.command.python.datascience.selectCellContents.title%",
"category": "Python"
},
{
"command": "python.datascience.extendSelectionByCellAbove",
"title": "%python.command.python.datascience.extendSelectionByCellAbove.title%",
"category": "Python"
},
{
"command": "python.datascience.extendSelectionByCellBelow",
"title": "%python.command.python.datascience.extendSelectionByCellBelow.title%",
"category": "Python"
},
{
"command": "python.datascience.moveCellsUp",
"title": "%python.command.python.datascience.moveCellsUp.title%",
"category": "Python"
},
{
"command": "python.datascience.moveCellsDown",
"title": "%python.command.python.datascience.moveCellsDown.title%",
"category": "Python"
},
{
"command": "python.datascience.changeCellToMarkdown",
"title": "%python.command.python.datascience.changeCellToMarkdown.title%",
"category": "Python"
},
{
"command": "python.datascience.changeCellToCode",
"title": "%python.command.python.datascience.changeCellToCode.title%",
"category": "Python"
},
{
"command": "python.datascience.runcurrentcelladvance",
"title": "%python.command.python.datascience.runcurrentcelladvance.title%",
Expand Down Expand Up @@ -942,6 +1002,78 @@
"category": "Python",
"when": "config.noExists"
},
{
"command": "python.datascience.insertCellBelowPosition",
"title": "%python.command.python.datascience.insertCellBelowPosition.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.insertCellBelow",
"title": "%python.command.python.datascience.insertCellBelow.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.insertCellAbove",
"title": "%python.command.python.datascience.insertCellAbove.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.deleteCells",
"title": "%python.command.python.datascience.deleteCells.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.selectCell",
"title": "%python.command.python.datascience.selectCell.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.selectCellContents",
"title": "%python.command.python.datascience.selectCellContents.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ispythonornativeactive will ensure this command is available in python files and notebook.
However in notebooks it does nothing. If this purpose of this PR is to add commnds for interactive window, then we shouldn't use this condition, i.e. it should be done only when a python file is active, e.,g. python.datascience.hascodecells && editorFocus && editorLangId == python && python.datascience.featureenabled

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I.e. we need to ensure these commands are only displayed when we are in a python file with cells.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @DonJayamanne. I pushed up a change for that. Should that also be the same for runcurrentcell or runcurrentcelladvance? Those are what I modeled my choices after.

},
{
"command": "python.datascience.extendSelectionByCellAbove",
"title": "%python.command.python.datascience.extendSelectionByCellAbove.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.extendSelectionByCellBelow",
"title": "%python.command.python.datascience.extendSelectionByCellBelow.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.moveCellsUp",
"title": "%python.command.python.datascience.moveCellsUp.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.moveCellsDown",
"title": "%python.command.python.datascience.moveCellsDown.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.changeCellToMarkdown",
"title": "%python.command.python.datascience.changeCellToMarkdown.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.changeCellToCode",
"title": "%python.command.python.datascience.changeCellToCode.title%",
"category": "Python",
"when": "python.datascience.hascodecells && python.datascience.featureenabled && python.datascience.ispythonornativeactive"
},
{
"command": "python.datascience.runcurrentcell",
"title": "%python.command.python.datascience.runcurrentcell.title%",
Expand Down
12 changes: 12 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@
"python.command.python.datascience.runcurrentcelladvance.title": "Run Current Cell And Advance",
"python.command.python.datascience.execSelectionInteractive.title": "Run Selection/Line in Python Interactive Window",
"python.command.python.datascience.runcell.title": "Run Cell",
"python.command.python.datascience.insertCellBelowPosition.title": "Insert Cell Below Position",
"python.command.python.datascience.insertCellBelow.title": "Insert Cell Below",
"python.command.python.datascience.insertCellAbove.title": "Insert Cell Above",
"python.command.python.datascience.deleteCells.title": "Delete Selected Cells",
"python.command.python.datascience.selectCell.title": "Select Cell",
"python.command.python.datascience.selectCellContents.title": "Select Cell Contents",
"python.command.python.datascience.extendSelectionByCellAbove.title": "Extend Selection By Cell Above",
"python.command.python.datascience.extendSelectionByCellBelow.title": "Extend Selection By Cell Below",
"python.command.python.datascience.moveCellsUp.title": "Move Selected Cells Up",
"python.command.python.datascience.moveCellsDown.title": "Move Selected Cells Down",
"python.command.python.datascience.changeCellToMarkdown.title": "Change Cell to Markdown",
"python.command.python.datascience.changeCellToCode.title": "Change Cell to Code",
"python.command.python.datascience.showhistorypane.title": "Show Python Interactive Window",
"python.command.python.datascience.selectjupyteruri.title": "Specify local or remote Jupyter server for connections",
"python.command.python.datascience.selectjupytercommandline.title": "Specify Jupyter command line arguments",
Expand Down
12 changes: 12 additions & 0 deletions src/client/common/application/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,18 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
[DSCommands.DebugStop]: [];
[DSCommands.DebugContinue]: [];
[DSCommands.RunCurrentCellAndAddBelow]: [string];
[DSCommands.InsertCellBelowPosition]: [];
[DSCommands.InsertCellBelow]: [];
[DSCommands.InsertCellAbove]: [];
[DSCommands.DeleteCells]: [];
[DSCommands.SelectCell]: [];
[DSCommands.SelectCellContents]: [];
[DSCommands.ExtendSelectionByCellAbove]: [];
[DSCommands.ExtendSelectionByCellBelow]: [];
[DSCommands.MoveCellsUp]: [];
[DSCommands.MoveCellsDown]: [];
[DSCommands.ChangeCellToMarkdown]: [];
[DSCommands.ChangeCellToCode]: [];
[DSCommands.ScrollToCell]: [string, string];
[DSCommands.ViewJupyterOutput]: [];
[DSCommands.ExportAsPythonScript]: [INotebookModel];
Expand Down
9 changes: 1 addition & 8 deletions src/client/datascience/cellFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { IDataScienceSettings, Resource } from '../common/types';
import { noop } from '../common/utils/misc';
import { CellMatcher } from './cellMatcher';
import { Identifiers } from './constants';
import { CellState, ICell } from './types';
import { CellState, ICell, ICellRange } from './types';

function generateCodeCell(
code: string[],
Expand Down Expand Up @@ -109,13 +109,6 @@ export function hasCells(document: TextDocument, settings?: IDataScienceSettings
return false;
}

// CellRange is used as the basis for creating new ICells. We only use it in this file.
export interface ICellRange {
range: Range;
title: string;
cell_type: string;
}

export function generateCellsFromString(source: string, settings?: IDataScienceSettings): ICell[] {
const lines: string[] = source.splitLines({ trim: false, removeEmptyEntries: false });

Expand Down
5 changes: 3 additions & 2 deletions src/client/datascience/cellMatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ import { noop } from '../common/utils/misc';
import { RegExpValues } from './constants';

export class CellMatcher {
public codeExecRegEx: RegExp;
public markdownExecRegEx: RegExp;

private codeMatchRegEx: RegExp;
private markdownMatchRegEx: RegExp;
private codeExecRegEx: RegExp;
private markdownExecRegEx: RegExp;
private defaultCellMarker: string;
private defaultCellMarkerExec: RegExp;

Expand Down
120 changes: 120 additions & 0 deletions src/client/datascience/commands/commandRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,18 @@ export class CommandRegistry implements IDisposable {
this.registerCommand(Commands.ExecSelectionInInteractiveWindow, this.runSelectionOrLine);
this.registerCommand(Commands.RunAllCellsAbove, this.runAllCellsAbove);
this.registerCommand(Commands.RunCellAndAllBelow, this.runCellAndAllBelow);
this.registerCommand(Commands.InsertCellBelowPosition, this.insertCellBelowPosition);
this.registerCommand(Commands.InsertCellBelow, this.insertCellBelow);
this.registerCommand(Commands.InsertCellAbove, this.insertCellAbove);
this.registerCommand(Commands.DeleteCells, this.deleteCells);
this.registerCommand(Commands.SelectCell, this.selectCell);
this.registerCommand(Commands.SelectCellContents, this.selectCellContents);
this.registerCommand(Commands.ExtendSelectionByCellAbove, this.extendSelectionByCellAbove);
this.registerCommand(Commands.ExtendSelectionByCellBelow, this.extendSelectionByCellBelow);
this.registerCommand(Commands.MoveCellsUp, this.moveCellsUp);
this.registerCommand(Commands.MoveCellsDown, this.moveCellsDown);
this.registerCommand(Commands.ChangeCellToMarkdown, this.changeCellToMarkdown);
this.registerCommand(Commands.ChangeCellToCode, this.changeCellToCode);
this.registerCommand(Commands.RunAllCellsAbovePalette, this.runAllCellsAboveFromCursor);
this.registerCommand(Commands.RunCellAndAllBelowPalette, this.runCellAndAllBelowFromCursor);
this.registerCommand(Commands.RunToLine, this.runToLine);
Expand Down Expand Up @@ -305,6 +317,114 @@ export class CommandRegistry implements IDisposable {
}
}

private async insertCellBelowPosition(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.insertCellBelowPosition();
} else {
return Promise.resolve();
}
}

private async insertCellBelow(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.insertCellBelow();
} else {
return Promise.resolve();
}
}

private async insertCellAbove(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.insertCellAbove();
} else {
return Promise.resolve();
}
}

private async deleteCells(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.deleteCells();
} else {
return Promise.resolve();
}
}

private async selectCell(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.selectCell();
} else {
return Promise.resolve();
}
}

private async selectCellContents(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.selectCellContents();
} else {
return Promise.resolve();
}
}

private async extendSelectionByCellAbove(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.extendSelectionByCellAbove();
} else {
return Promise.resolve();
}
}

private async extendSelectionByCellBelow(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.extendSelectionByCellBelow();
} else {
return Promise.resolve();
}
}

private async moveCellsUp(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.moveCellsUp();
} else {
return Promise.resolve();
}
}

private async moveCellsDown(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.moveCellsDown();
} else {
return Promise.resolve();
}
}

private async changeCellToMarkdown(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.changeCellToMarkdown();
} else {
return Promise.resolve();
}
}

private async changeCellToCode(): Promise<void> {
const activeCodeWatcher = this.getCurrentCodeWatcher();
if (activeCodeWatcher) {
return activeCodeWatcher.changeCellToCode();
} else {
return Promise.resolve();
}
}

private async runAllCellsAboveFromCursor(): Promise<void> {
const currentCodeLens = this.getCurrentCodeLens();
if (currentCodeLens) {
Expand Down
26 changes: 26 additions & 0 deletions src/client/datascience/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,18 @@ export namespace Commands {
export const DebugContinue = 'python.datascience.debugcontinue';
export const DebugStop = 'python.datascience.debugstop';
export const RunCurrentCellAndAddBelow = 'python.datascience.runcurrentcellandaddbelow';
export const InsertCellBelowPosition = 'python.datascience.insertCellBelowPosition';
export const InsertCellBelow = 'python.datascience.insertCellBelow';
export const InsertCellAbove = 'python.datascience.insertCellAbove';
export const DeleteCells = 'python.datascience.deleteCells';
export const SelectCell = 'python.datascience.selectCell';
export const SelectCellContents = 'python.datascience.selectCellContents';
export const ExtendSelectionByCellAbove = 'python.datascience.extendSelectionByCellAbove';
export const ExtendSelectionByCellBelow = 'python.datascience.extendSelectionByCellBelow';
export const MoveCellsUp = 'python.datascience.moveCellsUp';
export const MoveCellsDown = 'python.datascience.moveCellsDown';
export const ChangeCellToMarkdown = 'python.datascience.changeCellToMarkdown';
export const ChangeCellToCode = 'python.datascience.changeCellToCode';
export const ScrollToCell = 'python.datascience.scrolltocell';
export const CreateNewNotebook = 'python.datascience.createnewnotebook';
export const ViewJupyterOutput = 'python.datascience.viewJupyterOutput';
Expand Down Expand Up @@ -156,6 +168,20 @@ export enum Telemetry {
RunAllCells = 'DATASCIENCE.RUN_ALL_CELLS',
RunAllCellsAbove = 'DATASCIENCE.RUN_ALL_CELLS_ABOVE',
RunCellAndAllBelow = 'DATASCIENCE.RUN_CELL_AND_ALL_BELOW',
AddEmptyCellToBottom = 'DATASCIENCE.RUN_ADD_EMPTY_CELL_TO_BOTTOM',
RunCurrentCellAndAddBelow = 'DATASCIENCE.RUN_CURRENT_CELL_AND_ADD_BELOW',
InsertCellBelowPosition = 'DATASCIENCE.RUN_INSERT_CELL_BELOW_POSITION',
InsertCellBelow = 'DATASCIENCE.RUN_INSERT_CELL_BELOW',
InsertCellAbove = 'DATASCIENCE.RUN_INSERT_CELL_ABOVE',
DeleteCells = 'DATASCIENCE.RUN_DELETE_CELLS',
SelectCell = 'DATASCIENCE.RUN_SELECT_CELL',
SelectCellContents = 'DATASCIENCE.RUN_SELECT_CELL_CONTENTS',
ExtendSelectionByCellAbove = 'DATASCIENCE.RUN_EXTEND_SELECTION_BY_CELL_ABOVE',
ExtendSelectionByCellBelow = 'DATASCIENCE.RUN_EXTEND_SELECTION_BY_CELL_BELOW',
MoveCellsUp = 'DATASCIENCE.RUN_MOVE_CELLS_UP',
MoveCellsDown = 'DATASCIENCE.RUN_MOVE_CELLS_DOWN',
ChangeCellToMarkdown = 'DATASCIENCE.RUN_CHANGE_CELL_TO_MARKDOWN',
ChangeCellToCode = 'DATASCIENCE.RUN_CHANGE_CELL_TO_CODE',
RunSelectionOrLine = 'DATASCIENCE.RUN_SELECTION_OR_LINE',
RunToLine = 'DATASCIENCE.RUN_TO_LINE',
RunFromLine = 'DATASCIENCE.RUN_FROM_LINE',
Expand Down
Loading