fantomas-for-vs icon indicating copy to clipboard operation
fantomas-for-vs copied to clipboard

Formatting doesn't work with WSL2 hosted files in VS2022

Open Nekroido opened this issue 2 years ago • 31 comments

Steps to reproduce:

  • Create or open a solution/project hosted in WSL2;
  • Open a .fs file you wish to format;
  • Format the file with Edit > Advanced > Format Document.

Expected result:

The file is formatted according to the code style.

Actual result:

Nothing happens and no changes are introduced to the file.

Note:

Formatting works fine when I open projects in Windows host. Fantomas-tool is installed in both hosts and I can format files through both PowerShell in Windows and ZSH in WSL2 Debian.

Nekroido avatar Apr 21 '22 17:04 Nekroido

Hey @Nekroido, Sorry for the delayed reply. I suspect it could be a permissions issue. Here's the issue I'm seeing:

Fantomas.Client tried to run dotnet tool list but exited with code 1. File dotnet-tools.json came from another computer and might be blocked to help protect this computer. For more information, including how to unblock, see https://aka.ms/motw

If there's a dotnet tool version defined in dotnet-tools.json, Fantomas tries to use that specific version.

deviousasti avatar Apr 24 '22 18:04 deviousasti

It will work if there's no tool manifest defined - with the globally installed formatter.

deviousasti avatar Apr 24 '22 18:04 deviousasti

Hi! Sorry, looks like I never pressed the "Comment" button. I do have the manifest file, but only with the paket entry. The error I see in my "Output: F# Formatting" is this:

The operation is not supported:
 The FantomasResponseCode value '11' is unexpected.

Nekroido avatar May 05 '22 10:05 Nekroido

Hello, Code '11' means that Fantomas daemon (your global or local tool) could not be started. Can you execute:

open System
open System.IO

let userProfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)
Path.Combine(userProfile, ".dotnet", "tools", "fantomas.exe")

in a F# interactive session (dotnet fsi) and verify that the path that comes out of there exists.

nojaf avatar May 05 '22 11:05 nojaf

The path exists in the Windows host. It also exists in my Debian host but without the .exe extension.

Nekroido avatar May 05 '22 11:05 Nekroido

Alright, can you execute the exe in the command line? You shouldn't see anything, but if that crashes, that already tells us something.

nojaf avatar May 05 '22 12:05 nojaf

Both executables exit with Input path is missing...

Nekroido avatar May 05 '22 12:05 Nekroido

Ah apologies, you need to add the --daemon flag. So C:\fullPath\fantomas.exe --daemon

nojaf avatar May 05 '22 12:05 nojaf

Both executables wait for the input and crash with the following trace when I press Enter:

Unhandled exception. StreamJsonRpc.BadRpcHeaderException: No Content-Length header detected.
   at StreamJsonRpc.HeaderDelimitedMessageHandler.ReadCoreAsync(CancellationToken cancellationToken)
   at StreamJsonRpc.MessageHandlerBase.ReadAsync(CancellationToken cancellationToken)
   at StreamJsonRpc.JsonRpc.ReadAndHandleRequestsAsync()
   at Program.main(String[] argv) in C:\Users\nojaf\Projects\fantomas\src\Fantomas.CoreGlobalTool\Program.fs:line 441

Nekroido avatar May 05 '22 12:05 Nekroido

Yeah, that sounds about right. The error you get when pressing enter makes sense. So, I can conclude here that the daemon can be started but not programmatically on your end. There could be a bug in Fantomas.Client.

Could you create a script file with:

#r "nuget: Fantomas.Client"

open System.IO
open Fantomas.Client.Contracts
open Fantomas.Client.LSPFantomasService

let service = new LSPFantomasService() :> FantomasService

// TODO: change file path to existing file on your machine
let file = @"C:\Users\nojaf\Projects\HelloWorld\Math.fs"
let content = File.ReadAllText file

let response =
    service.FormatDocumentAsync { SourceCode = content; FilePath = file; Config = None }
    |> Async.AwaitTask
    |> Async.RunSynchronously

printfn "%A" response

What does that output?

nojaf avatar May 05 '22 12:05 nojaf

It outputs a formatted document in Windows environment when I provide a valid absolute \\wsl$\Debian\... path. Same for Debian for a /home/... path.

I see the error you mentioned initially if I use \\wsl.localhost\... path.

Nekroido avatar May 05 '22 12:05 Nekroido

Yeah, the behaviour we see is starting to make some sense. Something is going wrong when requests are made with UNIX paths inside the Windows host.

nojaf avatar May 05 '22 12:05 nojaf

Just chiming in as I'm running into the exact same issue. Nothing happens when I try to execute Format Document (or a variant, like saving with format-on-save set to 'on'). I'm on Windows 10, VS 2022, all recent updates, F# 6.0 etc. Just installed F# Formatting extension. Same output in the Output window:

The operation is not supported:
 The FantomasResponseCode value '11' is unexpected.

Running the commands above work just like @Nekroido mentions.

abelbraaksma avatar May 05 '22 13:05 abelbraaksma

@nojaf Is there a way to get more detailed output, or to set it up for debugging?

I should probably add that we use the .editorconfig file approach, as there's nothing that we can set inside the F# > Formatting options window. I know this is an open bug. I dunno if this may have anything to do with the extension not working.

abelbraaksma avatar May 05 '22 13:05 abelbraaksma

Hi, I don't think .editorconfig is relevant here. To debug you could create a sort of integration unit test where you reference Fantomas.Client and try to mimic what the editor is doing in https://github.com/fsprojects/fantomas-for-vs/blob/74e5da78e23dad2785b3f3866caf5b70d143cd8f/src/FantomasVs.Shared/FantomasHandler.cs#L178

If you can step into the Fantomas.Client source, I expect https://github.com/fsprojects/fantomas/blob/0e036ac3c54301fb8208205c1af0613e7bb06636/src/Fantomas.Client/LSPFantomasService.fs#L74 would be a good place to look what exactually happened.

nojaf avatar May 05 '22 14:05 nojaf

Btw, this is not WSL2. However, I just found out that the formatting does work correctly on an older .NET Framework project, using VS 2022.

@nojaf, thanks, I'll give it a go.

abelbraaksma avatar May 05 '22 14:05 abelbraaksma

I've published a new version for VS22 that has much better error logging for this case. Could you please update and post your logs here. 😊

deviousasti avatar May 06 '22 10:05 deviousasti

I'll try, let me update.

abelbraaksma avatar May 06 '22 12:05 abelbraaksma

@deviousasti, silly question, but I only installed this so far through Marketplace. Do you know what to update? I assume I run the build.ps1 script, but then what, just replace some dll somewhere, I guess?

abelbraaksma avatar May 06 '22 12:05 abelbraaksma

I've released 1.1.0 on the marketplace. You should be able to go Extensions > Manage Extensions > Update and install the new version.

On Fri, 6 May 2022, 5:41 pm Abel Braaksma, @.***> wrote:

@deviousasti https://github.com/deviousasti, silly question, but I only installed this so far through Marketplace. Do you know what to update? I assume I run the build.ps1 script, but then what, just replace some dll somewhere, I guess?

— Reply to this email directly, view it on GitHub https://github.com/fsprojects/fantomas-for-vs/issues/29#issuecomment-1119549477, or unsubscribe https://github.com/notifications/unsubscribe-auth/AASD6PTBDAS56RSQCJKGFKDVIUD5PANCNFSM5T76M2PQ . You are receiving this because you were mentioned.Message ID: @.***>

deviousasti avatar May 06 '22 12:05 deviousasti

I just did a local compile of the sln file, found the vsix, uninstalled old, re-installed with vsix from the release dir.

abelbraaksma avatar May 06 '22 12:05 abelbraaksma

Oh, yes, that'd work too! 😄

abelbraaksma avatar May 06 '22 12:05 abelbraaksma

Sir, you are flexing your build skills. 😄

On Fri, 6 May 2022, 5:56 pm Abel Braaksma, @.***> wrote:

Oh, yes, that'd work too! 😄

— Reply to this email directly, view it on GitHub https://github.com/fsprojects/fantomas-for-vs/issues/29#issuecomment-1119562194, or unsubscribe https://github.com/notifications/unsubscribe-auth/AASD6PXF2D3GTX2GDLQLORLVIUFW3ANCNFSM5T76M2PQ . You are receiving this because you were mentioned.Message ID: @.***>

deviousasti avatar May 06 '22 12:05 deviousasti

@deviousasti, this is the new output from the tool:

Creating the Fantomas Daemon failed:
Fantomas.Client tried to run `dotnet fantomas --daemon` but failed with "Daemon std error: Run "dotnet tool restore" to make the "fantomas" command available.
.
JsonRpc exception:One or more errors occurred."
Attempting to find Fantomas Tool...
Found at: FantomasToolFound
  (FantomasVersion "4.6.0",
   LocalTool
     (Folder
        "D:\Projects\MyProject.Tests\Hosting\Subscriptions"))

abelbraaksma avatar May 06 '22 12:05 abelbraaksma

That's an interesting error, as I installed the tool globally with the -g flag. Also, the Fantomas plugin worked in other projects.

The improved error reporting is very useful, thanks!

However, good news is that after doing a dotnet tool restore on the root of the project that didn't work, it now picks it up correctly. Is it possible that if fantomas is configured for a project that it does not attempt to find the tool on the global path?

I don't know if this would also solve it for @Nekroido, my project was not one with WSL2-hosted files.

abelbraaksma avatar May 06 '22 12:05 abelbraaksma

Is it possible that if fantomas is configured for a project that it does not attempt to find the tool on the global path?

Yes, this is the current behavior.

deviousasti avatar May 06 '22 12:05 deviousasti

Yup, it's much clearer where the issue lies now. I can confirm the "file came from another computer" error. I guess I'm out of luck and I need to consider setting up my dev env in Windows host. Unless it's possible to skip loading dotnet-tools.json and use the globally installed tool instead.

Nekroido avatar May 06 '22 17:05 Nekroido

The flow is the following: It will check if you have a local tool (using dotnet tool list), next, it will check if it has a global tool (using dotnet tool list -g).

So, if you have a global tool in both places that might work but I suspect you will bump into problems when detecting the .editorconfig.

nojaf avatar May 07 '22 08:05 nojaf

On WSL2, if there's no local config, I can confirm that the file formats with the global tool.

deviousasti avatar May 07 '22 10:05 deviousasti

I have a fresh machine and installed the extension into Visual Studio, getting the same error @abelbraaksma 👍

Tried many things, those are the steps that need to be done in addition to installing this VS extension:

dotnet tool install fantomas-tool -g 

Reopening of Visual Studio is sometimes needed. Also

dotnet restore

The options pane is not shown, but that is already mentioned in well handled in https://github.com/fsprojects/fantomas-for-vs/issues/28

snuup avatar Apr 02 '23 12:04 snuup