Skip to content

Commit

Permalink
Fix go to definition for AHK v1, other misc work (#562)
Browse files Browse the repository at this point in the history
  • Loading branch information
mark-wiemer authored Nov 8, 2024
1 parent 3028a64 commit e80f175
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 21 deletions.
2 changes: 1 addition & 1 deletion ahk2
Submodule ahk2 updated from 53d6b4 to cec559
9 changes: 9 additions & 0 deletions demos/manualTests/definitionProvider/included.ahk1
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#NoEnv
#SingleInstance, Force
SendMode, Input
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%

MyDefProviderFunc() {
MsgBox % "Hi from MyDefProviderFunc"
}
10 changes: 10 additions & 0 deletions demos/manualTests/definitionProvider/main.ahk1
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#NoEnv
#SingleInstance, Force
SendMode, Input
SetBatchLines, -1
SetWorkingDir, %A_ScriptDir%

#Include ./included.ahk1

;* Should be able to ctrl+click to jump to `included.ahk1`
MyDefProviderFunc()
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@
"@types/xml2js": "^0.4.11",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.3.10",
"@vscode/vsce": "^3.1.1",
"@vscode/vsce": "^3.2.1",
"del-cli": "^6.0.0",
"esbuild": "0.24.0",
"eslint": "^9.9.0",
Expand Down
5 changes: 3 additions & 2 deletions src/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ export class Parser {
options: BuildScriptOptions = {},
): Promise<Script> {
const funcName = 'buildScript';
if (options.usingCache && documentCache.get(document.uri.path)) {
return documentCache.get(document.uri.path);
const cachedDocument = documentCache.get(document.uri.path);
if (options.usingCache && cachedDocument) {
return cachedDocument;
}

const maxParseLength =
Expand Down
15 changes: 15 additions & 0 deletions src/providers/defProvider.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import assert from 'assert';
import { tryGetFileLink } from './defProvider';

suite(tryGetFileLink.name, () => {
const tests: [
name: string,
args: Parameters<typeof tryGetFileLink>,
expected: ReturnType<typeof tryGetFileLink>,
][] = [['non-match', ['/c:/path/to/file.ahk', 'foo'], undefined]];
tests.forEach(([name, args, expected]) =>
test(name, async () => {
assert.strictEqual(await tryGetFileLink(...args), expected);
}),
);
});
37 changes: 27 additions & 10 deletions src/providers/defProvider.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,42 @@
import * as vscode from 'vscode';
import { Parser } from '../parser/parser';
import { resolveIncludedPath } from './defProvider.utils';
import { Out } from 'src/common/out';
import { Out } from '../common/out';
import { stat } from 'fs/promises';

export class DefProvider implements vscode.DefinitionProvider {
public async provideDefinition(
document: vscode.TextDocument,
position: vscode.Position,
): Promise<vscode.Location | vscode.Location[] | vscode.LocationLink[]> {
const fileLink = await tryGetFileLink(document, position);
): Promise<
vscode.Location | vscode.Location[] | vscode.LocationLink[] | null
> {
const funcName = 'provideDefinition';
Out.debug(funcName);

const docPath = document.uri.path;
const { text } = document.lineAt(position.line);
const fileLink = await tryGetFileLink(docPath, text);
if (fileLink) {
Out.debug(`${funcName} returning fileLink`);
return fileLink;
}
Out.debug(`${funcName} after tryGetFileLink`);

const word = document.getText(
document.getWordRangeAtPosition(position),
);
Out.debug(`${funcName} word: ${word}`);

// get method
if (
new RegExp(word + '\\s*\\(.*?\\)').test(
document.lineAt(position.line).text,
)
) {
Out.debug(`${funcName} calling getMethodByName for word: ${word}`);
const method = await Parser.getMethodByName(document, word);
Out.debug(`${funcName} method.name: ${method?.name}`);
if (method) {
return new vscode.Location(
vscode.Uri.parse(method.uriString),
Expand Down Expand Up @@ -100,17 +112,22 @@ export class DefProvider implements vscode.DefinitionProvider {
** Currently assumes the working directory is the script path and
* does not respect previous `#include dir` directives
*/
async function tryGetFileLink(
document: vscode.TextDocument,
position: vscode.Position,
): Promise<vscode.Location> | undefined {
export async function tryGetFileLink(
/** @example '/c:/path/to/file.ahk' */
const docPath = document.uri.path;
const { text } = document.lineAt(position.line);
docPath: string,
text: string,
): Promise<vscode.Location | undefined> {
const funcName = 'tryGetFileLink';
Out.debug(`${funcName}('${docPath}', '${text}')`);

/** @example 'c:/path/to/included.ahk' */
const resolvedPath = resolveIncludedPath(docPath, text);
Out.debug(`resolvedPath: ${resolvedPath}`);
Out.debug(`${funcName} resolvedPath: ${resolvedPath}`);
if (!resolvedPath) return undefined;

const fsStat = await stat(resolvedPath);
const isFile = fsStat.isFile();
Out.debug(`${funcName} isFile: ${isFile}`);
return fsStat.isFile()
? new vscode.Location(
vscode.Uri.file(resolvedPath),
Expand Down
2 changes: 2 additions & 0 deletions src/providers/defProvider.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export const resolveIncludedPath = (
ahkLine: string,
): string | undefined => {
const includedPath = getIncludedPath(ahkLine);
if (!includedPath) return undefined;

/** @example 'c:/path/to' */
const parentGoodPath = basePath.substring(1, basePath.lastIndexOf('/'));
const normalizedPath = normalizeIncludedPath(
Expand Down

0 comments on commit e80f175

Please sign in to comment.