@@ -103,75 +103,72 @@ async function completionComplexEdit(
103103 newOffset : number ,
104104 outputChannel : vscode . OutputChannel
105105) : Promise < void > {
106- let success = false ;
107- const uri = UriConverter . deserialize ( uriStr ) ;
108- const editor = vscode . window . visibleTextEditors . find (
109- ( editor ) => editor . document . uri . path === uri . path || editor . document . uri . fsPath === uri . fsPath
110- ) ;
111-
112- if ( editor !== undefined ) {
113- const newRange = editor . document . validateRange (
114- new vscode . Range (
115- textEdit . range . start . line ,
116- textEdit . range . start . character ,
117- textEdit . range . end . line ,
118- textEdit . range . end . character
119- )
120- ) ;
106+ const componentName = '[roslyn.client.completionComplexEdit]' ;
121107
122- // HACK:
123- // ApplyEdit would fail the first time it's called when an item was committed with text modifying commit char (e.g. space, '(', etc.)
124- // so we retry a couple time here as a tempory workaround. We need to either figure our the reason of the failure, and/or try the
125- // approach of sending another edit request to server with updated document.
126- for ( let i = 0 ; i < 3 ; i ++ ) {
127- if ( isSnippetString ) {
128- editor . selection = new vscode . Selection ( newRange . start , newRange . end ) ;
129- success = await editor . insertSnippet ( new vscode . SnippetString ( textEdit . newText ) ) ;
130- } else {
131- const edit = new vscode . WorkspaceEdit ( ) ;
132- const newTextEdit = vscode . TextEdit . replace ( newRange , textEdit . newText ) ;
133- edit . set ( editor . document . uri , [ newTextEdit ] ) ;
134- success = await vscode . workspace . applyEdit ( edit ) ;
135-
136- if ( success && newOffset >= 0 ) {
137- const newPosition = editor . document . positionAt ( newOffset ) ;
138- editor . selections = [ new vscode . Selection ( newPosition , newPosition ) ] ;
139- }
140- }
108+ // Find TextDocument, opening if needed.
109+ const document = await vscode . workspace . openTextDocument ( uriStr ) ;
110+ if ( document === undefined ) {
111+ outputAndThrow ( outputChannel , `${ componentName } Can't open document with path: '${ uriStr } '` ) ;
112+ }
141113
142- if ( success ) {
143- break ;
144- }
114+ // Use editor if we need to deal with selection or snippets.
115+ let editor : vscode . TextEditor | undefined = undefined ;
116+ if ( isSnippetString || newOffset >= 0 ) {
117+ editor = await vscode . window . showTextDocument ( document ) ;
118+ if ( editor === undefined ) {
119+ outputAndThrow ( outputChannel , `${ componentName } Editor unavailable for document with path: '${ uriStr } '` ) ;
145120 }
146121 }
147122
148- if ( ! success ) {
149- const componentName = '[roslyn.client.completionComplexEdit]' ;
150- const errorMessage = 'Failed to make a complex text edit for completion.' ;
151- outputChannel . show ( ) ;
152- outputChannel . appendLine ( `${ componentName } ${ errorMessage } ` ) ;
123+ const newRange = document . validateRange (
124+ new vscode . Range (
125+ textEdit . range . start . line ,
126+ textEdit . range . start . character ,
127+ textEdit . range . end . line ,
128+ textEdit . range . end . character
129+ )
130+ ) ;
153131
154- if ( editor === undefined ) {
155- outputChannel . appendLine (
156- `${ componentName } Can't find visible document with uri.fsPath: '${ uri . fsPath } ' and uri.path: '${ uri . path } '`
157- ) ;
158-
159- outputChannel . appendLine ( `${ componentName } URIs of all visible documents:` ) ;
160- for ( const visibleEditor of vscode . window . visibleTextEditors ) {
161- outputChannel . appendLine (
162- `${ componentName } - uri.fsPath: '${ visibleEditor . document . uri . fsPath } ' and uri.path: '${ visibleEditor . document . uri . path } '`
163- ) ;
164- }
132+ // HACK:
133+ // ApplyEdit would fail the first time it's called when an item was committed with text modifying commit char (e.g. space, '(', etc.)
134+ // so we retry a couple time here as a tempory workaround. We need to either figure our the reason of the failure, and/or try the
135+ // approach of sending another edit request to server with updated document.
136+ let success = false ;
137+ for ( let i = 0 ; i < 3 ; i ++ ) {
138+ if ( isSnippetString ) {
139+ editor ! . selection = new vscode . Selection ( newRange . start , newRange . end ) ;
140+ success = await editor ! . insertSnippet ( new vscode . SnippetString ( textEdit . newText ) ) ;
165141 } else {
166- outputChannel . appendLine (
167- `${ componentName } ${ isSnippetString ? 'TextEditor.insertSnippet' : 'workspace.applyEdit' } failed.`
168- ) ;
142+ const edit = new vscode . WorkspaceEdit ( ) ;
143+ const newTextEdit = vscode . TextEdit . replace ( newRange , textEdit . newText ) ;
144+ edit . set ( document . uri , [ newTextEdit ] ) ;
145+ success = await vscode . workspace . applyEdit ( edit ) ;
146+
147+ if ( success && newOffset >= 0 ) {
148+ const newPosition = document . positionAt ( newOffset ) ;
149+ editor ! . selections = [ new vscode . Selection ( newPosition , newPosition ) ] ;
150+ }
151+ }
152+
153+ if ( success ) {
154+ return ;
169155 }
156+ }
170157
171- throw new Error ( `${ componentName } ${ errorMessage } ` ) ;
158+ if ( ! success ) {
159+ outputAndThrow (
160+ outputChannel ,
161+ `${ componentName } ${ isSnippetString ? 'TextEditor.insertSnippet' : 'workspace.applyEdit' } failed.`
162+ ) ;
172163 }
173164}
174165
166+ function outputAndThrow ( outputChannel : vscode . OutputChannel , message : string ) : void {
167+ outputChannel . show ( ) ;
168+ outputChannel . appendLine ( message ) ;
169+ throw new Error ( message ) ;
170+ }
171+
175172async function openSolution ( languageServer : RoslynLanguageServer ) : Promise < vscode . Uri | undefined > {
176173 if ( ! vscode . workspace . workspaceFolders ) {
177174 return undefined ;
0 commit comments