Skip to content

Commit 0c0629a

Browse files
committed
- Add clangd config auto gen
1 parent f87faec commit 0c0629a

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

src/EIDEProjectExplorer.ts

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ import {
9090
copyAndMakeObjectKeysToLowerCase,
9191
sortPaths,
9292
getGccBinutilsVersion,
93-
compareVersion
93+
compareVersion,
94+
getGccSystemSearchList
9495
} from './utility';
9596
import { concatSystemEnvPath, DeleteDir, exeSuffix, kill, osType, DeleteAllChildren } from './Platform';
9697
import { KeilARMOption, KeilC51Option, KeilParser, KeilRteDependence } from './KeilXmlParser';
@@ -3521,7 +3522,9 @@ export class ProjectExplorer implements CustomConfigurationProvider {
35213522
};
35223523
}
35233524

3524-
////////////////////////////////// cpptools intellisense provider ///////////////////////////////////
3525+
// -----------------------------------------
3526+
// cpptools intellisense provider
3527+
// -----------------------------------------
35253528

35263529
name: string = 'eide';
35273530

@@ -3712,7 +3715,61 @@ export class ProjectExplorer implements CustomConfigurationProvider {
37123715
});
37133716
}
37143717

3715-
////////////////////////////////// Project Explorer ///////////////////////////////////
3718+
// ----------------------------------------
3719+
// clangd config provider
3720+
// ----------------------------------------
3721+
3722+
private async registerClangdProvider(prj: AbstractProject) {
3723+
3724+
if (this.cppToolsApi) {
3725+
// 如果 cpptools 激活了,则禁用 clangd,防止两个冲突
3726+
return;
3727+
}
3728+
3729+
prj.on('cppConfigChanged', () => {
3730+
// todo
3731+
});
3732+
3733+
// ----------------------
3734+
// setup clangd config
3735+
// ----------------------
3736+
try {
3737+
let cfg: any = {};
3738+
const fclangd = File.fromArray([prj.getProjectRoot().path, '.clangd']);
3739+
if (fclangd.IsFile()) {
3740+
cfg = yaml.parse(fclangd.Read());
3741+
}
3742+
if (!cfg['CompileFlags']) cfg['CompileFlags'] = {};
3743+
if (!cfg['CompileFlags']['Add']) cfg['CompileFlags']['Add'] = []
3744+
//
3745+
cfg['CompileFlags']['CompilationDatabase'] = './' + File.ToUnixPath(prj.getOutputDir());
3746+
const toolchain = prj.getToolchain();
3747+
const gccLikePath = toolchain.getGccFamilyCompilerPathForCpptools();
3748+
if (gccLikePath) { // 仅兼容gcc的编译器
3749+
cfg['CompileFlags']['Compiler'] = gccLikePath;
3750+
let args: string[] = cfg['CompileFlags']['Add'];
3751+
if (/GCC/.test(toolchain.name)) {
3752+
let li = getGccSystemSearchList(File.ToLocalPath(gccLikePath));
3753+
if (li) {
3754+
li.forEach(p => {
3755+
args.push(`-I${File.normalize(p)}`);
3756+
});
3757+
}
3758+
} else {
3759+
args.push(`-I${toolchain.getToolchainDir().path}/include`);
3760+
args.push(`-I${toolchain.getToolchainDir().path}/include/libcxx`);
3761+
}
3762+
cfg['CompileFlags']['Add'] = ArrayDelRepetition(args);
3763+
}
3764+
fclangd.Write(yaml.stringify(cfg));
3765+
} catch (error) {
3766+
GlobalEvent.emit('globalLog', ExceptionToMessage(error, 'Error'));
3767+
}
3768+
}
3769+
3770+
// -----------------------------------------
3771+
// Project Explorer
3772+
// -----------------------------------------
37163773

37173774
private on(event: 'request_open_project', listener: (fsPath: string) => void): void;
37183775
private on(event: 'request_create_project', listener: (option: CreateOptions) => void): void;
@@ -3776,6 +3833,8 @@ export class ProjectExplorer implements CustomConfigurationProvider {
37763833

37773834
await this.registerCpptoolsProvider(prj);
37783835

3836+
await this.registerClangdProvider(prj);
3837+
37793838
this.updateCompilerDiagsAfterBuild(prj);
37803839

37813840
prj.on('projectFileChanged', () => this.onProjectFileChanged(prj));

src/utility.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import * as crypto from 'crypto';
2727
import * as child_process from 'child_process';
2828
import * as fs from 'fs';
2929
import * as os from 'os';
30+
import * as NodePath from "path";
3031

3132
import { WorkspaceManager } from "./WorkspaceManager";
3233
import { CmdLineHandler } from "./CmdLineHandler";
@@ -42,6 +43,25 @@ import { ExeCmd } from '../lib/node-utility/Executable';
4243
import { GlobalEvent } from './GlobalEvents';
4344
import { SettingManager } from './SettingManager';
4445

46+
export function getGccSystemSearchList(gccPath: string): string[] | undefined {
47+
try {
48+
const gccName = NodePath.basename(gccPath);
49+
const gccDir = NodePath.dirname(gccPath);
50+
const cmdLine = `${gccName} ` + ['-xc++', '-E', '-v', '-', `<${platform.osGetNullDev()}`, '2>&1'].join(' ');
51+
const lines = child_process.execSync(cmdLine, { cwd: gccDir }).toString().split(/\r\n|\n/);
52+
const iStart = lines.findIndex((line) => { return line.startsWith('#include <...>'); });
53+
const iEnd = lines.indexOf('End of search list.', iStart);
54+
return lines.slice(iStart + 1, iEnd)
55+
.map((line) => { return new File(File.ToLocalPath(line.trim())); })
56+
.filter((file) => { return file.IsDir(); })
57+
.map((f) => {
58+
return f.path;
59+
});
60+
} catch (error) {
61+
// do nothing
62+
}
63+
}
64+
4565
export function makeTextTable(rows: string[][], headerLines?: string[]): string[] | undefined {
4666

4767
if (rows.length == 0)

0 commit comments

Comments
 (0)