You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am working on an alternate screen feature for my cross-platform terminal manipulating crate.
Situation
When I want to write something to console I can use the following code to write to the current standard output. This works on both UNIX and Windows systems:
write!(::std::fmt::io::stdout(), "Some text").
When I switch to the alternate screen, I don't want to write to the current standard output but to the alternate screen. This works differently depending on which platform you are on. The basics are the same: I need to store the handle somewhere globally so that I could put the stored output handle in alternate screen mode and write all my output, commands and actions to that stored output handle.
When I am in alternate mode, my code writes to the alternate screen and when in main screen modes my code writes to the main screen.
Unix
For UNIX systems, I can use ANSI escape codes to switch to the alternate screen and back. I store the ::std::io::stdout() somewhere and all my UNIX code uses that handle for access to the terminal output. When in alternate screen mode, all the writes I do are done on the alternate screen and when on the main screen all the writes are done on the main screen.
If I would not have used the above-described way and switched to alternate screen and just called this write!(::std::fmt::io::stdout(), "Some text"), I would write to the main screen instead of the alternate screen on both Windows and Unix systems because stdout() is a handle to the standard output.
The Question
The way described above works to a certain point; when I want to write to the stored handle.
For Unix I can do the following:
// (...) some logic to get the handle to the current screen.
let stored_handle: Write = ...;
write!(stored_handle, "Some text);
But for Windows I could not do this:
// (...) some logic to get the handle to the current screen for windows.
let stored_handle: HANDLE = ...;
write!(stored_handle, "Some text);
I could implement std::io::Write for the struct where I store the stdout so that for Windows I create my own logic for writing to the console with WinAPI. If I would do that I would be able to write to that struct like the following:
#[cfg(target_os = "windows")]
let storage = WindowsScreenManager::new();
#[cfg(not(target_os = "windows"))]
let storage = UnixScreenManager::new();
write!(storage, "Some text");
This is not ideal for my situation because I can not use the Rust string escape characters like \n \t my string will not contain any newlines or tabs when doing it this way. Think because WinAPI does not know these formatting options. Also I don't want to manage all the writing to the console for Windows manually on my side.
I really want to use the WinAPI HANDLE as std::io::Write so that it can be used in the write! macro, just like I do in UNIX. Just store the stdout() and write to that stdout() using the write! macro, but storing the HANDLE and writing to that.
I suppose that this should work since when calling println!() or write!(stdout()) on Windows it will write the to the standard output handle of the current process. But now I want to write to the alternate handle and not only to the default handle. Or am I wrong with this?
If the above cannot be done, how would I write to the alternate screen HANDLE without using my own implementation for writing to the Console using WinAPI?
The text was updated successfully, but these errors were encountered:
In order for newlines and such to be interpreted correctly, the ENABLE_PROCESSED_OUTPUT mode must be enabled on the console screen buffer using SetConsoleMode.
ANSI escape sequences require Windows 10 with the ENABLE_VIRTUAL_TERMINAL_PROCESSING mode enabled, and will never work on older Windows. For older Windows you have to use the API to do things like changing the color.
Thanks, I will give it a try. I know that only Windows 10 supports ANSI escape codes. In this crate this option is turned on by default. If the current system does not support this it will fall back to WinAPI. And with this implementation, I got the problem with alternate screen and writing to that alternate screen. But I will try what you have suggested.
I am working on an alternate screen feature for my cross-platform terminal manipulating crate.
Situation
When I want to write something to console I can use the following code to write to the current standard output. This works on both UNIX and Windows systems:
When I switch to the alternate screen, I don't want to write to the current standard output but to the alternate screen. This works differently depending on which platform you are on. The basics are the same: I need to store the handle somewhere globally so that I could put the stored
output handle
in alternate screen mode and write all my output, commands and actions to that storedoutput handle
.When I am in alternate mode, my code writes to the alternate screen and when in main screen modes my code writes to the main screen.
Unix
For UNIX systems, I can use ANSI escape codes to switch to the alternate screen and back. I store the
::std::io::stdout()
somewhere and all my UNIX code uses that handle for access to the terminaloutput
. When in alternate screen mode, all thewrite
s I do are done on the alternate screen and when on the main screen all thewrite
s are done on the main screen.Windows
For Windows systems, I can use WinAPI to switch to the alternate screen buffer. I'll create a new screen buffer with
CreateConsoleScreenBuffer
then I'll useSetConsoleActiveScreenBuffer
to change the active buffer. At last, I need to store the handle gotten fromCreateConsoleScreenBuffer
. Through this output handle, I can write output to the alternate screen buffer.If I would not have used the above-described way and switched to alternate screen and just called this
write!(::std::fmt::io::stdout(), "Some text")
, I would write to the main screen instead of the alternate screen on both Windows and Unix systems becausestdout()
is a handle to the standard output.The Question
The way described above works to a certain point; when I want to write to the stored handle.
For Unix I can do the following:
But for Windows I could not do this:
I could implement
std::io::Write
for the struct where I store thestdout
so that for Windows I create my own logic for writing to the console with WinAPI. If I would do that I would be able to write to that struct like the following:This is not ideal for my situation because I can not use the Rust string escape characters like
\n \t
my string will not contain any newlines or tabs when doing it this way. Think because WinAPI does not know these formatting options. Also I don't want to manage all the writing to the console for Windows manually on my side.I really want to use the WinAPI
HANDLE
asstd::io::Write
so that it can be used in thewrite!
macro, just like I do in UNIX. Just store thestdout()
and write to thatstdout()
using thewrite!
macro, but storing theHANDLE
and writing to that.I suppose that this should work since when calling
println!()
orwrite!(stdout())
on Windows it will write the to the standard output handle of the current process. But now I want to write to the alternate handle and not only to the default handle. Or am I wrong with this?If the above cannot be done, how would I write to the alternate screen
HANDLE
without using my own implementation for writing to the Console using WinAPI?The text was updated successfully, but these errors were encountered: