ioeric created this revision.
ioeric added a reviewer: sammccall.
Herald added subscribers: cfe-commits, jkorous-apple, ilya-biryukov, klimek.

For features like go-to-definition, clangd can point clients to symlink paths
(e.g. in bazel execroot) which might not be desired if the symlink points to a
file in the workspace. Clangd might not be able to build the file, and users
might prefer to edit the file on the real path.

This change converts file paths from clangd to real path (e.g. resolving 
symlinks).
Long term, we might want to the symlink handling logic to clangd where clangd
can better decide whether symlinks should be resolved according to e.g. compile
commands.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D44158

Files:
  clangd/clients/clangd-vscode/src/extension.ts


Index: clangd/clients/clangd-vscode/src/extension.ts
===================================================================
--- clangd/clients/clangd-vscode/src/extension.ts
+++ clangd/clients/clangd-vscode/src/extension.ts
@@ -1,12 +1,13 @@
 import * as vscode from 'vscode';
 import * as vscodelc from 'vscode-languageclient';
+import { realpathSync } from 'fs';
 
 /**
  * Method to get workspace configuration option
  * @param option name of the option (e.g. for clangd.path should be path)
  * @param defaultValue default value to return if option is not set
  */
-function getConfig<T>(option: string, defaultValue?: any) : T {
+function getConfig<T>(option: string, defaultValue?: any): T {
     const config = vscode.workspace.getConfiguration('clangd');
     return config.get<T>(option, defaultValue);
 }
@@ -24,18 +25,25 @@
     };
     const traceFile = getConfig<string>('trace');
     if (!!traceFile) {
-      const trace = {CLANGD_TRACE : traceFile};
-      clangd.options = {env : {...process.env, ...trace}};
+        const trace = { CLANGD_TRACE: traceFile };
+        clangd.options = { env: { ...process.env, ...trace } };
     }
     const serverOptions: vscodelc.ServerOptions = clangd;
 
     const filePattern: string = '**/*.{' +
-      ['cpp', 'c', 'cc', 'cxx', 'c++', 'm', 'mm', 'h', 'hh', 'hpp', 'hxx', 
'inc'].join() + '}';
+        ['cpp', 'c', 'cc', 'cxx', 'c++', 'm', 'mm', 'h', 'hh', 'hpp', 'hxx', 
'inc'].join() + '}';
     const clientOptions: vscodelc.LanguageClientOptions = {
         // Register the server for C/C++ files
-        documentSelector: [{scheme: 'file', pattern: filePattern}],
+        documentSelector: [{ scheme: 'file', pattern: filePattern }],
         synchronize: !syncFileEvents ? undefined : {
             fileEvents: vscode.workspace.createFileSystemWatcher(filePattern)
+        },
+        // Resolve symlinks for all files provided by clangd.
+        // FIXME: it might make more sense to rely on clangd to handle 
symlinks.
+        uriConverters: {
+            code2Protocol: (value: vscode.Uri) => value.toString(),
+            protocol2Code: (value: string) =>
+                vscode.Uri.file(realpathSync(vscode.Uri.parse(value).fsPath))
         }
     };
 


Index: clangd/clients/clangd-vscode/src/extension.ts
===================================================================
--- clangd/clients/clangd-vscode/src/extension.ts
+++ clangd/clients/clangd-vscode/src/extension.ts
@@ -1,12 +1,13 @@
 import * as vscode from 'vscode';
 import * as vscodelc from 'vscode-languageclient';
+import { realpathSync } from 'fs';
 
 /**
  * Method to get workspace configuration option
  * @param option name of the option (e.g. for clangd.path should be path)
  * @param defaultValue default value to return if option is not set
  */
-function getConfig<T>(option: string, defaultValue?: any) : T {
+function getConfig<T>(option: string, defaultValue?: any): T {
     const config = vscode.workspace.getConfiguration('clangd');
     return config.get<T>(option, defaultValue);
 }
@@ -24,18 +25,25 @@
     };
     const traceFile = getConfig<string>('trace');
     if (!!traceFile) {
-      const trace = {CLANGD_TRACE : traceFile};
-      clangd.options = {env : {...process.env, ...trace}};
+        const trace = { CLANGD_TRACE: traceFile };
+        clangd.options = { env: { ...process.env, ...trace } };
     }
     const serverOptions: vscodelc.ServerOptions = clangd;
 
     const filePattern: string = '**/*.{' +
-      ['cpp', 'c', 'cc', 'cxx', 'c++', 'm', 'mm', 'h', 'hh', 'hpp', 'hxx', 'inc'].join() + '}';
+        ['cpp', 'c', 'cc', 'cxx', 'c++', 'm', 'mm', 'h', 'hh', 'hpp', 'hxx', 'inc'].join() + '}';
     const clientOptions: vscodelc.LanguageClientOptions = {
         // Register the server for C/C++ files
-        documentSelector: [{scheme: 'file', pattern: filePattern}],
+        documentSelector: [{ scheme: 'file', pattern: filePattern }],
         synchronize: !syncFileEvents ? undefined : {
             fileEvents: vscode.workspace.createFileSystemWatcher(filePattern)
+        },
+        // Resolve symlinks for all files provided by clangd.
+        // FIXME: it might make more sense to rely on clangd to handle symlinks.
+        uriConverters: {
+            code2Protocol: (value: vscode.Uri) => value.toString(),
+            protocol2Code: (value: string) =>
+                vscode.Uri.file(realpathSync(vscode.Uri.parse(value).fsPath))
         }
     };
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to