@@ -2,6 +2,14 @@ import vscode from 'vscode';
2
2
import { detectLanguage } from './processors/detectLanguage' ;
3
3
import { fileHeaders } from './processors/fileHeaders' ;
4
4
import { languages } from './processors/languages' ;
5
+ import { config } from '../config' ;
6
+
7
+ var decoder = new TextDecoder ( "utf8" ) ;
8
+
9
+ function getNotebookDocument ( document : vscode . TextDocument ) : vscode . NotebookDocument | undefined {
10
+ return vscode . workspace . notebookDocuments
11
+ . find ( x => x . uri . path === document . uri . path ) ;
12
+ }
5
13
6
14
export async function preparePrompt ( document : vscode . TextDocument , position : vscode . Position , context : vscode . InlineCompletionContext ) {
7
15
@@ -11,6 +19,75 @@ export async function preparePrompt(document: vscode.TextDocument, position: vsc
11
19
let prefix = text . slice ( 0 , offset ) ;
12
20
let suffix : string = text . slice ( offset ) ;
13
21
22
+ let notebookConfig = config . notebook ;
23
+
24
+ // If this is a notebook, add the surrounding cells to the prefix and suffix
25
+ let notebookDocument = getNotebookDocument ( document ) ;
26
+ let language = detectLanguage ( document . uri . fsPath , document . languageId ) ;
27
+ let commentStart : string | undefined = undefined ;
28
+ if ( language ) {
29
+ commentStart = languages [ language ] . comment ?. start ;
30
+ }
31
+
32
+ if ( notebookDocument ) {
33
+ let beforeCurrentCell = true ;
34
+
35
+ let prefixCells = "" ;
36
+ let suffixCells = "" ;
37
+
38
+ notebookDocument . getCells ( ) . forEach ( ( cell ) => {
39
+ let out = "" ;
40
+
41
+ if ( cell . document . uri . fragment === document . uri . fragment ) {
42
+ beforeCurrentCell = false ; // switch to suffix mode
43
+ return ;
44
+ }
45
+
46
+ // add the markdown cell output to the prompt as a comment
47
+ if ( cell . kind === vscode . NotebookCellKind . Markup && commentStart ) {
48
+ if ( notebookConfig . includeMarkup ) {
49
+ for ( const line of cell . document . getText ( ) . split ( '\n' ) ) {
50
+ out += `\n${ commentStart } ${ line } ` ;
51
+ }
52
+ }
53
+ } else {
54
+ out += cell . document . getText ( ) ;
55
+ }
56
+
57
+ // if there is any outputs add them to the prompt as a comment
58
+ const addCellOutputs = notebookConfig . includeCellOutputs
59
+ && beforeCurrentCell
60
+ && cell . kind === vscode . NotebookCellKind . Code
61
+ && commentStart ;
62
+ if ( addCellOutputs ) {
63
+ let cellOutputs = cell . outputs
64
+ . map ( x => x . items
65
+ . filter ( x => x . mime === 'text/plain' )
66
+ . map ( x => decoder . decode ( x . data ) )
67
+ . map ( x => x . slice ( 0 , notebookConfig . cellOutputLimit ) . split ( '\n' ) ) )
68
+ . flat ( 3 ) ;
69
+
70
+ if ( cellOutputs . length > 0 ) {
71
+ out += `\n${ commentStart } Output:` ;
72
+ for ( const line of cellOutputs ) {
73
+ out += `\n${ commentStart } ${ line } ` ;
74
+ }
75
+ }
76
+ }
77
+
78
+ // update the prefix/suffix
79
+ if ( beforeCurrentCell ) {
80
+ prefixCells += out ;
81
+ } else {
82
+ suffixCells += out ;
83
+ }
84
+
85
+ } ) ;
86
+
87
+ prefix = prefixCells + prefix ;
88
+ suffix = suffix + suffixCells ;
89
+ }
90
+
14
91
// Trim suffix
15
92
// If suffix is too small it is safe to assume that it could be ignored which would allow us to use
16
93
// more powerful completition instead of in middle one
@@ -22,7 +99,6 @@ export async function preparePrompt(document: vscode.TextDocument, position: vsc
22
99
// NOTE: Most networks don't have a concept of filenames and expected language, but we expect that some files in training set has something in title that
23
100
// would indicate filename and language
24
101
// NOTE: If we can't detect language, we could ignore this since the number of languages that need detection is limited
25
- let language = detectLanguage ( document . uri . fsPath , document . languageId ) ;
26
102
if ( language ) {
27
103
prefix = fileHeaders ( prefix , document . uri . fsPath , languages [ language ] ) ;
28
104
}
0 commit comments