6
6
* found in the LICENSE file at https://angular.io/license
7
7
*/
8
8
9
+ import * as ts from 'typescript/lib/tsserverlibrary' ;
9
10
import * as lsp from 'vscode-languageserver' ;
10
11
12
+ import { tsTextSpanToLspRange } from './utils' ;
13
+
11
14
// TODO: Move this to `@angular/language-service`.
12
15
enum CompletionKind {
13
16
attribute = 'attribute' ,
@@ -57,9 +60,11 @@ function ngCompletionKindToLspCompletionItemKind(kind: CompletionKind): lsp.Comp
57
60
* Convert ts.CompletionEntry to LSP Completion Item.
58
61
* @param entry completion entry
59
62
* @param position position where completion is requested.
63
+ * @param scriptInfo
60
64
*/
61
65
export function tsCompletionEntryToLspCompletionItem (
62
- entry : ts . CompletionEntry , position : lsp . Position ) : lsp . CompletionItem {
66
+ entry : ts . CompletionEntry , position : lsp . Position ,
67
+ scriptInfo : ts . server . ScriptInfo ) : lsp . CompletionItem {
63
68
const item = lsp . CompletionItem . create ( entry . name ) ;
64
69
// Even though `entry.kind` is typed as ts.ScriptElementKind, it's
65
70
// really Angular's CompletionKind. This is because ts.ScriptElementKind does
@@ -69,6 +74,12 @@ export function tsCompletionEntryToLspCompletionItem(
69
74
item . kind = ngCompletionKindToLspCompletionItemKind ( kind ) ;
70
75
item . detail = entry . kind ;
71
76
item . sortText = entry . sortText ;
72
- item . textEdit = lsp . TextEdit . insert ( position , entry . name ) ;
77
+ // Text that actually gets inserted to the document. It could be different
78
+ // from 'entry.name'. For example, a method name could be 'greet', but the
79
+ // insertText is 'greet()'.
80
+ const insertText = entry . insertText || entry . name ;
81
+ item . textEdit = entry . replacementSpan ?
82
+ lsp . TextEdit . replace ( tsTextSpanToLspRange ( scriptInfo , entry . replacementSpan ) , insertText ) :
83
+ lsp . TextEdit . insert ( position , insertText ) ;
73
84
return item ;
74
85
}
0 commit comments