77import { localize } from 'vs/nls' ;
88import * as strings from 'vs/base/common/strings' ;
99import { IModel } from 'vs/editor/common/editorCommon' ;
10- import { ISuggestion , LanguageId } from 'vs/editor/common/modes' ;
10+ import { ISuggestSupport , ISuggestResult , ISuggestion , LanguageId } from 'vs/editor/common/modes' ;
1111import { createDecorator } from 'vs/platform/instantiation/common/instantiation' ;
1212import { registerSingleton } from 'vs/platform/instantiation/common/extensions' ;
1313import { setSnippetSuggestSupport } from 'vs/editor/contrib/suggest/browser/suggest' ;
@@ -41,19 +41,12 @@ class SnippetsService implements ISnippetsService {
4141
4242 _serviceBrand : any ;
4343
44- private static _defaultDetail = localize ( 'detail.userSnippet' , "User Snippet" ) ;
45-
46- private _snippets = new Map < LanguageId , Map < string , ISnippet [ ] > > ( ) ;
44+ private readonly _snippets = new Map < LanguageId , Map < string , ISnippet [ ] > > ( ) ;
4745
4846 constructor (
49- @IModeService private _modeService : IModeService
47+ @IModeService modeService : IModeService
5048 ) {
51- setSnippetSuggestSupport ( {
52- provideCompletionItems : ( model , position ) => {
53- const suggestions = this . _getSnippetCompletions ( < any > model , position ) ;
54- return { suggestions } ;
55- }
56- } ) ;
49+ setSnippetSuggestSupport ( new SnippetSuggestProvider ( modeService , this ) ) ;
5750 }
5851
5952 public registerSnippets ( languageId : LanguageId , snippets : ISnippet [ ] , fileName : string ) : void {
@@ -74,33 +67,33 @@ class SnippetsService implements ISnippetsService {
7467 } ) ;
7568 }
7669 }
70+ }
7771
78- private _getLanguageIdAtPosition ( model : IModel , position : Position ) : LanguageId {
79- // validate the `languageId` to ensure this is a user
80- // facing language with a name and the chance to have
81- // snippets, else fall back to the outer language
82- model . forceTokenization ( position . lineNumber ) ;
83- let languageId = model . getLanguageIdAtPosition ( position . lineNumber , position . column ) ;
84- let { language } = this . _modeService . getLanguageIdentifier ( languageId ) ;
85- if ( ! this . _modeService . getLanguageName ( language ) ) {
86- languageId = model . getLanguageIdentifier ( ) . id ;
87- }
88- return languageId ;
72+ registerSingleton ( ISnippetsService , SnippetsService ) ;
73+
74+ export interface ISimpleModel {
75+ getLineContent ( lineNumber : number ) : string ;
76+ }
77+
78+ class SnippetSuggestProvider implements ISuggestSupport {
79+
80+ constructor (
81+ @IModeService private _modeService : IModeService ,
82+ @ISnippetsService private _snippets : ISnippetsService
83+ ) {
84+ //
8985 }
9086
91- private _getSnippetCompletions ( model : IModel , position : Position ) : ISuggestion [ ] {
92- const languageId = this . _getLanguageIdAtPosition ( model , position ) ;
93- if ( ! this . _snippets . has ( languageId ) ) {
94- return undefined ;
95- }
87+ provideCompletionItems ( model : IModel , position : Position ) : ISuggestResult {
9688
97- const result : ISnippetSuggestion [ ] = [ ] ;
89+ const languageId = this . _getLanguageIdAtPosition ( model , position ) ;
90+ const suggestions : ISnippetSuggestion [ ] = [ ] ;
9891
9992 const word = model . getWordAtPosition ( position ) ;
10093 const currentWord = word ? word . word . substring ( 0 , position . column - word . startColumn ) . toLowerCase ( ) : '' ;
10194 const currentFullWord = getNonWhitespacePrefix ( model , position ) . toLowerCase ( ) ;
10295
103- this . visitSnippets ( languageId , s => {
96+ this . _snippets . visitSnippets ( languageId , s => {
10497 const prefixLower = s . prefix . toLowerCase ( ) ;
10598
10699 let overwriteBefore = 0 ;
@@ -118,11 +111,11 @@ class SnippetsService implements ISnippetsService {
118111 }
119112
120113 // store in result
121- result . push ( {
114+ suggestions . push ( {
122115 type : 'snippet' ,
123116 label : s . prefix ,
124117 get disambiguateLabel ( ) { return localize ( 'snippetSuggest.longLabel' , "{0}, {1}" , s . prefix , s . name ) ; } ,
125- detail : s . extensionName || SnippetsService . _defaultDetail ,
118+ detail : s . extensionName || localize ( 'detail.userSnippet' , "User Snippet" ) ,
126119 documentation : s . description ,
127120 insertText : s . codeSnippet ,
128121 sortText : `${ s . prefix } -${ s . extensionName || '' } ` ,
@@ -136,7 +129,7 @@ class SnippetsService implements ISnippetsService {
136129
137130 // dismbiguate suggestions with same labels
138131 let lastSuggestion : ISnippetSuggestion ;
139- for ( const suggestion of result . sort ( SnippetsService . _compareSuggestionsByLabel ) ) {
132+ for ( const suggestion of suggestions . sort ( SnippetSuggestProvider . _compareSuggestionsByLabel ) ) {
140133 if ( lastSuggestion && lastSuggestion . label === suggestion . label ) {
141134 // use the disambiguateLabel instead of the actual label
142135 lastSuggestion . label = lastSuggestion . disambiguateLabel ;
@@ -145,20 +138,27 @@ class SnippetsService implements ISnippetsService {
145138 lastSuggestion = suggestion ;
146139 }
147140
148- return result ;
141+ return { suggestions } ;
142+ }
143+
144+ private _getLanguageIdAtPosition ( model : IModel , position : Position ) : LanguageId {
145+ // validate the `languageId` to ensure this is a user
146+ // facing language with a name and the chance to have
147+ // snippets, else fall back to the outer language
148+ model . forceTokenization ( position . lineNumber ) ;
149+ let languageId = model . getLanguageIdAtPosition ( position . lineNumber , position . column ) ;
150+ let { language } = this . _modeService . getLanguageIdentifier ( languageId ) ;
151+ if ( ! this . _modeService . getLanguageName ( language ) ) {
152+ languageId = model . getLanguageIdentifier ( ) . id ;
153+ }
154+ return languageId ;
149155 }
150156
151157 private static _compareSuggestionsByLabel ( a : ISuggestion , b : ISuggestion ) : number {
152158 return strings . compare ( a . label , b . label ) ;
153159 }
154160}
155161
156- registerSingleton ( ISnippetsService , SnippetsService ) ;
157-
158- export interface ISimpleModel {
159- getLineContent ( lineNumber : number ) : string ;
160- }
161-
162162export function getNonWhitespacePrefix ( model : ISimpleModel , position : Position ) : string {
163163 /**
164164 * Do not analyze more characters
0 commit comments