@@ -32,7 +32,13 @@ export async function resolveContextExpression(): Promise<void> {
3232 const data = response ?? { } ;
3333
3434 if ( typeof data === "string" ) {
35- await handleContextHelpDocumentationContent ( data ) ;
35+ const { previewContent, textExpression } = extractEmbeddedContextExpression ( data ) ;
36+
37+ if ( textExpression && textExpression . trim ( ) ) {
38+ await applyResolvedTextExpression ( editor , document , selection , contextInfo , contextExpression , textExpression ) ;
39+ }
40+
41+ await handleContextHelpDocumentationContent ( previewContent ) ;
3642 return ;
3743 }
3844
@@ -49,43 +55,14 @@ export async function resolveContextExpression(): Promise<void> {
4955 }
5056
5157 if ( isSuccessfulTextExpression ( data ) ) {
52- const hasGifCommand = / - - g i f \b / i. test ( contextExpression ) ;
53- let normalizedTextExpression = data . textExpression . replace ( / \r ? \n / g, "\n" ) ;
54- let gifUri : vscode . Uri | undefined ;
55-
56- if ( hasGifCommand ) {
57- const extracted = extractGifUri ( normalizedTextExpression ) ;
58- normalizedTextExpression = extracted . textWithoutGifUri ;
59- gifUri = extracted . gifUri ;
60- }
61-
62- if ( ! hasGifCommand ) {
63- const eol = document . eol === vscode . EndOfLine . CRLF ? "\r\n" : "\n" ;
64- const textExpression = normalizedTextExpression . replace ( / \r ? \n / g, eol ) ;
65- const formattedTextExpression = textExpression ;
66-
67- let rangeToReplace : vscode . Range ;
68- if ( selection . isEmpty ) {
69- const fallbackLine = document . lineAt ( selection . active . line ) ;
70- rangeToReplace = fallbackLine . range ;
71- } else {
72- const start = document . lineAt ( selection . start . line ) . range . start ;
73- const replacementEnd = contextInfo . replacementEnd ?? document . lineAt ( selection . end . line ) . range . end ;
74- rangeToReplace = new vscode . Range ( start , replacementEnd ) ;
75- }
76-
77- await editor . edit ( ( editBuilder ) => {
78- editBuilder . replace ( rangeToReplace , formattedTextExpression ) ;
79- } ) ;
80- }
81-
82- if ( gifUri ) {
83- try {
84- await showGifInWebview ( gifUri ) ;
85- } catch ( error ) {
86- handleError ( error , "Failed to open GIF from context expression." ) ;
87- }
88- }
58+ await applyResolvedTextExpression (
59+ editor ,
60+ document ,
61+ selection ,
62+ contextInfo ,
63+ contextExpression ,
64+ data . textExpression
65+ ) ;
8966 return ;
9067 }
9168
@@ -159,8 +136,56 @@ function extractGifUri(text: string): {
159136 return { textWithoutGifUri : processedLines . join ( "\n" ) , gifUri } ;
160137}
161138
139+ async function applyResolvedTextExpression (
140+ editor : vscode . TextEditor ,
141+ document : vscode . TextDocument ,
142+ selection : vscode . Selection ,
143+ contextInfo : ContextExpressionInfo ,
144+ contextExpression : string ,
145+ rawTextExpression : string
146+ ) : Promise < void > {
147+ const hasGifCommand = / - - g i f \b / i. test ( contextExpression ) ;
148+ let normalizedTextExpression = rawTextExpression . replace ( / \r ? \n / g, "\n" ) ;
149+ let gifUri : vscode . Uri | undefined ;
150+
151+ if ( hasGifCommand ) {
152+ const extracted = extractGifUri ( normalizedTextExpression ) ;
153+ normalizedTextExpression = extracted . textWithoutGifUri ;
154+ gifUri = extracted . gifUri ;
155+ }
156+
157+ if ( ! hasGifCommand ) {
158+ const eol = document . eol === vscode . EndOfLine . CRLF ? "\r\n" : "\n" ;
159+ const textExpression = normalizedTextExpression . replace ( / \r ? \n / g, eol ) ;
160+ const formattedTextExpression = textExpression ;
161+
162+ let rangeToReplace : vscode . Range ;
163+ if ( selection . isEmpty ) {
164+ const fallbackLine = document . lineAt ( selection . active . line ) ;
165+ rangeToReplace = fallbackLine . range ;
166+ } else {
167+ const start = document . lineAt ( selection . start . line ) . range . start ;
168+ const replacementEnd = contextInfo . replacementEnd ?? document . lineAt ( selection . end . line ) . range . end ;
169+ rangeToReplace = new vscode . Range ( start , replacementEnd ) ;
170+ }
171+
172+ await editor . edit ( ( editBuilder ) => {
173+ editBuilder . replace ( rangeToReplace , formattedTextExpression ) ;
174+ } ) ;
175+ }
176+
177+ if ( gifUri ) {
178+ try {
179+ await showGifInWebview ( gifUri ) ;
180+ } catch ( error ) {
181+ handleError ( error , "Failed to open GIF from context expression." ) ;
182+ }
183+ }
184+ }
185+
162186async function handleContextHelpDocumentationContent ( rawContent : string ) : Promise < void > {
163- const sanitizedContent = sanitizeContextHelpContent ( rawContent ) ;
187+ const { previewContent } = extractEmbeddedContextExpression ( rawContent ) ;
188+ const sanitizedContent = sanitizeContextHelpContent ( previewContent ) ;
164189
165190 if ( ! sanitizedContent . trim ( ) ) {
166191 void vscode . window . showInformationMessage ( "A ajuda de contexto não retornou nenhum conteúdo." ) ;
@@ -176,6 +201,44 @@ async function handleContextHelpDocumentationContent(rawContent: string): Promis
176201 await showContextHelpPreview ( sanitizedContent ) ;
177202}
178203
204+ function extractEmbeddedContextExpression ( content : string ) : {
205+ previewContent : string ;
206+ textExpression ?: string ;
207+ } {
208+ const jsonPattern = / \{ [ \s \S ] * \} \s * $ / ;
209+ const match = jsonPattern . exec ( content ) ;
210+ if ( ! match || match . index === undefined ) {
211+ return { previewContent : content } ;
212+ }
213+
214+ const previewWithoutJson = content . slice ( 0 , match . index ) . replace ( / \s + $ / , "" ) ;
215+ const jsonText = content . slice ( match . index ) . trim ( ) ;
216+
217+ try {
218+ const parsed = JSON . parse ( jsonText ) ;
219+ if ( ! isRecord ( parsed ) ) {
220+ return { previewContent : previewWithoutJson } ;
221+ }
222+
223+ const { status, textExpression } = parsed as ResolveContextExpressionResponse ;
224+ if ( typeof status !== "string" || status . toLowerCase ( ) !== "success" ) {
225+ return { previewContent : previewWithoutJson } ;
226+ }
227+
228+ if ( typeof textExpression !== "string" ) {
229+ return { previewContent : previewWithoutJson } ;
230+ }
231+
232+ if ( ! textExpression . trim ( ) ) {
233+ return { previewContent : previewWithoutJson } ;
234+ }
235+
236+ return { previewContent : previewWithoutJson , textExpression } ;
237+ } catch ( _error ) {
238+ return { previewContent : content } ;
239+ }
240+ }
241+
179242function sanitizeContextHelpContent ( content : string ) : string {
180243 let sanitized = content . replace ( / \{ " s t a t u s " : " s u c c e s s " , " t e x t E x p r e s s i o n " : " " \} \s * $ / i, "" ) ;
181244
0 commit comments