vezel-dev / cathode Goto Github PK
View Code? Open in Web Editor NEWA terminal-centric replacement for the .NET console APIs.
Home Page: https://docs.vezel.dev/cathode
License: BSD Zero Clause License
A terminal-centric replacement for the .NET console APIs.
Home Page: https://docs.vezel.dev/cathode
License: BSD Zero Clause License
This should be a property on SystemVirtualTerminal
(and Terminal
).
To replace things such as:
We should provide these out of the box since they will be commonly needed in .NET Core applications.
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
.
This would be similar in behavior to the Windows driver where we try each one in case there are redirections.
install
command.It seems after this point that reading from standard input never returns.
This is in case ioctl(TIOCGWINSZ)
/GetConsoleScreenBufferInfo()
fails. Most shells will set these variables.
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.
There were some changes made to these APIs in .NET 6 that need to be mirrored.
TerminalException
should probably derived from IOException
.
Additionally, it might make sense to have some more specific exception types for things like switching raw mode.
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
.
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
This is needed to respect the discard
parameter of Terminal.SetRawMode
.
More details in: microsoft/terminal#4931
Inspecting memory usage, threads, modules, etc is useful for diagnostic purposes.
We more or less need full API coverage for these: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
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.
This API integrates better with the runtime than the one provided by Mono.Posix/Mono.Unix.
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.
When switching to virtual terminal mode, it seems that the behaviors of Backspace and Ctrl-Backspace are swapped.
More details in: microsoft/terminal#4949
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.
termios
state after a program exits.More details in: microsoft/terminal#4949
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.
This API will probably wrap TermInfo.
The API should be simplified so as to not bother with quirks of ancient terminals and emulators almost nobody uses anymore.
This would be the list of terminal emulators that we strive to have first-class support for.
This would have a number of benefits:
SIGCONT
) will be resolved.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.
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.
Blocked on microsoft/win32metadata#753 being included in a release.
Initially, we'll just use Wcwidth, but the API might evolve over time to handle more complex scripts correctly.
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.
Applications should be able to bundle a bunch of escape sequences and emit them all at once. This will require decoupling construction of escape sequences from the terminal driver.
Serilog is a popular logging library. We should provide a library with a System.Terminal-based sink.
Details on writing sinks: https://github.com/serilog/serilog/wiki/Developing-a-sink
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
).
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.
For example, we would want to tell users to avoid System.Console
.
It turns out that even when all standard I/O descriptors are redirected, we can still access the controlling terminal directly. We should do that.
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:
/dev/null
.|
, >
, and <
operators.TerminalProcess.SendSignal
should throw an exception if the given signal cannot be synthesized (e.g. CTRL_CLOSE_EVENT
on Windows).TerminalProcess
to ChildProcess
and move it to System.Processes
namespace.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.
It gets interpreted as EOF even in raw mode, so ReadFile
returns success but with zero bytes read.
More details in: microsoft/terminal#4958
We need to mark the assemblies as trimmable and enable trim analysis.
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.
Some kind of compromise between Mono.Options (too simple) and System.CommandLine (way too complex).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.