Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ jobs:
override: true
- name: Checkout
uses: actions/checkout@v3
- name: MSRV dependencies
if: matrix.rust == '1.71.0'
run: make msrv-lock
- name: Check
env:
CARGO_BUILD_TARGET: ${{ matrix.target }}
Expand Down Expand Up @@ -79,9 +76,6 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install gcc-multilib
- name: MSRV dependencies
if: matrix.rust == '1.71.0'
run: make msrv-lock
- name: Test
env:
CARGO_BUILD_TARGET: ${{ matrix.target }}
Expand Down
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ include = ["CHANGELOG.md", "Cargo.toml", "LICENSE", "README.md", "src/**/*.rs"]

[features]
default = ["unicode-width", "ansi-parsing", "std"]
std = ["dep:libc", "dep:once_cell", "alloc"]
std = ["dep:libc", "alloc"]
alloc = []
windows-console-colors = ["ansi-parsing"]
ansi-parsing = []

[dependencies]
libc = { version = "0.2.99", optional = true }
once_cell = { version = "1.8", optional = true }
unicode-width = { version = "0.2", optional = true }

[target.'cfg(windows)'.dependencies]
Expand Down
5 changes: 1 addition & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,4 @@ lint:
@rustup component add clippy 2> /dev/null
@cargo clippy --examples --tests --all-features -- --deny warnings

msrv-lock:
@cargo update -p once_cell --precise 1.20.3

.PHONY: all doc build check test format format-check lint check-minver msrv-lock
.PHONY: all doc build check test format format-check lint check-minver
19 changes: 10 additions & 9 deletions src/ansi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,18 +292,19 @@ mod tests {
use super::*;

use core::fmt::Write;
use once_cell::sync::Lazy;
use proptest::prelude::*;
use regex::Regex;
use std::sync::OnceLock;

// The manual dfa `State` is a handwritten translation from the previously used regex. That
// regex is kept here and used to ensure that the new matches are the same as the old
static STRIP_ANSI_RE: Lazy<Regex> = Lazy::new(|| {
Regex::new(
fn strip_ansi_re() -> &'static Regex {
static RE: OnceLock<Regex> = OnceLock::new();

RE.get_or_init(|| Regex::new(
r"[\x1b\x9b]([()][012AB]|[\[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-PRZcf-nqry=><])",
)
.unwrap()
});
).unwrap())
}

impl<'a> PartialEq<Match<'a>> for regex::Match<'_> {
fn eq(&self, other: &Match<'a>) -> bool {
Expand All @@ -314,7 +315,7 @@ mod tests {
proptest! {
#[test]
fn dfa_matches_old_regex(s in r"([\x1b\x9b]?.*){0,5}") {
let old_matches: Vec<_> = STRIP_ANSI_RE.find_iter(&s).collect();
let old_matches: Vec<_> = strip_ansi_re().find_iter(&s).collect();
let new_matches: Vec<_> = Matches::new(&s).collect();
assert_eq!(old_matches, new_matches);
}
Expand All @@ -334,7 +335,7 @@ mod tests {
fn _check_all_strings_of_len(len: usize, chunk: &mut Vec<u8>) {
if len == 0 {
if let Ok(s) = core::str::from_utf8(chunk) {
let old_matches: Vec<_> = STRIP_ANSI_RE.find_iter(s).collect();
let old_matches: Vec<_> = strip_ansi_re().find_iter(s).collect();
let new_matches: Vec<_> = Matches::new(s).collect();
assert_eq!(old_matches, new_matches);
}
Expand Down Expand Up @@ -363,7 +364,7 @@ mod tests {
)
.unwrap();

let old_matches: Vec<_> = STRIP_ANSI_RE.find_iter(&s).collect();
let old_matches: Vec<_> = strip_ansi_re().find_iter(&s).collect();
let new_matches: Vec<_> = Matches::new(&s).collect();
assert_eq!(old_matches, new_matches);
}
Expand Down
15 changes: 7 additions & 8 deletions src/unix_term.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::io::{self, BufRead, BufReader};
use std::os::fd::{AsRawFd, RawFd};

#[cfg(not(target_os = "macos"))]
use once_cell::sync::Lazy;
use std::sync::OnceLock;

use crate::kb::Key;
use crate::term::Term;
Expand Down Expand Up @@ -380,20 +380,19 @@ fn key_from_utf8(buf: &[u8]) -> Key {
Key::Unknown
}

#[cfg(not(target_os = "macos"))]
static IS_LANG_UTF8: Lazy<bool> = Lazy::new(|| match std::env::var("LANG") {
Ok(lang) => lang.to_uppercase().ends_with("UTF-8"),
_ => false,
});

#[cfg(target_os = "macos")]
pub(crate) fn wants_emoji() -> bool {
true
}

#[cfg(not(target_os = "macos"))]
pub(crate) fn wants_emoji() -> bool {
*IS_LANG_UTF8
static IS_LANG_UTF8: OnceLock<bool> = OnceLock::new();

*IS_LANG_UTF8.get_or_init(|| match std::env::var("LANG") {
Ok(lang) => lang.to_uppercase().ends_with("UTF-8"),
_ => false,
})
}

pub(crate) fn set_title<T: Display>(title: T) {
Expand Down
42 changes: 25 additions & 17 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::{
};
use std::env;

use once_cell::sync::Lazy;
use std::sync::OnceLock;

use crate::term::{wants_emoji, Term};

Expand All @@ -22,14 +22,22 @@ fn default_true_colors_enabled(out: &Term) -> bool {
out.features().true_colors_supported()
}

static STDOUT_COLORS: Lazy<AtomicBool> =
Lazy::new(|| AtomicBool::new(default_colors_enabled(&Term::stdout())));
static STDOUT_TRUE_COLORS: Lazy<AtomicBool> =
Lazy::new(|| AtomicBool::new(default_true_colors_enabled(&Term::stdout())));
static STDERR_COLORS: Lazy<AtomicBool> =
Lazy::new(|| AtomicBool::new(default_colors_enabled(&Term::stderr())));
static STDERR_TRUE_COLORS: Lazy<AtomicBool> =
Lazy::new(|| AtomicBool::new(default_true_colors_enabled(&Term::stderr())));
fn stdout_colors() -> &'static AtomicBool {
static ENABLED: OnceLock<AtomicBool> = OnceLock::new();
ENABLED.get_or_init(|| AtomicBool::new(default_colors_enabled(&Term::stdout())))
}
fn stdout_true_colors() -> &'static AtomicBool {
static ENABLED: OnceLock<AtomicBool> = OnceLock::new();
ENABLED.get_or_init(|| AtomicBool::new(default_true_colors_enabled(&Term::stdout())))
}
fn stderr_colors() -> &'static AtomicBool {
static ENABLED: OnceLock<AtomicBool> = OnceLock::new();
ENABLED.get_or_init(|| AtomicBool::new(default_colors_enabled(&Term::stderr())))
}
fn stderr_true_colors() -> &'static AtomicBool {
static ENABLED: OnceLock<AtomicBool> = OnceLock::new();
ENABLED.get_or_init(|| AtomicBool::new(default_true_colors_enabled(&Term::stderr())))
}

/// Returns `true` if colors should be enabled for stdout.
///
Expand All @@ -40,13 +48,13 @@ static STDERR_TRUE_COLORS: Lazy<AtomicBool> =
/// * `CLICOLOR_FORCE != 0`: ANSI colors should be enabled no matter what.
#[inline]
pub fn colors_enabled() -> bool {
STDOUT_COLORS.load(Ordering::Relaxed)
stdout_colors().load(Ordering::Relaxed)
}

/// Returns `true` if true colors should be enabled for stdout.
#[inline]
pub fn true_colors_enabled() -> bool {
STDOUT_TRUE_COLORS.load(Ordering::Relaxed)
stdout_true_colors().load(Ordering::Relaxed)
}

/// Forces colorization on or off for stdout.
Expand All @@ -55,7 +63,7 @@ pub fn true_colors_enabled() -> bool {
/// `colors_enabled` function.
#[inline]
pub fn set_colors_enabled(val: bool) {
STDOUT_COLORS.store(val, Ordering::Relaxed)
stdout_colors().store(val, Ordering::Relaxed)
}

/// Forces true colorization on or off for stdout.
Expand All @@ -64,7 +72,7 @@ pub fn set_colors_enabled(val: bool) {
/// `true_colors_enabled` function.
#[inline]
pub fn set_true_colors_enabled(val: bool) {
STDOUT_TRUE_COLORS.store(val, Ordering::Relaxed)
stdout_true_colors().store(val, Ordering::Relaxed)
}

/// Returns `true` if colors should be enabled for stderr.
Expand All @@ -76,13 +84,13 @@ pub fn set_true_colors_enabled(val: bool) {
/// * `CLICOLOR_FORCE != 0`: ANSI colors should be enabled no matter what.
#[inline]
pub fn colors_enabled_stderr() -> bool {
STDERR_COLORS.load(Ordering::Relaxed)
stderr_colors().load(Ordering::Relaxed)
}

/// Returns `true` if true colors should be enabled for stderr.
#[inline]
pub fn true_colors_enabled_stderr() -> bool {
STDERR_TRUE_COLORS.load(Ordering::Relaxed)
stderr_true_colors().load(Ordering::Relaxed)
}

/// Forces colorization on or off for stderr.
Expand All @@ -91,7 +99,7 @@ pub fn true_colors_enabled_stderr() -> bool {
/// `colors_enabled_stderr` function.
#[inline]
pub fn set_colors_enabled_stderr(val: bool) {
STDERR_COLORS.store(val, Ordering::Relaxed)
stderr_colors().store(val, Ordering::Relaxed)
}

/// Forces true colorization on or off for stderr.
Expand All @@ -100,7 +108,7 @@ pub fn set_colors_enabled_stderr(val: bool) {
/// `true_colors_enabled_stderr` function.
#[inline]
pub fn set_true_colors_enabled_stderr(val: bool) {
STDERR_TRUE_COLORS.store(val, Ordering::Relaxed)
stderr_true_colors().store(val, Ordering::Relaxed)
}

/// Measure the width of a string in terminal characters.
Expand Down
Loading