From 02c83d699aaab8955e7d4abd15b3b3fdf9805cc9 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Sun, 8 Sep 2019 00:36:59 +0200 Subject: [PATCH] Trim down dependencies (#32) This upgrades to 2018 edition and cuts down on dependencies. --- .travis.yml | 3 +- Cargo.toml | 8 +++-- Makefile | 26 +++++++++++++++++ README.md | 71 +++++++++++++++++++++++++++++++++++++++++---- examples/colors.rs | 2 -- examples/term.rs | 2 -- src/common_term.rs | 2 +- src/lib.rs | 24 ++++++--------- src/term.rs | 8 ++--- src/unix_term.rs | 10 +++---- src/utils.rs | 42 +++++++++++++++++++++------ src/windows_term.rs | 19 ++++++------ 12 files changed, 159 insertions(+), 58 deletions(-) create mode 100644 Makefile diff --git a/.travis.yml b/.travis.yml index 21a7d854..c16f6deb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,4 +6,5 @@ rust: - nightly script: - - cargo test + - make test + - if [ "$TRAVIS_RUST_VERSION" = stable ]; then make lint; fi diff --git a/Cargo.toml b/Cargo.toml index 5075ed3a..e6a5a4f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,16 +5,20 @@ version = "0.8.0" keywords = ["cli", "terminal", "colors", "console", "ansi"] authors = ["Armin Ronacher "] license = "MIT" +edition = "2018" homepage = "https://github.com/mitsuhiko/console" documentation = "https://docs.rs/console" readme = "README.md" +[features] +default = ["unicode-width"] + [dependencies] clicolors-control = "1.0.0" lazy_static = "1" libc = "0.2" -regex = "1" -unicode-width = "0.1" +regex = { version = "1.3.1", default-features = false, features = ["std"] } +unicode-width = { version = "0.1", optional = true } [target.'cfg(unix)'.dependencies] termios = "0.3" diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..bb41852f --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +all: test +.PHONY: all + +format: + @rustup component add rustfmt 2> /dev/null + @cargo fmt --all +.PHONY: format + +format-check: + @rustup component add rustfmt 2> /dev/null + @cargo fmt --all -- --check +.PHONY: format-check + +lint: + @rustup component add clippy 2> /dev/null + @cargo clippy +.PHONY: lint + +update-readme: + @cargo readme > README.md +.PHONY: update-readme + +test: + @cargo test + @cargo test --no-default-features +.PHONY: test diff --git a/README.md b/README.md index f7fd18d1..7e0c07be 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,70 @@ # console -[![Build Status](https://travis-ci.org/mitsuhiko/console.svg?branch=master)](https://travis-ci.org/mitsuhiko/console) -[![Latest Version](https://img.shields.io/crates/v/console.svg)](https://crates.io/crates/console) -[![docs](https://docs.rs/console/badge.svg)](https://docs.rs/console) +console is a library for Rust that provides access to various terminal +features so you can build nicer looking command line interfaces. It +comes with various tools and utilities for working with Terminals and +formatting text. -A console and terminal abstraction for Rust. +Best paired with other libraries in the family: -Adds colors and other useful things to your terminal life. +* [dialoguer](https://docs.rs/dialoguer) +* [indicatif](https://docs.rs/indicatif) + +## Terminal Access + +The terminal is abstracted through the `console::Term` type. It can +either directly provide access to the connected terminal or by buffering +up commands. A buffered terminal will however not be completely buffered +on windows where cursor movements are currently directly passed through. + +Example usage: + +```rust +use std::thread; +use std::time::Duration; + +use console::Term; + +let term = Term::stdout(); +term.write_line("Hello World!")?; +thread::sleep(Duration::from_millis(2000)); +term.clear_line()?; +``` + +## Colors and Styles + +`console` uses `clicolors-control` to control colors. It also +provides higher level wrappers for styling text and other things +that can be displayed with the `style` function and utility types. + +Example usage: + +```rust +use console::style; + +println!("This is {} neat", style("quite").cyan()); +``` + +You can also store styles and apply them to text later: + +```rust +use console::Style; + +let cyan = Style::new().cyan(); +println!("This is {} neat", cyan.apply_to("quite")); +``` + +## Working with ANSI Codes + +The crate provids the function `strip_ansi_codes` to remove ANSI codes +from a string as well as `measure_text_width` to calculate the width of a +string as it would be displayed by the terminal. Both of those together +are useful for more complex formatting. + +## Unicode Support + +By default this crate depends on the `unicode_width` crate to calculate +the width of terminal characters. If you do not need this you can disable +the `unicode` feature which will cut down on dependencies. + +License: MIT diff --git a/examples/colors.rs b/examples/colors.rs index ebef0443..01149a6f 100644 --- a/examples/colors.rs +++ b/examples/colors.rs @@ -1,5 +1,3 @@ -extern crate console; - use console::style; fn main() { diff --git a/examples/term.rs b/examples/term.rs index 0f83dd43..f26198f2 100644 --- a/examples/term.rs +++ b/examples/term.rs @@ -1,5 +1,3 @@ -extern crate console; - use std::io::{self, Write}; use std::thread; use std::time::Duration; diff --git a/src/common_term.rs b/src/common_term.rs index 85e26393..36231751 100644 --- a/src/common_term.rs +++ b/src/common_term.rs @@ -1,6 +1,6 @@ use std::io; -use term::Term; +use crate::term::Term; pub fn move_cursor_down(out: &Term, n: usize) -> io::Result<()> { if n > 0 { diff --git a/src/lib.rs b/src/lib.rs index dd6379ff..c04f7c8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,22 +60,16 @@ //! from a string as well as `measure_text_width` to calculate the width of a //! string as it would be displayed by the terminal. Both of those together //! are useful for more complex formatting. -#[cfg(windows)] -extern crate encode_unicode; -extern crate libc; -#[cfg(unix)] -extern crate termios; -#[cfg(windows)] -extern crate winapi; -#[macro_use] -extern crate lazy_static; -extern crate clicolors_control; -extern crate regex; -extern crate unicode_width; +//! +//! # Unicode Width Support +//! +//! By default this crate depends on the `unicode-width` crate to calculate +//! the width of terminal characters. If you do not need this you can disable +//! the `unicode-width` feature which will cut down on dependencies. -pub use kb::Key; -pub use term::{user_attended, Term, TermFamily, TermFeatures, TermTarget}; -pub use utils::{ +pub use crate::kb::Key; +pub use crate::term::{user_attended, Term, TermFamily, TermFeatures, TermTarget}; +pub use crate::utils::{ colors_enabled, measure_text_width, pad_str, set_colors_enabled, strip_ansi_codes, style, truncate_str, Alignment, AnsiCodeIterator, Attribute, Color, Emoji, Style, StyledObject, }; diff --git a/src/term.rs b/src/term.rs index 1fe2e9ae..adaaec63 100644 --- a/src/term.rs +++ b/src/term.rs @@ -8,9 +8,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; #[cfg(windows)] use std::os::windows::io::{AsRawHandle, RawHandle}; -use kb::Key; - -use clicolors_control; +use crate::kb::Key; /// Where the term is writing. #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -427,6 +425,6 @@ impl<'a> io::Read for &'a Term { } #[cfg(unix)] -pub use unix_term::*; +pub use crate::unix_term::*; #[cfg(windows)] -pub use windows_term::*; +pub use crate::windows_term::*; diff --git a/src/unix_term.rs b/src/unix_term.rs index b8d1b94b..baa6aa91 100644 --- a/src/unix_term.rs +++ b/src/unix_term.rs @@ -6,13 +6,10 @@ use std::mem; use std::os::unix::io::AsRawFd; use std::str; -use libc; -use termios; +use crate::kb::Key; +use crate::term::Term; -use kb::Key; -use term::Term; - -pub use common_term::*; +pub use crate::common_term::*; pub const DEFAULT_WIDTH: u16 = 80; @@ -31,6 +28,7 @@ pub fn terminal_size() -> Option<(u16, u16)> { // FIXME: ".into()" used as a temporary fix for a libc bug // https://github.com/rust-lang/libc/pull/704 + #[allow(clippy::identity_conversion)] libc::ioctl(libc::STDOUT_FILENO, libc::TIOCGWINSZ.into(), &mut winsize); if winsize.ws_row > 0 && winsize.ws_col > 0 { Some((winsize.ws_row as u16, winsize.ws_col as u16)) diff --git a/src/utils.rs b/src/utils.rs index 60db82bd..c0e01087 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,13 +2,11 @@ use std::borrow::Cow; use std::collections::BTreeSet; use std::fmt; -use clicolors_control; use regex::{Matches, Regex}; -use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; -use term::wants_emoji; +use crate::term::wants_emoji; -lazy_static! { +lazy_static::lazy_static! { static ref STRIP_ANSI_RE: Regex = Regex::new(r"[\x1b\x9b][\[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><]") .unwrap(); @@ -46,7 +44,7 @@ pub fn strip_ansi_codes(s: &str) -> Cow { /// Measure the width of a string in terminal characters. pub fn measure_text_width(s: &str) -> usize { - strip_ansi_codes(s).width() + str_width(&strip_ansi_codes(s)) } /// A terminal color. @@ -599,6 +597,31 @@ impl<'a> Iterator for AnsiCodeIterator<'a> { } } +fn str_width(s: &str) -> usize { + #[cfg(feature = "unicode")] + { + use unicode_width::UnicodeWidthStr; + s.width() + } + #[cfg(not(feature = "unicode"))] + { + s.chars().count() + } +} + +fn char_width(c: char) -> usize { + #[cfg(feature = "unicode")] + { + use unicode_width::UnicodeWidthChar; + c.width().unwrap_or(0) + } + #[cfg(not(feature = "unicode"))] + { + let _c = c; + 1 + } +} + /// Truncates a string to a certain number of characters. /// /// This ensures that escape codes are not screwed up in the process. @@ -614,15 +637,15 @@ pub fn truncate_str<'a>(s: &'a str, width: usize, tail: &str) -> Cow<'a, str> { match item { (s, false) => { if rv.is_none() { - if s.width() + length > width - tail.width() { + if str_width(s) + length > width - str_width(tail) { let ts = iter.current_slice(); let mut s_byte = 0; let mut s_width = 0; - let rest_width = width - tail.width() - length; + let rest_width = width - str_width(tail) - length; for c in s.chars() { s_byte += c.len_utf8(); - s_width += c.width().unwrap_or(0); + s_width += char_width(c); if s_width == rest_width { break; } else if s_width > rest_width { @@ -636,7 +659,7 @@ pub fn truncate_str<'a>(s: &'a str, width: usize, tail: &str) -> Cow<'a, str> { buf.push_str(tail); rv = Some(buf); } - length += s.width(); + length += str_width(s); } } (s, true) => { @@ -721,6 +744,7 @@ fn test_text_width() { } #[test] +#[cfg(feature = "unicode")] fn test_truncate_str() { let s = format!("foo {}", style("bar").red().force_styling(true)); assert_eq!( diff --git a/src/windows_term.rs b/src/windows_term.rs index f810db51..97a03df5 100644 --- a/src/windows_term.rs +++ b/src/windows_term.rs @@ -10,7 +10,6 @@ use std::slice; use encode_unicode::error::InvalidUtf16Tuple; use encode_unicode::CharExt; -use winapi; use winapi::ctypes::c_void; use winapi::shared::minwindef::DWORD; use winapi::shared::minwindef::MAX_PATH; @@ -28,9 +27,9 @@ use winapi::um::wincon::{ }; use winapi::um::winnt::{CHAR, HANDLE, INT, WCHAR}; -use common_term; -use kb::Key; -use term::{Term, TermTarget}; +use crate::common_term; +use crate::kb::Key; +use crate::term::{Term, TermTarget}; pub const DEFAULT_WIDTH: u16 = 79; @@ -90,7 +89,7 @@ pub fn move_cursor_to(out: &Term, x: usize, y: usize) -> io::Result<()> { if msys_tty_on(out) { return common_term::move_cursor_to(out, x, y); } - if let Some((hand, csbi)) = get_console_screen_buffer_info(as_handle(out)) { + if let Some((hand, _)) = get_console_screen_buffer_info(as_handle(out)) { unsafe { SetConsoleCursorPosition( hand, @@ -109,8 +108,8 @@ pub fn move_cursor_up(out: &Term, n: usize) -> io::Result<()> { return common_term::move_cursor_up(out, n); } - if let Some((hand, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - move_cursor_to(out, 0, csbi.dwCursorPosition.Y as usize - n); + if let Some((_, csbi)) = get_console_screen_buffer_info(as_handle(out)) { + move_cursor_to(out, 0, csbi.dwCursorPosition.Y as usize - n)?; } Ok(()) } @@ -120,8 +119,8 @@ pub fn move_cursor_down(out: &Term, n: usize) -> io::Result<()> { return common_term::move_cursor_down(out, n); } - if let Some((hand, csbi)) = get_console_screen_buffer_info(as_handle(out)) { - move_cursor_to(out, 0, csbi.dwCursorPosition.Y as usize + n); + if let Some((_, csbi)) = get_console_screen_buffer_info(as_handle(out)) { + move_cursor_to(out, 0, csbi.dwCursorPosition.Y as usize + n)?; } Ok(()) } @@ -372,4 +371,4 @@ pub fn set_title(title: T) { } } -pub use common_term::{hide_cursor, show_cursor}; +pub use crate::common_term::{hide_cursor, show_cursor};