@@ -12,32 +12,45 @@ import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer'
1212import { DisposableStore } from 'vs/base/common/lifecycle' ;
1313import { score } from 'vs/editor/common/modes/languageSelector' ;
1414import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon' ;
15- import { isEqual } from 'vs/base/common/resources' ;
15+ import { basename } from 'vs/base/common/resources' ;
16+ import { ResourceMap } from 'vs/base/common/map' ;
17+ import { ExtHostDocumentLine } from 'vs/workbench/api/common/extHostDocumentData' ;
1618
17- export class ExtHostNotebookConcatDocument implements vscode . NotebookConcatTextDocument {
19+ export class ExtHostNotebookConcatDocument implements vscode . NotebookConcatTextDocument , vscode . TextDocument {
1820
1921 private _disposables = new DisposableStore ( ) ;
2022 private _isClosed = false ;
2123
2224 private _cells ! : ExtHostCell [ ] ;
25+ private _cellByUri ! : ResourceMap < number > ;
2326 private _cellLengths ! : PrefixSumComputer ;
2427 private _cellLines ! : PrefixSumComputer ;
2528 private _versionId = 0 ;
2629
2730 private readonly _onDidChange = new Emitter < void > ( ) ;
2831 readonly onDidChange : Event < void > = this . _onDidChange . event ;
2932
33+ readonly uri : vscode . Uri ;
34+ readonly fileName : string ;
35+ readonly languageId : string ;
36+ readonly isUntitled : boolean = false ;
37+ readonly isDirty : boolean = false ;
38+
3039 constructor (
3140 extHostNotebooks : ExtHostNotebookController ,
3241 extHostDocuments : ExtHostDocuments ,
3342 private readonly _notebook : vscode . NotebookDocument ,
3443 private readonly _selector : vscode . DocumentSelector | undefined ,
3544 ) {
45+ this . uri = _notebook . uri . with ( { scheme : 'vscode-notebook-concat-doc' } ) ;
46+ this . fileName = basename ( this . uri ) ;
47+ this . languageId = this . _createLanguageId ( ) ;
48+
3649 this . _init ( ) ;
3750
3851 this . _disposables . add ( extHostDocuments . onDidChangeDocument ( e => {
39- let cellIdx = this . _cells . findIndex ( cell => isEqual ( cell . uri , e . document . uri ) ) ;
40- if ( cellIdx >= 0 ) {
52+ const cellIdx = this . _cellByUri . get ( e . document . uri ) ;
53+ if ( typeof cellIdx === 'number' ) {
4154 this . _cellLengths . changeValue ( cellIdx , this . _cells [ cellIdx ] . document . getText ( ) . length + 1 ) ;
4255 this . _cellLines . changeValue ( cellIdx , this . _cells [ cellIdx ] . document . lineCount ) ;
4356 this . _versionId += 1 ;
@@ -68,10 +81,12 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
6881
6982 private _init ( ) {
7083 this . _cells = [ ] ;
84+ this . _cellByUri = new ResourceMap ( ) ;
7185 const cellLengths : number [ ] = [ ] ;
7286 const cellLineCounts : number [ ] = [ ] ;
7387 for ( let cell of this . _notebook . cells ) {
7488 if ( cell . cellKind === CellKind . Code && ( ! this . _selector || score ( this . _selector , cell . uri , cell . language , true ) ) ) {
89+ this . _cellByUri . set ( cell . uri , this . _cells . length ) ;
7590 this . _cells . push ( < ExtHostCell > cell ) ;
7691 cellLengths . push ( cell . document . getText ( ) . length + 1 ) ;
7792 cellLineCounts . push ( cell . document . lineCount ) ;
@@ -81,6 +96,67 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
8196 this . _cellLines = new PrefixSumComputer ( new Uint32Array ( cellLineCounts ) ) ;
8297 }
8398
99+ private _createLanguageId ( ) : string {
100+ const languageIds = new Set < string > ( ) ;
101+ ( function fillInLanguageIds ( selector : vscode . DocumentSelector | undefined ) {
102+ if ( Array . isArray ( selector ) ) {
103+ selector . forEach ( fillInLanguageIds ) ;
104+ } else if ( typeof selector === 'string' ) {
105+ languageIds . add ( selector ) ;
106+ } else if ( selector ?. language ) {
107+ languageIds . add ( selector . language ) ;
108+ }
109+ } ) ( this . _selector ) ;
110+
111+ if ( languageIds . size === 0 ) {
112+ return 'unknown' ;
113+ }
114+ return [ ...languageIds . values ( ) ] . sort ( ) . join ( ';' ) ;
115+ }
116+
117+ save ( ) : Thenable < boolean > {
118+ // todo@jrieken throw error instead?
119+ return Promise . resolve ( false ) ;
120+ }
121+
122+ get eol ( ) : vscode . EndOfLine {
123+ return types . EndOfLine . LF ;
124+ }
125+
126+ get lineCount ( ) : number {
127+ let total = 0 ;
128+ for ( let cell of this . _cells ) {
129+ total += cell . document . lineCount ;
130+ }
131+ return total ;
132+ }
133+
134+ lineAt ( lineOrPosition : number | vscode . Position ) : vscode . TextLine {
135+ const line = typeof lineOrPosition === 'number' ? lineOrPosition : lineOrPosition . line ;
136+ const cellIdx = this . _cellLines . getIndexOf ( line ) ;
137+ return new ExtHostDocumentLine (
138+ line ,
139+ this . _cells [ cellIdx . index ] . document . lineAt ( cellIdx . remainder ) . text ,
140+ line >= this . lineCount
141+ ) ;
142+ }
143+
144+ getWordRangeAtPosition ( position : vscode . Position , regex ?: RegExp | undefined ) : vscode . Range | undefined {
145+ const cellIdx = this . _cellLines . getIndexOf ( position . line ) ;
146+ return this . _cells [ cellIdx . index ] . document . getWordRangeAtPosition ( position . with ( { line : cellIdx . remainder } ) , regex ) ;
147+ }
148+
149+ validateRange ( range : vscode . Range ) : vscode . Range {
150+ const start = this . validatePosition ( range . start ) ;
151+ const end = this . validatePosition ( range . end ) ;
152+ return range . with ( { start, end } ) ;
153+ }
154+
155+ validatePosition ( position : vscode . Position ) : vscode . Position {
156+ const cellIdx = this . _cellLines . getIndexOf ( position . line ) ;
157+ return this . _cells [ cellIdx . index ] . document . validatePosition ( position . with ( { line : cellIdx . remainder } ) ) ;
158+ }
159+
84160 get version ( ) : number {
85161 return this . _versionId ;
86162 }
@@ -103,8 +179,8 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
103179 // get start and end locations and create substrings
104180 const start = this . locationAt ( range . start ) ;
105181 const end = this . locationAt ( range . end ) ;
106- const startCell = this . _cells . find ( cell => isEqual ( cell . uri , start . uri ) ) ;
107- const endCell = this . _cells . find ( cell => isEqual ( cell . uri , end . uri ) ) ;
182+ const startCell = this . _cells [ this . _cellByUri . get ( start . uri ) ?? - 1 ] ;
183+ const endCell = this . _cells [ this . _cellByUri . get ( end . uri ) ?? - 1 ] ;
108184
109185 if ( ! startCell || ! endCell ) {
110186 return '' ;
@@ -131,8 +207,8 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
131207 return this . _cells [ idx . index ] . document . positionAt ( idx . remainder ) . translate ( lineCount ) ;
132208 }
133209
134- const idx = this . _cells . findIndex ( cell => isEqual ( cell . uri , locationOrOffset . uri ) ) ;
135- if ( idx >= 0 ) {
210+ const idx = this . _cellByUri . get ( locationOrOffset . uri ) ;
211+ if ( typeof idx === 'number' ) {
136212 let line = this . _cellLines . getAccumulatedValue ( idx - 1 ) ;
137213 return new types . Position ( line + locationOrOffset . range . start . line , locationOrOffset . range . start . character ) ;
138214 }
0 commit comments