Giter Club home page Giter Club logo

crossterm's Introduction

Donate Travis Latest Version MIT docs Lines of Code Join us on Discord

Cross-platform Terminal Manipulation Library

Crossterm is a pure-rust, terminal manipulation library that makes it possible to write cross-platform text-based interfaces (see features). It supports all UNIX and Windows terminals down to Windows 7 (not all terminals are tested, see Tested Terminals for more info).

Table of Contents

Features

  • Cross-platform
  • Multi-threaded (send, sync)
  • Detailed documentation
  • Few dependencies
  • Full control over writing and flushing output buffer
  • Is tty
  • Cursor
    • Move the cursor N times (up, down, left, right)
    • Move to previous / next line
    • Move to column
    • Set/get the cursor position
    • Store the cursor position and restore to it later
    • Hide/show the cursor
    • Enable/disable cursor blinking (not all terminals do support this feature)
  • Styled output
    • Foreground color (16 base colors)
    • Background color (16 base colors)
    • 256 (ANSI) color support (Windows 10 and UNIX only)
    • RGB color support (Windows 10 and UNIX only)
    • Text attributes like bold, italic, underscore, crossed, etc
  • Terminal
    • Clear (all lines, current line, from cursor down and up, until new line)
    • Scroll up, down
    • Set/get the terminal size
    • Exit current process
    • Alternate screen
    • Raw screen
    • Set terminal title
    • Enable/disable line wrapping
  • Event
    • Input Events
    • Mouse Events (press, release, position, button, drag)
    • Terminal Resize Events
    • Advanced modifier (SHIFT | ALT | CTRL) support for both mouse and key events and
    • futures Stream (feature 'event-stream')
    • Poll/read API

Tested Terminals

  • Console Host
    • Windows 10 (Pro)
    • Windows 8.1 (N)
  • Ubuntu Desktop Terminal
    • Ubuntu 17.10
    • Pop!_OS ( Ubuntu ) 20.04
  • (Arch, Manjaro) KDE Konsole
  • (Arch, NixOS) Kitty
  • Linux Mint
  • (OpenSuse) Alacritty
  • (Chrome OS) Crostini
  • Apple
    • macOS Monterey 12.7.1 (Intel-Chip)

This crate supports all UNIX terminals and Windows terminals down to Windows 7; however, not all of the terminals have been tested. If you have used this library for a terminal other than the above list without issues, then feel free to add it to the above list - I really would appreciate it!

Getting Started

see the examples directory and documentation for more advanced examples.

Click to show Cargo.toml.
[dependencies]
crossterm = "0.27"

use std::io::{stdout, Write};

use crossterm::{
    execute,
    style::{Color, Print, ResetColor, SetBackgroundColor, SetForegroundColor},
    ExecutableCommand,
    event,
};

fn main() -> std::io::Result<()> {
    // using the macro
    execute!(
        stdout(),
        SetForegroundColor(Color::Blue),
        SetBackgroundColor(Color::Red),
        Print("Styled text here."),
        ResetColor
    )?;

    // or using functions
    stdout()
        .execute(SetForegroundColor(Color::Blue))?
        .execute(SetBackgroundColor(Color::Red))?
        .execute(Print("Styled text here."))?
        .execute(ResetColor)?;
    
    Ok(())
}

Checkout this list with all possible commands.

Feature Flags

[dependencies.crossterm]
version = "0.27"
features = ["event-stream"] 
Feature Description
event-stream futures::Stream producing Result<Event>.
serde (De)serializing of events.
events Reading input/system events (enabled by default)
filedescriptor Use raw filedescriptor for all events rather then mio dependency

To use crossterm as a very thin layer you can disable the events feature or use filedescriptor feature. This can disable mio / signal-hook / signal-hook-mio dependencies.

Dependency Justification

Dependency Used for Included
bitflags KeyModifiers, those are differ based on input. always
parking_lot locking RwLocks with a timeout, const mutexes. always
libc UNIX terminal_size/raw modes/set_title and several other low level functionality. optional (events feature), UNIX only
Mio event readiness polling, waking up poller optional (events feature), UNIX only
signal-hook signal-hook is used to handle terminal resize SIGNAL with Mio. optional (events feature),UNIX only
winapi Used for low-level windows system calls which ANSI codes can't replace windows only
futures-core For async stream of events only with event-stream feature flag
serde serializing and deserializing of events only with serde feature flag

Other Resources

Used By

Contributing

We highly appreciate when anyone contributes to this crate. Before you do, please, read the Contributing guidelines.

Authors

  • Timon Post - Project Owner & creator

License

This project, crossterm and all its sub-crates: crossterm_screen, crossterm_cursor, crossterm_style, crossterm_input, crossterm_terminal, crossterm_winapi, crossterm_utils are licensed under the MIT License - see the LICENSE file for details.

crossterm's People

Contributors

ahoyiski avatar andy128k avatar benjajaja avatar byron avatar canop avatar cowboy8625 avatar groves avatar kdheepak avatar kesslern avatar kestrer avatar kevin-vigor avatar lucretiel avatar mgunyho avatar michaelmcdonnell avatar mitmaro avatar pianohacker avatar piturnah avatar purplebooth avatar riey avatar sharnoff avatar sigmasd avatar svartalf avatar the-mikedavis avatar timonpost avatar truchi avatar twe4ked avatar windsoilder avatar yjhn avatar yyogo avatar zrzka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

crossterm's Issues

Input events not consistent between *nix and Windows

Pressing up, down, left, right arrows, delete, insert, home, F1-10, and Alt + Shift + in read_async_demo() all returns some kind of byte sequence as captured by tty.

On Windows, however, these inputs crash the program or cause it to lock up. Is there a way to handle these inputs as well? Or be explicit in the docs regarding the limitations.

I could try to help, if it's regarding documentation, but I have limited exposure to how terminals work between posix and windows. If you could point me in the right direction, perhaps I can help later down the line.

EDIT:
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/078sfkak(v=vs.110)

For some keys or key sequences, like arrows, all that is needed is to call the _getwch or _getwche a second time. I think all that is needed is to remove this: https://github.com/TimonPost/crossterm/blob/master/src/modules/input/windows_input.rs#L72

or have a different kind of error detection than 0 or 0xe0...like calling _getwch() a second time with kbhit() --> https://github.com/genotrance/snip/blob/master/src/snip/key.nim#L35

Please add LICENSE

License text needs to be added both in top directory and in each crate (you can use symlink for that).

Thanks in advance!

Is possible to handle key input event?

I saw the TerminalInput can be used to read a char or a hole line of input. But I want to read a key event, like Up(โ†‘) or Down(โ†“). Is any way to do this?

Namespace collision with the same method name when using the `*` symbol on the cursor and style module.

Calling the functions all get is in my opinion a bit inconvenient as you always have to include the module name if you want to use e.g. cursor and terminal.

use cross_terminal::terminal;
use cross_terminal::terminal::ClearType;
use cross_terminal::cursor;

fn main() {
    let term = terminal::get();
    let cur = cursor::get();

    terminal.clear(ClearType::All);
}

And you cant just use cross_terminal::terminal::* for having ClearType. Because both terminal and cursor have an get() method.

This will be fixed in crossterm v0.2.1

How to add more tested terminals

My development environment is deepin linux, I want to test and use the crossterm tool in deepin linux.

Is there a basic set of use cases to test crossterm compatibility on a new terminal. Do I need to execute all the test cases in the code?

Short Question to clear Screen

Hello,

i'm a relative new in rust and i'm hanging here at one simple solution to clear the terminal. Your solution use the winapi pure, or? No ansi escape sequence.

I have searched the whole internet:), and not find an solution why a cargo run accept ansi escapes codes and directly run of an .exe don't display the codes:).

Is it possible to easily strip down your crate to an simple code fragment where only cross clear the terminal?

thx

Multiple inputs = multiple threads for AsyncReader?

I am trying to implement a toy terminal app that can open up multiple files in alternate screens for editing.

It is not clear from the comments/documentation, that using the recommended

let input = crossterm::input::from_screen(&screen);
let stdin = input.read_async().bytes();

creates a new thread per call to input.read_async().

Do the threads end after the screen gets dropped?

Windows 10: Getting mode failed

This seems to be similar to last years issue of #15 . I just had a user report this issue on Windows 10.

He is using Powershell without Administrator rights on his machine. He can't try it on cmd, only Powershell.

This code triggers the issue:

    println!("\nWelcome to saml2aws-auto. Let's configure a few things to get started.");
    println!("Currently, only Keycloak is supported as Identity Provider. When setting the");
    println!(
        "IDP URL, please note that you will have to pass {} of Keycloak.\n",
        style("the exact path to the saml client")
            .with(Color::Yellow)
            
    );

it seems to be this line that fails: https://github.com/TimonPost/crossterm/blob/ad74f6b5242e6ed998bef6240b738785ea449ffe/crossterm_winapi/src/console_mode.rs#L53

The crossterm version is the latest.
If there are any additional steps I can do to get you more information please let me know, I want to help as much as I can here.

Thanks!

Colored output out of order WinApi

There is a problem occurring where WinaApi is the default like Windows 7,8.

Here's the code:

    let crossterm = Crossterm::new();
    ...

    println!("Currently, only Keycloak is supported as Identity Provider. When setting the");
    println!(
        "IDP URL, please note that you will have to pass {} of Keycloak.\n",
        crossterm
            .paint("the exact path to the saml client")
            .with(Color::Yellow)
    );

But it gets displayed as this:
image

As you can see, the "the exact path to the saml client" gets put to the start of the message. It also seems like the color is cleared to "white" instead of the default gray.

To print an colored text in the middle of a phrase you can call into_displayable() on a StyledObject. But with WinApi the colored text will not be at the place you have placed the formatting {} symbols. But instead, it will be printed at the start of the console.

Here you have some code to reproduce.

fn main()
{
    let screen= Screen::default();
    let crossterm = Crossterm::new(&screen);

    println!(
        "Some text line 1 \n \
          Some test line to {} and more text.\n",
        crossterm
            .style("Some yellow collored text")
            .with(Color::Yellow)
            .into_displayable(&screen)
    );
}

I don't really know what this is I think it has to be doing something with buffering of text. Like when you call into_dispayable() your text will be written with WinApi. Maybe because of that WinApi will write first before rust writes the text to the console.

How to write to the alternate screen buffer on Windows using only the standard libary?

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.

  • 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 use SetConsoleActiveScreenBuffer to change the active buffer. At last, I need to store the handle gotten from CreateConsoleScreenBuffer. 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 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?

Multiple parralell terminals?

Hi! is it possible to handle more than one terminals in parallel.
I want to use alternate one while main is recieving some data constantly and when i drop alternate i see whats happening in main?

P.S.: Or i want too much from terminal? :)

Colored output out of order on Windows 7

Hi,

I'm having an issue with the Windows Command line on Windows 7.

Here's the code:

    let crossterm = Crossterm::new();
    ...

    println!("Currently, only Keycloak is supported as Identity Provider. When setting the");
    println!(
        "IDP URL, please note that you will have to pass {} of Keycloak.\n",
        crossterm
            .paint("the exact path to the saml client")
            .with(Color::Yellow)
    );

But it gets displayed as this:
image

As you can see, the "the exact path to the saml client" gets put to the start of the message. It also seems like the color is cleared to "white" instead of the default gray.

Raw mode improvement

Currently, there are somethings what could be done better according to raw mode.

I can't explain what it is because there are playing a lot of factors a role and that story will be longer than me fixing it.

However, this is just a tracking issue.

panicked: cannot get console mode

Hey,

one of my users is getting a weird error:

thread 'main' panicked at 'Cannot get console mode', /cargo/registry/src/github.com-1ecc6299db9ec823/crossterm-0.2.1/src/state/commands/win_commands.rs:48:21

He's on Windows 7, tried using cmd, cygwin and cmder but always gets the same error.

Set multiple markers (like with Vim)?

The comments for cursor.save_position and cursor.reset_position aren't clear as to whether the position is single use?

Is it possible to use this API to make something like markers in Vim where you can set up to N markers to jump around in the screeen?

Dropping AlternateScreen breaks alternate screen mode with Crossterm instance

extern crate crossterm;
use self::crossterm::{Crossterm, Screen, ClearType};
use std::io::Read;
use std::{thread, time};

fn main() {
    let raw_mode = true;
    let screen = Screen::new(raw_mode);
    let crossterm: Crossterm;
    {
        let alternate_screen = screen.enable_alternate_modes(raw_mode).unwrap();
        crossterm = Crossterm::from_screen(&alternate_screen.screen);
    }
    // <-- Dropping alternate_screen here

    let mut input = crossterm.input().read_async().bytes();
    let terminal = crossterm.terminal();
    let cursor = crossterm.cursor();
    cursor.hide().unwrap();

    loop {
        terminal.clear(ClearType::All).unwrap();
        cursor.goto(1, 1).unwrap();
        match input.next() {
            // These user inputs are not in raw mode
            Some(ipt) => {
                terminal.write(format!("{:?}    <- Character pressed", ipt)).unwrap();
                match ipt {
                    // Does not return to original screen
                    Ok(b'q') => break,
                    _ => {},
                };
            },
            _ => {}
        };
        thread::sleep(time::Duration::from_millis(200));
    }
}

When creating a Crossterm instance from an AlternateScreen, dropping the AlternateScreen breaks both raw and alternate screen mode, see example above. This gets tricky when users assume it is possible to only store the Crossterm instance to draw to the alternate screen.

Terminal window size does not update when resizing with 'ioctl'

We can change the terminal size like the following two ways:

  1. Using ANSI escape code:
println!("\x1B[8;{},{}t", 40, 40)
  1. Using the call to ioctl()
/// Get the current terminal size.
pub fn terminal_size() -> (u16, u16) {
    // http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
    let us = UnixSize {
        rows: 0,
        cols: 0,
        ws_xpixel: 0,
        ws_ypixel: 0,
    };
    let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
    if r == 0 {
        // because crossterm works starts counting at 0 and unix terminal starts at cell 1 you have subtract one to get 0-based results.
        (us.cols - 1, us.rows - 1)
    } else {
        (0, 0)
    }
}

Problem

If I set the terminal size with ANSI escape code and call directly the ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut winsize); after it to get the new terminal dimensions, the dimensions gotten back are not the same as we have set the terminal size to and will be instead the old dimentions before resizing. However, when running the application again we'll get the new (right) dimensions from the terminal.

The weird thing is that when adding thread::sleep() between the function calls to set and get the terminal size. We will get the new (right)dimensions back from ioctl

Steps to reproduce:

use crossterm::terminal::Terminal;
use std::{thread,time};

fn main()
{
    let screen = Screen::new(false);
    let terminal = Terminal::new(&screen.stdout);

    // get terminal size
    let (x, y) = terminal.terminal_size();

    // set size to 30, 50
    terminal.set_size(30,50);

    // if we uncomment the line below the code will work perfectly fine and we will get the new dimensions.
    // if we comment the line below the terminal dimensions gotten from terminal_size() are equal to the old dimensions. 
    
    // thread::sleep(time::Duration::from_millis(20));

    // get new dimensions
    let (x_new, y_new) = terminal.terminal_size();

    println!("old width: {} old height: {}", x, y);
    println!("new width: {} new height: {}", x_new, y_new);
}

To try the above code just comment and uncomment the code and see the result yourself.

I have found a StackOverflow post that could be useful please take a look.

utils: Tests are failing on linux

error[E0432]: unresolved import `super::WinApiOutput`
 --> src/output/test.rs:1:34
  |
1 | use super::{AnsiOutput, IStdout, WinApiOutput};
  |                                  ^^^^^^^^^^^^ no `WinApiOutput` in `output`. Did you mean to use `AnsiOutput`?

cursor.hide() isn't scoped to the current screen reference

a quick example is if I pass in a new alternative screen and call

let ct = Crossterm::from_screen(&alternative.screen);
let cursor = ct.cursor();
cursor.hide();

When switching back -- dropping the new screen that was created just for the alternative screen; the terminal still has the cursor hidden. Is this intended behavior, or do we want to have cursor behaviors scoped to the current screen?

I would imagine something like cursor.show() and .hide() works at the terminal level, so even if we create new screens, it's not like we can only modify cursor behavior for those screens...

Edit: yep, just confirmed with the alternate_screen.rs example file and it indeed doesn't scope the cursor only to the alt screen. Haven't checked by starting a new screen from within the example; but I'm sure it's related.

termion style ansi api

I do like how it is very easy to get started with termion because it just uses ansi escape sequences. Would it be possible to support something similar in crossterm?

let stdout = MouseTerminal::from(AlternateScreen::from(io::stdout().into_raw_mode().unwrap()));
write!(stdout,
    "{}{}{}{}Hi{}",
    cursor::Hide, 
    clear::All,
    cursor::Goto(0,0),
    color::Fg(color::Red),
    cursor::Show);
stdout.flush();

For terminals that do not support it might need to add custom parser though it could be a bit slow.

Cannot borrow `a` as mutable because it is also borrowed as immutable

I got an interesting problem first of the error message: cannot borrow a as mutable because it is also borrowed as immutable.

Simplefied sittuation

First of some code

struct A
{
    b: B
}

impl A
{
 fn immutable(&self) -> C
 {
    // some function that does not mutate A but returns a new instance to some type with a refrence to `B` in `A`
    C { b: &self.b }
 }

 fn mutable(&mut self)
 {
     // some function that mutates A
 }
}

struct B;

struct C<'b>
{
     b: &'b B
}

fn main()
{
    let mut a = A { b: B{} };
    let b =  a.immutable();
    a.mutable();
}

I get the point of this error message and why it is thrown. I have an immutable reference to C wilts has a immutable reference to B when I call mutable() b: B in structA will be mutable and this is a dangerous problem because when we mutate b: B the immutable reference we have in C could not be valid anymore. That is why rust helps here.

The code above is a simple demonstration of the code architecture I currently have. I could solve this error by just doing the following:

fn main()
{   
    let mut a = A { b: B{} };
    
    {
        let b =  a.immutable();
    }
    
    a.mutable();
}

But I find this an ugly solution. Because I am working on a library I will not push the user to add own scopes around function calls to get it to work properly. Is there a better way with managing the lifetime of the reference to B in C?

Application to Crossterm
The types in the examples could be mapped to the following types of crossterm.
A: Crossterm
B: ScreenManager
C: TerminalCursor, TerminalColor, Terminal

The reason why this error occurs is that TerminalCursor, TerminalColor, Terminal has a reference to an ScreenManager stored in Crossterm. Because I have a type with an immutable reference to SceenManager I cannot create another mutable borrow when calling: to_alternate_screen() on the Crossterm type. This would cause the reference to be invalid stored in TerminalCursor and lucky (or maybe not) rust comes into play and prevents this behavior.

Flush buffer does not clear internal buffer.

    terminal(&screen).clear(ClearType::All);
    cursor(&screen).goto(0, 0);
    screen.write_buf(b"https://www.google.com").expect("");
    screen.flush_buf().expect("");
    cursor(&screen).goto(4, 0);
    screen.write_buf(b"FFF").expect("");
    screen.flush_buf().expect("");

expecting the result to be:

httpFFF/www.google.com

actual:

httphttps://www.google.comFFF

seems like code isn't synchronous here...

Expose the WinApi and Libc from crossterm to the user.

I think it would be cool to expose the WinApi and libc API of cross term. Before this could be done those Api's should be a little reformated. By exposing it the user is able to directly act on the opeating system instead of doing it via crossterm.

Access to alternate screen without Drop

I'm trying to wrap an external lib to make use of Crossterm from python (or ruby). However, when considering the use of AlternateScreen, there is no way to pass the Screen from AlternateScreen into a Box because of the Drop trait.

Is there a way to do this for FFI interop?

Suggestion: make unsupported functionality no-op

Hello,

I'm trying to compile my project for multiple platforms. Windows doesn't seem to support bold, whereas other platforms do. I now had to remove all calls to bold in order to fix compiler errors. My suggestion would be to instead of failing compilation for unsupported methods on different platforms allow me to have these functions as no-ops (so just do nothing with it), but maybe with some sort of warnings. What do you think?

Examples Improvements

The example folder has too many folders and should be refactored a little. Like color with only one mod.rs and cursor with only one mod.rs file. Those mod.rs files could just be renamed to color.rs and cursor.rs, this applies to more folders.

Any interest in supporting input, not only output?

I realize this is a big ask :)

I was playing with crossterm today, and I really like it. But I need to deal with input, not only output. Do you have any intention of adding input someday? This isn't for anything important, but I'm curious...

How to change font size

I want to make the font size smaller, what should I do?

I didn't find the information in the documentation and examples.

Input Expansion

This is a tracking issue for the work what still needs to be done for reading input.

  • Reading Keys Presses
    This feature should porovide support for the following Key Events
    - winapi example code.
    - Special key combinations
  • Mouse Events (example)
    - Allow to capture mouse down, up and hold events.
    - Allow seeing which mouse button is pressed.
  • cleaning up old threads
  • Testing

Problems with input()::read_line() on version 5.1

I've been experiencing a a few bugs related to character deletion on input::read_line().

I believe this issues to be deeply related to the fact that I'm using a portuguese-configured keyboard, which may map keys in a slightly different fashion. Also, I haven't tested this in any other platform besides Windows 10.

There are three main problems:

First

When I press the backspace key the cursor will move to the left accordingly, but the last character of the displayed text will not be remove. If I then type another key, this new character will take it's place.

Also if I press the backspace key and then press enter, read_line() will return the text as if I hadn't pressed backspace in the first place.

Second

If I keep pressing backspace until I get to the start of the line, crossterm will keep moving the cursor back over previously printed text.

Third

If I press any of the arrow keys, instead of moving the cursor, crossterm will count that as an ร  character.

Library contains bin

The library contains an bin project. This will be removed in crossterm v0.2.1.

StyledObject does not implement Display

I am trying to upgrade from 0.3 to 0.4 but got over 60 errors in my project due to the breaking changes. I do a lot of calls where I just want to have some part of the output colored and use the println! macro a lot.

println!(
    "\nExample:\n\n\taws --profile {} s3 ls\n",
    crossterm.paint(&group.accounts[0].name).with(Color::Yellow)
);

I was trying to update the code with as little change as possible and ended up with attempting this:

println!(
    "\nExample:\n\n\taws --profile {} s3 ls\n",
    style(&group.accounts[0].name).with(Color::Yellow)
);

But that yields the following error

error[E0277]: `crossterm::StyledObject<&str>` doesn't implement `std::fmt::Display`

Any chance to implement Display? I don't really know how the library works so please forgive my ignorance. If this can't be done, I'll have to pull apart all of my print statements and squeeze style()..paint(&screen) between my print calls which definitely would be a huge pain. Maybe there's an easier way if you could guide me to one.

Tui backend: Getting crossterm::common::screen::screen::Screen Screen from backend instead of crossterm::Screen

This is probably an issue with tui-rs (feel free to close if it is), but in case it can be solved here I thought I'd mention it. tui-rs issue is posted here: fdehau/tui-rs#123

error[E0308]: mismatched types
  --> src/main.rs:70:46
   |
70 |     let scr = crossterm::Crossterm::from_screen(term.backend().screen());
   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^ expected struct `crossterm::Screen`, found struct `crossterm::common::screen::screen::Screen`
   |
   = note: expected type `&crossterm::Screen`
              found type `&crossterm::common::screen::screen::Screen`

I'm doing this with an attempt to access it's input handler, as it seems like just running it async doesn't seem to work (keep getting "No Characters Pressed" String error when calling next on AsyncReader).

Implementing terminal::pause() functinality

So apparently doing the equivalent of C's System('pause') in Rust is a bit harder than it should be, as you can see in this discussion.

I just thought that since the focus of this crate is cross-platform terminal functionality and this is such a common thing to do (Press any key to continue...), maybe it could get implemented as a simple function like terminal::pause() or something along this lines.

If you think pause() is a bit too specific, terminal::read_char() or stdin().read_char() would be nice too.

Panics after upgrading from 0.5.1 to 0.5.3

Thank you for the great library. I like it ๐Ÿ‘

I am not sure if close issue 40 fixes the trouble but version 0.6 is not published yet.

OS: Window 7 Home 64 bit
Rust: 1.30 GNU-MinGW
Crossterm: 0.5.3

I started using your library a few weeks ago. It was 0.5.1. It worked smoothly. Today I ran cargo update and my application started panicking at line let term = crossterm::terminal::terminal();.

It shows:

thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 87, kind: Other, message: "The parameter is incorrect." }', libcore\result.rs:1009:5

I rolled back to 0.5.1. Should I wait for 0.6? Or it is a new bug and it needs some investigation?

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.