diff --git a/out/CompletionItemProvider.js b/out/CompletionItemProvider.js index 7e8d108..3c82951 100644 --- a/out/CompletionItemProvider.js +++ b/out/CompletionItemProvider.js @@ -84,7 +84,7 @@ exports.CompletionItemProvider = { else { grammarDocText = grammarPatternsText.slice(0, 99900); } - grammarDocumentation.appendCodeblock(grammarDocText, 'json-textmate'); + grammarDocumentation.appendCodeblock(grammarDocText, 'json-textmate'); // but no, it doesn't work.... } } else { @@ -115,32 +115,39 @@ exports.CompletionItemProvider = { }; function repoCompletionItems(completionItems, tree, cursorRange, scopeName) { const rootNode = tree.rootNode; - const repoQuery = `(json (repository (repo (key) @repo (.not-match? @repo "^\\\\$(self|base)$"))))`; - const repoCaptures = (0, TreeSitter_1.queryNode)(rootNode, repoQuery); + const repoQuery = `(json (repository (repo (key) @rootRepo (.not-match? @rootRepo "^\\\\$(self|base)$"))))` + + (scopeName ? `` : + `(repo + [(patterns) (include)] (repository + (repo + (key) @nestRepo (.not-match? @nestRepo "^\\\\$(self|base)$"))) + !match !begin)`); + // const repoCaptures = queryNode(rootNode, repoQuery); + const repoCaptures = scopeName ? (0, TreeSitter_1.queryNode)(rootNode, repoQuery) : (0, TreeSitter_1.queryNode)(rootNode, repoQuery, (0, TreeSitter_1.toPoint)(cursorRange.start), (0, TreeSitter_1.toPoint)(cursorRange.end)); for (const repoCapture of repoCaptures) { const repoNode = repoCapture.node; const repoText = repoNode.text; - const parentRepoNode = repoText ? repoNode.parent : repoNode.parent.parent; // Tree-sitter buggy on 0width nodes + const repoNodeParent = repoText ? repoNode.parent : repoNode.parent.parent; // Tree-sitter buggy on 0width nodes const commentQuery = `(comment (value) @comment (.not-eq? @comment ""))` + `(comment_slash (value) @comment (.not-eq? @comment ""))`; - const commentText = (0, TreeSitter_1.queryNode)(parentRepoNode, commentQuery)[0]?.node?.text; + const commentText = (0, TreeSitter_1.queryNode)(repoNodeParent, commentQuery)[0]?.node?.text?.replace(/\\(.)?/g, '$1'); const repoLabel = { label: (scopeName ?? '') + '#' + repoText, description: commentText }; - const parentRepoNodeText = parentRepoNode.text; + const repoNodeParentText = repoNodeParent.text; let repoDocText; if (rootNode.startPosition.row == rootNode.endPosition.row) { try { - const parsedRepo = JSON.parse('{' + parentRepoNodeText + '}'); - repoDocText = `"${repoText}": ` + JSON.stringify(parsedRepo[repoText], null, 2).slice(0, 99900); + const repoParsed = JSON.parse('{' + repoNodeParentText + '}'); + repoDocText = `"${repoText}": ` + JSON.stringify(repoParsed[repoText], null, 2).slice(0, 99900); } catch (error) { - repoDocText = parentRepoNodeText.slice(0, 1000); // How to enable Word Wrap? + repoDocText = repoNodeParentText.slice(0, 1000); // How to enable Word Wrap? } } else { - repoDocText = parentRepoNodeText.slice(0, 99900); + repoDocText = repoNodeParentText.slice(0, 99900); } const documentation = new vscode.MarkdownString(); documentation.appendCodeblock(repoDocText, 'json-textmate'); @@ -150,7 +157,11 @@ function repoCompletionItems(completionItems, tree, cursorRange, scopeName) { range: cursorRange, kind: vscode.CompletionItemKind.Function, documentation: documentation + // sortText: '~#' + repoText }; + if (repoCapture.name == 'nestRepo') { + repoCompletionItem.sortText = ' #' + repoText; + } completionItems.push(repoCompletionItem); } } diff --git a/out/DefinitionProvider.js b/out/DefinitionProvider.js index fdfd2d7..533ef33 100644 --- a/out/DefinitionProvider.js +++ b/out/DefinitionProvider.js @@ -15,10 +15,12 @@ exports.DefinitionProvider = { (repo (key) @repo) (include (value) @include)`; const cursorCapture = (0, TreeSitter_1.queryNode)(tree.rootNode, queryString, point); + // vscode.window.showInformationMessage(JSON.stringify(cursorCapture)); if (cursorCapture == null) { return; } const node = cursorCapture.node; + // vscode.window.showInformationMessage(JSON.stringify(node)); const originSelectionRange = (0, TreeSitter_1.toRange)(node); if (!originSelectionRange.contains(position)) { return; @@ -117,7 +119,8 @@ exports.DefinitionProvider = { for (const grammar of grammars) { if (grammar.scopeName == scopeName) { const uri = vscode.Uri.joinPath(extension.extensionUri, grammar.path); - await vscode.workspace.openTextDocument(uri); + const document = await vscode.workspace.openTextDocument(uri); + vscode.languages.setTextDocumentLanguage(document, 'json-textmate'); } } } diff --git a/out/TreeSitter.js b/out/TreeSitter.js index f693793..effcb60 100644 --- a/out/TreeSitter.js +++ b/out/TreeSitter.js @@ -14,10 +14,16 @@ exports.getTree = getTree; function queryNode(node, queryString, startPoint, endPoint) { const language = node.tree.getLanguage(); const query = language.query(queryString); - const queryCaptures = query.captures(node, startPoint, endPoint ?? startPoint); + const queryCaptures = query.captures(node, startPoint, endPoint ?? startPoint); // would || be better? if (startPoint && !endPoint) { - const queryCapture = queryCaptures.pop(); // the last/inner most node - return queryCapture ?? null; + const position = new vscode.Position(startPoint.row, startPoint.column); + while (queryCaptures.length) { // TreeSitter doesn't check if the captured node actually touches the startPoint :/ + const queryCapture = queryCaptures.pop(); // the last/inner most node + if (toRange(queryCapture.node).contains(position)) { + return queryCapture; + } + } + return null; } return queryCaptures; } diff --git a/src/CompletionItemProvider.ts b/src/CompletionItemProvider.ts index d286992..baa4ec7 100644 --- a/src/CompletionItemProvider.ts +++ b/src/CompletionItemProvider.ts @@ -98,7 +98,7 @@ export const CompletionItemProvider = { else { grammarDocText = grammarPatternsText.slice(0, 99900); } - grammarDocumentation.appendCodeblock(grammarDocText, 'json-textmate'); + grammarDocumentation.appendCodeblock(grammarDocText, 'json-textmate'); // but no, it doesn't work.... } } else { @@ -135,37 +135,45 @@ export const CompletionItemProvider = { function repoCompletionItems(completionItems: vscode.CompletionItem[], tree: Parser.Tree, cursorRange: vscode.Range, scopeName?: string): void { const rootNode = tree.rootNode; - const repoQuery = `(json (repository (repo (key) @repo (.not-match? @repo "^\\\\$(self|base)$"))))`; - const repoCaptures = queryNode(rootNode, repoQuery); + const repoQuery = + `(json (repository (repo (key) @rootRepo (.not-match? @rootRepo "^\\\\$(self|base)$"))))` + + (scopeName ? `` : + `(repo + [(patterns) (include)] (repository + (repo + (key) @nestRepo (.not-match? @nestRepo "^\\\\$(self|base)$"))) + !match !begin)`); + // const repoCaptures = queryNode(rootNode, repoQuery); + const repoCaptures = scopeName ? queryNode(rootNode, repoQuery) : queryNode(rootNode, repoQuery, toPoint(cursorRange.start), toPoint(cursorRange.end)); for (const repoCapture of repoCaptures) { const repoNode = repoCapture.node; const repoText = repoNode.text; - const parentRepoNode = repoText ? repoNode.parent : repoNode.parent.parent; // Tree-sitter buggy on 0width nodes + const repoNodeParent = repoText ? repoNode.parent : repoNode.parent.parent; // Tree-sitter buggy on 0width nodes const commentQuery = `(comment (value) @comment (.not-eq? @comment ""))` + `(comment_slash (value) @comment (.not-eq? @comment ""))`; - const commentText = queryNode(parentRepoNode, commentQuery)[0]?.node?.text; + const commentText = queryNode(repoNodeParent, commentQuery)[0]?.node?.text?.replace(/\\(.)?/g, '$1'); const repoLabel: vscode.CompletionItemLabel = { label: (scopeName ?? '') + '#' + repoText, description: commentText }; - const parentRepoNodeText = parentRepoNode.text; + const repoNodeParentText = repoNodeParent.text; let repoDocText: string; if (rootNode.startPosition.row == rootNode.endPosition.row) { try { - const parsedRepo = JSON.parse('{' + parentRepoNodeText + '}'); - repoDocText = `"${repoText}": ` + JSON.stringify(parsedRepo[repoText], null, 2).slice(0, 99900); + const repoParsed = JSON.parse('{' + repoNodeParentText + '}'); + repoDocText = `"${repoText}": ` + JSON.stringify(repoParsed[repoText], null, 2).slice(0, 99900); } catch (error) { - repoDocText = parentRepoNodeText.slice(0, 1000); // How to enable Word Wrap? + repoDocText = repoNodeParentText.slice(0, 1000); // How to enable Word Wrap? } } else { - repoDocText = parentRepoNodeText.slice(0, 99900); + repoDocText = repoNodeParentText.slice(0, 99900); } const documentation = new vscode.MarkdownString(); documentation.appendCodeblock(repoDocText, 'json-textmate'); @@ -176,7 +184,11 @@ function repoCompletionItems(completionItems: vscode.CompletionItem[], tree: Par range: cursorRange, kind: vscode.CompletionItemKind.Function, documentation: documentation + // sortText: '~#' + repoText }; + if (repoCapture.name == 'nestRepo') { + repoCompletionItem.sortText = ' #' + repoText; + } completionItems.push(repoCompletionItem); } diff --git a/src/DefinitionProvider.ts b/src/DefinitionProvider.ts index 3285270..4b77872 100644 --- a/src/DefinitionProvider.ts +++ b/src/DefinitionProvider.ts @@ -15,10 +15,12 @@ export const DefinitionProvider = { (repo (key) @repo) (include (value) @include)`; const cursorCapture = queryNode(tree.rootNode, queryString, point); + // vscode.window.showInformationMessage(JSON.stringify(cursorCapture)); if (cursorCapture == null) { return; } const node = cursorCapture.node; + // vscode.window.showInformationMessage(JSON.stringify(node)); const originSelectionRange = toRange(node); if (!originSelectionRange.contains(position)) { return; diff --git a/src/TreeSitter.ts b/src/TreeSitter.ts index 0837dd5..ecfe42c 100644 --- a/src/TreeSitter.ts +++ b/src/TreeSitter.ts @@ -22,10 +22,19 @@ export function queryNode(node: Parser.SyntaxNode, queryString: string, startPoi export function queryNode(node: Parser.SyntaxNode, queryString: string, startPoint?: Parser.Point, endPoint?: Parser.Point): Parser.QueryCapture[] | Parser.QueryCapture | null { const language = node.tree.getLanguage(); const query = language.query(queryString); - const queryCaptures = query.captures(node, startPoint, endPoint ?? startPoint); + const queryCaptures = query.captures(node, startPoint, endPoint ?? startPoint); // would || be better? if (startPoint && !endPoint) { - const queryCapture = queryCaptures.pop(); // the last/inner most node - return queryCapture ?? null; + const position = new vscode.Position( + startPoint.row, + startPoint.column + ); + while (queryCaptures.length) { // TreeSitter doesn't check if the captured node actually touches the startPoint :/ + const queryCapture = queryCaptures.pop(); // the last/inner most node + if (toRange(queryCapture.node).contains(position)) { + return queryCapture; + } + } + return null; } return queryCaptures; }