diff --git a/Readme.md b/Readme.md index a0e2b6f..b176008 100644 --- a/Readme.md +++ b/Readme.md @@ -193,6 +193,7 @@ some regex patterns can't be supported by javascript, including - `snippets.userSnippetsDirectory`, Directory that contains custom user ultisnips snippets, use ultisnips in extension root by default. - `snippets.shortcut`, shortcut in completion menu, default `S`. - `snippets.autoTrigger`: enable auto trigger for auto trigger ultisnips snippets, default `true`. +- `snippets.execContext`: execute a snippet's `context` (if it exists) to check if the snippet should be shown in completion menu, default `false` (i.e., snippets with a `context` are never shown in completion menu) - `snippets.triggerCharacters`: trigger characters for completion, default `[]`. - `snippets.loadFromExtensions`: load snippets from coc.nvim extensions, default: `true`. - `snippets.loadVSCodeProjectSnippets`: Load code snippets in folder `${workspaceFolder}/.vscode`, default: `true`. diff --git a/package.json b/package.json index b91a421..8c63114 100644 --- a/package.json +++ b/package.json @@ -113,6 +113,11 @@ "default": true, "description": "Enable trigger auto trigger snippet after type character." }, + "snippets.execContext": { + "type": "boolean", + "default": false, + "description": "Execute a snippet's context (if it exists) to check if the snippet should be shown in completion menu" + }, "snippets.ultisnips.enable": { "type": "boolean", "default": true, diff --git a/src/provider.ts b/src/provider.ts index 531024f..f4eb924 100644 --- a/src/provider.ts +++ b/src/provider.ts @@ -124,11 +124,27 @@ export class ProviderManager implements CompletionItemProvider { let after = line.slice(characterIndex(line, colnr - 1)) let res: CompletionItem[] = [] let noneWords = before_content.endsWith(' ') ? '' : before_content.match(/\W*$/)[0] + let contextPrefixes: string[] = [] + const configuration = workspace.getConfiguration('snippets') + const execContext = configuration.get('execContext', false) for (let snip of snippets) { - // Avoid context during completion. - if (snip.context || snip.prefix === '') continue + if (!execContext && snip.context) continue + if (snip.prefix === '') continue if (input.length == 0 && (!snip.special || !before_content.endsWith(snip.special))) continue + if (contextPrefixes.indexOf(snip.prefix) !== -1) continue let contentBefore = before_content + if (snip.context) { + let provider = this.providers.get(snip.provider) + let valid: boolean + try { + valid = await provider.checkContext(snip.context) + } catch (e) { + this.appendError(`checkContext of ${snip.provider}`, e) + valid = false + } + if (!valid) continue + contextPrefixes.push(snip.prefix) + } let head = this.getPrefixHead(doc, snip.prefix) let ultisnip = snip.provider == 'ultisnips' || snip.provider == 'snipmate' let startCharacter = character