Remove unused stuff and switch to pub(crate) whenever possible.

This commit is contained in:
Charles Lew 2021-07-18 15:35:37 +08:00
parent 950f569c91
commit 4486795d02
7 changed files with 57 additions and 298 deletions

View File

@ -6,123 +6,62 @@
//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
//! API][win].
//!
//! ```
//!
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
//! [ti]: https://en.wikipedia.org/wiki/Terminfo
#![deny(missing_docs)]
use std::io::prelude::*;
use std::io::{self, Stderr, Stdout};
use std::io::{self, prelude::*};
pub use terminfo::TerminfoTerminal;
pub(crate) use terminfo::TerminfoTerminal;
#[cfg(windows)]
pub use win::WinConsole;
pub(crate) use win::WinConsole;
pub mod terminfo;
pub(crate) mod terminfo;
#[cfg(windows)]
mod win;
/// Alias for stdout terminals.
pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
/// Alias for stderr terminals.
pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
pub(crate) type StdoutTerminal = dyn Terminal + Send;
#[cfg(not(windows))]
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<StdoutTerminal>> {
pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
}
#[cfg(windows)]
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
/// opened.
pub fn stdout() -> Option<Box<StdoutTerminal>> {
pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
TerminfoTerminal::new(io::stdout())
.map(|t| Box::new(t) as Box<StdoutTerminal>)
.or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
}
#[cfg(not(windows))]
/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<StderrTerminal>> {
TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
}
#[cfg(windows)]
/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
/// opened.
pub fn stderr() -> Option<Box<StderrTerminal>> {
TerminfoTerminal::new(io::stderr())
.map(|t| Box::new(t) as Box<StderrTerminal>)
.or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
}
/// Terminal color definitions
#[allow(missing_docs)]
pub mod color {
#[cfg_attr(not(windows), allow(dead_code))]
pub(crate) mod color {
/// Number for a terminal color
pub type Color = u32;
pub(crate) type Color = u32;
pub const BLACK: Color = 0;
pub const RED: Color = 1;
pub const GREEN: Color = 2;
pub const YELLOW: Color = 3;
pub const BLUE: Color = 4;
pub const MAGENTA: Color = 5;
pub const CYAN: Color = 6;
pub const WHITE: Color = 7;
pub const BRIGHT_BLACK: Color = 8;
pub const BRIGHT_RED: Color = 9;
pub const BRIGHT_GREEN: Color = 10;
pub const BRIGHT_YELLOW: Color = 11;
pub const BRIGHT_BLUE: Color = 12;
pub const BRIGHT_MAGENTA: Color = 13;
pub const BRIGHT_CYAN: Color = 14;
pub const BRIGHT_WHITE: Color = 15;
}
/// Terminal attributes for use with term.attr().
///
/// Most attributes can only be turned on and must be turned off with term.reset().
/// The ones that can be turned off explicitly take a boolean value.
/// Color is also represented as an attribute for convenience.
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
pub enum Attr {
/// Bold (or possibly bright) mode
Bold,
/// Dim mode, also called faint or half-bright. Often not supported
Dim,
/// Italics mode. Often not supported
Italic(bool),
/// Underline mode
Underline(bool),
/// Blink mode
Blink,
/// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
Standout(bool),
/// Reverse mode, inverts the foreground and background colors
Reverse,
/// Secure mode, also called invis mode. Hides the printed text
Secure,
/// Convenience attribute to set the foreground color
ForegroundColor(color::Color),
/// Convenience attribute to set the background color
BackgroundColor(color::Color),
pub(crate) const BLACK: Color = 0;
pub(crate) const RED: Color = 1;
pub(crate) const GREEN: Color = 2;
pub(crate) const YELLOW: Color = 3;
pub(crate) const BLUE: Color = 4;
pub(crate) const MAGENTA: Color = 5;
pub(crate) const CYAN: Color = 6;
pub(crate) const WHITE: Color = 7;
}
/// A terminal with similar capabilities to an ANSI Terminal
/// (foreground/background colors etc).
pub trait Terminal: Write {
/// The terminal's output writer type.
type Output: Write;
/// Sets the foreground color to the given color.
///
/// If the color is a bright color, but the terminal only supports 8 colors,
@ -132,23 +71,6 @@ pub trait Terminal: Write {
/// if there was an I/O error.
fn fg(&mut self, color: color::Color) -> io::Result<bool>;
/// Sets the background color to the given color.
///
/// If the color is a bright color, but the terminal only supports 8 colors,
/// the corresponding normal color will be used instead.
///
/// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
/// if there was an I/O error.
fn bg(&mut self, color: color::Color) -> io::Result<bool>;
/// Sets the given terminal attribute, if supported. Returns `Ok(true)`
/// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
/// there was an I/O error.
fn attr(&mut self, attr: Attr) -> io::Result<bool>;
/// Returns `true` if the given terminal attribute is supported.
fn supports_attr(&self, attr: Attr) -> bool;
/// Resets all terminal attributes and colors to their defaults.
///
/// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
@ -160,15 +82,4 @@ pub trait Terminal: Write {
/// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
/// calling reset.
fn reset(&mut self) -> io::Result<bool>;
/// Gets an immutable reference to the stream inside
fn get_ref(&self) -> &Self::Output;
/// Gets a mutable reference to the stream inside
fn get_mut(&mut self) -> &mut Self::Output;
/// Returns the contained stream, destroying the `Terminal`
fn into_inner(self) -> Self::Output
where
Self: Sized;
}

View File

@ -9,7 +9,6 @@ use std::io::{self, prelude::*, BufReader};
use std::path::Path;
use super::color;
use super::Attr;
use super::Terminal;
use parm::{expand, Param, Variables};
@ -18,20 +17,20 @@ use searcher::get_dbpath_for_term;
/// A parsed terminfo database entry.
#[derive(Debug)]
pub struct TermInfo {
pub(crate) struct TermInfo {
/// Names for the terminal
pub names: Vec<String>,
pub(crate) names: Vec<String>,
/// Map of capability name to boolean value
pub bools: HashMap<String, bool>,
pub(crate) bools: HashMap<String, bool>,
/// Map of capability name to numeric value
pub numbers: HashMap<String, u32>,
pub(crate) numbers: HashMap<String, u32>,
/// Map of capability name to raw (unexpanded) string
pub strings: HashMap<String, Vec<u8>>,
pub(crate) strings: HashMap<String, Vec<u8>>,
}
/// A terminfo creation error.
#[derive(Debug)]
pub enum Error {
pub(crate) enum Error {
/// TermUnset Indicates that the environment doesn't include enough information to find
/// the terminfo entry.
TermUnset,
@ -64,7 +63,7 @@ impl fmt::Display for Error {
impl TermInfo {
/// Creates a TermInfo based on current environment.
pub fn from_env() -> Result<TermInfo, Error> {
pub(crate) fn from_env() -> Result<TermInfo, Error> {
let term = match env::var("TERM") {
Ok(name) => TermInfo::from_name(&name),
Err(..) => return Err(Error::TermUnset),
@ -79,7 +78,7 @@ impl TermInfo {
}
/// Creates a TermInfo for the named terminal.
pub fn from_name(name: &str) -> Result<TermInfo, Error> {
pub(crate) fn from_name(name: &str) -> Result<TermInfo, Error> {
get_dbpath_for_term(name)
.ok_or_else(|| {
Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
@ -88,7 +87,7 @@ impl TermInfo {
}
/// Parse the given TermInfo.
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
pub(crate) fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
Self::_from_path(path.as_ref())
}
// Keep the metadata small
@ -99,43 +98,24 @@ impl TermInfo {
}
}
pub mod searcher;
pub(crate) mod searcher;
/// TermInfo format parsing.
pub mod parser {
pub(crate) mod parser {
//! ncurses-compatible compiled terminfo format parsing (term(5))
pub mod compiled;
}
pub mod parm;
fn cap_for_attr(attr: Attr) -> &'static str {
match attr {
Attr::Bold => "bold",
Attr::Dim => "dim",
Attr::Italic(true) => "sitm",
Attr::Italic(false) => "ritm",
Attr::Underline(true) => "smul",
Attr::Underline(false) => "rmul",
Attr::Blink => "blink",
Attr::Standout(true) => "smso",
Attr::Standout(false) => "rmso",
Attr::Reverse => "rev",
Attr::Secure => "invis",
Attr::ForegroundColor(_) => "setaf",
Attr::BackgroundColor(_) => "setab",
}
pub(crate) mod compiled;
}
pub(crate) mod parm;
/// A Terminal that knows how many colors it supports, with a reference to its
/// parsed Terminfo database record.
pub struct TerminfoTerminal<T> {
pub(crate) struct TerminfoTerminal<T> {
num_colors: u32,
out: T,
ti: TermInfo,
}
impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
type Output = T;
fn fg(&mut self, color: color::Color) -> io::Result<bool> {
let color = self.dim_if_necessary(color);
if self.num_colors > color {
@ -144,32 +124,6 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
Ok(false)
}
fn bg(&mut self, color: color::Color) -> io::Result<bool> {
let color = self.dim_if_necessary(color);
if self.num_colors > color {
return self.apply_cap("setab", &[Param::Number(color as i32)]);
}
Ok(false)
}
fn attr(&mut self, attr: Attr) -> io::Result<bool> {
match attr {
Attr::ForegroundColor(c) => self.fg(c),
Attr::BackgroundColor(c) => self.bg(c),
_ => self.apply_cap(cap_for_attr(attr), &[]),
}
}
fn supports_attr(&self, attr: Attr) -> bool {
match attr {
Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => self.num_colors > 0,
_ => {
let cap = cap_for_attr(attr);
self.ti.strings.get(cap).is_some()
}
}
}
fn reset(&mut self) -> io::Result<bool> {
// are there any terminals that have color/attrs and not sgr0?
// Try falling back to sgr, then op
@ -182,26 +136,11 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
};
self.out.write_all(&cmd).and(Ok(true))
}
fn get_ref(&self) -> &T {
&self.out
}
fn get_mut(&mut self) -> &mut T {
&mut self.out
}
fn into_inner(self) -> T
where
Self: Sized,
{
self.out
}
}
impl<T: Write + Send> TerminfoTerminal<T> {
/// Creates a new TerminfoTerminal with the given TermInfo and Write.
pub fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
pub(crate) fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab")
{
terminfo.numbers.get("colors").map_or(0, |&n| n)
@ -215,7 +154,7 @@ impl<T: Write + Send> TerminfoTerminal<T> {
/// Creates a new TerminfoTerminal for the current environment with the given Write.
///
/// Returns `None` when the terminfo cannot be found or parsed.
pub fn new(out: T) -> Option<TerminfoTerminal<T>> {
pub(crate) fn new(out: T) -> Option<TerminfoTerminal<T>> {
TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
}

View File

@ -35,13 +35,12 @@ enum FormatState {
/// Types of parameters a capability can use
#[allow(missing_docs)]
#[derive(Clone)]
pub enum Param {
Words(String),
pub(crate) enum Param {
Number(i32),
}
/// Container for static and dynamic variable arrays
pub struct Variables {
pub(crate) struct Variables {
/// Static variables A-Z
sta_va: [Param; 26],
/// Dynamic variables a-z
@ -50,7 +49,7 @@ pub struct Variables {
impl Variables {
/// Returns a new zero-initialized Variables
pub fn new() -> Variables {
pub(crate) fn new() -> Variables {
Variables {
sta_va: [
Number(0),
@ -121,7 +120,11 @@ impl Variables {
///
/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
/// multiple capabilities for the same terminal.
pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<u8>, String> {
pub(crate) fn expand(
cap: &[u8],
params: &[Param],
vars: &mut Variables,
) -> Result<Vec<u8>, String> {
let mut state = Nothing;
// expanded cap will only rarely be larger than the cap itself
@ -168,7 +171,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
Some(Number(0)) => output.push(128u8),
// Don't check bounds. ncurses just casts and truncates.
Some(Number(c)) => output.push(c as u8),
Some(_) => return Err("a non-char was used with %c".to_string()),
None => return Err("stack is empty".to_string()),
}
}
@ -178,7 +180,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
'\'' => state = CharConstant,
'{' => state = IntConstant(0),
'l' => match stack.pop() {
Some(Words(s)) => stack.push(Number(s.len() as i32)),
Some(_) => return Err("a non-str was used with %l".to_string()),
None => return Err("stack is empty".to_string()),
},
@ -195,9 +196,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
'm' => x % y,
_ => unreachable!("All cases handled"),
})),
(Some(_), Some(_)) => {
return Err(format!("non-numbers on stack with {}", cur));
}
_ => return Err("stack is empty".to_string()),
}
}
@ -216,9 +214,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
0
},
)),
(Some(_), Some(_)) => {
return Err(format!("non-numbers on stack with {}", cur));
}
_ => return Err("stack is empty".to_string()),
},
'!' | '~' => match stack.pop() {
@ -228,7 +223,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
'~' => !x,
_ => unreachable!(),
})),
Some(_) => return Err(format!("non-numbers on stack with {}", cur)),
None => return Err("stack is empty".to_string()),
},
'i' => match (&mparams[0], &mparams[1]) {
@ -236,7 +230,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
mparams[0] = Number(x + 1);
mparams[1] = Number(y + 1);
}
_ => return Err("first two params not numbers with %i".to_string()),
},
// printf-style support for %doxXs
@ -271,7 +264,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
't' => match stack.pop() {
Some(Number(0)) => state = SeekIfElse(0),
Some(Number(_)) => (),
Some(_) => return Err("non-number on stack with conditional".to_string()),
None => return Err("stack is empty".to_string()),
},
'e' => state = SeekIfEnd(0),
@ -480,15 +472,6 @@ impl FormatOp {
_ => panic!("bad FormatOp char"),
}
}
fn to_char(self) -> char {
match self {
FormatOp::Digit => 'd',
FormatOp::Octal => 'o',
FormatOp::LowerHex => 'x',
FormatOp::UpperHex => 'X',
FormatOp::String => 's',
}
}
}
fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
@ -533,16 +516,6 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
}
.into_bytes()
}
Words(s) => match op {
FormatOp::String => {
let mut s = s.into_bytes();
if flags.precision > 0 && flags.precision < s.len() {
s.truncate(flags.precision);
}
s
}
_ => return Err(format!("non-string on stack with %{}", op.to_char())),
},
};
if flags.width > s.len() {
let n = flags.width - s.len();

View File

@ -51,7 +51,10 @@ fn test_param_stack_failure_conditions() {
for &cap in caps.iter() {
let res = get_res("", cap, &[], vars);
assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap);
let p = if cap == "%s" || cap == "%l" { Words("foo".to_string()) } else { Number(97) };
if cap == "%s" || cap == "%l" {
continue;
}
let p = Number(97);
let res = get_res("%p1", cap, &[p], vars);
assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err());
}
@ -109,23 +112,6 @@ fn test_conditionals() {
fn test_format() {
let mut varstruct = Variables::new();
let vars = &mut varstruct;
assert_eq!(
expand(
b"%p1%s%p2%2s%p3%2s%p4%.2s",
&[
Words("foo".to_string()),
Words("foo".to_string()),
Words("f".to_string()),
Words("foo".to_string())
],
vars
),
Ok("foofoo ffo".bytes().collect::<Vec<_>>())
);
assert_eq!(
expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars),
Ok("fo ".bytes().collect::<Vec<_>>())
);
assert_eq!(
expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),

View File

@ -13,7 +13,7 @@ mod tests;
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
#[rustfmt::skip]
pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
pub(crate) static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
"no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
"hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
"memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
@ -26,13 +26,13 @@ pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
"return_does_clr_eol"];
#[rustfmt::skip]
pub static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
pub(crate) static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
"gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
"nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
"xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
#[rustfmt::skip]
pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
pub(crate) static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
"lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
"width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
"maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
@ -43,13 +43,13 @@ pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
"new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
#[rustfmt::skip]
pub static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
pub(crate) static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
"vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
"spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
"btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
#[rustfmt::skip]
pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
pub(crate) static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
"change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
"column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
"cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
@ -123,7 +123,7 @@ pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
"acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
#[rustfmt::skip]
pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
pub(crate) static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
"_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
"ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
"dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
@ -178,7 +178,7 @@ fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
/// Parse a compiled terminfo entry, using long capability names if `longnames`
/// is true
pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
pub(crate) fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
macro_rules! t( ($e:expr) => (
match $e {
Ok(e) => e,
@ -317,7 +317,7 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin
}
/// Creates a dummy TermInfo struct for msys terminals
pub fn msys_terminfo() -> TermInfo {
pub(crate) fn msys_terminfo() -> TermInfo {
let mut strings = HashMap::new();
strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
strings.insert("bold".to_string(), b"\x1B[1m".to_vec());

View File

@ -11,7 +11,7 @@ mod tests;
/// Return path to database entry for `term`
#[allow(deprecated)]
pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
pub(crate) fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
let mut dirs_to_search = Vec::new();
let first_char = term.chars().next()?;

View File

@ -6,11 +6,10 @@ use std::io;
use std::io::prelude::*;
use super::color;
use super::Attr;
use super::Terminal;
/// A Terminal implementation that uses the Win32 Console API.
pub struct WinConsole<T> {
pub(crate) struct WinConsole<T> {
buf: T,
def_foreground: color::Color,
def_background: color::Color,
@ -115,7 +114,7 @@ impl<T: Write + Send + 'static> WinConsole<T> {
}
/// Returns `None` whenever the terminal cannot be created for some reason.
pub fn new(out: T) -> io::Result<WinConsole<T>> {
pub(crate) fn new(out: T) -> io::Result<WinConsole<T>> {
use std::mem::MaybeUninit;
let fg;
@ -154,8 +153,6 @@ impl<T: Write> Write for WinConsole<T> {
}
impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
type Output = T;
fn fg(&mut self, color: color::Color) -> io::Result<bool> {
self.foreground = color;
self.apply();
@ -163,38 +160,6 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
Ok(true)
}
fn bg(&mut self, color: color::Color) -> io::Result<bool> {
self.background = color;
self.apply();
Ok(true)
}
fn attr(&mut self, attr: Attr) -> io::Result<bool> {
match attr {
Attr::ForegroundColor(f) => {
self.foreground = f;
self.apply();
Ok(true)
}
Attr::BackgroundColor(b) => {
self.background = b;
self.apply();
Ok(true)
}
_ => Ok(false),
}
}
fn supports_attr(&self, attr: Attr) -> bool {
// it claims support for underscore and reverse video, but I can't get
// it to do anything -cmr
match attr {
Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => true,
_ => false,
}
}
fn reset(&mut self) -> io::Result<bool> {
self.foreground = self.def_foreground;
self.background = self.def_background;
@ -202,19 +167,4 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
Ok(true)
}
fn get_ref(&self) -> &T {
&self.buf
}
fn get_mut(&mut self) -> &mut T {
&mut self.buf
}
fn into_inner(self) -> T
where
Self: Sized,
{
self.buf
}
}