3

I'm writing a language server protocol extension for a custom language for VS Code. I'm writing the server part in C# using OmniSharp Language Server API.

I'm having trouble implementing DidChangeWatchedFile functionality. Even if I implement the IDidChangeWatchedFilesHandler interface the notification is not sent from the client or the server.

According to the specification there ought to be a DidChangeWatchedFilesRegistrationOptions interface where one could register for custom file events but I can't find this interface anywhere in OmniSharp. I want to be able to react to situations where a specific file is changed/added/deleted in the workspace and the file is not opened in the editor (thus not handled by DidChangeTextDocument handler).

Any tip/suggestion would be more than welcomed.

Thank you!

1 Answers1

3

I just had to figure this out myself! This comes from two places, assuming you have an extension host and language server:

  1. In your extension host (extension.ts) you need to create the LanguageClientOptions and set the synchronize property. Here is an example straight from the vscode extension samples:

    https://github.com/microsoft/vscode-extension-samples/blob/master/lsp-sample/client/src/extension.ts#L39-L46

  2. In your server (server.ts) just add a callback for onDidChangeWatchedFiles, which also comes from the extension sample:

    https://github.com/microsoft/vscode-extension-samples/blob/master/lsp-sample/server/src/server.ts#L173-L176

If you add or remove files caught by your file system watcher, then you should see the events pop up.

Only other thing worth noting is that you get an array of changes and have to handle each one. Below is how I handle this for my extension.

import { FileChangeType } from 'vscode-languageserver';

connection.onDidChangeWatchedFiles(async _change => {
  // Monitored files have change in VSCode
  connection.console.log('We received an file change event');

  // process each change
  for (let i = 0; i < _change.changes.length; i++) {
    const change = _change.changes[i];
    switch (change.type) {
      case FileChangeType.Created:
        await idl.addDocumentSymbols(change.uri);
        break;
      case FileChangeType.Deleted:
        await idl.removeDocumentSymbols(change.uri);
        break;
      case FileChangeType.Changed:
        await idl.updateDocumentSymbols(change.uri);
        break;
      default:
        // do nothing
        break;
    }
  }

  // detect and send problems
  idl.detectProblems(true);
});
Zach
  • 199
  • 5