Skip to content

Commit dd40e6f

Browse files
authored
Respect exclude without requiring restart (#545)
1 parent bca5ff7 commit dd40e6f

File tree

11 files changed

+128
-89
lines changed

11 files changed

+128
-89
lines changed

ahk2

Submodule ahk2 updated from f75b53e to d5a3f83

changelog.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
## 6.3.0 - unreleased 🕳️
44

55
- Add exclude setting ([#488](https://github.com/mark-wiemer-org/ahkpp/issues/488))
6+
- Excluded files are not included in IntelliSense completion suggestions, even when they're added via `#include`
67
- Changed `v2.exclude` setting to `exclude`
78
- One setting works for both v1 and v2
9+
- Changes to this setting take effect immediately, no need to restart your IDE (different than thqby's extension)
810
- v2 will exclude excluded files from suggestions even if they're opened in the IDE (different than thqby's extension)
9-
- v1 no longer automatically ignores files with `out`, `target`, and `node_modules` in their name
11+
- v1 no longer automatically ignores files with `out`, `target`, or `node_modules` in their name
1012
- Fixup output channel names: "AHK++ (v1)" and "AHK++ (v2)" instead of "AHK" and "AHK++" respectively
1113
- Fix duplicate output channels
1214

e2e/main.ahk1

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#NoEnv
2+
#SingleInstance, Force
3+
SendMode, Input
4+
SetBatchLines, -1
5+
SetWorkingDir, %A_ScriptDir%
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#Requires AutoHotkey v2.0
22

33
; Exclude pattern: excluded.ahk
4-
;* Should not suggest "my excluded func" in completion
4+
;* Should not suggest "MyExcludedFunc" in completion
55
MyExclu

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@
4848
],
4949
"scripts": {
5050
"prebuild": "npm run clean:dist",
51-
"build": "node src/build.mjs --mode=production && cd ahk2 && npm run build",
52-
"build:ahk1": "node src/build.mjs --mode=production",
53-
"build:dev": "node src/build.mjs && cd ahk2 && npm run build",
51+
"build": "npm run compile:grammar && node src/build.mjs --mode=production && cd ahk2 && npm run build",
52+
"build:ahk1": "npm run compile:grammar && node src/build.mjs --mode=production",
53+
"build:dev": "npm run compile:grammar && node src/build.mjs && cd ahk2 && npm run build",
5454
"clean": "npm run clean:dist && npm run clean:language && npm run clean:out",
5555
"clean:dist": "del-cli dist",
5656
"clean:language": "del-cli \"language/*.tmLanguage.json\"",
@@ -72,7 +72,7 @@
7272
"sort-package-json:fix": "sort-package-json",
7373
"test": "npm run test:grammar && npm run test:unit && npm run test:e2e",
7474
"test:ci": "npm run test:grammar && npm run test:e2e:ci",
75-
"pretest:e2e": "npm run vscode:prepublish && npm run compile:ts",
75+
"pretest:e2e": "npm run build && npm run compile:ts",
7676
"test:e2e": "vscode-test",
7777
"test:e2e:ci": "npm run test:e2e -- -i --fgrep @ignoreCI",
7878
"pretest:grammar": "npm run compile:grammar",
@@ -83,7 +83,7 @@
8383
"validate:ci": "npm run lint && npm run test:ci && npm run package",
8484
"validate:deep": "cd ahk2 && npm run validate && cd .. && npm run validate",
8585
"validate:fix": "npm run lint:fix && npm run test && npm run package",
86-
"vscode:prepublish": "npm run compile:grammar && npm run build && echo Packaging..."
86+
"vscode:prepublish": "npm run build && echo Packaging..."
8787
},
8888
"contributes": {
8989
"breakpoints": [

package.nls.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"ahk++.config.v2.diagnostics.classNonDynamicMemberCheck": "Check whether non-dynamic members of a class exist",
2323
"ahk++.config.v2.diagnostics.paramsCheck": "Check that the function call has the correct number of arguments",
2424
"ahk++.config.v2.file.interpreterPath": "Path to the `AutoHotkey.exe` executable file for AHK v2.",
25-
"ahk++.config.exclude": "[Glob patterns](<https://en.wikipedia.org/wiki/Glob_(programming)>) for excluding files and folders. Applies even when files are opened. Changes take effect after restart.",
25+
"ahk++.config.exclude": "[Glob patterns](<https://en.wikipedia.org/wiki/Glob_(programming)>) for excluding files and folders from completion suggestions. Applies even when files are opened.",
2626
"ahk++.config.v2.file.maxScanDepth": "Depth of folders to scan for IntelliSense. Negative values mean infinite depth.",
2727
"ahk++.config.v2.librarySuggestions": "Which libraries to suggest functions from, if any. In case of issues, restart your IDE.",
2828
"ahk++.config.v2.symbolFoldingFromOpenBrace": "Fold parameter lists separately from definitions.",

src/common/global.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export enum ConfigKey {
4141
compileIcon = 'compiler.compileIcon',
4242
compilerPath = 'compiler.compilerPath',
4343
exclude = 'exclude',
44+
general = 'general',
45+
generalV2 = 'v2.general',
4446
helpPathV1 = 'v1.file.helpPath',
4547
helpPathV2 = 'v2.file.helpPath',
4648
indentCodeAfterIfDirective = 'v1.formatter.indentCodeAfterIfDirective',
@@ -61,3 +63,13 @@ export enum LanguageId {
6163
ahk1 = 'ahk',
6264
ahk2 = 'ahk2',
6365
}
66+
67+
/** Defined in package.json */
68+
export type ShowOutput = 'always' | 'never';
69+
70+
export enum LibIncludeType {
71+
Disabled = 'Off',
72+
Local = 'Local',
73+
UserAndStandard = 'User and Standard',
74+
All = 'All',
75+
}

src/extension.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as vscode from 'vscode';
22
import { ProviderResult } from 'vscode';
3-
import { Parser } from './parser/parser';
3+
import { clearCache, Parser } from './parser/parser';
44
import { RunnerService } from './service/runnerService';
55
import { DebugSession } from './debugger/debugSession';
66
import { DefProvider } from './providers/defProvider';
@@ -10,7 +10,7 @@ import { SymbolProvider } from './providers/symbolProvider';
1010
import { FileManager } from './common/fileManager';
1111
import { AhkHoverProvider } from './providers/ahkHoverProvider';
1212
import { RefProvider } from './providers/refProvider';
13-
import { Global } from './common/global';
13+
import { ConfigKey, configPrefix, Global } from './common/global';
1414
import { AhkRenameProvider } from './providers/ahkRenameProvider';
1515
import { SignatureProvider } from './providers/signatureProvider';
1616
import { CompletionProvider } from './providers/completionProvider';
@@ -84,6 +84,16 @@ export function activate(context: vscode.ExtensionContext) {
8484
),
8585
);
8686

87+
vscode.workspace.onDidChangeConfiguration(async (e) => {
88+
if (!e.affectsConfiguration(`${configPrefix}.${ConfigKey.exclude}`))
89+
return;
90+
91+
clearCache();
92+
await Parser.buildByPath(
93+
vscode.workspace.workspaceFolders?.[0].uri.fsPath,
94+
);
95+
});
96+
8797
activateV2(context);
8898
}
8999

src/parser/parser.ts

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import { Script, Method, Ref, Label, Block, Variable } from './model';
55
import { pathsToBuild } from './parser.utils';
66
import { Out } from '../common/out';
77

8+
const startBlockComment = / *\/\*/;
9+
const endBlockComment = / *\*\//;
10+
const documentCache = new Map<string, Script>();
11+
12+
export const clearCache = () => {
13+
Out.debug('Clearing cache');
14+
documentCache.clear();
15+
};
16+
817
export interface BuildScriptOptions {
918
/** Defaults to false. If true, short-circuits when document is in cache. */
1019
usingCache?: boolean;
@@ -14,10 +23,8 @@ export interface BuildScriptOptions {
1423

1524
/** Parses v1 files */
1625
export class Parser {
17-
private static documentCache = new Map<string, Script>();
18-
1926
/**
20-
* load method list by path
27+
* Load method list by path
2128
* @param buildPath
2229
*/
2330
public static async buildByPath(buildPath: string) {
@@ -46,8 +53,8 @@ export class Parser {
4653
document: vscode.TextDocument,
4754
options: BuildScriptOptions = {},
4855
): Promise<Script> {
49-
if (options.usingCache && this.documentCache.get(document.uri.path)) {
50-
return this.documentCache.get(document.uri.path);
56+
if (options.usingCache && documentCache.get(document.uri.path)) {
57+
return documentCache.get(document.uri.path);
5158
}
5259

5360
const maxParseLength =
@@ -128,7 +135,7 @@ export class Parser {
128135
}
129136
}
130137
const script: Script = { methods, labels, refs, variables, blocks };
131-
this.documentCache.set(document.uri.path, script);
138+
documentCache.set(document.uri.path, script);
132139
return script;
133140
}
134141

@@ -137,14 +144,13 @@ export class Parser {
137144
name: string,
138145
) {
139146
name = name.toLowerCase();
140-
for (const method of this.documentCache.get(document.uri.path)
141-
.methods) {
147+
for (const method of documentCache.get(document.uri.path).methods) {
142148
if (method.name.toLowerCase() === name) {
143149
return method;
144150
}
145151
}
146-
for (const filePath of this.documentCache.keys()) {
147-
for (const method of this.documentCache.get(filePath).methods) {
152+
for (const filePath of documentCache.keys()) {
153+
for (const method of documentCache.get(filePath).methods) {
148154
if (method.name.toLowerCase() === name) {
149155
return method;
150156
}
@@ -155,8 +161,8 @@ export class Parser {
155161

156162
public static async getAllMethod(): Promise<Method[]> {
157163
const methods = [];
158-
for (const filePath of this.documentCache.keys()) {
159-
for (const method of this.documentCache.get(filePath).methods) {
164+
for (const filePath of documentCache.keys()) {
165+
for (const method of documentCache.get(filePath).methods) {
160166
methods.push(method);
161167
}
162168
}
@@ -168,13 +174,13 @@ export class Parser {
168174
name: string,
169175
) {
170176
name = name.toLowerCase();
171-
for (const label of this.documentCache.get(document.uri.path).labels) {
177+
for (const label of documentCache.get(document.uri.path).labels) {
172178
if (label.name.toLowerCase() === name) {
173179
return label;
174180
}
175181
}
176-
for (const filePath of this.documentCache.keys()) {
177-
for (const label of this.documentCache.get(filePath).labels) {
182+
for (const filePath of documentCache.keys()) {
183+
for (const label of documentCache.get(filePath).labels) {
178184
if (label.name.toLowerCase() === name) {
179185
return label;
180186
}
@@ -186,8 +192,8 @@ export class Parser {
186192
public static getAllRefByName(name: string): Ref[] {
187193
const refs = [];
188194
name = name.toLowerCase();
189-
for (const filePath of this.documentCache.keys()) {
190-
const document = this.documentCache.get(filePath);
195+
for (const filePath of documentCache.keys()) {
196+
const document = documentCache.get(filePath);
191197
for (const ref of document.refs) {
192198
if (ref.name.toLowerCase() === name) {
193199
refs.push(ref);
@@ -388,6 +394,3 @@ export class Parser {
388394
}
389395
}
390396
}
391-
392-
const startBlockComment = / *\/\*/;
393-
const endBlockComment = / *\*\//;

src/test/config.e2e.ts

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
updateConfig,
1111
} from './utils';
1212
import { resolve } from 'path';
13+
import { ConfigKey, LibIncludeType, ShowOutput } from '../common/global';
14+
import { suite, before, test } from 'mocha';
1315

1416
const rootPath = path.join(__dirname, '..', '..', '..');
1517

@@ -18,14 +20,16 @@ const samplesParentPath = path.join(rootPath, 'src/test/samples');
1820

1921
// CI does not have AHK installed
2022
suite('general.showOutput @ignoreCI', () => {
21-
const before = async (show: 'always' | 'never') => {
22-
await updateConfig('general', { showOutput: show });
23+
const before = async (show: ShowOutput) => {
24+
await updateConfig<{ showOutput: ShowOutput }>(ConfigKey.general, {
25+
showOutput: show,
26+
});
2327
const filePath = path.join(samplesParentPath, 'ahk2.ahk2');
2428
const doc = await getDocument(filePath);
2529
await showDocument(doc);
2630
};
2731

28-
const runTests: [name: string, show: 'always' | 'never'][] = [
32+
const runTests: [name: string, show: ShowOutput][] = [
2933
['always + run', 'always'],
3034
['never + run', 'never'],
3135
];
@@ -45,62 +49,64 @@ suite('general.showOutput @ignoreCI', () => {
4549
});
4650

4751
suite('exclude', () => {
48-
// todo can only run one test at a time as changes take effect after restart
49-
test.skip('no exclusions', async () => {
50-
await vscode.workspace
51-
.getConfiguration('AHK++')
52-
.update('exclude', [], vscode.ConfigurationTarget.Workspace);
53-
const filePath = resolve(rootPath, './e2e/main.ahk');
54-
const doc = await getDocument(filePath);
55-
const editor = await showDocument(doc);
56-
editor.insertSnippet(
57-
new vscode.SnippetString('MyExclu')
58-
.appendTabstop(0)
59-
.appendText('\n'),
60-
);
61-
await sleep(100);
62-
editor.selection = new vscode.Selection(0, 0, 0, 'MyExclu'.length);
63-
await sleep(100);
52+
/**
53+
* These tests run in a specific order to update the config correctly
54+
* Config does not update on v2 for speed
55+
*/
56+
const tests: [
57+
name: string,
58+
version: 1 | 2,
59+
exclude: string[],
60+
expected: boolean,
61+
][] = [
62+
['v1 no exclusions', 1, [], true],
63+
['v2 no exclusions', 2, [], true],
64+
['v1 exclusions', 1, ['excluded.ahk'], false],
65+
['v2 exclusions', 2, ['excluded.ahk'], false],
66+
['back to v1 no exclusions', 1, [], true],
67+
['back to v2 no exclusions', 2, [], true],
68+
];
6469

65-
// Get completion items
66-
const completionItems =
67-
await vscode.commands.executeCommand<vscode.CompletionList>(
68-
'vscode.executeCompletionItemProvider',
69-
doc.uri,
70-
editor.selection.active,
71-
);
72-
const labels = completionItems?.items.map((i) => i.label);
73-
assert.strictEqual(labels.includes('MyExcludedFunc'), true);
70+
before(async () => {
71+
await updateConfig<{ librarySuggestions: LibIncludeType }>(
72+
ConfigKey.generalV2,
73+
{ librarySuggestions: LibIncludeType.All },
74+
);
7475
});
7576

76-
test('exclusions', async () => {
77-
await vscode.workspace
78-
.getConfiguration('AHK++')
79-
.update(
80-
'exclude',
81-
['excluded.ahk'],
82-
vscode.ConfigurationTarget.Workspace,
77+
tests.forEach(([name, version, exclude, expected]) => {
78+
test(name, async () => {
79+
const snippetText = 'MyExclu';
80+
const funcName = 'MyExcludedFunc';
81+
if (version === 1)
82+
await updateConfig<string[]>(ConfigKey.exclude, exclude);
83+
const filePath = resolve(rootPath, `./e2e/main.ahk${version}`);
84+
const doc = await getDocument(filePath);
85+
const editor = await showDocument(doc);
86+
editor.insertSnippet(
87+
new vscode.SnippetString(snippetText)
88+
.appendTabstop(0)
89+
.appendText('\n'),
8390
);
84-
const filePath = resolve(rootPath, './e2e/main.ahk');
85-
const doc = await getDocument(filePath);
86-
const editor = await showDocument(doc);
87-
editor.insertSnippet(
88-
new vscode.SnippetString('MyExclu')
89-
.appendTabstop(0)
90-
.appendText('\n'),
91-
);
92-
await sleep(100);
93-
editor.selection = new vscode.Selection(0, 0, 0, 'MyExclu'.length);
94-
await sleep(100);
95-
96-
// Get completion items
97-
const completionItems =
98-
await vscode.commands.executeCommand<vscode.CompletionList>(
99-
'vscode.executeCompletionItemProvider',
100-
doc.uri,
101-
editor.selection.active,
91+
await sleep(1_000);
92+
editor.selection = new vscode.Selection(
93+
0,
94+
0,
95+
0,
96+
snippetText.length,
10297
);
103-
const labels = completionItems?.items.map((i) => i.label);
104-
assert.strictEqual(labels.includes('MyExcludedFunc'), false);
98+
await sleep(1_000);
99+
100+
// Get completion items
101+
const completionItems =
102+
await vscode.commands.executeCommand<vscode.CompletionList>(
103+
'vscode.executeCompletionItemProvider',
104+
doc.uri,
105+
editor.selection.active,
106+
);
107+
await sleep(1_000);
108+
const labels = completionItems?.items.map((i) => i.label);
109+
assert.strictEqual(labels.includes(funcName), expected);
110+
});
105111
});
106112
});

0 commit comments

Comments
 (0)