@@ -15,6 +15,9 @@ const triggerCharacterSets: { [key: string]: string[]; } = {
1515 schema_new : [ ':' ] ,
1616 scopeName : [ '"' , '.' ] ,
1717 name : [ '"' ] ,
18+ repo : [ '"' , '#' , '.' , '$' ] ,
19+ _nothing_ : [ ] ,
20+ repo_new : [ '"' ] ,
1821 include : [ '"' , '#' , '.' , '$' ] ,
1922 replace_capture : [ '$' , '{' ] ,
2023 scope : [ '.' , '$' ] ,
@@ -70,6 +73,9 @@ export const CompletionItemProvider: vscode.CompletionItemProvider = {
7073 (schema) @schema_new
7174 (scopeName (value) @scopeName)
7275 (name_display (value) @name)
76+ (repository (repo (key) @repo))
77+ (repository (repo) @_nothing_)
78+ (repository) @repo_new
7379 (include (value) @include)
7480 (name (value (scope (replace_capture) @replace_capture)))
7581 (name (value (scope) @scope))
@@ -208,6 +214,69 @@ export const CompletionItemProvider: vscode.CompletionItemProvider = {
208214
209215 break ;
210216 }
217+ case 'repo' :
218+ case 'repo_new' : {
219+ const includeQuery = `;scm
220+ (include (value !scopeName (ruleName) @include !self !base))
221+ ` ;
222+ const repoQuery = `;scm
223+ (repo (key) @repo)
224+ ` ;
225+
226+ const includeCaptures = queryNode ( rootNode , includeQuery ) ;
227+ const repoCaptures = queryNode ( rootNode , repoQuery ) ;
228+
229+ // find includes with no repo
230+ for ( const repo of repoCaptures ) {
231+ const text = repo . node . text ;
232+ // TS query's are slow
233+ for ( let index = 0 ; index < includeCaptures . length ; index ++ ) {
234+ const includeCapture = includeCaptures [ index ] ;
235+ if ( text == includeCapture . node . text ) {
236+ includeCaptures . splice ( index , 1 ) ;
237+ index -- ; // array is shorter now
238+ }
239+ }
240+ }
241+ // vscode.window.showInformationMessage(`includeCaptures ${includeCaptures.length}\n${JSON.stringify(includeCaptures)}`);
242+
243+ const rootScopeNameQuery = `(json (scopeName (value) @rootScopeName))` ;
244+ const rootScopeName = queryNode ( rootNode , rootScopeNameQuery ) . pop ( ) ?. node . text || 'source.langId' ;
245+
246+ for ( const includeCapture of includeCaptures ) {
247+ const text = includeCapture . node . text ;
248+ const documentation = new vscode . MarkdownString ( ) ;
249+ documentation . appendText ( "A repository item. Reference using:" ) ;
250+ documentation . appendCodeblock ( `"include": "#${ text } "` , 'json-textmate' ) ;
251+ documentation . appendText ( "Or from another grammar:" ) ;
252+ documentation . appendCodeblock ( `"include": "${ rootScopeName } #${ text } "` , 'json-textmate' ) ;
253+ completionItems . push ( {
254+ label : text ,
255+ range : cursorRange ,
256+ kind : vscode . CompletionItemKind . Property ,
257+ documentation : documentation ,
258+ insertText : cursorName == 'repo' ? text : new vscode . SnippetString ( `"${ text } ": {$0}${ comma ( cursorNode , position ) } ` ) ,
259+ } ) ;
260+ }
261+ const documentation = new vscode . MarkdownString ( ) ;
262+ documentation . appendText ( "A repository item. Reference using:" ) ;
263+ documentation . appendCodeblock ( `"include": "#repo-item"` , 'json-textmate' ) ;
264+ documentation . appendText ( "Or from another grammar:" ) ;
265+ documentation . appendCodeblock ( `"include": "${ rootScopeName } #repo-item"` , 'json-textmate' ) ;
266+ completionItems . push ( {
267+ label : "repo-item" ,
268+ range : cursorRange ,
269+ kind : vscode . CompletionItemKind . Property ,
270+ documentation : documentation ,
271+ insertText : cursorName == 'repo' ?
272+ "repo-item" :
273+ new vscode . SnippetString (
274+ `"\${1:repo-item}": {$0}${ comma ( cursorNode , position ) } `
275+ ) ,
276+ sortText : "~repo-item" , // bottom
277+ } ) ;
278+ break ;
279+ }
211280 case 'include' :
212281 const rootPatternsQuery = `(json (patterns) @patterns)` ;
213282 const rootPatternsText = queryNode ( tree . rootNode , rootPatternsQuery ) . pop ( ) ?. node ?. text ;
0 commit comments