-
Notifications
You must be signed in to change notification settings - Fork 416
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
Added support for a global omnisharp.json #809
Added support for a global omnisharp.json #809
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good. Is APPDATA the right place on Windows?
@@ -38,6 +40,20 @@ public class OmniSharpEnvironment : IOmniSharpEnvironment | |||
TraceType = traceType; | |||
TransportType = transportType; | |||
OtherArgs = otherArgs; | |||
|
|||
// On Windows: %APPDATA%\OmniSharp\omnisharp.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be "%USERPROFILE%.omnisharp\omnisharp.json" to match more closely to the Unix location? Usually, users aren't expected to edit or place files under %APPDATA%.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't there a huge fight about that when dotnet
was still dnx
? And they moved things to APPDATA
because that was the "windows way"? Some people wanted .dotnet
and others wanted it elsewhere?
Personally I like using USERPROFILE
myself, but I don't to make things any more confusing than they have to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No idea. On my machine, I see the following under USERPROFILE
:
- .dnx
- .node-gyp
- .nuget
- .templateengine
- .vscode
- .vscode-insiders
- .vscode-oss-dev
I think we're in good company in picking USERPROFILE
. 😄
src/OmniSharp.Host/Startup.cs
Outdated
@@ -20,6 +20,8 @@ | |||
using OmniSharp.Services.FileWatching; | |||
using OmniSharp.Stdio.Logging; | |||
using OmniSharp.Stdio.Services; | |||
using System.IO; | |||
using OmniSharp.Host.Internal; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sort usings?
.AddEnvironmentVariables(); | ||
|
||
if (env.OtherArgs?.Length > 0) | ||
{ | ||
configBuilder.AddCommandLine(env.OtherArgs); | ||
} | ||
|
||
// Use the global omnisharp config if there's any in the shared path | ||
configBuilder.CreateAndAddGlobalOptionsFile(env); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It strikes me a little weird that we'd start creating files on the user's machine without them knowing, even if it's an empty file for convenience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, I was a bit on the fence with this one. The idea was to be able to say: "go here, and edit the omnisharp.json
file to have global shared settings", rather than having to say "please create it".
However, you are right, an empty file is a bit silly.
I think we should still create the folder though, it would be somewhat awkward to have to manually create folders that OmniSharp needs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other things (not necessarily language servers specificly) do this kind of thing. If the files don't exist create them. Atom or VSCode both on start.
From a UX point of view it would be easier to point the user to a file and say "Edit your global settings here". However since we (omnisharp) aren't really an editor, we could leave that for the editors to implement themselves.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup. I gated my review on APPDATA vs. USERPROFILE and not whether we create the file or not. I just commented that it struck me as a little weird. 😄
Shall we keep it as is and change it if we need to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the local file {working_dir}/omnisharp.json
is not implicitly created, and users have to manually add it, so at least in that sense the behavior for the global one is consistent
internal const string OmnisharpConfigFile = "config.json"; | ||
internal const string OmnisharpOptionsFile = "omnisharp.json"; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple references to "OmniSharp" seem redundant. Maybe remove it from the member names? Also, the member names have different casing of "OmniSharp". 😄
configBuilder.AddJsonFile( | ||
new PhysicalFileProvider(env.SharedPath), | ||
OmniSharpConstants.OmnisharpOptionsFile, | ||
optional: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We make the file optional but always create it anyway?
@@ -1,12 +1,14 @@ | |||
using System; | |||
using Microsoft.Extensions.Logging; | |||
using System.IO; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sort usings
|
||
namespace OmniSharp.Services | ||
{ | ||
public class OmniSharpEnvironment : IOmniSharpEnvironment | ||
{ | ||
public string Path { get; } | ||
public string SolutionFilePath { get; } | ||
public string SharedPath { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be SharedDirectoryPath
for clarity?
var root = Environment.GetEnvironmentVariable("APPDATA") ?? | ||
Environment.GetEnvironmentVariable("HOME"); | ||
|
||
if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("APPDATA"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: It seems a little funny that we get the environment variable for APPDATA and then get it again immediately.
I moved it from Aside from convenience for the user, having the directory there allows us to use the file watcher under the hood of the Options library - as it can watch for a non-existing file, and light up as soon as it's created, which is a nice user experience. This wouldn't be possible if the folder wasn't there. Also addressed all the other code review feedback. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for making those changes!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, I have a question on ordering of local config vs command line args vs environment args but that isn't directly related to this change.
@@ -38,6 +40,20 @@ public class OmniSharpEnvironment : IOmniSharpEnvironment | |||
TraceType = traceType; | |||
TransportType = transportType; | |||
OtherArgs = otherArgs; | |||
|
|||
// On Windows: %APPDATA%\OmniSharp\omnisharp.json |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't there a huge fight about that when dotnet
was still dnx
? And they moved things to APPDATA
because that was the "windows way"? Some people wanted .dotnet
and others wanted it elsewhere?
Personally I like using USERPROFILE
myself, but I don't to make things any more confusing than they have to be.
.AddEnvironmentVariables(); | ||
|
||
if (env.OtherArgs?.Length > 0) | ||
{ | ||
configBuilder.AddCommandLine(env.OtherArgs); | ||
} | ||
|
||
// Use the global omnisharp config if there's any in the shared path | ||
configBuilder.CreateAndAddGlobalOptionsFile(env); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other things (not necessarily language servers specificly) do this kind of thing. If the files don't exist create them. Atom or VSCode both on start.
From a UX point of view it would be easier to point the user to a file and say "Edit your global settings here". However since we (omnisharp) aren't really an editor, we could leave that for the editors to implement themselves.
I think we're in good shape here. @david-driscoll, holler if you disagree. |
@filipw: I think this change warrants an update to https://github.com/OmniSharp/omnisharp-roslyn/wiki/Configuration-Options. |
indeed 📚 |
Fixes #717
The global
omnisharp.json
file location is:%APPDATA%\OmniSharp\omnisharp.json
~/.omnisharp/omnisharp.json
The folder and an empty
{}
file are created automatically if they are not there.The live reload logic introduced here #804 also supports this global file, meaning any changes to it are automatically reflected.
The global
omnisharp.json
file is given a lower precedence than a local one, so global settings can be overridden locally. It is however given a higher precedence than environment variables and command line arguments.