Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add file watcher for compile_commands.json and other configuration files #33

Merged
merged 11 commits into from
Sep 28, 2020
15 changes: 15 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,21 @@
"type": "boolean",
"default": false,
"description": "Check for language server updates on startup."
},
"clangd.onConfigChanged": {
"type": "string",
"default": "prompt",
"description": "What to do when clangd configuration files are changed.",
"enum": [
"prompt",
"restart",
"ignore"
],
"enumDescriptions": [
"Prompt the user for restarting the server",
"Automatically restart the server",
"Do nothing"
]
}
}
},
Expand Down
73 changes: 73 additions & 0 deletions src/config-file-watcher.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import * as path from 'path';
import * as vscode from 'vscode';

import * as config from './config';

export function activate(context: vscode.ExtensionContext) {
if (config.get<string>('onConfigChanged') != 'ignore') {
const watcher = new ConfigFileWatcher(context);
}
}

class ConfigFileWatcher {
private databaseWatcher: vscode.FileSystemWatcher = undefined;

constructor(private context: vscode.ExtensionContext) {
this.createFileSystemWatcher();
context.subscriptions.push(vscode.workspace.onDidChangeWorkspaceFolders(
() => { this.createFileSystemWatcher(); }));
}

createFileSystemWatcher() {
if (this.databaseWatcher)
this.databaseWatcher.dispose();
this.databaseWatcher = vscode.workspace.createFileSystemWatcher(
'{' +
vscode.workspace.workspaceFolders.map(f => f.uri.fsPath).join(',') +
'}/{build/compile_commands.json,compile_commands.json,compile_flags.txt,.clang-tidy}');
this.context.subscriptions.push(this.databaseWatcher.onDidChange(
this.handleConfigFilesChanged.bind(this)));
this.context.subscriptions.push(this.databaseWatcher.onDidCreate(
this.handleConfigFilesChanged.bind(this)));
this.context.subscriptions.push(this.databaseWatcher);
}

async handleConfigFilesChanged(uri: vscode.Uri) {
// Sometimes the tools that generate the compilation database, before
// writing to it, they create a new empty file or they clear the existing
// one, and after the compilation they write the new content. In this cases
// the server is not supposed to restart
if ((await vscode.workspace.fs.stat(uri)).size <= 0)
return;

switch (config.get<string>('onConfigChanged')) {
case 'restart':
vscode.commands.executeCommand('clangd.restart');
break;
case 'ignore':
break;
case 'prompt':
default:
switch (await vscode.window.showInformationMessage(
'Clangd configuration file at \'' + uri.fsPath +
rapgenic marked this conversation as resolved.
Show resolved Hide resolved
'\' has been changed. Do you want to restart it?',
'Yes', 'Yes, always', 'No, never')) {
case 'Yes':
vscode.commands.executeCommand('clangd.restart');
break;
case 'Yes, always':
vscode.commands.executeCommand('clangd.restart');
config.update<string>('onConfigChanged', 'restart',
vscode.ConfigurationTarget.Global);
break;
case 'No, never':
config.update<string>('onConfigChanged', 'ignore',
vscode.ConfigurationTarget.Global);
break;
default:
break;
}
break;
}
}
}
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as vscode from 'vscode';
import * as vscodelc from 'vscode-languageclient/node';

import * as config from './config';
import * as configFileWatcher from './config-file-watcher';
import * as fileStatus from './file-status';
import * as install from './install';
import * as semanticHighlighting from './semantic-highlighting';
Expand Down Expand Up @@ -140,6 +141,7 @@ export async function activate(context: vscode.ExtensionContext) {
console.log('Clang Language Server is now active!');
fileStatus.activate(client, context);
switchSourceHeader.activate(client, context);
configFileWatcher.activate(context);
// An empty place holder for the activate command, otherwise we'll get an
// "command is not registered" error.
context.subscriptions.push(
Expand Down