Skip to content

Commit

Permalink
Add nested repositories to #include code completions
Browse files Browse the repository at this point in the history
  • Loading branch information
RedCMD committed Jan 10, 2024
1 parent 26491be commit f8694af
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 27 deletions.
31 changes: 21 additions & 10 deletions out/CompletionItemProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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');
Expand All @@ -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);
}
}
5 changes: 4 additions & 1 deletion out/DefinitionProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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');
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions out/TreeSitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
32 changes: 22 additions & 10 deletions src/CompletionItemProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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');
Expand All @@ -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);
}
Expand Down
2 changes: 2 additions & 0 deletions src/DefinitionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 12 additions & 3 deletions src/TreeSitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit f8694af

Please sign in to comment.