11import * as vscode from 'vscode' ;
2- import { Commands } from '../../common/constants' ;
3- import { JupyterCodeLensProvider } from '../editorIntegration/codeLensProvider' ;
2+ import { Commands } from '../../common/constants' ;
3+ import { JupyterCodeLensProvider } from '../editorIntegration/codeLensProvider' ;
4+ import { CellHelper } from '../common/cellHelper' ;
45
56export class CellOptions extends vscode . Disposable {
67 private disposables : vscode . Disposable [ ] ;
8+ private cellHelper : CellHelper ;
79 constructor ( private cellCodeLenses : JupyterCodeLensProvider ) {
810 super ( ( ) => { } ) ;
11+ this . cellHelper = new CellHelper ( this . cellCodeLenses ) ;
912 this . disposables = [ ] ;
1013 this . registerCommands ( ) ;
1114 }
@@ -15,107 +18,31 @@ export class CellOptions extends vscode.Disposable {
1518
1619 private registerCommands ( ) {
1720 this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . DisplayCellMenu , this . displayCellOptions . bind ( this ) ) ) ;
18- this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . AdcanceToCell , this . advanceToCell . bind ( this ) ) ) ;
21+ this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . AdcanceToCell , this . cellHelper . advanceToCell . bind ( this . cellHelper ) ) ) ;
1922 this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . ExecuteCurrentCell , this . executeCell . bind ( this , false ) ) ) ;
2023 this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . ExecuteCurrentCellAndAdvance , this . executeCell . bind ( this , true ) ) ) ;
21- this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . GoToNextCell , this . goToNextCell . bind ( this ) ) ) ;
22- this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . GoToPreviousCell , this . goToPreviousCell . bind ( this ) ) ) ;
24+ this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . GoToNextCell , this . cellHelper . goToNextCell . bind ( this . cellHelper ) ) ) ;
25+ this . disposables . push ( vscode . commands . registerCommand ( Commands . Jupyter . Cell . GoToPreviousCell , this . cellHelper . goToPreviousCell . bind ( this . cellHelper ) ) ) ;
2326 }
24- private getActiveCell ( ) : Thenable < { cell : vscode . Range , nextCell ?: vscode . Range , previousCell ?: vscode . Range } > {
25- const activeEditor = vscode . window . activeTextEditor ;
26- if ( ! activeEditor || ! activeEditor . document ) {
27- return Promise . resolve ( null ) ;
28- }
2927
30- return this . cellCodeLenses . provideCodeLenses ( activeEditor . document , null ) . then ( lenses => {
31- let currentCellRange : vscode . Range ;
32- let nextCellRange : vscode . Range ;
33- let previousCellRange : vscode . Range ;
34- lenses . forEach ( ( lens , index ) => {
35- if ( lens . range . contains ( activeEditor . selection . start ) ) {
36- currentCellRange = lens . range ;
37- if ( index < ( lenses . length - 1 ) ) {
38- nextCellRange = lenses [ index + 1 ] . range ;
39- }
40- if ( index > 0 ) {
41- previousCellRange = lenses [ index - 1 ] . range ;
42- }
43- }
44- } ) ;
45- if ( ! currentCellRange ) {
46- return null ;
47- }
48- return { cell : currentCellRange , nextCell : nextCellRange , previousCell : previousCellRange } ;
49- } ) ;
50- }
51- private goToPreviousCell ( ) : Thenable < any > {
52- const activeEditor = vscode . window . activeTextEditor ;
53- if ( ! activeEditor || ! activeEditor . document ) {
54- return Promise . resolve ( ) ;
55- }
56- return this . getActiveCell ( ) . then ( cellInfo => {
57- if ( ! cellInfo || ! cellInfo . previousCell ) {
58- return ;
59- }
60- return this . advanceToCell ( activeEditor . document , cellInfo . previousCell ) ;
61- } ) ;
62- }
63- private goToNextCell ( ) : Thenable < any > {
64- const activeEditor = vscode . window . activeTextEditor ;
65- if ( ! activeEditor || ! activeEditor . document ) {
66- return Promise . resolve ( ) ;
67- }
68- return this . getActiveCell ( ) . then ( cellInfo => {
69- if ( ! cellInfo || ! cellInfo . nextCell ) {
70- return ;
71- }
72- return this . advanceToCell ( activeEditor . document , cellInfo . nextCell ) ;
73- } ) ;
74- }
7528 private executeCell ( advanceToNext : boolean ) : Thenable < any > {
7629 const activeEditor = vscode . window . activeTextEditor ;
7730 if ( ! activeEditor || ! activeEditor . document ) {
7831 return Promise . resolve ( ) ;
7932 }
8033
81- return this . getActiveCell ( ) . then ( cellInfo => {
34+ return this . cellHelper . getActiveCell ( ) . then ( cellInfo => {
8235 if ( ! cellInfo || ! cellInfo . cell ) {
8336 return ;
8437 }
8538 return vscode . commands . executeCommand ( Commands . Jupyter . ExecuteRangeInKernel , activeEditor . document , cellInfo . cell ) . then ( ( ) => {
8639 if ( ! advanceToNext ) {
8740 return ;
8841 }
89- return this . advanceToCell ( activeEditor . document , cellInfo . nextCell ) ;
42+ return this . cellHelper . advanceToCell ( activeEditor . document , cellInfo . nextCell ) ;
9043 } ) ;
9144 } ) ;
9245 }
93- private advanceToCell ( document : vscode . TextDocument , range : vscode . Range ) : Promise < any > {
94- if ( ! range || ! document ) {
95- return ;
96- }
97- const textEditor = vscode . window . visibleTextEditors . find ( editor => editor . document && editor . document . fileName === document . fileName ) ;
98- if ( ! textEditor ) {
99- return ;
100- }
101-
102- // Remember, we use comments to identify cells
103- // Setting the cursor to the comment doesn't make sense
104- // Quirk 1: Besides the document highlighter doesn't kick in (event' not fired), when you have placed the cursor on a comment
105- // Quirk 2: If the first character starts with a %, then for some reason the highlighter doesn't kick in (event' not fired)
106- let firstLineOfCellRange = range ;
107- if ( range . start . line < range . end . line ) {
108- // let line = textEditor.document.lineAt(range.start.line + 1);
109- // let start = new vscode.Position(range.start.line + 1, range.start.character);
110- // firstLineOfCellRange = new vscode.Range(start, range.end);
111- const start = this . findStartPositionWithCode ( document , range . start . line + 1 , range . end . line ) ;
112- firstLineOfCellRange = new vscode . Range ( start , range . end ) ;
113- }
114- textEditor . selections = [ ] ;
115- textEditor . selection = new vscode . Selection ( firstLineOfCellRange . start , firstLineOfCellRange . start ) ;
116- textEditor . revealRange ( range ) ;
117- vscode . window . showTextDocument ( textEditor . document ) ;
118- }
11946 private displayCellOptions ( document : vscode . TextDocument , range : vscode . Range , nextCellRange ?: vscode . Range ) {
12047 interface Option extends vscode . QuickPickItem {
12148 command : string ;
@@ -154,24 +81,4 @@ export class CellOptions extends vscode.Disposable {
15481 } ) ;
15582 }
15683
157- private findStartPositionWithCode ( document : vscode . TextDocument , startLine : number , endLine : number ) : vscode . Position {
158- for ( let lineNumber = startLine ; lineNumber < endLine ; lineNumber ++ ) {
159- let line = document . lineAt ( startLine ) ;
160- if ( line . isEmptyOrWhitespace ) {
161- continue ;
162- }
163- const lineText = line . text ;
164- const trimmedLine = lineText . trim ( ) ;
165- if ( trimmedLine . startsWith ( '#' ) ) {
166- continue ;
167- }
168- // Yay we have a line
169- // Remember, we need to set the cursor to a character other than white space
170- // Highlighting doesn't kick in for comments or white space
171- return new vscode . Position ( lineNumber , lineText . indexOf ( trimmedLine ) ) ;
172- }
173-
174- // give up
175- return new vscode . Position ( startLine , 0 ) ;
176- }
17784}
0 commit comments