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

Added support for a global omnisharp.json #809

Merged
merged 7 commits into from
Mar 31, 2017

Conversation

filipw
Copy link
Member

@filipw filipw commented Mar 30, 2017

Fixes #717

The global omnisharp.json file location is:

  • On Windows: %APPDATA%\OmniSharp\omnisharp.json
  • On Mac/Linux: ~/.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.

Copy link
Contributor

@DustinCampbell DustinCampbell left a 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
Copy link
Contributor

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%.

Copy link
Member

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.

Copy link
Contributor

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. 😄

@@ -20,6 +20,8 @@
using OmniSharp.Services.FileWatching;
using OmniSharp.Stdio.Logging;
using OmniSharp.Stdio.Services;
using System.IO;
using OmniSharp.Host.Internal;
Copy link
Contributor

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);
Copy link
Contributor

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.

Copy link
Member Author

@filipw filipw Mar 30, 2017

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.

Copy link
Member

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.

Copy link
Contributor

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?

Copy link
Member Author

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";
}
}
Copy link
Contributor

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,
Copy link
Contributor

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;
Copy link
Contributor

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; }
Copy link
Contributor

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")))
Copy link
Contributor

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.

@filipw
Copy link
Member Author

filipw commented Mar 30, 2017

I moved it from APPDATA to USERPROFILE as suggested - the paths are now unified for both OS families ({HOME}|{USERPROFILE}/.omnisharp/omnisharp.json). There is no more automatic file creation, but we still have directory creation there.

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.

Copy link
Contributor

@DustinCampbell DustinCampbell left a 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!

Copy link
Member

@david-driscoll david-driscoll left a 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
Copy link
Member

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);
Copy link
Member

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.

@DustinCampbell
Copy link
Contributor

I think we're in good shape here. @david-driscoll, holler if you disagree.

@DustinCampbell DustinCampbell merged commit 3c3a8e5 into OmniSharp:dev Mar 31, 2017
@DustinCampbell
Copy link
Contributor

@filipw
Copy link
Member Author

filipw commented Mar 31, 2017

indeed 📚

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants