GithubHelp home page GithubHelp logo

vezel-dev / cathode Goto Github PK

View Code? Open in Web Editor NEW
91.0 4.0 7.0 1.06 MB

A terminal-centric replacement for the .NET console APIs.

Home Page: https://docs.vezel.dev/cathode

License: BSD Zero Clause License

C# 87.93% Shell 0.08% C 11.98%
console csharp dotnet terminal

cathode's Issues

Figure out what to do about certain signals

CoreCLR registers a number of signal handlers if System.Console is used: https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/libraries/Native/Unix/System.Native/pal_signal.c#L307-L314

We need to figure out what to do with these.

  • SIGINT, SIGQUIT: We should probably intercept these and expose an interface similar to what exists on System.Console for handling them.
  • SIGCONT, SIGWINCH: We already handle these (for restoring termios state and updating window width/height).
  • SIGCHLD: Not relevant for this issue; see #2.

It might make sense to let System.Console initialize these handlers first, and then hijacking them after. This would reduce the level of damage that could be done to System.Terminal internal state if a user accidentally accesses System.Console.

Provide asynchronous API surface

A common complaint with System.Console is that it has very limited support for asynchronous operations. The only real support is grabbing e.g. Console.Out and using the asynchronous methods on TextWriter. We support that too, but I think we can do better.

Investigate whether we need to set other `termios` bits

man 3 termios lists a ton of other bits that we could be toggling in the Unix drivers. Need to investigate whether any of these make sense to do for cooked and raw mode. For instance, while it seems to be on by default, we should probably still enforce IUTF8.

Handle `SIGTTOU` when switching to cooked mode on Unix

Currently, when we call tcsetattr during driver initialization to ensure we're in cooked mode, we can be suspended by a SIGTTOU if we're a background process. The question is: Should we handle SIGTTOU instead (so that we don't get suspended) and just proceed, trusting that the terminal is probably in cooked mode?

Arguably, this is probably fine most of the time. But what about the times when the foreground process is in raw mode and we end up completely garbling the screen? I'm not sure there's really a 'correct' answer. Need to think more on this.

Useful reference: http://curiousthing.org/sigttin-sigttou-deep-dive-linux

Locale support on Unix systems

Right now, we assume that all systems use UTF-8. This is true for what's probably 99% of Unix systems, but we should still handle the 1% correctly.

We need to parse the LC_ALL, LC_MESSAGES, and LANG environment variables (in that order) to find the character set, falling back to UTF-8 if we can't find it.

We will still present the illusion to library users that the world is only UTF-8, just like we do on Windows.

Investigate dropping Mono.Unix dependency

With #21 done, we now only use Mono.Unix for a few system calls like read, write, isatty, kill, etc.

kill in particular is troublesome. We need a way to translate PosixSignal values to native signal numbers.

Set the `TOSTOP` bit when switching to raw mode

When an application switches to raw mode, it's because it wants exclusive control over the terminal to run some kind of interface. To prevent that interface from being messed up by arbitrary background processes, we should set the TOSTOP bit.

This is not completely bulletproof: A really determined background process could block/ignore SIGTTOU to get around TOSTOP, but that's an edge case that we can't do anything about.

Provide a Readline-like library

The .NET Core ecosystem doesn't have a Readline-like library that is of high quality. To be clear, it's not for lack of trying (see Mono.Terminal and ReadLine). Rather, the issue is that System.Console is a poor abstraction for terminal interaction - the entire reason why Cathode exists.

It would be good to provide an additional NuGet package (Vezel.Cathode.Editor?) that provides a line editor based on the core Cathode APIs, and which draws design inspiration from the libraries mentioned above.

Switch to a native library for driver implementations

This would have a number of benefits:

  • Some unfixable race conditions relating to signals (e.g. SIGCONT) will be resolved.
  • No more duplicated code between Linux and macOS.
  • Significantly reduced metadata size from removing P/Invoke declarations.
  • Faster managed builds and editing as CsWin32 will no longer be needed.
  • Easier porting to new platforms.

The native library would probably be written in Zig or C. For this to be as painless as possible, we would need vezel-dev/zig-sdk#8 (and by extension dotnet/sdk#19929) to be implemented first.

Support Mono runtime (.NET 8)

Whenever the final .NET 7 (8?) release is out, users will be able to switch between CoreCLR and Mono for .NET 7+ projects. When that time comes, we need to make sure that we support Mono as well.

The support should be clearly documented and should be exercised to some degree on CI.

Expand sample project

Needs to be refactored a bit so you can pick individual sample scenarios with a command line argument. Also needs to actually demo more of the API surface.

Refactor Unix interop classes to not contain logic

There's too much logic in the LinuxTerminalInterop and MacOSTerminalInterop classes. Most of this can be factored into the drivers if we apply a bit of inheritance (e.g. LinuxTerminalDriver : UnixTerminalDriver).

Figure out a `System.Diagnostics.Process` story

Right now, executing a System.Diagnostics.Process will mess up the termios state on Unix systems. We need to figure out a way of dealing with this. It's not clear what the right thing to do actually is given that we could be in raw mode, while a child process expects cooked mode.

Further, on Windows, we need to consider how we'll deal with child processes that alter the console mode via System.Terminal and leave it in a state that the parent doesn't expect.

Provide a more extensive process API

Since we're banning System.Diagnostics.Process and providing an API-incompatible replacement, it means people will not be able to use libraries like MedallionShell.

We should provide a similarly rich API to make up for that fact.

Here are some of the main things I think I'd like to change:

  • When a process output stream is redirected, we should buffer up all the output so it can be read at any point. This is going to be a reasonable default for the vast majority of cases.
  • There should be a way to redirect process output to the moral equivalent of /dev/null.
  • Provide convenient piping syntax with overloaded |, >, and < operators.
  • TerminalProcess.SendSignal should throw an exception if the given signal cannot be synthesized (e.g. CTRL_CLOSE_EVENT on Windows).
  • Drop support for process diagnostic inspection properties. Most of this stuff is poorly implemented outside of Windows and rarely used.
  • Translate non-zero exit codes to an exception (with an option to turn this off).
  • Rename TerminalProcess to ChildProcess and move it to System.Processes namespace.

Support some notion of exclusive terminal access

For input processing scenarios, one might either subscribe to TerminalReader.InputRead or call TerminalReader.ReadBuffer directly. The latter will have higher overhead, especially if the event handler needs to fire off a task to prevent blocking. The former will have lower overhead but will essentially take over standard input. (Both are valid options.)

For the latter case, we need a way to formalize the exclusive access to the terminal such that anyone else attempting to access it will get an exception.

Mechanism to cancel reading from standard input

For input processing we will need to constantly be reading standard in. But we also need a way to cancel that reading so the input thread doesn't just sit there forever.

Investigate how we can do this on each supported platform. Might be worth checking what, if anything, Notcurses does.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.