@@ -8,6 +8,9 @@ import { LanguageServiceDefaultsImpl } from './monaco.contribution';
88import * as ts from './lib/typescriptServices' ;
99import { TypeScriptWorker } from './tsWorker' ;
1010
11+ import * as emmet from './lib/emmet/emmetHelper' ;
12+ import * as ls from './lib/emmet/expand/languageserver-types' ;
13+
1114import Uri = monaco . Uri ;
1215import Position = monaco . Position ;
1316import Range = monaco . Range ;
@@ -25,6 +28,44 @@ enum IndentStyle {
2528 Smart = 2 ,
2629}
2730
31+ export enum Priority {
32+ Emmet ,
33+ Platform
34+ }
35+
36+ function toCompletionItemKind ( kind : number ) : monaco . languages . CompletionItemKind {
37+ let mItemKind = monaco . languages . CompletionItemKind ;
38+
39+ switch ( kind ) {
40+ case ls . CompletionItemKind . Text : return mItemKind . Text ;
41+ case ls . CompletionItemKind . Method : return mItemKind . Method ;
42+ case ls . CompletionItemKind . Function : return mItemKind . Function ;
43+ case ls . CompletionItemKind . Constructor : return mItemKind . Constructor ;
44+ case ls . CompletionItemKind . Field : return mItemKind . Field ;
45+ case ls . CompletionItemKind . Variable : return mItemKind . Variable ;
46+ case ls . CompletionItemKind . Class : return mItemKind . Class ;
47+ case ls . CompletionItemKind . Interface : return mItemKind . Interface ;
48+ case ls . CompletionItemKind . Module : return mItemKind . Module ;
49+ case ls . CompletionItemKind . Property : return mItemKind . Property ;
50+ case ls . CompletionItemKind . Unit : return mItemKind . Unit ;
51+ case ls . CompletionItemKind . Value : return mItemKind . Value ;
52+ case ls . CompletionItemKind . Enum : return mItemKind . Enum ;
53+ case ls . CompletionItemKind . Keyword : return mItemKind . Keyword ;
54+ case ls . CompletionItemKind . Snippet : return mItemKind . Snippet ;
55+ case ls . CompletionItemKind . Color : return mItemKind . Color ;
56+ case ls . CompletionItemKind . File : return mItemKind . File ;
57+ case ls . CompletionItemKind . Reference : return mItemKind . Reference ;
58+ }
59+ return mItemKind . Property ;
60+ }
61+
62+ function toRange ( range : ls . Range ) : Range {
63+ if ( ! range ) {
64+ return void 0 ;
65+ }
66+ return new Range ( range . start . line + 1 , range . start . character + 1 , range . end . line + 1 , range . end . character + 1 ) ;
67+ }
68+
2869function flattenDiagnosticMessageText (
2970 messageText : string | ts . DiagnosticMessageChain ,
3071 newLine : '\n'
@@ -233,17 +274,19 @@ interface MyCompletionItem extends monaco.languages.CompletionItem {
233274 position : Position ;
234275}
235276
277+ const emmetTriggerCharacters = [ '!' , '.' , '}' , ':' , '*' , '$' , ']' , '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' ] ;
278+
236279export class SuggestAdapter extends Adapter
237280 implements monaco . languages . CompletionItemProvider {
238281 public get triggerCharacters ( ) : string [ ] {
239- return [ '.' ] ;
282+ return [ ... emmetTriggerCharacters , '.' ] ;
240283 }
241284
242285 provideCompletionItems (
243286 model : monaco . editor . IReadOnlyModel ,
244287 position : Position ,
245288 token : CancellationToken
246- ) : Thenable < monaco . languages . CompletionItem [ ] > {
289+ ) : Thenable < monaco . languages . CompletionList > {
247290 const wordInfo = model . getWordUntilPosition ( position ) ;
248291 const resource = model . uri ;
249292 const offset = this . _positionToOffset ( resource , position ) ;
@@ -258,17 +301,53 @@ export class SuggestAdapter extends Adapter
258301 if ( ! info ) {
259302 return ;
260303 }
261- let suggestions : MyCompletionItem [ ] = info . entries . map ( entry => {
262- return {
263- uri : resource ,
264- position : position ,
265- label : entry . name ,
304+
305+ const emmetItems = info . emmetCompletions ? info . emmetCompletions . items . map ( i => {
306+ const entry = {
307+ ...i ,
308+ sortText : Priority . Emmet + i . label
309+ } ;
310+
311+ let item : MyCompletionItem = {
312+ label : entry . label ,
313+ insertText : entry . insertText ,
266314 sortText : entry . sortText ,
267- kind : SuggestAdapter . convertKind ( entry . kind ) ,
315+ filterText : entry . filterText ,
316+ documentation : entry . documentation ,
317+ detail : entry . detail ,
318+ uri : resource ,
319+ position,
320+ kind : toCompletionItemKind ( entry . kind ) ,
268321 } ;
269- } ) ;
322+ if ( entry . textEdit ) {
323+ item . range = toRange ( entry . textEdit . range ) ;
324+ item . insertText = entry . textEdit . newText ;
325+ }
326+ if ( entry . insertTextFormat === ls . InsertTextFormat . Snippet ) {
327+ item . insertText = { value : < string > item . insertText } ;
328+ }
329+ return item ;
330+ } ) : [ ] ;
331+
332+ let suggestions : MyCompletionItem [ ] ;
333+ if ( info . languageCompletions ) {
334+ suggestions = info . languageCompletions . entries . map ( entry => {
335+ return {
336+ uri : resource ,
337+ position : position ,
338+ label : entry . name ,
339+ sortText : entry . sortText ,
340+ kind : SuggestAdapter . convertKind ( entry . kind ) ,
341+ } ;
342+ } ) ;
343+ } else {
344+ suggestions = [ ]
345+ }
270346
271- return suggestions ;
347+ return {
348+ isIncomplete : emmetItems . length !== 0 ,
349+ items : emmetItems . concat ( suggestions )
350+ } ;
272351 } )
273352 ) ;
274353 }
0 commit comments