Skip to content

Commit 0d2672b

Browse files
authored
Merge pull request #193 from github0null/dev
v3.10.6 update
2 parents 3238fa6 + 87d0dca commit 0d2672b

10 files changed

Lines changed: 176 additions & 92 deletions

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ All notable version changes will be recorded in this file.
66

77
***
88

9+
### [v3.10.6] revision
10+
11+
**Fix**:
12+
- `cpptools configuration provider not work`: Fix provider file filter bug.
13+
14+
**Optimize**:
15+
- `Resource Explorer`: Keep `non-existed` filesystem source folders. Optimize folder watcher
16+
- `Settings Scope`: Allow user override more eide settings by `workspace settings`.
17+
- `FileWatcher`: Auto close file watcher if watcher has an error.
18+
- `Prompt messages`: Optimize some UI hint messages.
19+
20+
***
21+
922
### [v3.10.5] revision
1023

1124
**Fix**:

lib/node-utility

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"homepage": "https://em-ide.com",
3636
"license": "MIT",
3737
"description": "A mcu development environment for 8051/AVR/STM8/Cortex-M/RISC-V",
38-
"version": "3.10.5",
38+
"version": "3.10.6",
3939
"preview": false,
4040
"engines": {
4141
"vscode": "^1.63.0"

src/CodeBuilder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ export abstract class CodeBuilder {
278278
this.logWatcher = new FileWatcher(builderLog, false);
279279
this.logWatcher.OnChanged = () => {
280280
this.logWatcher?.Close();
281-
setTimeout(() => this.emit('finished', checkBuildDone(builderLog)), 400);
281+
setTimeout(() => this.emit('finished', checkBuildDone(builderLog)), 500);
282282
};
283283

284284
// start watch

src/EIDEProject.ts

Lines changed: 107 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export interface FolderInfo {
9696
}
9797

9898
interface SourceRootInfo extends FolderInfo {
99+
isValid: () => boolean;
99100
fileWatcher: FileWatcher;
100101
fileGroups: ProjectFileGroup[];
101102
incList: string[];
@@ -383,6 +384,7 @@ class SourceRootList implements SourceProvider {
383384
this.project = _project;
384385
this._event = new events.EventEmitter();
385386
this.srcFolderMaps = new Map();
387+
FileWatcher.on('rename', f => this.onFolderRenamed(this.getSourceRootKeyByAbspath(f.path), f));
386388
}
387389

388390
isAutoSearchObjectFile(): boolean {
@@ -400,13 +402,7 @@ class SourceRootList implements SourceProvider {
400402
const srcFolders = this.project.GetConfiguration().config.srcDirs;
401403
srcFolders.forEach((path) => {
402404
const f = new File(path);
403-
if (f.IsDir()) {
404-
const key: string = this.getRelativePath(path);
405-
const watcher = platform.createSafetyFileWatcher(f, true).Watch();
406-
watcher.on('error', (err) => GlobalEvent.emit('msg', ExceptionToMessage(err, 'Hidden')));
407-
watcher.OnRename = (file) => this.onFolderRenamed(key, file);
408-
this.srcFolderMaps.set(key, this.newSourceInfo(key, watcher));
409-
}
405+
this._add(f);
410406
});
411407

412408
// update all
@@ -417,23 +413,24 @@ class SourceRootList implements SourceProvider {
417413
if (!notEmitEvt) { this.emit('dataChanged', 'dataChanged'); }
418414
}
419415

416+
private _add(dir: File): SourceRootInfo {
417+
const key: string = this.getSourceRootKeyByAbspath(dir.path);
418+
const watcher = platform.createSafetyFileWatcher(dir, true);
419+
watcher.on('error', (err) => GlobalEvent.emit('globalLog', ExceptionToMessage(err, 'Warning')));
420+
const sourceInfo = this.newSourceInfo(key, watcher);
421+
this.srcFolderMaps.set(key, sourceInfo);
422+
return sourceInfo;
423+
}
424+
420425
add(absPath: string): boolean {
421-
const f = new File(absPath);
422-
if (f.IsDir()) {
423-
const key: string = this.getRelativePath(absPath);
424-
const watcher = platform.createSafetyFileWatcher(f, true).Watch();
425-
watcher.on('error', (err) => GlobalEvent.emit('msg', ExceptionToMessage(err, 'Hidden')));
426-
watcher.OnRename = (file) => this.onFolderRenamed(key, file);
427-
const sourceInfo = this.newSourceInfo(key, watcher);
428-
this.srcFolderMaps.set(key, sourceInfo);
429-
this.updateFolder(sourceInfo);
430-
return true;
431-
}
432-
return false;
426+
const dir = new File(absPath);
427+
const sourceInfo = this._add(dir);
428+
this.updateFolder(sourceInfo);
429+
return true;
433430
}
434431

435432
remove(absPath: string): boolean {
436-
const key = this.getRelativePath(absPath);
433+
const key = this.getSourceRootKeyByAbspath(absPath);
437434
return this.removeByKey(key);
438435
}
439436

@@ -470,7 +467,7 @@ class SourceRootList implements SourceProvider {
470467
if (rootSrcUpdateList.length > 0) {
471468

472469
for (const rootInfo of rootSrcUpdateList) {
473-
if (rootInfo.fileWatcher.file.IsDir()) {
470+
if (rootInfo.isValid()) {
474471
this.updateFolder(rootInfo, [targetDir]);
475472
}
476473
}
@@ -527,6 +524,26 @@ class SourceRootList implements SourceProvider {
527524
return res;
528525
}
529526

527+
isIncludes(abspath: string): boolean {
528+
529+
if (!File.isAbsolute(abspath)) {
530+
abspath = this.project.toAbsolutePath(abspath);
531+
}
532+
533+
const unixPath = File.ToUnixPath(abspath);
534+
535+
for (const rootInfo of this.srcFolderMaps.values()) {
536+
const unixRootPath = File.ToUnixPath(rootInfo.fileWatcher.file.path);
537+
const unixRootRealPath = File.ToUnixPath(platform.realpathSync(rootInfo.fileWatcher.file.path));
538+
if (unixPath.startsWith(unixRootPath) ||
539+
unixPath.startsWith(unixRootRealPath)) {
540+
return true;
541+
}
542+
}
543+
544+
return false;
545+
}
546+
530547
forceUpdateAllFolders() {
531548
for (const info of this.srcFolderMaps.values()) {
532549
this.updateFolder(info);
@@ -537,13 +554,8 @@ class SourceRootList implements SourceProvider {
537554
forceUpdateFolder(rePath: string) {
538555
const rootInfo = this.srcFolderMaps.get(rePath);
539556
if (rootInfo) {
540-
if (rootInfo.fileWatcher.file.IsDir()) {
541-
this.updateFolder(rootInfo);
542-
this.emit('dataChanged', 'folderChanged');
543-
} else {
544-
this.removeByKey(rePath);
545-
this.emit('dataChanged', 'dataChanged');
546-
}
557+
this.updateFolder(rootInfo);
558+
this.emit('dataChanged', 'folderChanged');
547559
}
548560
}
549561

@@ -554,42 +566,51 @@ class SourceRootList implements SourceProvider {
554566
this._event.emit(event, arg);
555567
}
556568

557-
private getRelativePath(abspath: string): string {
569+
private getSourceRootKeyByAbspath(abspath: string): string {
558570
return this.project.toRelativePath(abspath);
559571
}
560572

561573
private newSourceInfo(displayName: string, watcher: FileWatcher): SourceRootInfo {
562574
return {
563575
displayName: displayName,
564576
fileWatcher: watcher,
577+
isValid: () => watcher.file.IsDir(),
565578
needUpdate: false,
566579
fileGroups: [],
567580
incList: []
568581
};
569582
}
570583

571-
private removeByKey(key: string): boolean {
584+
private disposeWatcher(key: string): void {
572585
this.srcFolderMaps.get(key)?.fileWatcher.Close();
586+
}
587+
588+
private removeByKey(key: string): boolean {
589+
this.disposeWatcher(key);
573590
return this.srcFolderMaps.delete(key);
574591
}
575592

576593
private onFolderRenamed(folderKey: string, targetFile: File) {
577594
const rootInfo = this.srcFolderMaps.get(folderKey);
578595
if (rootInfo) {
579-
if (targetFile.path === rootInfo.fileWatcher.file.path) { // root folder has been renamed
580-
if (this.removeByKey(folderKey)) { this.emit('dataChanged', 'dataChanged'); }
596+
597+
// folder self has been renamed ?
598+
// - if true, this folder's file watcher is invalid, dispose it
599+
if (targetFile.path == rootInfo.fileWatcher.file.path) {
600+
this.disposeWatcher(folderKey);
601+
this.emit('dataChanged', 'folderStatusChanged');
602+
}
603+
604+
if (rootInfo.refreshTimeout) {
605+
rootInfo.refreshTimeout.refresh();
581606
} else {
582-
if (rootInfo.refreshTimeout) {
583-
rootInfo.refreshTimeout.refresh();
584-
} else {
585-
rootInfo.refreshTimeout = setTimeout((folderInfo: SourceRootInfo) => {
586-
if (folderInfo.refreshTimeout) {
587-
folderInfo.refreshTimeout = undefined;
588-
this.updateFolder(folderInfo);
589-
this.emit('dataChanged', 'folderChanged');
590-
}
591-
}, 100, rootInfo);
592-
}
607+
rootInfo.refreshTimeout = setTimeout((folderInfo: SourceRootInfo) => {
608+
if (folderInfo.refreshTimeout) {
609+
folderInfo.refreshTimeout = undefined;
610+
this.updateFolder(folderInfo);
611+
this.emit('dataChanged', 'folderChanged');
612+
}
613+
}, 200, rootInfo);
593614
}
594615
}
595616
}
@@ -619,6 +640,9 @@ class SourceRootList implements SourceProvider {
619640
rootFolderInfo.incList = [];
620641
rootFolderInfo.fileGroups = [];
621642
folderStack.push(rootFolder);
643+
// if source root have no watcher, watch it !
644+
if (rootFolderInfo.isValid() && !rootFolderInfo.fileWatcher.IsWatched())
645+
rootFolderInfo.fileWatcher.Watch();
622646
}
623647

624648
rootFolderInfo.needUpdate = false;
@@ -629,9 +653,14 @@ class SourceRootList implements SourceProvider {
629653

630654
const cFolder = <File>folderStack.pop();
631655
const isSourceRoot = cFolder.path === rootFolder.path;
632-
if (cFolder.name.startsWith('.') && !isSourceRoot) continue; // skip '.xxx' folders, not root folder
633-
const fileList = cFolder.GetList(fileFilter, File.EXCLUDE_ALL_FILTER);
634656

657+
if (!cFolder.IsDir())
658+
continue; // skip not-existed folder
659+
660+
if (cFolder.name.startsWith('.') && !isSourceRoot)
661+
continue; // skip sub '.xxx' folders, but not root folder
662+
663+
const fileList = cFolder.GetList(fileFilter, File.EXCLUDE_ALL_FILTER);
635664
if (fileList.length > 0) {
636665

637666
// filter source file and add to file group
@@ -679,7 +708,7 @@ class SourceRootList implements SourceProvider {
679708

680709
} catch (error) {
681710
rootFolderInfo.needUpdate = true; // set need update flag
682-
GlobalEvent.emit('msg', ExceptionToMessage(error, 'Hidden'));
711+
GlobalEvent.emit('globalLog', ExceptionToMessage(error, 'Warning'));
683712
}
684713
}
685714
}
@@ -724,7 +753,7 @@ export abstract class AbstractProject implements CustomConfigurationProvider, Pr
724753
static readonly excludeDirFilter: RegExp = /^\./;
725754

726755
// to show output files
727-
static readonly buildOutputMatcher: RegExp = /\.(?:elf|axf|out|a|lib|hex|ihx|bin|s19|s37|sct|icf|ld[s]?|map|map\.view)$/i;
756+
static readonly buildOutputMatcher: RegExp = /\.(?:elf|axf|out|a|lib|hex|ihx|bin|s19|s37|sct|icf|ld[s]?|map|map\.view|lst)$/i;
728757

729758
//-------
730759

@@ -1125,7 +1154,7 @@ export abstract class AbstractProject implements CustomConfigurationProvider, Pr
11251154

11261155
replacePathEnv(path: string): string {
11271156

1128-
for (let cnt = 0; cnt < 5; cnt++) {
1157+
for (let cnt = 0; cnt < 3; cnt++) {
11291158

11301159
if (!File.isEnvPath(path))
11311160
break; // not have any env var, end
@@ -2367,6 +2396,12 @@ class EIDEProject extends AbstractProject {
23672396
return this.srcRefMap.get(file.path) || [];
23682397
}
23692398

2399+
public getSourceRefsAll(): string[] {
2400+
const allHeaders: string[] = [];
2401+
this.srcRefMap.forEach(v => v.forEach(f => allHeaders.push(f.path)));
2402+
return ArrayDelRepetition(allHeaders);
2403+
}
2404+
23702405
private whitespaceMatcher = /(?<![\\:]) /;
23712406

23722407
private gnu_parseRefLines(lines: string[]): string[] {
@@ -2668,6 +2703,7 @@ class EIDEProject extends AbstractProject {
26682703

26692704
const fileAssCfg: any = {
26702705
".eideignore": "ignore",
2706+
"*.a51": "a51",
26712707
"*.h": "c",
26722708
"*.c": "c",
26732709
"*.hxx": "cpp",
@@ -2856,20 +2892,6 @@ class EIDEProject extends AbstractProject {
28562892
//
28572893
}
28582894
}
2859-
2860-
/* const cppConfig = this.GetCppConfig();
2861-
const cppConfigItem = cppConfig.getConfig();
2862-
if (cppConfigItem.configurationProvider) {
2863-
const newCfg: CppConfigItem = {
2864-
name: os.platform(),
2865-
includePath: <any>undefined,
2866-
defines: <any>undefined,
2867-
intelliSenseMode: "${default}",
2868-
configurationProvider: this.extensionId
2869-
};
2870-
cppConfig.setConfig(newCfg);
2871-
cppConfig.saveToFile();
2872-
} */
28732895
}
28742896

28752897
// show warnings if we have
@@ -3107,14 +3129,30 @@ class EIDEProject extends AbstractProject {
31073129
}
31083130

31093131
canProvideConfiguration(uri: vscode.Uri, token?: vscode.CancellationToken | undefined): Thenable<boolean> {
3132+
31103133
return new Promise((resolve) => {
3111-
const filePath = platform.realpathSync(uri.fsPath);
3134+
3135+
const realPath = platform.realpathSync(uri.fsPath);
3136+
const lowcasePath = uri.fsPath.toLowerCase();
31123137
const prjRoot = platform.realpathSync(this.GetRootDir().path);
3113-
resolve(
3114-
AbstractProject.headerFilter.test(filePath) ||
3115-
filePath.startsWith(prjRoot) ||
3116-
this.vSourceList.has(filePath)
3117-
);
3138+
const allIncPaths = this.cppToolsConfig.includePath.map(p => File.ToLocalPath(p.toLowerCase()));
3139+
3140+
// filter source files that can provide
3141+
let result: boolean =
3142+
realPath.startsWith(prjRoot) || // All source files in current workspace
3143+
allIncPaths.some(p => lowcasePath.startsWith(p)) || // All files in IncludePaths
3144+
this.vSourceList.has(realPath) || // All virtual source files
3145+
this.sourceRoots.isIncludes(realPath); // All source files in linked source folders
3146+
3147+
// other .h files
3148+
if (!result && AbstractProject.headerFilter.test(lowcasePath)) {
3149+
const allHeaders = this.getSourceRefsAll().map(p => File.ToLocalPath(p.toLowerCase()));
3150+
result = result ||
3151+
allHeaders.some(p => p == lowcasePath) || // All .h files for this project
3152+
lowcasePath.startsWith(this.getToolchain().getToolchainDir().path.toLowerCase()); // All .h files in toolchain dir
3153+
}
3154+
3155+
resolve(result);
31183156
});
31193157
}
31203158

@@ -3123,6 +3161,7 @@ class EIDEProject extends AbstractProject {
31233161
provideConfigurations(uris: vscode.Uri[], token?: vscode.CancellationToken | undefined): Thenable<SourceFileConfigurationItem[]> {
31243162

31253163
return new Promise((resolve) => {
3164+
31263165
resolve(uris.map((uri) => {
31273166

31283167
let fileArgs: string[] | undefined;

0 commit comments

Comments
 (0)