mirror of
https://github.com/eza-community/eza.git
synced 2025-12-23 05:36:50 +00:00
feat(mercurial): Implemented mercurial cache
PLEASE WAIT FOR LATER COMMITS THIS ONLY WORK ON MY MACHINE feat(mercurial): displaying the info in columns and feature flagging feat(mercurial): feat finished this is not prod ready feat(ignoring): adding the ability to ignore docs: add documentation for mercurial options chore: styling
This commit is contained in:
parent
27edee1e7d
commit
9ae60d1a2b
29 changed files with 525 additions and 31 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
|
@ -394,6 +394,7 @@ dependencies = [
|
|||
"criterion",
|
||||
"git2",
|
||||
"glob",
|
||||
"hgrs",
|
||||
"libc",
|
||||
"locale",
|
||||
"log",
|
||||
|
|
@ -489,6 +490,14 @@ version = "0.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
|
||||
|
||||
[[package]]
|
||||
name = "hgrs"
|
||||
version = "0.2.5"
|
||||
source = "git+https://github.com/MartinFillon/hgrs.git#b28fef5f9801c4705cd524673fa8bc155d66c1a9"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ timeago = { version = "0.4.2", default-features = false }
|
|||
unicode-width = "0.1"
|
||||
zoneinfo_compiled = "0.5.1"
|
||||
|
||||
[dependencies.hgrs]
|
||||
git = "https://github.com/MartinFillon/hgrs.git"
|
||||
version = "0.2.5"
|
||||
optional = true
|
||||
|
||||
[dependencies.git2]
|
||||
version = "0.18"
|
||||
optional = true
|
||||
|
|
@ -129,6 +134,7 @@ nix-local = []
|
|||
# Shouldn't ever be used in CI (slow!)
|
||||
powertest = []
|
||||
nix-generated = []
|
||||
mercurial = ["hgrs"]
|
||||
|
||||
# use LTO for smaller binaries (that take longer to build)
|
||||
[profile.release]
|
||||
|
|
|
|||
|
|
@ -143,6 +143,9 @@ These options are available when running with `--long` (`-l`):
|
|||
- **--no-user**: suppress the user field
|
||||
- **--no-time**: suppress the time field
|
||||
- **--stdin**: read file names from stdin
|
||||
- **--mercurial**: list each file’s Mercurial status, if tracked or ignored
|
||||
- **--mercurial-ignore**: ignore files ignored by Mercurial
|
||||
- **--no-mercurial**: suppress Mercurial status (always overrides `--mercurial`, `--mercurial-ignore`)
|
||||
|
||||
Some of the options accept parameters:
|
||||
|
||||
|
|
|
|||
|
|
@ -121,3 +121,6 @@ complete -c eza -l git-repos -d "List each git-repos status and branch name"
|
|||
complete -c eza -l git-repos-no-status -d "List each git-repos branch name (much faster)"
|
||||
complete -c eza -s '@' -l extended -d "List each file's extended attributes and sizes"
|
||||
complete -c eza -s Z -l context -d "List each file's security context"
|
||||
complete -c eza -l mercurial -d "List each file's Mercurial status, if tracked"
|
||||
complete -c eza -l mercurial-ignore -d "Ignore files that are ignored by Mercurial"
|
||||
complete -c eza -l no-mercurial -d "Suppress Mercurial status"
|
||||
|
|
|
|||
|
|
@ -59,4 +59,7 @@ export extern "eza" [
|
|||
--context(-Z) # List each file's security context
|
||||
--smart-group # Only show group if it has a different name from owner
|
||||
--stdin # When piping to eza. Read file paths from stdin
|
||||
--mercurial # List each file's Mercurial status, if tracked
|
||||
--mercurial-ignore # Ignore files ignored ly Mercurial
|
||||
--no-mercurial # Suppress Mercurial status
|
||||
]
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ __eza() {
|
|||
'*:filename:_files' \
|
||||
--smart-group"[Only show group if it has a different name from owner]" \
|
||||
--stdin"[When piping to eza. Read file names from stdin]"
|
||||
--mercurial"[List each file's Mercurial status, if tracked]" \
|
||||
--mercurial-ignore"[Ignore files ignored by Mercurial]" \
|
||||
--no-mercurial"[Suppress Mercurial status]" \
|
||||
}
|
||||
|
||||
__eza
|
||||
|
|
|
|||
11
man/eza.1.md
11
man/eza.1.md
|
|
@ -269,6 +269,17 @@ All Git repository directories will be shown as (themed) `-` without status indi
|
|||
`--no-git`
|
||||
: Don't show Git status (always overrides `--git`, `--git-repos`, `--git-repos-no-status`)
|
||||
|
||||
`--mercurial` [if eza was built with mercurial support]
|
||||
: List each file’s Mercurial status, if tracked.
|
||||
hg command Needed !!! This adds a character column indicating status. The status character can be ‘`-`’ for not directories, ‘`M`’ for a modified file, ‘`A`’ for a added file, ‘`R`’ for deleted, ‘`C`’ for cleaned, ‘`!`’ for missing, ‘`I`’ for ignored.
|
||||
|
||||
`--mercurial-ignore` [if eza was built with mercurial support]
|
||||
: Do not list files that are ignored by Mercurial.
|
||||
hg command Needed !!!
|
||||
|
||||
`--no-mercurial` [if eza was built with mercurial support]
|
||||
: Don't show Mercurial status (always overrides `--mercurial`, `--mercurial-ignore`)
|
||||
hg command Needed !!!
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
=====================
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use crate::fs::feature::git::GitCache;
|
||||
use crate::fs::fields::GitStatus;
|
||||
use crate::fs::fields::{GitStatus, MercurialStatus};
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::slice::Iter as SliceIter;
|
||||
|
||||
use crate::fs::feature::mercurial::MercurialCache;
|
||||
use log::*;
|
||||
|
||||
use crate::fs::File;
|
||||
|
|
@ -52,6 +53,8 @@ impl Dir {
|
|||
git_ignoring: bool,
|
||||
deref_links: bool,
|
||||
total_size: bool,
|
||||
mercurial: Option<&'ig MercurialCache>,
|
||||
mercurial_ignore: bool,
|
||||
) -> Files<'dir, 'ig> {
|
||||
Files {
|
||||
inner: self.contents.iter(),
|
||||
|
|
@ -62,6 +65,8 @@ impl Dir {
|
|||
git_ignoring,
|
||||
deref_links,
|
||||
total_size,
|
||||
mercurial,
|
||||
mercurial_ignore,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,6 +106,10 @@ pub struct Files<'dir, 'ig> {
|
|||
|
||||
/// Whether to calculate the directory size recursively
|
||||
total_size: bool,
|
||||
|
||||
mercurial: Option<&'ig MercurialCache>,
|
||||
|
||||
mercurial_ignore: bool,
|
||||
}
|
||||
|
||||
impl<'dir, 'ig> Files<'dir, 'ig> {
|
||||
|
|
@ -137,6 +146,13 @@ impl<'dir, 'ig> Files<'dir, 'ig> {
|
|||
}
|
||||
}
|
||||
|
||||
if self.mercurial_ignore {
|
||||
let mercurial_status = self.mercurial.map(|g| g.get(path)).unwrap_or_default();
|
||||
if mercurial_status.status == MercurialStatus::Ignored {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let file = File::from_args(
|
||||
path.clone(),
|
||||
self.dir,
|
||||
|
|
|
|||
80
src/fs/feature/mercurial.rs
Normal file
80
src/fs/feature/mercurial.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
use hgrs::{FileStatus, MercurialRepository};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::fs::fields as f;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MercurialCache {
|
||||
pub repos: Vec<MercurialRepo>,
|
||||
|
||||
pub misses: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl MercurialCache {
|
||||
pub fn get(&self, file_path: &PathBuf) -> f::Mercurial {
|
||||
f::Mercurial {
|
||||
status: self
|
||||
.repos
|
||||
.iter()
|
||||
.find(|r| r.has_path(file_path))
|
||||
.map(|r| r.get(file_path))
|
||||
.unwrap_or_default()
|
||||
.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromIterator<PathBuf> for MercurialCache {
|
||||
fn from_iter<T: IntoIterator<Item = PathBuf>>(iter: T) -> Self {
|
||||
let iter = iter.into_iter();
|
||||
let mut mercurial = Self {
|
||||
repos: Vec::with_capacity(iter.size_hint().0),
|
||||
misses: Vec::new(),
|
||||
};
|
||||
|
||||
for path in iter {
|
||||
match MercurialRepo::discover(&path) {
|
||||
Ok(repo) => mercurial.repos.push(repo),
|
||||
Err(path) => mercurial.misses.push(path),
|
||||
}
|
||||
}
|
||||
mercurial
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MercurialRepo {
|
||||
pub repo: MercurialRepository,
|
||||
pub path: PathBuf,
|
||||
pub extra_paths: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
impl MercurialRepo {
|
||||
pub fn get(&self, file_path: &PathBuf) -> FileStatus {
|
||||
self.repo.get_status(file_path)
|
||||
}
|
||||
|
||||
pub fn has_path(&self, file_path: &PathBuf) -> bool {
|
||||
let dir = file_path.parent().unwrap();
|
||||
|
||||
if dir == self.path {
|
||||
return true;
|
||||
}
|
||||
if self.extra_paths.contains(&dir.into()) {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn discover(path: &PathBuf) -> Result<Self, PathBuf> {
|
||||
let r = match hgrs::find_repo_recursively(path, 10) {
|
||||
Some(r) => r,
|
||||
None => return Err(path.clone()),
|
||||
};
|
||||
Ok(Self {
|
||||
repo: r,
|
||||
path: path.into(),
|
||||
extra_paths: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,39 @@ pub mod xattr;
|
|||
#[cfg(feature = "git")]
|
||||
pub mod git;
|
||||
|
||||
#[cfg(feature = "mercurial")]
|
||||
pub mod mercurial;
|
||||
|
||||
#[cfg(not(feature = "mercurial"))]
|
||||
pub mod mercurial {
|
||||
|
||||
use std::iter::FromIterator;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::fs::fields as f;
|
||||
|
||||
pub struct MercurialCache;
|
||||
|
||||
impl FromIterator<PathBuf> for MercurialCache {
|
||||
fn from_iter<I>(_iter: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = PathBuf>,
|
||||
{
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl MercurialCache {
|
||||
pub fn has_anything_for(&self, _index: &Path) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn get(&self, _index: &Path) -> f::Mercurial {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "git"))]
|
||||
pub mod git {
|
||||
use std::iter::FromIterator;
|
||||
|
|
|
|||
|
|
@ -246,6 +246,46 @@ impl Default for Git {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone)]
|
||||
pub enum MercurialStatus {
|
||||
Modified,
|
||||
Added,
|
||||
Removed,
|
||||
Clean,
|
||||
Missing,
|
||||
NotTracked,
|
||||
Ignored,
|
||||
Directory,
|
||||
}
|
||||
|
||||
#[cfg(feature = "mercurial")]
|
||||
impl From<hgrs::FileStatus> for MercurialStatus {
|
||||
fn from(value: hgrs::FileStatus) -> Self {
|
||||
match value {
|
||||
hgrs::FileStatus::Modified => MercurialStatus::Modified,
|
||||
hgrs::FileStatus::Added => MercurialStatus::Added,
|
||||
hgrs::FileStatus::Removed => MercurialStatus::Removed,
|
||||
hgrs::FileStatus::Clean => MercurialStatus::Clean,
|
||||
hgrs::FileStatus::Missing => MercurialStatus::Missing,
|
||||
hgrs::FileStatus::NotTracked => MercurialStatus::NotTracked,
|
||||
hgrs::FileStatus::Ignored => MercurialStatus::Ignored,
|
||||
hgrs::FileStatus::Directory => MercurialStatus::Directory,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Mercurial {
|
||||
pub status: MercurialStatus,
|
||||
}
|
||||
|
||||
impl Default for Mercurial {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
status: MercurialStatus::NotTracked,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum SecurityContextType<'a> {
|
||||
SELinux(&'a str),
|
||||
None,
|
||||
|
|
|
|||
|
|
@ -593,7 +593,15 @@ impl<'dir> File<'dir> {
|
|||
let mut size = 0;
|
||||
let mut blocks = 0;
|
||||
for file in dir
|
||||
.files(super::DotFilter::Dotfiles, None, false, false, true)
|
||||
.files(
|
||||
super::DotFilter::Dotfiles,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.flatten()
|
||||
{
|
||||
match file.recursive_directory_size() {
|
||||
|
|
@ -695,7 +703,15 @@ impl<'dir> File<'dir> {
|
|||
match Dir::read_dir(self.path.clone()) {
|
||||
// . & .. are skipped, if the returned iterator has .next(), it's not empty
|
||||
Ok(has_files) => has_files
|
||||
.files(super::DotFilter::Dotfiles, None, false, false, false)
|
||||
.files(
|
||||
super::DotFilter::Dotfiles,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
false,
|
||||
)
|
||||
.next()
|
||||
.is_none(),
|
||||
Err(_) => false,
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ pub struct FileFilter {
|
|||
|
||||
/// Whether to ignore Git-ignored patterns.
|
||||
pub git_ignore: GitIgnore,
|
||||
|
||||
/// Whether to ignore Mercurial-ignored patterns.
|
||||
pub mercurial_ignore: MercurialIgnore,
|
||||
}
|
||||
|
||||
impl FileFilter {
|
||||
|
|
@ -354,6 +357,15 @@ pub enum GitIgnore {
|
|||
Off,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Debug, Copy, Clone)]
|
||||
pub enum MercurialIgnore {
|
||||
/// Ignore files that Mercurial would ignore.
|
||||
CheckAndIgnore,
|
||||
|
||||
/// Display files, even if Mercurial would ignore them.
|
||||
Off,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_ignores {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![allow(clippy::too_many_arguments)]
|
||||
#[allow(unused)]
|
||||
pub mod fs;
|
||||
#[allow(unused)]
|
||||
|
|
|
|||
36
src/main.rs
36
src/main.rs
|
|
@ -20,6 +20,8 @@
|
|||
#![allow(clippy::unused_self)]
|
||||
#![allow(clippy::upper_case_acronyms)]
|
||||
#![allow(clippy::wildcard_imports)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
#![allow(clippy::fn_params_excessive_bools)]
|
||||
|
||||
use std::env;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
|
|
@ -30,7 +32,8 @@ use std::process::exit;
|
|||
use ansiterm::{ANSIStrings, Style};
|
||||
|
||||
use crate::fs::feature::git::GitCache;
|
||||
use crate::fs::filter::GitIgnore;
|
||||
use crate::fs::feature::mercurial::MercurialCache;
|
||||
use crate::fs::filter::{GitIgnore, MercurialIgnore};
|
||||
use crate::fs::{Dir, File};
|
||||
use crate::options::stdin::FilesInput;
|
||||
use crate::options::{vars, Options, OptionsResult, Vars};
|
||||
|
|
@ -87,6 +90,7 @@ fn main() {
|
|||
}
|
||||
|
||||
let git = git_options(&options, &input_paths);
|
||||
let mercurial = mercurial_options(&options, &input_paths);
|
||||
let writer = io::stdout();
|
||||
let git_repos = git_repos(&options, &input_paths);
|
||||
|
||||
|
|
@ -100,6 +104,7 @@ fn main() {
|
|||
console_width,
|
||||
git,
|
||||
git_repos,
|
||||
mercurial,
|
||||
};
|
||||
|
||||
info!("matching on exa.run");
|
||||
|
|
@ -169,6 +174,8 @@ pub struct Exa<'args> {
|
|||
pub git: Option<GitCache>,
|
||||
|
||||
pub git_repos: bool,
|
||||
|
||||
pub mercurial: Option<MercurialCache>,
|
||||
}
|
||||
|
||||
/// The “real” environment variables type.
|
||||
|
|
@ -191,6 +198,14 @@ fn git_options(options: &Options, args: &[&OsStr]) -> Option<GitCache> {
|
|||
}
|
||||
}
|
||||
|
||||
fn mercurial_options(options: &Options, args: &[&OsStr]) -> Option<MercurialCache> {
|
||||
if options.should_scan_for_mercurial() {
|
||||
Some(args.iter().map(PathBuf::from).collect())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "git"))]
|
||||
fn git_repos(_options: &Options, _args: &[&OsStr]) -> bool {
|
||||
return false;
|
||||
|
|
@ -332,12 +347,16 @@ impl<'args> Exa<'args> {
|
|||
|
||||
let mut children = Vec::new();
|
||||
let git_ignore = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
|
||||
let mercurial_ignore =
|
||||
self.options.filter.mercurial_ignore == MercurialIgnore::CheckAndIgnore;
|
||||
for file in dir.files(
|
||||
self.options.filter.dot_filter,
|
||||
self.git.as_ref(),
|
||||
git_ignore,
|
||||
self.options.view.deref_links,
|
||||
self.options.view.total_size,
|
||||
self.mercurial.as_ref(),
|
||||
mercurial_ignore,
|
||||
) {
|
||||
match file {
|
||||
Ok(file) => children.push(file),
|
||||
|
|
@ -427,7 +446,10 @@ impl<'args> Exa<'args> {
|
|||
let recurse = self.options.dir_action.recurse_options();
|
||||
|
||||
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
|
||||
let mercurial_ignoring =
|
||||
self.options.filter.mercurial_ignore == MercurialIgnore::CheckAndIgnore;
|
||||
let git = self.git.as_ref();
|
||||
let mercurial = self.mercurial.as_ref();
|
||||
let git_repos = self.git_repos;
|
||||
let r = details::Render {
|
||||
dir,
|
||||
|
|
@ -440,6 +462,8 @@ impl<'args> Exa<'args> {
|
|||
git_ignoring,
|
||||
git,
|
||||
git_repos,
|
||||
mercurial,
|
||||
mercurial_ignoring,
|
||||
};
|
||||
r.render(&mut self.writer)
|
||||
}
|
||||
|
|
@ -451,7 +475,10 @@ impl<'args> Exa<'args> {
|
|||
|
||||
let filter = &self.options.filter;
|
||||
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
|
||||
let mercurial_ignoring =
|
||||
self.options.filter.mercurial_ignore == MercurialIgnore::CheckAndIgnore;
|
||||
let git = self.git.as_ref();
|
||||
let mercurial = self.mercurial.as_ref();
|
||||
let git_repos = self.git_repos;
|
||||
|
||||
let r = grid_details::Render {
|
||||
|
|
@ -467,6 +494,8 @@ impl<'args> Exa<'args> {
|
|||
git,
|
||||
console_width,
|
||||
git_repos,
|
||||
mercurial,
|
||||
mercurial_ignoring,
|
||||
};
|
||||
r.render(&mut self.writer)
|
||||
}
|
||||
|
|
@ -476,7 +505,10 @@ impl<'args> Exa<'args> {
|
|||
let filter = &self.options.filter;
|
||||
let recurse = self.options.dir_action.recurse_options();
|
||||
let git_ignoring = self.options.filter.git_ignore == GitIgnore::CheckAndIgnore;
|
||||
let mercurial_ignoring =
|
||||
self.options.filter.mercurial_ignore == MercurialIgnore::CheckAndIgnore;
|
||||
let git = self.git.as_ref();
|
||||
let mercurial = self.mercurial.as_ref();
|
||||
let git_repos = self.git_repos;
|
||||
|
||||
let r = details::Render {
|
||||
|
|
@ -490,6 +522,8 @@ impl<'args> Exa<'args> {
|
|||
git_ignoring,
|
||||
git,
|
||||
git_repos,
|
||||
mercurial,
|
||||
mercurial_ignoring,
|
||||
};
|
||||
r.render(&mut self.writer)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Parsing the options for `FileFilter`.
|
||||
|
||||
use crate::fs::filter::{
|
||||
FileFilter, FileFilterFlags, GitIgnore, IgnorePatterns, SortCase, SortField,
|
||||
FileFilter, FileFilterFlags, GitIgnore, IgnorePatterns, MercurialIgnore, SortCase, SortField,
|
||||
};
|
||||
use crate::fs::DotFilter;
|
||||
|
||||
|
|
@ -32,6 +32,7 @@ impl FileFilter {
|
|||
dot_filter: DotFilter::deduce(matches)?,
|
||||
ignore_patterns: IgnorePatterns::deduce(matches)?,
|
||||
git_ignore: GitIgnore::deduce(matches)?,
|
||||
mercurial_ignore: MercurialIgnore::deduce(matches)?,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -193,6 +194,16 @@ impl GitIgnore {
|
|||
}
|
||||
}
|
||||
|
||||
impl MercurialIgnore {
|
||||
pub fn deduce(matches: &MatchedFlags<'_>) -> Result<Self, OptionsError> {
|
||||
if matches.has(&flags::MERCURIAL_IGNORE)? {
|
||||
Ok(Self::CheckAndIgnore)
|
||||
} else {
|
||||
Ok(Self::Off)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ pub static OCTAL: Arg = Arg { short: Some(b'o'), long: "octal-permis
|
|||
pub static SECURITY_CONTEXT: Arg = Arg { short: Some(b'Z'), long: "context", takes_value: TakesValue::Forbidden };
|
||||
pub static STDIN: Arg = Arg { short: None, long: "stdin", takes_value: TakesValue::Forbidden };
|
||||
pub static FILE_FLAGS: Arg = Arg { short: Some(b'O'), long: "flags", takes_value: TakesValue::Forbidden };
|
||||
pub static MERCURIAL: Arg = Arg { short: None, long: "mercurial", takes_value: TakesValue::Forbidden };
|
||||
pub static NO_MERCURIAL: Arg = Arg { short: None, long: "no-mercurial", takes_value: TakesValue::Forbidden };
|
||||
pub static MERCURIAL_IGNORE: Arg = Arg { short: None, long: "mercurial-ignore", takes_value: TakesValue::Forbidden };
|
||||
|
||||
pub static ALL_ARGS: Args = Args(&[
|
||||
&VERSION, &HELP,
|
||||
|
|
@ -98,5 +101,6 @@ pub static ALL_ARGS: Args = Args(&[
|
|||
&NO_PERMISSIONS, &NO_FILESIZE, &NO_USER, &NO_TIME, &SMART_GROUP,
|
||||
|
||||
&GIT, &NO_GIT, &GIT_REPOS, &GIT_REPOS_NO_STAT,
|
||||
&EXTENDED, &OCTAL, &SECURITY_CONTEXT, &STDIN, &FILE_FLAGS
|
||||
&EXTENDED, &OCTAL, &SECURITY_CONTEXT, &STDIN, &FILE_FLAGS,
|
||||
&MERCURIAL, &NO_MERCURIAL, &MERCURIAL_IGNORE,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -90,6 +90,11 @@ static EXTENDED_HELP: &str = " \
|
|||
static SECATTR_HELP: &str = " \
|
||||
-Z, --context list each file's security context";
|
||||
|
||||
static MERCURIAL_HELP: &str = " \
|
||||
--mercurial list each file's Mercurial status (hg command needed) \
|
||||
--no-mercurial ignore ignored files in Mercurial (hg command needed) \
|
||||
--no-mercurial suppress Mercurial status (always overrides --mercurial)";
|
||||
|
||||
/// All the information needed to display the help text, which depends
|
||||
/// on which features are enabled and whether the user only wants to
|
||||
/// see one section’s help.
|
||||
|
|
@ -129,6 +134,10 @@ impl fmt::Display for HelpString {
|
|||
write!(f, "\n{GIT_VIEW_HELP}")?;
|
||||
}
|
||||
|
||||
if cfg!(feature = "mercurial") {
|
||||
write!(f, "\n{MERCURIAL_HELP}")?;
|
||||
}
|
||||
|
||||
if xattr::ENABLED {
|
||||
write!(f, "\n{EXTENDED_HELP}")?;
|
||||
write!(f, "\n{SECATTR_HELP}")?;
|
||||
|
|
|
|||
|
|
@ -188,6 +188,24 @@ impl Options {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn should_scan_for_mercurial(&self) -> bool {
|
||||
match self.view.mode {
|
||||
Mode::Details(details::Options {
|
||||
table: Some(ref table),
|
||||
..
|
||||
})
|
||||
| Mode::GridDetails(grid_details::Options {
|
||||
details:
|
||||
details::Options {
|
||||
table: Some(ref table),
|
||||
..
|
||||
},
|
||||
..
|
||||
}) => table.columns.mercurial,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Determines the complete set of options based on the given command-line
|
||||
/// arguments, after they’ve been parsed.
|
||||
fn deduce<V: Vars>(matches: &MatchedFlags<'_>, vars: &V) -> Result<Self, OptionsError> {
|
||||
|
|
@ -201,6 +219,16 @@ impl Options {
|
|||
)));
|
||||
}
|
||||
|
||||
if cfg!(not(feature = "mercurial"))
|
||||
&& matches
|
||||
.has_where_any(|f| f.matches(&flags::MERCURIAL) || f.matches(&flags::NO_MERCURIAL))
|
||||
.is_some()
|
||||
{
|
||||
return Err(OptionsError::Unsupported(String::from(
|
||||
"Options --mercurial and --no-mercurial can't be used because `mercurial` feature is not enabled in this build of exa"
|
||||
)));
|
||||
}
|
||||
|
||||
let view = View::deduce(matches, vars)?;
|
||||
let dir_action = DirAction::deduce(matches, matches!(view.mode, Mode::Details(_)))?;
|
||||
let filter = FileFilter::deduce(matches)?;
|
||||
|
|
|
|||
|
|
@ -266,6 +266,8 @@ impl Columns {
|
|||
&& !matches.has(&flags::NO_GIT)?
|
||||
&& !no_git_env;
|
||||
|
||||
let mercurial = matches.has(&flags::MERCURIAL)? && !matches.has(&flags::NO_MERCURIAL)?;
|
||||
|
||||
let blocksize = matches.has(&flags::BLOCKSIZE)?;
|
||||
let group = matches.has(&flags::GROUP)?;
|
||||
let inode = matches.has(&flags::INODE)?;
|
||||
|
|
@ -285,6 +287,7 @@ impl Columns {
|
|||
blocksize,
|
||||
group,
|
||||
git,
|
||||
mercurial,
|
||||
subdir_git_repos,
|
||||
subdir_git_repos_no_stat,
|
||||
octal,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use ansiterm::{Colour, Style};
|
|||
use log::trace;
|
||||
use palette::{FromColor, Oklab, Srgb};
|
||||
|
||||
use crate::fs::feature::mercurial::MercurialCache;
|
||||
use crate::{
|
||||
fs::{dir_action::RecurseOptions, feature::git::GitCache, fields::Size, DotFilter, File},
|
||||
output::{table::TimeType, tree::TreeDepth},
|
||||
|
|
@ -42,6 +43,8 @@ impl ColorScaleInformation {
|
|||
git: Option<&GitCache>,
|
||||
git_ignoring: bool,
|
||||
r: Option<RecurseOptions>,
|
||||
mercurial: Option<&MercurialCache>,
|
||||
mercurial_ignoring: bool,
|
||||
) -> Option<Self> {
|
||||
if color_scale.mode == ColorScaleMode::Fixed {
|
||||
None
|
||||
|
|
@ -63,6 +66,8 @@ impl ColorScaleInformation {
|
|||
git_ignoring,
|
||||
TreeDepth::root(),
|
||||
r,
|
||||
mercurial,
|
||||
mercurial_ignoring,
|
||||
);
|
||||
|
||||
Some(information)
|
||||
|
|
@ -110,6 +115,8 @@ fn update_information_recursively(
|
|||
git_ignoring: bool,
|
||||
depth: TreeDepth,
|
||||
r: Option<RecurseOptions>,
|
||||
mercurial: Option<&MercurialCache>,
|
||||
mercurial_ignoring: bool,
|
||||
) {
|
||||
for file in files {
|
||||
if information.options.age {
|
||||
|
|
@ -143,7 +150,15 @@ fn update_information_recursively(
|
|||
match file.to_dir() {
|
||||
Ok(dir) => {
|
||||
let files: Vec<File<'_>> = dir
|
||||
.files(dot_filter, git, git_ignoring, false, false)
|
||||
.files(
|
||||
dot_filter,
|
||||
git,
|
||||
git_ignoring,
|
||||
false,
|
||||
false,
|
||||
mercurial,
|
||||
mercurial_ignoring,
|
||||
)
|
||||
.flatten()
|
||||
.collect();
|
||||
|
||||
|
|
@ -155,6 +170,8 @@ fn update_information_recursively(
|
|||
git_ignoring,
|
||||
depth.deeper(),
|
||||
r,
|
||||
mercurial,
|
||||
mercurial_ignoring,
|
||||
);
|
||||
}
|
||||
Err(e) => trace!("Unable to access directory {}: {}", file.name, e),
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ use log::*;
|
|||
|
||||
use crate::fs::dir_action::RecurseOptions;
|
||||
use crate::fs::feature::git::GitCache;
|
||||
use crate::fs::feature::mercurial::MercurialCache;
|
||||
use crate::fs::feature::xattr::Attribute;
|
||||
use crate::fs::fields::SecurityContextType;
|
||||
use crate::fs::filter::FileFilter;
|
||||
|
|
@ -139,6 +140,10 @@ pub struct Render<'a> {
|
|||
pub git: Option<&'a GitCache>,
|
||||
|
||||
pub git_repos: bool,
|
||||
|
||||
pub mercurial: Option<&'a MercurialCache>,
|
||||
|
||||
pub mercurial_ignoring: bool,
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
|
|
@ -172,6 +177,8 @@ impl<'a> Render<'a> {
|
|||
self.git,
|
||||
self.git_ignoring,
|
||||
self.recurse,
|
||||
self.mercurial,
|
||||
self.mercurial_ignoring,
|
||||
);
|
||||
|
||||
if let Some(ref table) = self.opts.table {
|
||||
|
|
@ -189,7 +196,7 @@ impl<'a> Render<'a> {
|
|||
(None, _) => { /* Keep Git how it is */ }
|
||||
}
|
||||
|
||||
let mut table = Table::new(table, self.git, self.theme, self.git_repos);
|
||||
let mut table = Table::new(table, self.git, self.theme, self.git_repos, self.mercurial);
|
||||
|
||||
if self.opts.header {
|
||||
let header = table.header_row();
|
||||
|
|
@ -365,6 +372,8 @@ impl<'a> Render<'a> {
|
|||
self.git_ignoring,
|
||||
egg.file.deref_links,
|
||||
egg.file.is_recursive_size(),
|
||||
self.mercurial,
|
||||
self.mercurial_ignoring,
|
||||
) {
|
||||
match file_to_add {
|
||||
Ok(f) => {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use ansiterm::ANSIStrings;
|
|||
use term_grid as grid;
|
||||
|
||||
use crate::fs::feature::git::GitCache;
|
||||
use crate::fs::feature::mercurial::MercurialCache;
|
||||
use crate::fs::filter::FileFilter;
|
||||
use crate::fs::{Dir, File};
|
||||
use crate::output::cell::{DisplayWidth, TextCell};
|
||||
|
|
@ -90,6 +91,10 @@ pub struct Render<'a> {
|
|||
pub console_width: usize,
|
||||
|
||||
pub git_repos: bool,
|
||||
|
||||
pub mercurial: Option<&'a MercurialCache>,
|
||||
|
||||
pub mercurial_ignoring: bool,
|
||||
}
|
||||
|
||||
impl<'a> Render<'a> {
|
||||
|
|
@ -102,16 +107,18 @@ impl<'a> Render<'a> {
|
|||
fn details_for_column(&self) -> DetailsRender<'a> {
|
||||
#[rustfmt::skip]
|
||||
return DetailsRender {
|
||||
dir: self.dir,
|
||||
files: Vec::new(),
|
||||
theme: self.theme,
|
||||
file_style: self.file_style,
|
||||
opts: self.details,
|
||||
recurse: None,
|
||||
filter: self.filter,
|
||||
git_ignoring: self.git_ignoring,
|
||||
git: self.git,
|
||||
git_repos: self.git_repos,
|
||||
dir: self.dir,
|
||||
files: Vec::new(),
|
||||
theme: self.theme,
|
||||
file_style: self.file_style,
|
||||
opts: self.details,
|
||||
recurse: None,
|
||||
filter: self.filter,
|
||||
git_ignoring: self.git_ignoring,
|
||||
git: self.git,
|
||||
git_repos: self.git_repos,
|
||||
mercurial: self.mercurial,
|
||||
mercurial_ignoring: self.mercurial_ignoring,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -122,16 +129,18 @@ impl<'a> Render<'a> {
|
|||
pub fn give_up(self) -> DetailsRender<'a> {
|
||||
#[rustfmt::skip]
|
||||
return DetailsRender {
|
||||
dir: self.dir,
|
||||
files: self.files,
|
||||
theme: self.theme,
|
||||
file_style: self.file_style,
|
||||
opts: self.details,
|
||||
recurse: None,
|
||||
filter: self.filter,
|
||||
git_ignoring: self.git_ignoring,
|
||||
git: self.git,
|
||||
git_repos: self.git_repos,
|
||||
dir: self.dir,
|
||||
files: self.files,
|
||||
theme: self.theme,
|
||||
file_style: self.file_style,
|
||||
opts: self.details,
|
||||
recurse: None,
|
||||
filter: self.filter,
|
||||
git_ignoring: self.git_ignoring,
|
||||
git: self.git,
|
||||
git_repos: self.git_repos,
|
||||
mercurial: self.mercurial,
|
||||
mercurial_ignoring: self.mercurial_ignoring,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +171,8 @@ impl<'a> Render<'a> {
|
|||
self.git,
|
||||
self.git_ignoring,
|
||||
None,
|
||||
self.mercurial,
|
||||
self.mercurial_ignoring,
|
||||
);
|
||||
|
||||
let (first_table, _) = self.make_table(options, &drender);
|
||||
|
|
@ -275,7 +286,13 @@ impl<'a> Render<'a> {
|
|||
(None, _) => { /* Keep Git how it is */ }
|
||||
}
|
||||
|
||||
let mut table = Table::new(options, self.git, self.theme, self.git_repos);
|
||||
let mut table = Table::new(
|
||||
options,
|
||||
self.git,
|
||||
self.theme,
|
||||
self.git_repos,
|
||||
self.mercurial,
|
||||
);
|
||||
let mut rows = Vec::new();
|
||||
|
||||
if self.details.header {
|
||||
|
|
|
|||
34
src/output/render/mercurial.rs
Normal file
34
src/output/render/mercurial.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use crate::fs::fields as f;
|
||||
use crate::fs::fields::MercurialStatus;
|
||||
use crate::output::{DisplayWidth, TextCell};
|
||||
use ansiterm::Style;
|
||||
|
||||
impl f::Mercurial {
|
||||
pub fn render(self, colours: &dyn MercurialColours) -> TextCell {
|
||||
let status = match self.status {
|
||||
MercurialStatus::Modified => colours.modified().paint("M"),
|
||||
MercurialStatus::Added => colours.added().paint("A"),
|
||||
MercurialStatus::Removed => colours.removed().paint("R"),
|
||||
MercurialStatus::Clean => colours.clean().paint("C"),
|
||||
MercurialStatus::Missing => colours.missing().paint("!"),
|
||||
MercurialStatus::NotTracked => colours.not_tracked().paint("?"),
|
||||
MercurialStatus::Ignored => colours.ignored().paint("I"),
|
||||
MercurialStatus::Directory => colours.ignored().paint("-"),
|
||||
};
|
||||
|
||||
TextCell {
|
||||
width: DisplayWidth::from(1),
|
||||
contents: vec![status].into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MercurialColours {
|
||||
fn modified(&self) -> Style;
|
||||
fn added(&self) -> Style;
|
||||
fn removed(&self) -> Style;
|
||||
fn clean(&self) -> Style;
|
||||
fn missing(&self) -> Style;
|
||||
fn not_tracked(&self) -> Style;
|
||||
fn ignored(&self) -> Style;
|
||||
}
|
||||
|
|
@ -67,3 +67,5 @@ mod flags_windows;
|
|||
target_os = "windows"
|
||||
)))]
|
||||
mod flags;
|
||||
mod mercurial;
|
||||
pub use self::mercurial::MercurialColours;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use once_cell::sync::Lazy;
|
|||
use uzers::UsersCache;
|
||||
|
||||
use crate::fs::feature::git::GitCache;
|
||||
use crate::fs::feature::mercurial::MercurialCache;
|
||||
use crate::fs::{fields as f, File};
|
||||
use crate::options::vars::EZA_WINDOWS_ATTRIBUTES;
|
||||
use crate::options::Vars;
|
||||
|
|
@ -48,6 +49,7 @@ pub struct Columns {
|
|||
pub blocksize: bool,
|
||||
pub group: bool,
|
||||
pub git: bool,
|
||||
pub mercurial: bool,
|
||||
pub subdir_git_repos: bool,
|
||||
pub subdir_git_repos_no_stat: bool,
|
||||
pub octal: bool,
|
||||
|
|
@ -61,7 +63,12 @@ pub struct Columns {
|
|||
}
|
||||
|
||||
impl Columns {
|
||||
pub fn collect(&self, actually_enable_git: bool, git_repos: bool) -> Vec<Column> {
|
||||
pub fn collect(
|
||||
&self,
|
||||
actually_enable_git: bool,
|
||||
git_repos: bool,
|
||||
actually_enable_mercurial: bool,
|
||||
) -> Vec<Column> {
|
||||
let mut columns = Vec::with_capacity(4);
|
||||
|
||||
if self.inode {
|
||||
|
|
@ -139,6 +146,10 @@ impl Columns {
|
|||
columns.push(Column::SubdirGitRepo(false));
|
||||
}
|
||||
|
||||
if self.mercurial && actually_enable_mercurial {
|
||||
columns.push(Column::MercurialStatus);
|
||||
}
|
||||
|
||||
columns
|
||||
}
|
||||
}
|
||||
|
|
@ -161,6 +172,7 @@ pub enum Column {
|
|||
Inode,
|
||||
GitStatus,
|
||||
SubdirGitRepo(bool),
|
||||
MercurialStatus,
|
||||
#[cfg(unix)]
|
||||
Octal,
|
||||
#[cfg(unix)]
|
||||
|
|
@ -219,6 +231,7 @@ impl Column {
|
|||
Self::Inode => "inode",
|
||||
Self::GitStatus => "Git",
|
||||
Self::SubdirGitRepo(_) => "Repo",
|
||||
Self::MercurialStatus => "Mercurial",
|
||||
#[cfg(unix)]
|
||||
Self::Octal => "Octal",
|
||||
#[cfg(unix)]
|
||||
|
|
@ -417,6 +430,7 @@ pub struct Table<'a> {
|
|||
group_format: GroupFormat,
|
||||
flags_format: FlagsFormat,
|
||||
git: Option<&'a GitCache>,
|
||||
mercurial: Option<&'a MercurialCache>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
@ -430,8 +444,11 @@ impl<'a> Table<'a> {
|
|||
git: Option<&'a GitCache>,
|
||||
theme: &'a Theme,
|
||||
git_repos: bool,
|
||||
mercurial: Option<&'a MercurialCache>,
|
||||
) -> Table<'a> {
|
||||
let columns = options.columns.collect(git.is_some(), git_repos);
|
||||
let columns = options
|
||||
.columns
|
||||
.collect(git.is_some(), git_repos, mercurial.is_some());
|
||||
let widths = TableWidths::zero(columns.len());
|
||||
let env = &*ENVIRONMENT;
|
||||
|
||||
|
|
@ -450,6 +467,7 @@ impl<'a> Table<'a> {
|
|||
#[cfg(unix)]
|
||||
group_format: options.group_format,
|
||||
flags_format: options.flags_format,
|
||||
mercurial,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -554,6 +572,7 @@ impl<'a> Table<'a> {
|
|||
Column::FileFlags => file.flags().render(self.theme.ui.flags, self.flags_format),
|
||||
Column::GitStatus => self.git_status(file).render(self.theme),
|
||||
Column::SubdirGitRepo(status) => self.subdir_git_repo(file, status).render(self.theme),
|
||||
Column::MercurialStatus => self.mercurial_status(file).render(self.theme),
|
||||
#[cfg(unix)]
|
||||
Column::Octal => self.octal_permissions(file).render(self.theme.ui.octal),
|
||||
|
||||
|
|
@ -582,6 +601,14 @@ impl<'a> Table<'a> {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn mercurial_status(&self, file: &File<'_>) -> f::Mercurial {
|
||||
debug!("Getting Mercurial status for file {:?}", file.path);
|
||||
|
||||
self.mercurial
|
||||
.map(|m| m.get(&file.path))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn subdir_git_repo(&self, file: &File<'_>, status: bool) -> f::SubdirGitRepo {
|
||||
debug!("Getting subdir repo status for path {:?}", file.path);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,17 @@ impl UiStyles {
|
|||
git_dirty: Yellow.bold(),
|
||||
},
|
||||
|
||||
#[rustfmt::skip]
|
||||
mercurial: Mercurial {
|
||||
modified: Blue.normal(),
|
||||
added: Green.normal(),
|
||||
removed: Red.normal(),
|
||||
clean: Green.normal(),
|
||||
missing: Red.normal(),
|
||||
not_tracked: Red.normal(),
|
||||
ignored: Style::default().dimmed(),
|
||||
},
|
||||
|
||||
security_context: SecurityContext {
|
||||
none: Style::default(),
|
||||
#[rustfmt::skip]
|
||||
|
|
|
|||
|
|
@ -275,6 +275,37 @@ impl render::GitColours for Theme {
|
|||
fn conflicted(&self) -> Style { self.ui.git.conflicted }
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl render::MercurialColours for Theme {
|
||||
fn modified(&self) -> Style {
|
||||
self.ui.mercurial.modified
|
||||
}
|
||||
|
||||
fn added(&self) -> Style {
|
||||
self.ui.mercurial.added
|
||||
}
|
||||
|
||||
fn removed(&self) -> Style {
|
||||
self.ui.mercurial.removed
|
||||
}
|
||||
|
||||
fn clean(&self) -> Style {
|
||||
self.ui.mercurial.clean
|
||||
}
|
||||
|
||||
fn missing(&self) -> Style {
|
||||
self.ui.mercurial.missing
|
||||
}
|
||||
|
||||
fn not_tracked(&self) -> Style {
|
||||
self.ui.mercurial.not_tracked
|
||||
}
|
||||
|
||||
fn ignored(&self) -> Style {
|
||||
self.ui.mercurial.ignored
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
impl render::GitRepoColours for Theme {
|
||||
fn branch_main(&self) -> Style { self.ui.git_repo.branch_main }
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ pub struct UiStyles {
|
|||
pub git_repo: GitRepo,
|
||||
pub security_context: SecurityContext,
|
||||
pub file_type: FileType,
|
||||
pub mercurial: Mercurial,
|
||||
|
||||
pub punctuation: Style, // xx
|
||||
pub date: Style, // da
|
||||
|
|
@ -117,6 +118,18 @@ pub struct Git {
|
|||
pub conflicted: Style, // gc
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
pub struct Mercurial {
|
||||
pub modified: Style, // mm
|
||||
pub added: Style, // ma
|
||||
pub removed: Style, // mr
|
||||
pub clean: Style, // mc
|
||||
pub missing: Style, // mx
|
||||
pub not_tracked: Style, // mn
|
||||
pub ignored: Style, // mi
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||
pub struct GitRepo {
|
||||
|
|
@ -243,6 +256,14 @@ impl UiStyles {
|
|||
"gi" => self.git.ignored = pair.to_style(),
|
||||
"gc" => self.git.conflicted = pair.to_style(),
|
||||
|
||||
"mm" => self.mercurial.modified = pair.to_style(),
|
||||
"ma" => self.mercurial.added = pair.to_style(),
|
||||
"mr" => self.mercurial.removed = pair.to_style(),
|
||||
"mc" => self.mercurial.clean = pair.to_style(),
|
||||
"mx" => self.mercurial.missing = pair.to_style(),
|
||||
"mn" => self.mercurial.not_tracked = pair.to_style(),
|
||||
"mi" => self.mercurial.ignored = pair.to_style(),
|
||||
|
||||
"Gm" => self.git_repo.branch_main = pair.to_style(),
|
||||
"Go" => self.git_repo.branch_other = pair.to_style(),
|
||||
"Gc" => self.git_repo.git_clean = pair.to_style(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue