Skip to content

Commit 53296c3

Browse files
Merge pull request #14 from Lokesh-Garg-22/dev
2 parents e824e09 + 1eb2ef8 commit 53296c3

27 files changed

Lines changed: 400 additions & 257 deletions

.github/workflows/tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ jobs:
2727
- 1.100.0
2828
- 1.101.0
2929
- 1.102.0
30+
- 1.103.0
31+
- 1.104.0
32+
- 1.105.0
3033

3134
steps:
3235
- uses: actions/checkout@v4

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,26 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.1.4] – 2025-11-07
6+
7+
### Added
8+
9+
- Configuration options to control when file processing is triggered:
10+
- **processOnEdit** — runs processing when editing files.
11+
- **processOnSave** — runs processing when saving files.
12+
13+
### Fixed
14+
15+
- Class names defined after comments were not being recognized.
16+
**Example:**
17+
18+
```scss
19+
// Working on it
20+
.container {
21+
width: 100%;
22+
}
23+
```
24+
525
## [0.1.3] – 2025-07-30
626

727
### Fixed
@@ -97,6 +117,7 @@ All notable changes to this project will be documented in this file.
97117
- Go-to-Definition support for `styles.className` references.
98118
- Autocompletion of class names in JavaScript and TypeScript.
99119

120+
[0.1.4]: https://github.com/Lokesh-Garg-22/CSS-Modules-IntelliSense/compare/v0.1.3...v0.1.4
100121
[0.1.3]: https://github.com/Lokesh-Garg-22/CSS-Modules-IntelliSense/compare/v0.1.2...v0.1.3
101122
[0.1.2]: https://github.com/Lokesh-Garg-22/CSS-Modules-IntelliSense/compare/v0.1.1...v0.1.2
102123
[0.1.1]: https://github.com/Lokesh-Garg-22/CSS-Modules-IntelliSense/compare/v0.1.0...v0.1.1

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "css-scss-modules-intellisense",
33
"displayName": "CSS/SCSS Modules IntelliSense",
44
"description": "Linter and tooling for CSS Modules with support for SCSS, LESS, Go-to-Definition, and Rename in JS/TS files.",
5-
"version": "0.1.3",
5+
"version": "0.1.4",
66
"publisher": "lokesh-garg",
77
"repository": {
88
"type": "git",
@@ -57,6 +57,16 @@
5757
"configuration": {
5858
"title": "CSS Modules Intellisense Extension",
5959
"properties": {
60+
"cssModulesIntellisense.processOnEdit": {
61+
"type": "boolean",
62+
"description": "Process the file on Edit.",
63+
"default": true
64+
},
65+
"cssModulesIntellisense.processOnSave": {
66+
"type": "boolean",
67+
"description": "Process the file on save.",
68+
"default": true
69+
},
6070
"cssModulesIntellisense.aliases": {
6171
"type": "object",
6272
"description": "Define path aliases (like webpack or tsconfig).",

src/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,13 @@ export const DEBOUNCE_TIMER = {
4545
};
4646

4747
export const MAX_CHECK_DOCUMENT_QUEUE_LENGTH = 100;
48+
49+
export const CONFIGURATION_KEY = "cssModulesIntellisense";
50+
export const CONFIGURATIONS = {
51+
ALIASES: "aliases",
52+
BLACKLIST_PATTERNS: "blacklistPatterns",
53+
PROCESS_ON_EDIT: "processOnEdit",
54+
PROCESS_ON_SAVE: "processOnSave",
55+
};
56+
57+
export const CSS_MODULES_CACHE_FILENAME = "cache.json";

src/extension.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import * as vscode from "vscode";
22
import { SUPPORTED_LANGS, SUPPORTED_MODULES } from "./config";
3-
import {
4-
ModulesRenameProvider,
5-
ScriptsRenameProvider,
6-
} from "./providers/renameProvider";
3+
import Cache from "./libs/cache";
4+
import loadCaches from "./libs/loadCaches";
5+
import CheckDocument from "./libs/checkDocument";
6+
import { registerTriggerOnEdit } from "./libs/processConfig";
7+
import CssModuleDependencyCache from "./libs/cssModuleDependencyCache";
78
import CompletionItemProvider from "./providers/completionProvider";
89
import {
910
ScriptDefinitionProvider,
1011
ModuleDefinitionProvider as ModuleDefinitionProvider,
1112
} from "./providers/definitionProvider";
12-
import Cache from "./libs/cache";
13-
import loadCaches from "./libs/loadCaches";
14-
import CheckDocument from "./libs/checkDocument";
15-
import CssModuleDependencyCache from "./libs/cssModuleDependencyCache";
13+
import {
14+
ModulesRenameProvider,
15+
ScriptsRenameProvider,
16+
} from "./providers/renameProvider";
1617

1718
export async function activate(context: vscode.ExtensionContext) {
1819
const diagnosticCollection =
@@ -33,9 +34,9 @@ export async function activate(context: vscode.ExtensionContext) {
3334
vscode.workspace.onDidOpenTextDocument((document) =>
3435
CheckDocument.push(document)
3536
);
36-
vscode.workspace.onDidChangeTextDocument((e) =>
37-
CheckDocument.push(e.document)
38-
);
37+
registerTriggerOnEdit((e) => {
38+
CheckDocument.push(e.document);
39+
});
3940

4041
// Commands
4142
const resetCacheCommand = vscode.commands.registerCommand(

src/libs/cache.ts

Lines changed: 23 additions & 188 deletions
Original file line numberDiff line numberDiff line change
@@ -1,189 +1,15 @@
1-
import * as vscode from "vscode";
21
import * as fs from "fs";
32
import * as path from "path";
4-
import { DEBOUNCE_TIMER } from "../config";
5-
import { LRUCache } from "lru-cache";
6-
7-
type CacheJsonObject = {
8-
pathMapCache: Array<string>;
9-
modulePathCache: Record<number, number[]>;
10-
classNameCache: Record<number, Record<string, ClassNameData[]>>;
11-
};
12-
13-
export type ClassNameData = { range: vscode.Range };
14-
15-
const cacheFile = "cache.json";
16-
17-
export const isLRUCache = <K extends {}, V extends {}, FC = unknown>(
18-
cache: Map<K, V> | LRUCache<K, V, FC>
19-
): cache is LRUCache<K, V, FC> => Object.keys(cache).includes("fetch");
20-
21-
class PathMapCache extends Array<string> {
22-
protected reverseMap = new Map<string, number>();
23-
24-
clear() {
25-
while (this.length) {
26-
this.pop();
27-
}
28-
this.reverseMap.clear();
29-
return this;
30-
}
31-
32-
push(...items: string[]): number {
33-
const length = super.push(...items);
34-
items.forEach((item) => {
35-
this.reverseMap.set(item, this.indexOf(item));
36-
});
37-
return length;
38-
}
39-
40-
setArray(entries: readonly string[]) {
41-
this.clear();
42-
entries.forEach((entry) => {
43-
this.push(entry);
44-
});
45-
}
46-
47-
getKeyFormIndex(index: number) {
48-
return this[index];
49-
}
50-
51-
getIndexFormKey(key: string) {
52-
if (this.reverseMap.has(key)) {
53-
return this.reverseMap.get(key) as NonNullable<
54-
ReturnType<typeof this.reverseMap.get>
55-
>;
56-
}
57-
this.push(key);
58-
return this.reverseMap.get(key) as NonNullable<
59-
ReturnType<typeof this.reverseMap.get>
60-
>;
61-
}
62-
}
63-
64-
class BaseCache<V extends {}, FC = unknown> {
65-
protected cache: Map<number, V> | LRUCache<number, V, FC>;
66-
protected pathMapCache: PathMapCache;
67-
68-
constructor(pathMapCache: PathMapCache, cache: typeof this.cache) {
69-
this.cache = cache;
70-
this.pathMapCache = pathMapCache;
71-
}
72-
73-
clear() {
74-
return this.cache.clear();
75-
}
76-
delete(key: number) {
77-
return this.cache.delete(key);
78-
}
79-
get(key: number) {
80-
return this.cache.get(key);
81-
}
82-
has(key: number) {
83-
return this.cache.has(key);
84-
}
85-
set(key: number, value: V) {
86-
this.cache.set(key, value);
87-
return this;
88-
}
89-
entries() {
90-
return this.cache.entries();
91-
}
92-
keys() {
93-
return this.cache.keys();
94-
}
95-
values() {
96-
return this.cache.values();
97-
}
98-
[Symbol.iterator]() {
99-
return this.cache[Symbol.iterator]();
100-
}
101-
102-
hasByKey(key: string): boolean {
103-
const keyIndex = this.pathMapCache.getIndexFormKey(key);
104-
return this.has(keyIndex);
105-
}
106-
107-
getByKey(key: string) {
108-
const keyIndex = this.pathMapCache.getIndexFormKey(key);
109-
return this.get(keyIndex);
110-
}
111-
112-
setByKey(key: string, value: V): this {
113-
const keyIndex = this.pathMapCache.getIndexFormKey(key);
114-
return this.set(keyIndex, value);
115-
}
116-
117-
setMap(entries: readonly (readonly [string, V])[]) {
118-
this.clear;
119-
entries.forEach((entry) => {
120-
this.setByKey(entry[0], entry[1]);
121-
});
122-
}
123-
124-
deleteByKey(key: string): boolean {
125-
const keyIndex = this.pathMapCache.getIndexFormKey(key);
126-
return this.delete(keyIndex);
127-
}
128-
}
129-
130-
class ModulePathCacheSet extends Set<number> {
131-
protected pathMapCache: PathMapCache;
132-
133-
constructor(pathMapCache: PathMapCache, values?: readonly number[] | null) {
134-
super(values ?? undefined);
135-
this.pathMapCache = pathMapCache;
136-
}
137-
138-
addByKey(value: string): this {
139-
const valueIndex = this.pathMapCache.getIndexFormKey(value);
140-
return this.add(valueIndex);
141-
}
142-
143-
toKeyArray() {
144-
const arr = [...this];
145-
return arr.map((ele) => this.pathMapCache.getKeyFormIndex(ele));
146-
}
147-
}
148-
149-
class ModulePathCache extends BaseCache<ModulePathCacheSet> {
150-
constructor(pathMap: PathMapCache) {
151-
super(pathMap, new Map<number, ModulePathCacheSet>());
152-
}
153-
154-
createKey(key: string) {
155-
const set = new ModulePathCacheSet(this.pathMapCache);
156-
this.setByKey(key, set);
157-
return set;
158-
}
159-
}
160-
161-
export class ClassNameDataMap extends Map<string, ClassNameData[]> {
162-
add(key: string, value: ClassNameData) {
163-
if (this.has(key)) {
164-
const arr = this.get(key)!;
165-
arr.push(value);
166-
} else {
167-
const arr = [value];
168-
this.set(key, arr);
169-
}
170-
return this;
171-
}
172-
}
173-
174-
class ClassNameCache extends BaseCache<ClassNameDataMap> {
175-
constructor(
176-
pathMap: PathMapCache,
177-
options:
178-
| LRUCache<number, ClassNameDataMap>
179-
| LRUCache.Options<number, ClassNameDataMap, unknown>
180-
) {
181-
const lruCache: ConstructorParameters<
182-
typeof BaseCache<ClassNameDataMap>
183-
>[1] = new LRUCache(options);
184-
super(pathMap, lruCache);
185-
}
186-
}
3+
import * as vscode from "vscode";
4+
import { CSS_MODULES_CACHE_FILENAME, DEBOUNCE_TIMER } from "../config";
5+
import {
6+
CacheJsonObject,
7+
ClassNameCache,
8+
ClassNameRangeMap,
9+
ModulePathCache,
10+
ModulePathCacheSet,
11+
PathMapCache,
12+
} from "../types/cache";
18713

18814
export default class Cache {
18915
static pathMapCache = new PathMapCache();
@@ -220,7 +46,10 @@ export default class Cache {
22046
this.classNameCache.clear();
22147
this.pathMapCache.clear();
22248

223-
const cacheFilePath = path.join(this.context.storageUri.fsPath, cacheFile);
49+
const cacheFilePath = path.join(
50+
this.context.storageUri.fsPath,
51+
CSS_MODULES_CACHE_FILENAME
52+
);
22453
const cacheAsObject: CacheJsonObject = {
22554
pathMapCache: [],
22655
modulePathCache: {},
@@ -259,7 +88,10 @@ export default class Cache {
25988
return false;
26089
}
26190

262-
const cacheFilePath = path.join(this.context.storageUri.fsPath, cacheFile);
91+
const cacheFilePath = path.join(
92+
this.context.storageUri.fsPath,
93+
CSS_MODULES_CACHE_FILENAME
94+
);
26395
const cacheAsObject: CacheJsonObject = {
26496
pathMapCache: [],
26597
modulePathCache: {},
@@ -297,7 +129,10 @@ export default class Cache {
297129
return false;
298130
}
299131

300-
const cacheFilePath = path.join(this.context.storageUri.fsPath, cacheFile);
132+
const cacheFilePath = path.join(
133+
this.context.storageUri.fsPath,
134+
CSS_MODULES_CACHE_FILENAME
135+
);
301136
if (!fs.existsSync(cacheFilePath)) {
302137
return false;
303138
}
@@ -321,7 +156,7 @@ export default class Cache {
321156
this.classNameCache.setMap(
322157
Object.entries(parsed.classNameCache || {}).map(([key, value]) => [
323158
key,
324-
new ClassNameDataMap(Object.entries(value)),
159+
new ClassNameRangeMap(Object.entries(value)),
325160
])
326161
);
327162
} catch (error) {

0 commit comments

Comments
 (0)