Skip to content

Commit

Permalink
Trim down dependencies (#32)
Browse files Browse the repository at this point in the history
This upgrades to 2018 edition and cuts down on dependencies.
  • Loading branch information
mitsuhiko committed Sep 7, 2019
1 parent 29025fb commit 02c83d6
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 58 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Expand Up @@ -6,4 +6,5 @@ rust:
- nightly

script:
- cargo test
- make test
- if [ "$TRAVIS_RUST_VERSION" = stable ]; then make lint; fi
8 changes: 6 additions & 2 deletions Cargo.toml
Expand Up @@ -5,16 +5,20 @@ version = "0.8.0"
keywords = ["cli", "terminal", "colors", "console", "ansi"]
authors = ["Armin Ronacher <armin.ronacher@active-4.com>"]
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"
Expand Down
26 changes: 26 additions & 0 deletions 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
71 changes: 66 additions & 5 deletions 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
2 changes: 0 additions & 2 deletions examples/colors.rs
@@ -1,5 +1,3 @@
extern crate console;

use console::style;

fn main() {
Expand Down
2 changes: 0 additions & 2 deletions examples/term.rs
@@ -1,5 +1,3 @@
extern crate console;

use std::io::{self, Write};
use std::thread;
use std::time::Duration;
Expand Down
2 changes: 1 addition & 1 deletion 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 {
Expand Down
24 changes: 9 additions & 15 deletions src/lib.rs
Expand Up @@ -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,
};
Expand Down
8 changes: 3 additions & 5 deletions src/term.rs
Expand Up @@ -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)]
Expand Down Expand Up @@ -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::*;
10 changes: 4 additions & 6 deletions src/unix_term.rs
Expand Up @@ -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;

Expand All @@ -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))
Expand Down
42 changes: 33 additions & 9 deletions src/utils.rs
Expand Up @@ -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();
Expand Down Expand Up @@ -46,7 +44,7 @@ pub fn strip_ansi_codes(s: &str) -> Cow<str> {

/// 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.
Expand Down Expand Up @@ -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.
Expand All @@ -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 {
Expand All @@ -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) => {
Expand Down Expand Up @@ -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!(
Expand Down
19 changes: 9 additions & 10 deletions src/windows_term.rs
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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,
Expand All @@ -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(())
}
Expand All @@ -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(())
}
Expand Down Expand Up @@ -372,4 +371,4 @@ pub fn set_title<T: Display>(title: T) {
}
}

pub use common_term::{hide_cursor, show_cursor};
pub use crate::common_term::{hide_cursor, show_cursor};

0 comments on commit 02c83d6

Please sign in to comment.