CK2R6STAMMOQCX3HD676VNU6LCNG4BSIV2ZSEEFWVUWW4TPFW73AC
T4BZASPWFKHE74WO42QDVPKKWBCK64E73EI45VVZNIUX7BVMRVMAC
B2MSSEJB4GIBFA6F2HRMK7FXUHJBZIZFK6NOHY7YZUSHRB53URGQC
IA2CJ4HDSST6MPDLX2FVE2ZZR7EP5O6AIAUFGZIMWJ6NODVMKOKAC
4LR5AJ4AX277G4G3SRDHNCIJIOCRZ6I4TUNTSZOAVUX4MW5GYFTQC
F2QYIRKBFYFWSTB7Z5CNGSZVYI6XQO3MHPUHJLBHPGLIOG7UNVNQC
AIF5IVL7B5S2X3N4RLS6GNKUCASQZPOH6NCVGECUFHQ5ZUJVDU6QC
V74ZMPLHZQYD4MXOYTT6SLVV5AY2B3MAAS27L2M7PIM3D3RZZKCQC
EDCVYHTHMBCI3VIBGMA35H7MFYK3MTEJH36ET36PQBB5WGKDXQ5QC
MIIKFTYUUN5UC74HIC5SMCPAWU7ZYOHWANZLCPWREKSPD4UE65JQC
PPVF6CAUFB6GIKSYLQ2IYIOPSRRNNBQUG5CLXJDMO6PRD23M4F3AC
5PDXNCBBHM3UXTGZNX76FUMWUHBL6BGB7MFBXFGVN5TJECMBYUJAC
6CEULYGBZ5W2OW6WNT4UMZIR5ESTPGZWAHWBN5EXZK2CREIQWZXAC
FTI67CGF4MMPDFA6YJN6UKOADQLFAECKGYPTWSPSALVQK76BJMJAC
LJ6NSNMT4MVRLROHDZZAYPJBR7ZLUQGHFSOCILNK2FJFZZUS6OTQC
T2HK3ZSDLLLGHROM77MND4UZF663WSHT5J2CT7ZMXDH6MMIZFOAQC
VEN5WJYRT23IT77JAAZ5CJRSW3GUTTNMAECT3WVTHQA34HI4646AC
YQSLDBVSLMXMWYHDASV2QOSYZMMLV2T2QT2IWJT6WYWQKOL2MKFQC
K7M77GF5ILC4KKKYPTLZRZ2OND7DOQDQNRYKM3N6XV2DMJURYA3QC
VK3SMPPCGTZANUZKMXBUMIZWXQDNR3PZU3DE7SRWXTMXNSI7XBJAC
NXADNFPSCM7ETIGZ676I7X3WENZPRBEZGIOLDWC2FSY652QK2UBAC
RAVOIZIUDSG2A44PKQP3KY7IVBWBYSQY4I744B6I7QZFRL3AE4EQC
let no_format = self.default_args.no_format;
let host = self.default_args.host;
let duration = self.default_args.duration;
let status = self.default_args.status;
let show_pwd = self.default_args.show_pwd;
let show_session = self.default_args.show_session;
let format = !self.default_args.disable_formatting;
let duration = Display::should_show(self.default_args.show_duration);
let header = Display::should_hide(self.default_args.hide_header);
let host = Display::should_show(self.default_args.show_host);
let pwd = Display::should_show(self.default_args.show_pwd);
let session = Display::should_show(self.default_args.show_session);
let status = Display::should_show(self.default_args.show_status);
run::default(
in_current,
folder,
all_hosts,
hostname,
data_dir,
entries_count,
&command,
no_subdirs,
&command_text,
no_format,
let filter = Filter::default()
.directory(folder, in_current, no_subdirs)?
.hostname(hostname, all_hosts)?
.count(entries_count)
.command(command, command_text);
let display = TableDisplay {
format,
duration,
header,
#[allow(clippy::fn_params_excessive_bools)]
#[allow(clippy::too_many_arguments)]
#[allow(clippy::too_many_lines)]
#[allow(clippy::cognitive_complexity)]
pub fn default(
in_current: bool,
folder: Option<PathBuf>,
all_hosts: bool,
hostname: Option<String>,
data_dir: PathBuf,
entries_count: usize,
command: &Option<String>,
no_subdirs: bool,
command_text: &Option<Regex>,
no_format: bool,
host: bool,
duration: bool,
status: bool,
show_pwd: bool,
show_session: bool,
) -> Result<(), Error> {
let dir_filter = if in_current {
Some(std::env::current_dir().map_err(Error::GetCurrentDir)?)
} else {
folder
};
#[derive(Debug)]
pub struct TableDisplay {
pub format: bool,
let entries = store::new(data_dir).get_entries(
hostname_filter,
entries_count,
command,
&dir_filter,
no_subdirs,
command_text,
)?;
duration: Display::Hide,
header: Display::Show,
host: Display::Hide,
pwd: Display::Hide,
session: Display::Hide,
status: Display::Hide,
}
}
}
if show_pwd {
header.push("pwd");
}
pub fn default_no_format(display: &TableDisplay, entries: Vec<Entry>) -> Result<(), Error> {
let mut header = vec!["tmn"];
if display.host.is_show() {
header.push("host")
};
if display.duration.is_show() {
header.push("duration")
};
if display.status.is_show() {
header.push("res")
};
if display.session.is_show() {
header.push("ses");
}
if display.pwd.is_show() {
header.push("pwd");
}
handle
.write_all(row.join("\t").as_bytes())
.map_err(Error::WriteStdout)?;
handle.write_all(b"\n").map_err(Error::WriteStdout)?;
}
} else {
let mut table = Table::new();
table.load_preset(" ");
table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
handle
.write_all(row.join("\t").as_bytes())
.map_err(Error::WriteStdout)?;
handle.write_all(b"\n").map_err(Error::WriteStdout)?;
}
if host {
header.push(Cell::new("host").add_attribute(Attribute::Bold))
};
pub fn default_format(display: &TableDisplay, entries: Vec<Entry>) -> Result<(), Error> {
let mut table = Table::new();
table.load_preset(" ");
table.set_content_arrangement(comfy_table::ContentArrangement::Dynamic);
if show_session {
header.push(Cell::new("ses").add_attribute(Attribute::Bold));
}
if display.duration.is_show() {
header.push(Cell::new("duration").add_attribute(Attribute::Bold))
};
if show_pwd {
header.push(Cell::new("pwd").add_attribute(Attribute::Bold));
}
if display.status.is_show() {
header.push(Cell::new("res").add_attribute(Attribute::Bold))
};
use crate::entry::Entry;
use regex::Regex;
use std::path::PathBuf;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum Error {
#[error("can not get hostname: {0}")]
GetHostname(std::io::Error),
#[error("can not get current directory: {0}")]
GetCurrentDir(std::io::Error),
}
#[derive(Debug, Default)]
pub struct Filter {
hostname: Option<String>,
directory: Option<PathBuf>,
command: Option<String>,
no_subdirs: bool,
command_text: Option<Regex>,
count: usize,
}
impl Filter {
pub const fn get_hostname(&self) -> Option<&String> {
self.hostname.as_ref()
}
pub fn hostname(self, hostname: Option<String>, all_hosts: bool) -> Result<Self, Error> {
let current_hostname = hostname::get()
.map_err(Error::GetHostname)?
.to_string_lossy()
.to_string();
let hostname = if all_hosts {
None
} else {
Some(hostname.unwrap_or(current_hostname))
};
Ok(Self { hostname, ..self })
}
pub fn directory(
self,
folder: Option<PathBuf>,
in_current: bool,
no_subdirs: bool,
) -> Result<Self, Error> {
let directory = if in_current {
Some(std::env::current_dir().map_err(Error::GetCurrentDir)?)
} else {
folder
};
Ok(Self {
directory,
no_subdirs,
..self
})
}
pub fn count(self, count: usize) -> Self {
Self { count, ..self }
}
pub fn command(self, command: Option<String>, command_text: Option<Regex>) -> Self {
Self {
command,
command_text,
..self
}
}
pub fn filter_entries(&self, entries: Vec<Entry>) -> Result<Vec<Entry>, Error> {
let entries = entries
.into_iter()
.filter(|entry| {
self.command
.as_ref()
.map_or(true, |command| entry.command.starts_with(command))
})
.filter(|entry| {
self.directory.as_ref().map_or(true, |dir| {
if self.no_subdirs {
entry.pwd == *dir
} else {
entry.pwd.as_path().starts_with(dir)
}
})
})
.filter(|entry| {
self.command_text
.as_ref()
.map_or(true, |regex| regex.is_match(&entry.command))
})
.collect::<Vec<_>>()
.into_iter()
.rev()
.take(self.count)
.rev()
.collect();
Ok(entries)
}
}
pub fn get_entries(
&self,
hostname: Option<String>,
count: usize,
command_filter: &Option<String>,
dir_filter: &Option<PathBuf>,
no_subdirs: bool,
command_text: &Option<Regex>,
) -> Result<Vec<Entry>, Error> {
let mut entries: Vec<_> = if let Some(hostname) = hostname {
pub fn get_entries(&self, filter: &Filter) -> Result<Vec<Entry>, Error> {
let mut entries: Vec<_> = if let Some(hostname) = filter.get_hostname() {
let entries = entries
.into_iter()
.filter(|entry| {
command_filter
.as_ref()
.map_or(true, |command| entry.command.starts_with(command))
})
.filter(|entry| {
dir_filter.as_ref().map_or(true, |dir| {
if no_subdirs {
entry.pwd == *dir
} else {
entry.pwd.as_path().starts_with(dir)
}
})
})
.filter(|entry| {
command_text
.as_ref()
.map_or(true, |regex| regex.is_match(&entry.command))
})
.collect::<Vec<_>>()
.into_iter()
.rev()
.take(count)
.rev()
.collect();
let entries = filter.filter_entries(entries)?;