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

Width detection fails when running Windows apps in WSL #216

Open
mcon opened this issue Jan 9, 2021 · 6 comments · May be fixed by #1190
Open

Width detection fails when running Windows apps in WSL #216

mcon opened this issue Jan 9, 2021 · 6 comments · May be fixed by #1190
Labels
bug Something isn't working on-hold

Comments

@mcon
Copy link
Contributor

mcon commented Jan 9, 2021

Information

  • OS: Windows 10
  • Version: WSL 1
  • Terminal: WSL Shell

Describe the bug
Spectre.Console gets the terminal width by getting System.Console.BufferWidth however, when running a Windows app in WSL, this throws an IOException, leaving Spectre.Console using the default of 80 columns wide whatever the actual size of the terminal.

To Reproduce
Run a Spectre.Console app running using the Windows .net core runtime in WSL, log out IAnsiConsole.Width.

Expected behavior
It's not straightforward what the best solution to this is. For my purposes, as a workaround, I've just implemented IAnsiConsole, passing through all implementations to AnsiBackend aside from Width which I've hardcoded to a large value - clearly this won't produce desirable behaviour in case of output overflow.

Clearly, it would be possible to do the classic "try moving the cursor by some large amount, check where it is, return it to initial position" trick using escape codes (https://en.wikipedia.org/wiki/ANSI_escape_code#Terminal_output_sequences), however if you're redirecting the output of a Spectre.Console app to a file then this approach isn't going to work well, as Spectre.Console would have to wait for the terminal dimensions to be returned on stdin, which wouldn't happen in the case of a redirect.

It would be possible to time out waiting for terminal dimensions, however that doesn't feel ideal either, as programs would then take longer to run when redirected to file. One "solution" would be to allow the user to hard code the width more easily (e.g. in capabilities), without having to resort to implementing IAnsiConsole boilerplate.

Crucially, the best approach depends on the Spectre.Console philosophy: if the library is meant for applications that only run in the terminal, then terminal escape codes with timeout is probably the way to go, otherwise perhaps overriding Width is better?


Please upvote 👍 this issue if you are interested in it.

@mcon mcon added the bug Something isn't working label Jan 9, 2021
@patriksvensson
Copy link
Contributor

patriksvensson commented Jan 9, 2021

@mcon Yes, it's not optimal. I'm currently reworking the capabilities API which will make it possible to override things without creating a new console (as well as implementing specific profiles for known environments). I would suggest that we add some specific (opt-in) logic for more advanced detection once that is in place.

@mcon
Copy link
Contributor Author

mcon commented Jan 9, 2021

Sounds good to me, certainly I'm not advocating moving away from Console.BufferWidth, and this approach would only be sensible as a fallback.

@Frassle
Copy link
Contributor

Frassle commented Apr 13, 2021

Running in mintty has a similar issue. stdout/err aren't console handles because mintty does it's own redirection.

@patriksvensson
Copy link
Contributor

@mcon I revisited this issue, but can't reproduce it. Could you verify if it's working for you now and if not produce a minimal reproducible example?

image

@mcon
Copy link
Contributor Author

mcon commented Jul 5, 2021

Had a crack in Windows terminal, and was unable to reproduce, but can still see the same issue in my cygwin mintty terminal - probably a misnomer to mention WSL in the initial issue description.

I used the following code which, when using mintty always outputs width of 80 - as I typically user Windows terminal now, the issue doesn't affect me terribly. Thanks for coming back to this one @patriksvensson.

using Spectre.Console;

namespace SpectreConsoleDebug
{
  class Program
  {
    static void Main(string[] args)
    {
      var console = AnsiConsole.Create(new AnsiConsoleSettings());

      console.Write(new Text($"Width: {console.Profile.Out.Width}"));
    }
  }
}

@jaredthirsk
Copy link

My scenario: Linux csx script writing stdout to a log file in a cron job.

My workaround to get a custom width: https://gist.github.com/jaredthirsk/4bffdb3fdc3a71dae4515145420c43f2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working on-hold
Projects
Status: No status
4 participants