@@ -22,19 +22,87 @@ import { AuthUtil } from './authUtil'
2222
2323let tabSize : number = getTabSizeSetting ( )
2424
25+ const languageCommentChars : Record < string , string > = {
26+ python : '# ' ,
27+ java : '// ' ,
28+ }
29+
30+ export function extractSingleCellContext ( cell : vscode . NotebookCell , commentPrefix : string ) : string {
31+ const cellText = cell . document . getText ( )
32+ if ( cell . kind === vscode . NotebookCellKind . Markup ) {
33+ // Converting markdown to a comment block is language dependent.
34+ // If a commentPrefix is specified, add it to each line of markdown.
35+ // Otherwise, just return the text as is.
36+ if ( commentPrefix === '' ) {
37+ return cellText
38+ }
39+ return cell . document
40+ . getText ( )
41+ . split ( '\n' )
42+ . map ( ( line ) => `${ commentPrefix } ${ line } ` )
43+ . join ( '\n' )
44+ }
45+ return cellText
46+ }
47+
48+ export function extractPrefixCellsContext (
49+ cells : vscode . NotebookCell [ ] ,
50+ maxLength : number ,
51+ commentPrefix : string
52+ ) : string {
53+ const output : string [ ] = [ ]
54+ for ( let i = cells . length - 1 ; i >= 0 ; i -- ) {
55+ let cellText = extractSingleCellContext ( cells [ i ] , commentPrefix )
56+ if ( cellText . length > 0 ) {
57+ if ( ! cellText . endsWith ( '\n' ) ) {
58+ cellText += '\n'
59+ }
60+ if ( cellText . length >= maxLength ) {
61+ output . unshift ( cellText . substring ( cellText . length - maxLength ) )
62+ break
63+ }
64+ output . unshift ( cellText )
65+ maxLength -= cellText . length
66+ }
67+ }
68+ return output . join ( '' )
69+ }
70+
71+ export function extractSuffixCellsContext (
72+ cells : vscode . NotebookCell [ ] ,
73+ maxLength : number ,
74+ commentPrefix : string
75+ ) : string {
76+ const output : string [ ] = [ ]
77+ for ( let i = 0 ; i < cells . length ; i ++ ) {
78+ let cellText = extractSingleCellContext ( cells [ i ] , commentPrefix )
79+ if ( cellText . length > 0 ) {
80+ if ( ! cellText . endsWith ( '\n' ) ) {
81+ cellText += '\n'
82+ }
83+ if ( cellText . length >= maxLength ) {
84+ output . push ( cellText . substring ( 0 , maxLength ) )
85+ break
86+ }
87+ output . push ( cellText )
88+ maxLength -= cellText . length
89+ }
90+ }
91+ return output . join ( '' )
92+ }
93+
2594export function extractContextForCodeWhisperer ( editor : vscode . TextEditor ) : codewhispererClient . FileContext {
2695 const document = editor . document
2796 const curPos = editor . selection . active
2897 const offset = document . offsetAt ( curPos )
2998
30- const caretLeftFileContext = editor . document . getText (
99+ let caretLeftFileContext = editor . document . getText (
31100 new vscode . Range (
32101 document . positionAt ( offset - CodeWhispererConstants . charactersLimit ) ,
33102 document . positionAt ( offset )
34103 )
35104 )
36-
37- const caretRightFileContext = editor . document . getText (
105+ let caretRightFileContext = editor . document . getText (
38106 new vscode . Range (
39107 document . positionAt ( offset ) ,
40108 document . positionAt ( offset + CodeWhispererConstants . charactersLimit )
@@ -45,6 +113,45 @@ export function extractContextForCodeWhisperer(editor: vscode.TextEditor): codew
45113 languageName =
46114 runtimeLanguageContext . normalizeLanguage ( editor . document . languageId ) ?? editor . document . languageId
47115 }
116+ if ( editor . document . uri . scheme === 'vscode-notebook-cell' ) {
117+ // For notebook cells, first find the existing notebook with a cell that matches the current editor.
118+ const notebook = vscode . workspace . notebookDocuments . find (
119+ ( nb ) =>
120+ nb . notebookType === 'jupyter-notebook' &&
121+ nb . getCells ( ) . some ( ( cell ) => cell . document === editor . document )
122+ )
123+ if ( notebook ) {
124+ const allCells = notebook . getCells ( )
125+ const cellIndex = allCells . findIndex ( ( cell ) => cell . document === editor . document )
126+
127+ // Add appropriate comment string at beginning of each line if language is recognized
128+ const commentPrefix = languageCommentChars [ languageName ] ?? ''
129+
130+ // Extract text from prior cells if there is enough room in left file context
131+ if ( caretLeftFileContext . length < CodeWhispererConstants . charactersLimit - 1 ) {
132+ const leftCellsText = extractPrefixCellsContext (
133+ allCells . slice ( 0 , cellIndex ) ,
134+ CodeWhispererConstants . charactersLimit - ( caretLeftFileContext . length + 1 ) ,
135+ commentPrefix
136+ )
137+ if ( leftCellsText . length > 0 ) {
138+ caretLeftFileContext = leftCellsText + '\n' + caretLeftFileContext
139+ }
140+ }
141+ // Extract text from subsequent cells if there is enough room in right file context
142+ if ( caretRightFileContext . length < CodeWhispererConstants . charactersLimit - 1 ) {
143+ const rightCellsText = extractSuffixCellsContext (
144+ allCells . slice ( cellIndex + 1 ) ,
145+ CodeWhispererConstants . charactersLimit - ( caretRightFileContext . length + 1 ) ,
146+ commentPrefix
147+ )
148+ if ( rightCellsText . length > 0 ) {
149+ caretRightFileContext = caretRightFileContext + '\n' + rightCellsText
150+ }
151+ }
152+ }
153+ }
154+
48155 return {
49156 filename : getFileRelativePath ( editor ) ,
50157 programmingLanguage : {
0 commit comments