mirror of
https://github.com/dandavison/delta.git
synced 2024-10-04 03:47:53 +03:00
Compare commits
22 Commits
4d824c20d3
...
98aeecee17
Author | SHA1 | Date | |
---|---|---|---|
|
98aeecee17 | ||
|
c384eed937 | ||
|
7dd279284b | ||
|
9b80e68904 | ||
|
a589ff9deb | ||
|
3f092c7e74 | ||
|
3ccdd2d21f | ||
|
df43b77fa5 | ||
|
c5696757c0 | ||
|
8220cefb3c | ||
|
46c72682d5 | ||
|
a66ac8e182 | ||
|
cba999a99f | ||
|
e1f3e618b7 | ||
|
5363030e96 | ||
|
9830f595b4 | ||
|
b595a2fe01 | ||
|
3a9c7ad296 | ||
|
2d7015c774 | ||
|
329ab6376e | ||
|
ba0bfaf9ec | ||
|
aabfcfe0ef |
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -591,7 +591,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "git-delta"
|
||||
version = "0.18.1"
|
||||
version = "0.18.2"
|
||||
dependencies = [
|
||||
"ansi_colours",
|
||||
"ansi_term",
|
||||
@ -1559,9 +1559,9 @@ checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.11"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
|
||||
checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6"
|
||||
|
||||
[[package]]
|
||||
name = "unsafe-libyaml"
|
||||
|
@ -8,7 +8,7 @@ edition = "2018"
|
||||
homepage = "https://github.com/dandavison/delta"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/dandavison/delta"
|
||||
version = "0.18.1"
|
||||
version = "0.18.2"
|
||||
|
||||
[[bin]]
|
||||
name = "delta"
|
||||
@ -55,7 +55,7 @@ syntect = "5.0.0"
|
||||
sysinfo = { version = "0.29.0", default-features = false, features = [] }
|
||||
terminal-colorsaurus = "0.4.1"
|
||||
unicode-segmentation = "1.10.1"
|
||||
unicode-width = "0.1.10"
|
||||
unicode-width = "=0.1.12"
|
||||
xdg = "2.4.1"
|
||||
|
||||
[lints.rust]
|
||||
|
8
Makefile
8
Makefile
@ -26,12 +26,6 @@ release:
|
||||
version:
|
||||
@grep version Cargo.toml | head -n1 | sed -E 's,.*version = "([^"]+)",\1,'
|
||||
|
||||
hash:
|
||||
@version=$$(make version) && \
|
||||
printf "$$version-tar.gz %s\n" $$(curl -sL https://github.com/dandavison/delta/archive/$$version.tar.gz | sha256sum -) && \
|
||||
printf "delta-$$version-x86_64-apple-darwin.tar.gz %s\n" $$(curl -sL https://github.com/dandavison/delta/releases/download/$$version/delta-$$version-x86_64-apple-darwin.tar.gz | sha256sum -) && \
|
||||
printf "delta-$$version-x86_64-unknown-linux-musl.tar.gz %s\n" $$(curl -sL https://github.com/dandavison/delta/releases/download/$$version/delta-$$version-x86_64-unknown-linux-musl.tar.gz | sha256sum -)
|
||||
|
||||
BENCHMARK_INPUT_FILE = /tmp/delta-benchmark-input.gitdiff
|
||||
BENCHMARK_COMMAND = git log -p 23c292d3f25c67082a2ba315a187268be1a9b0ab
|
||||
benchmark: build
|
||||
@ -47,4 +41,4 @@ flamegraph: build
|
||||
chronologer:
|
||||
chronologer etc/performance/chronologer.yaml
|
||||
|
||||
.PHONY: build format lint test unit-test end-to-end-test release shell-completion version hash benchmark flamegraph chronologer
|
||||
.PHONY: build format lint test unit-test end-to-end-test release shell-completion version benchmark flamegraph chronologer
|
||||
|
@ -32,7 +32,7 @@
|
||||
# light = true
|
||||
|
||||
[merge]
|
||||
conflictstyle = diff3
|
||||
conflictStyle = zdiff3
|
||||
|
||||
[diff]
|
||||
colorMoved = default
|
||||
|
@ -48,10 +48,9 @@ BUMP_VERSION_IN_DOCUMENTATION_LINKS_SENTINEL=.make-sentinels/bump-version-in-doc
|
||||
bump-version-in-documentation-links: $(BUMP_VERSION_IN_DOCUMENTATION_LINKS_SENTINEL)
|
||||
$(BUMP_VERSION_IN_DOCUMENTATION_LINKS_SENTINEL):
|
||||
sed -i -E "s,$$DELTA_OLD_VERSION,$$DELTA_NEW_VERSION,g" manual/src/full---help-output.md manual/src/installation.md
|
||||
rg -qF "$$DELTA_NEW_VERSION" manual/src/full---help-output.md
|
||||
rg -qF "$$DELTA_NEW_VERSION" manual/src/installation.md
|
||||
git add manual/src/full---help-output.md manual/src/installation.md
|
||||
git commit -m "Bump version in links to executables"
|
||||
git commit -m "Link to new binaries"
|
||||
touch $(BUMP_VERSION_IN_DOCUMENTATION_LINKS_SENTINEL)
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
navigate = true
|
||||
|
||||
[merge]
|
||||
conflictstyle = diff3
|
||||
conflictStyle = zdiff3
|
||||
|
||||
[diff]
|
||||
colorMoved = default
|
||||
|
@ -1,13 +1,13 @@
|
||||
# Installation
|
||||
|
||||
You can download an executable for your system:
|
||||
[Linux (glibc)](https://github.com/dandavison/delta/releases/download/0.18.1/delta-0.18.1-x86_64-unknown-linux-gnu.tar.gz)
|
||||
[Linux (glibc)](https://github.com/dandavison/delta/releases/download/0.18.2/delta-0.18.2-x86_64-unknown-linux-gnu.tar.gz)
|
||||
|
|
||||
[Linux (musl)](https://github.com/dandavison/delta/releases/download/0.18.1/delta-0.18.1-x86_64-unknown-linux-musl.tar.gz)
|
||||
[Linux (musl)](https://github.com/dandavison/delta/releases/download/0.18.2/delta-0.18.2-x86_64-unknown-linux-musl.tar.gz)
|
||||
|
|
||||
[MacOS](https://github.com/dandavison/delta/releases/download/0.18.1/delta-0.18.1-x86_64-apple-darwin.tar.gz)
|
||||
[MacOS](https://github.com/dandavison/delta/releases/download/0.18.2/delta-0.18.2-x86_64-apple-darwin.tar.gz)
|
||||
|
|
||||
[Windows](https://github.com/dandavison/delta/releases/download/0.18.1/delta-0.18.1-x86_64-pc-windows-msvc.zip)
|
||||
[Windows](https://github.com/dandavison/delta/releases/download/0.18.2/delta-0.18.2-x86_64-pc-windows-msvc.zip)
|
||||
|
|
||||
[All](https://github.com/dandavison/delta/releases)
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
# Merge conflicts
|
||||
|
||||
Consider setting
|
||||
Consider setting [`merge.conflictStyle`](https://git-scm.com/docs/git-config#Documentation/git-config.txt-mergeconflictStyle) to `zdiff3`:
|
||||
|
||||
```gitconfig
|
||||
[merge]
|
||||
conflictstyle = diff3
|
||||
conflictStyle = zdiff3
|
||||
```
|
||||
|
||||
With that setting, when a merge conflict is encountered, delta will display diffs between the ancestral commit and each of the two merge parents:
|
||||
With that setting, when a merge conflict is encountered, Git will display merge conflicts with the contents of the merge base as well.
|
||||
delta will then display this as two diffs, from the ancestor to each side of the conflict:
|
||||
|
||||
<table><tr><td><img width=500px src="https://user-images.githubusercontent.com/52205/144783121-bb549100-69d8-41b8-ac62-1704f1f7b43e.png" alt="image" /></td></tr></table>
|
||||
|
||||
|
@ -12,4 +12,4 @@ To format file links for opening in VSCode from other terminal emulators, use th
|
||||
|
||||
(To use VSCode Insiders, change that to `vscode-insiders://file/{path}:{line}`).
|
||||
|
||||
See [hyperlinks](./hyperlinks.md).
|
||||
See [hyperlinks](../hyperlinks.md).
|
||||
|
@ -11,6 +11,7 @@ use syntect::highlighting::Theme as SyntaxTheme;
|
||||
use syntect::parsing::SyntaxSet;
|
||||
|
||||
use crate::ansi::{ANSI_SGR_BOLD, ANSI_SGR_RESET, ANSI_SGR_UNDERLINE};
|
||||
use crate::color::ColorMode;
|
||||
use crate::config::delta_unreachable;
|
||||
use crate::env::DeltaEnv;
|
||||
use crate::git_config::GitConfig;
|
||||
@ -411,9 +412,9 @@ pub struct Opt {
|
||||
/// and line numbers link to the local file using a file URL, whereas commit hashes link to the
|
||||
/// commit in GitHub, if the remote repository is hosted by GitHub. See
|
||||
/// --hyperlinks-file-link-format for full control over the file URLs emitted. Hyperlinks are
|
||||
/// supported by several common terminal emulators. To make them work, you must use less version
|
||||
/// >= 581 with the -R flag (or use -r with older less versions, but this will break e.g.
|
||||
/// --navigate). If you use tmux, then you will also need a patched fork of tmux (see
|
||||
/// supported by several common terminal emulators. To make them work, you must use less
|
||||
/// version >= 581 with the -R flag (or use -r with older less versions, but this will break
|
||||
/// e.g. --navigate). If you use tmux, then you will also need a patched fork of tmux (see
|
||||
/// <https://github.com/dandavison/tmux>).
|
||||
pub hyperlinks: bool,
|
||||
|
||||
@ -1180,7 +1181,7 @@ pub struct ComputedValues {
|
||||
pub background_color_extends_to_terminal_width: bool,
|
||||
pub decorations_width: Width,
|
||||
pub inspect_raw_lines: InspectRawLines,
|
||||
pub is_light_mode: bool,
|
||||
pub color_mode: ColorMode,
|
||||
pub paging_mode: PagingMode,
|
||||
pub syntax_set: SyntaxSet,
|
||||
pub syntax_theme: Option<SyntaxTheme>,
|
||||
|
60
src/color.rs
60
src/color.rs
@ -8,6 +8,7 @@ use syntect::highlighting::Color as SyntectColor;
|
||||
use crate::fatal;
|
||||
use crate::git_config::GitConfig;
|
||||
use crate::utils;
|
||||
use ColorMode::*;
|
||||
|
||||
pub fn parse_color(s: &str, true_color: bool, git_config: Option<&GitConfig>) -> Option<Color> {
|
||||
if s == "normal" {
|
||||
@ -105,39 +106,50 @@ fn ansi_16_color_number_to_name(n: u8) -> Option<&'static str> {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_minus_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
|
||||
match (is_light_mode, is_true_color) {
|
||||
(true, true) => LIGHT_THEME_MINUS_COLOR,
|
||||
(true, false) => LIGHT_THEME_MINUS_COLOR_256,
|
||||
(false, true) => DARK_THEME_MINUS_COLOR,
|
||||
(false, false) => DARK_THEME_MINUS_COLOR_256,
|
||||
/// The color mode determines some default color choices
|
||||
/// such as the diff background color or the palette used for blame.
|
||||
#[derive(Default, Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum ColorMode {
|
||||
#[default]
|
||||
/// Dark background with light text.
|
||||
Dark,
|
||||
/// Light background with dark text.
|
||||
Light,
|
||||
}
|
||||
|
||||
pub fn get_minus_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
|
||||
match (mode, is_true_color) {
|
||||
(Light, true) => LIGHT_THEME_MINUS_COLOR,
|
||||
(Light, false) => LIGHT_THEME_MINUS_COLOR_256,
|
||||
(Dark, true) => DARK_THEME_MINUS_COLOR,
|
||||
(Dark, false) => DARK_THEME_MINUS_COLOR_256,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_minus_emph_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
|
||||
match (is_light_mode, is_true_color) {
|
||||
(true, true) => LIGHT_THEME_MINUS_EMPH_COLOR,
|
||||
(true, false) => LIGHT_THEME_MINUS_EMPH_COLOR_256,
|
||||
(false, true) => DARK_THEME_MINUS_EMPH_COLOR,
|
||||
(false, false) => DARK_THEME_MINUS_EMPH_COLOR_256,
|
||||
pub fn get_minus_emph_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
|
||||
match (mode, is_true_color) {
|
||||
(Light, true) => LIGHT_THEME_MINUS_EMPH_COLOR,
|
||||
(Light, false) => LIGHT_THEME_MINUS_EMPH_COLOR_256,
|
||||
(Dark, true) => DARK_THEME_MINUS_EMPH_COLOR,
|
||||
(Dark, false) => DARK_THEME_MINUS_EMPH_COLOR_256,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_plus_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
|
||||
match (is_light_mode, is_true_color) {
|
||||
(true, true) => LIGHT_THEME_PLUS_COLOR,
|
||||
(true, false) => LIGHT_THEME_PLUS_COLOR_256,
|
||||
(false, true) => DARK_THEME_PLUS_COLOR,
|
||||
(false, false) => DARK_THEME_PLUS_COLOR_256,
|
||||
pub fn get_plus_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
|
||||
match (mode, is_true_color) {
|
||||
(Light, true) => LIGHT_THEME_PLUS_COLOR,
|
||||
(Light, false) => LIGHT_THEME_PLUS_COLOR_256,
|
||||
(Dark, true) => DARK_THEME_PLUS_COLOR,
|
||||
(Dark, false) => DARK_THEME_PLUS_COLOR_256,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_plus_emph_background_color_default(is_light_mode: bool, is_true_color: bool) -> Color {
|
||||
match (is_light_mode, is_true_color) {
|
||||
(true, true) => LIGHT_THEME_PLUS_EMPH_COLOR,
|
||||
(true, false) => LIGHT_THEME_PLUS_EMPH_COLOR_256,
|
||||
(false, true) => DARK_THEME_PLUS_EMPH_COLOR,
|
||||
(false, false) => DARK_THEME_PLUS_EMPH_COLOR_256,
|
||||
pub fn get_plus_emph_background_color_default(mode: ColorMode, is_true_color: bool) -> Color {
|
||||
match (mode, is_true_color) {
|
||||
(Light, true) => LIGHT_THEME_PLUS_EMPH_COLOR,
|
||||
(Light, false) => LIGHT_THEME_PLUS_EMPH_COLOR_256,
|
||||
(Dark, true) => DARK_THEME_PLUS_EMPH_COLOR,
|
||||
(Dark, false) => DARK_THEME_PLUS_EMPH_COLOR_256,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ use syntect::parsing::SyntaxSet;
|
||||
|
||||
use crate::ansi;
|
||||
use crate::cli;
|
||||
use crate::color;
|
||||
use crate::color::{self, ColorMode};
|
||||
use crate::delta::State;
|
||||
use crate::fatal;
|
||||
use crate::features::navigate;
|
||||
@ -214,7 +214,7 @@ impl From<cli::Opt> for Config {
|
||||
));
|
||||
});
|
||||
|
||||
let blame_palette = make_blame_palette(opt.blame_palette, opt.computed.is_light_mode);
|
||||
let blame_palette = make_blame_palette(opt.blame_palette, opt.computed.color_mode);
|
||||
|
||||
if blame_palette.is_empty() {
|
||||
fatal("Option 'blame-palette' must not be empty.")
|
||||
@ -437,17 +437,17 @@ impl From<cli::Opt> for Config {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_blame_palette(blame_palette: Option<String>, is_light_mode: bool) -> Vec<String> {
|
||||
match (blame_palette, is_light_mode) {
|
||||
fn make_blame_palette(blame_palette: Option<String>, mode: ColorMode) -> Vec<String> {
|
||||
match (blame_palette, mode) {
|
||||
(Some(string), _) => string
|
||||
.split_whitespace()
|
||||
.map(|s| s.to_owned())
|
||||
.collect::<Vec<String>>(),
|
||||
(None, true) => color::LIGHT_THEME_BLAME_PALETTE
|
||||
(None, ColorMode::Light) => color::LIGHT_THEME_BLAME_PALETTE
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<String>>(),
|
||||
(None, false) => color::DARK_THEME_BLAME_PALETTE
|
||||
(None, ColorMode::Dark) => color::DARK_THEME_BLAME_PALETTE
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<String>>(),
|
||||
|
@ -3,6 +3,7 @@ use std::cmp::max;
|
||||
use lazy_static::lazy_static;
|
||||
use regex::Regex;
|
||||
|
||||
use crate::color::ColorMode::*;
|
||||
use crate::config;
|
||||
use crate::delta::State;
|
||||
use crate::features::hyperlinks;
|
||||
@ -38,26 +39,27 @@ pub fn make_feature() -> Vec<(String, OptionValueFunction)> {
|
||||
"line-numbers-minus-style",
|
||||
String,
|
||||
None,
|
||||
opt => if opt.computed.is_light_mode {
|
||||
"red".to_string()
|
||||
} else {
|
||||
"88".to_string()
|
||||
opt => match opt.computed.color_mode {
|
||||
Light => "red",
|
||||
Dark => "88",
|
||||
}
|
||||
),
|
||||
(
|
||||
"line-numbers-zero-style",
|
||||
String,
|
||||
None,
|
||||
opt => if opt.computed.is_light_mode {"#dddddd"} else {"#444444"}
|
||||
opt => match opt.computed.color_mode {
|
||||
Light => "#dddddd",
|
||||
Dark => "#444444",
|
||||
}
|
||||
),
|
||||
(
|
||||
"line-numbers-plus-style",
|
||||
String,
|
||||
None,
|
||||
opt => if opt.computed.is_light_mode {
|
||||
"green".to_string()
|
||||
} else {
|
||||
"28".to_string()
|
||||
opt => match opt.computed.color_mode {
|
||||
Light => "green",
|
||||
Dark => "28",
|
||||
}
|
||||
)
|
||||
])
|
||||
|
@ -105,7 +105,7 @@ fn run_app() -> std::io::Result<i32> {
|
||||
Some(subcommands::show_themes::show_themes(
|
||||
opt.dark,
|
||||
opt.light,
|
||||
opt.computed.is_light_mode,
|
||||
opt.computed.color_mode,
|
||||
))
|
||||
} else if opt.show_colors {
|
||||
Some(subcommands::show_colors::show_colors())
|
||||
|
@ -237,7 +237,7 @@ pub fn set_options(
|
||||
// Setting ComputedValues
|
||||
set_widths_and_isatty(opt);
|
||||
set_true_color(opt);
|
||||
theme::set__is_light_mode__syntax_theme__syntax_set(opt, assets);
|
||||
theme::set__color_mode__syntax_theme__syntax_set(opt, assets);
|
||||
opt.computed.inspect_raw_lines =
|
||||
cli::InspectRawLines::from_str(&opt.inspect_raw_lines).unwrap();
|
||||
opt.computed.paging_mode = parse_paging_mode(&opt.paging_mode);
|
||||
|
@ -1,30 +1,33 @@
|
||||
//! Delta doesn't have a formal concept of a "theme". What it has is
|
||||
//!
|
||||
//! 1. The choice of "theme". This is the language syntax highlighting theme; you have to make this
|
||||
//! choice when using `bat` also.
|
||||
//! 2. The choice of "light vs dark mode". This determines whether the background colors should be
|
||||
//! chosen for a light or dark terminal background. (`bat` has no equivalent.)
|
||||
//!
|
||||
//! Basically:
|
||||
//! 1. The theme is specified by the `--syntax-theme` option. If this isn't supplied then it is specified
|
||||
//! by the `BAT_THEME` environment variable.
|
||||
//! 2. Light vs dark mode is specified by the `--light` or `--dark` options. If these aren't
|
||||
//! supplied then it detected from the terminal. If this fails it is inferred from the chosen theme.
|
||||
//!
|
||||
//! In the absence of other factors, the default assumes a dark terminal background.
|
||||
|
||||
use std::io::{stdout, IsTerminal};
|
||||
|
||||
/// Delta doesn't have a formal concept of a "theme". What it has is
|
||||
/// (a) the choice of syntax-highlighting theme
|
||||
/// (b) the choice of light-background-mode vs dark-background-mode, which determine certain
|
||||
/// default color choices
|
||||
/// This module sets those options. If the light/dark background mode choice is not made explicitly
|
||||
/// by the user, it is determined by the classification of the syntax theme into light-background
|
||||
/// vs dark-background syntax themes. If the user didn't choose a syntax theme, a dark-background
|
||||
/// default is selected.
|
||||
use bat;
|
||||
use bat::assets::HighlightingAssets;
|
||||
#[cfg(not(test))]
|
||||
use terminal_colorsaurus::{color_scheme, QueryOptions};
|
||||
|
||||
use crate::cli::{self, DetectDarkLight};
|
||||
use crate::color::{ColorMode, ColorMode::*};
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn set__is_light_mode__syntax_theme__syntax_set(
|
||||
opt: &mut cli::Opt,
|
||||
assets: HighlightingAssets,
|
||||
) {
|
||||
let syntax_theme_name_from_bat_theme = &opt.env.bat_theme;
|
||||
let (is_light_mode, syntax_theme_name) = get_is_light_mode_and_syntax_theme_name(
|
||||
opt.syntax_theme.as_ref(),
|
||||
syntax_theme_name_from_bat_theme.as_ref(),
|
||||
get_is_light(opt),
|
||||
);
|
||||
opt.computed.is_light_mode = is_light_mode;
|
||||
pub fn set__color_mode__syntax_theme__syntax_set(opt: &mut cli::Opt, assets: HighlightingAssets) {
|
||||
let (color_mode, syntax_theme_name) =
|
||||
get_color_mode_and_syntax_theme_name(opt.syntax_theme.as_ref(), get_color_mode(opt));
|
||||
opt.computed.color_mode = color_mode;
|
||||
|
||||
opt.computed.syntax_theme = if is_no_syntax_highlighting_syntax_theme_name(&syntax_theme_name) {
|
||||
None
|
||||
@ -38,6 +41,14 @@ pub fn is_light_syntax_theme(theme: &str) -> bool {
|
||||
LIGHT_SYNTAX_THEMES.contains(&theme) || theme.to_lowercase().contains("light")
|
||||
}
|
||||
|
||||
pub fn color_mode_from_syntax_theme(theme: &str) -> ColorMode {
|
||||
if is_light_syntax_theme(theme) {
|
||||
ColorMode::Light
|
||||
} else {
|
||||
ColorMode::Dark
|
||||
}
|
||||
}
|
||||
|
||||
const LIGHT_SYNTAX_THEMES: [&str; 7] = [
|
||||
"Catppuccin Latte",
|
||||
"GitHub",
|
||||
@ -55,69 +66,34 @@ fn is_no_syntax_highlighting_syntax_theme_name(theme_name: &str) -> bool {
|
||||
theme_name.to_lowercase() == "none"
|
||||
}
|
||||
|
||||
/// Return a (theme_name, is_light_mode) tuple.
|
||||
/// Return a (theme_name, color_mode) tuple.
|
||||
/// theme_name == None in return value means syntax highlighting is disabled.
|
||||
///
|
||||
/// There are two types of color choices that have to be made:
|
||||
|
||||
/// 1. The choice of "theme". This is the language syntax highlighting theme; you have to make this
|
||||
/// choice when using `bat` also.
|
||||
/// 2. The choice of "light vs dark mode". This determines whether the background colors should be
|
||||
/// chosen for a light or dark terminal background. (`bat` has no equivalent.)
|
||||
///
|
||||
/// Basically:
|
||||
/// 1. The theme is specified by the `--syntax-theme` option. If this isn't supplied then it is specified
|
||||
/// by the `BAT_THEME` environment variable.
|
||||
/// 2. Light vs dark mode is specified by the `--light` or `--dark` options. If these aren't
|
||||
/// supplied then it is inferred from the chosen theme.
|
||||
///
|
||||
/// In the absence of other factors, the default assumes a dark terminal background.
|
||||
///
|
||||
/// Specifically, the rules are as follows:
|
||||
///
|
||||
/// | --theme | $BAT_THEME | --light/--dark | Behavior |
|
||||
/// |------------|------------|----------------|----------------------------------------------------------------------------|
|
||||
/// | - | - | - | default dark theme, dark mode |
|
||||
/// | some_theme | (IGNORED) | - | some_theme with light/dark mode inferred accordingly |
|
||||
/// | - | BAT_THEME | - | BAT_THEME, with light/dark mode inferred accordingly |
|
||||
/// | - | - | yes | default light/dark theme, light/dark mode |
|
||||
/// | some_theme | (IGNORED) | yes | some_theme, light/dark mode (even if some_theme conflicts with light/dark) |
|
||||
/// | - | BAT_THEME | yes | BAT_THEME, light/dark mode (even if BAT_THEME conflicts with light/dark) |
|
||||
fn get_is_light_mode_and_syntax_theme_name(
|
||||
theme_arg: Option<&String>,
|
||||
bat_theme_env_var: Option<&String>,
|
||||
light_mode: bool,
|
||||
) -> (bool, String) {
|
||||
match (theme_arg, bat_theme_env_var, light_mode) {
|
||||
(None, None, false) => (false, DEFAULT_DARK_SYNTAX_THEME.to_string()),
|
||||
(Some(theme_name), _, false) => (is_light_syntax_theme(theme_name), theme_name.to_string()),
|
||||
(None, Some(theme_name), false) => {
|
||||
(is_light_syntax_theme(theme_name), theme_name.to_string())
|
||||
}
|
||||
(None, None, true) => (true, DEFAULT_LIGHT_SYNTAX_THEME.to_string()),
|
||||
(Some(theme_name), _, is_light_mode) => (is_light_mode, theme_name.to_string()),
|
||||
(None, Some(theme_name), is_light_mode) => (is_light_mode, theme_name.to_string()),
|
||||
fn get_color_mode_and_syntax_theme_name(
|
||||
syntax_theme: Option<&String>,
|
||||
mode: Option<ColorMode>,
|
||||
) -> (ColorMode, String) {
|
||||
match (syntax_theme, mode) {
|
||||
(Some(theme), None) => (color_mode_from_syntax_theme(theme), theme.to_string()),
|
||||
(Some(theme), Some(mode)) => (mode, theme.to_string()),
|
||||
(None, None | Some(Dark)) => (Dark, DEFAULT_DARK_SYNTAX_THEME.to_string()),
|
||||
(None, Some(Light)) => (Light, DEFAULT_LIGHT_SYNTAX_THEME.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_is_light(opt: &cli::Opt) -> bool {
|
||||
get_is_light_opt(opt)
|
||||
.or_else(|| should_detect_dark_light(opt).then(detect_light_mode))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn get_is_light_opt(opt: &cli::Opt) -> Option<bool> {
|
||||
fn get_color_mode(opt: &cli::Opt) -> Option<ColorMode> {
|
||||
if opt.light {
|
||||
Some(true)
|
||||
Some(Light)
|
||||
} else if opt.dark {
|
||||
Some(false)
|
||||
Some(Dark)
|
||||
} else if should_detect_color_mode(opt) {
|
||||
detect_color_mode()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// See [`cli::Opt::detect_dark_light`] for a detailed explanation.
|
||||
fn should_detect_dark_light(opt: &cli::Opt) -> bool {
|
||||
fn should_detect_color_mode(opt: &cli::Opt) -> bool {
|
||||
match opt.detect_dark_light {
|
||||
DetectDarkLight::Auto => opt.color_only || stdout().is_terminal(),
|
||||
DetectDarkLight::Always => true,
|
||||
@ -126,19 +102,26 @@ fn should_detect_dark_light(opt: &cli::Opt) -> bool {
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
fn detect_light_mode() -> bool {
|
||||
use terminal_colorsaurus::{color_scheme, ColorScheme, QueryOptions};
|
||||
color_scheme(QueryOptions::default()).unwrap_or_default() == ColorScheme::Light
|
||||
fn detect_color_mode() -> Option<ColorMode> {
|
||||
color_scheme(QueryOptions::default())
|
||||
.ok()
|
||||
.map(ColorMode::from)
|
||||
}
|
||||
|
||||
impl From<terminal_colorsaurus::ColorScheme> for ColorMode {
|
||||
fn from(value: terminal_colorsaurus::ColorScheme) -> Self {
|
||||
match value {
|
||||
terminal_colorsaurus::ColorScheme::Dark => ColorMode::Dark,
|
||||
terminal_colorsaurus::ColorScheme::Light => ColorMode::Light,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn detect_light_mode() -> bool {
|
||||
LIGHT_MODE_IN_TESTS
|
||||
fn detect_color_mode() -> Option<ColorMode> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) const LIGHT_MODE_IN_TESTS: bool = false;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -148,41 +131,24 @@ mod tests {
|
||||
// TODO: Test influence of BAT_THEME env var. E.g. see utils::process::tests::FakeParentArgs.
|
||||
#[test]
|
||||
fn test_syntax_theme_selection() {
|
||||
#[derive(PartialEq)]
|
||||
enum Mode {
|
||||
Light,
|
||||
Dark,
|
||||
}
|
||||
for (
|
||||
syntax_theme,
|
||||
mode, // (--light, --dark)
|
||||
expected_syntax_theme,
|
||||
expected_mode,
|
||||
) in vec![
|
||||
(None, None, DEFAULT_DARK_SYNTAX_THEME, Mode::Dark),
|
||||
(Some("GitHub"), None, "GitHub", Mode::Light),
|
||||
(Some("GitHub"), None, "GitHub", Mode::Light),
|
||||
(
|
||||
None,
|
||||
Some(Mode::Light),
|
||||
DEFAULT_LIGHT_SYNTAX_THEME,
|
||||
Mode::Light,
|
||||
),
|
||||
(
|
||||
None,
|
||||
Some(Mode::Dark),
|
||||
DEFAULT_DARK_SYNTAX_THEME,
|
||||
Mode::Dark,
|
||||
),
|
||||
(
|
||||
None,
|
||||
Some(Mode::Light),
|
||||
DEFAULT_LIGHT_SYNTAX_THEME,
|
||||
Mode::Light,
|
||||
),
|
||||
(None, Some(Mode::Light), "GitHub", Mode::Light),
|
||||
(Some("none"), None, "none", Mode::Dark),
|
||||
(Some("None"), Some(Mode::Light), "none", Mode::Light),
|
||||
(None, None, DEFAULT_DARK_SYNTAX_THEME, Dark),
|
||||
(Some("GitHub"), None, "GitHub", Light),
|
||||
(Some("Nord"), None, "Nord", Dark),
|
||||
(None, Some(Dark), DEFAULT_DARK_SYNTAX_THEME, Dark),
|
||||
(None, Some(Light), DEFAULT_LIGHT_SYNTAX_THEME, Light),
|
||||
(Some("GitHub"), Some(Light), "GitHub", Light),
|
||||
(Some("GitHub"), Some(Dark), "GitHub", Dark),
|
||||
(Some("Nord"), Some(Light), "Nord", Light),
|
||||
(Some("Nord"), Some(Dark), "Nord", Dark),
|
||||
(Some("none"), None, "none", Dark),
|
||||
(Some("none"), Some(Dark), "none", Dark),
|
||||
(Some("None"), Some(Light), "none", Light),
|
||||
] {
|
||||
let mut args = vec![];
|
||||
if let Some(syntax_theme) = syntax_theme {
|
||||
@ -198,10 +164,10 @@ mod tests {
|
||||
args.push("never");
|
||||
}
|
||||
match mode {
|
||||
Some(Mode::Light) => {
|
||||
Some(Light) => {
|
||||
args.push("--light");
|
||||
}
|
||||
Some(Mode::Dark) => {
|
||||
Some(Dark) => {
|
||||
args.push("--dark");
|
||||
}
|
||||
None => {}
|
||||
@ -225,31 +191,19 @@ mod tests {
|
||||
}
|
||||
assert_eq!(
|
||||
config.minus_style.ansi_term_style.background.unwrap(),
|
||||
color::get_minus_background_color_default(
|
||||
expected_mode == Mode::Light,
|
||||
is_true_color
|
||||
)
|
||||
color::get_minus_background_color_default(expected_mode, is_true_color)
|
||||
);
|
||||
assert_eq!(
|
||||
config.minus_emph_style.ansi_term_style.background.unwrap(),
|
||||
color::get_minus_emph_background_color_default(
|
||||
expected_mode == Mode::Light,
|
||||
is_true_color
|
||||
)
|
||||
color::get_minus_emph_background_color_default(expected_mode, is_true_color)
|
||||
);
|
||||
assert_eq!(
|
||||
config.plus_style.ansi_term_style.background.unwrap(),
|
||||
color::get_plus_background_color_default(
|
||||
expected_mode == Mode::Light,
|
||||
is_true_color
|
||||
)
|
||||
color::get_plus_background_color_default(expected_mode, is_true_color)
|
||||
);
|
||||
assert_eq!(
|
||||
config.plus_emph_style.ansi_term_style.background.unwrap(),
|
||||
color::get_plus_emph_background_color_default(
|
||||
expected_mode == Mode::Light,
|
||||
is_true_color
|
||||
)
|
||||
color::get_plus_emph_background_color_default(expected_mode, is_true_color)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -115,15 +115,14 @@ fn parse_as_reference_to_git_config(style_string: &str, opt: &cli::Opt) -> Style
|
||||
}
|
||||
|
||||
fn make_hunk_styles<'a>(opt: &'a cli::Opt, styles: &'a mut HashMap<&str, StyleReference>) {
|
||||
let is_light_mode = opt.computed.is_light_mode;
|
||||
let color_mode = opt.computed.color_mode;
|
||||
let true_color = opt.computed.true_color;
|
||||
let minus_style = style_from_str(
|
||||
&opt.minus_style,
|
||||
Some(Style::from_colors(
|
||||
None,
|
||||
Some(color::get_minus_background_color_default(
|
||||
is_light_mode,
|
||||
true_color,
|
||||
color_mode, true_color,
|
||||
)),
|
||||
)),
|
||||
None,
|
||||
@ -136,8 +135,7 @@ fn make_hunk_styles<'a>(opt: &'a cli::Opt, styles: &'a mut HashMap<&str, StyleRe
|
||||
Some(Style::from_colors(
|
||||
None,
|
||||
Some(color::get_minus_emph_background_color_default(
|
||||
is_light_mode,
|
||||
true_color,
|
||||
color_mode, true_color,
|
||||
)),
|
||||
)),
|
||||
None,
|
||||
@ -160,8 +158,7 @@ fn make_hunk_styles<'a>(opt: &'a cli::Opt, styles: &'a mut HashMap<&str, StyleRe
|
||||
Some(Style::from_colors(
|
||||
None,
|
||||
Some(color::get_minus_background_color_default(
|
||||
is_light_mode,
|
||||
true_color,
|
||||
color_mode, true_color,
|
||||
)),
|
||||
)),
|
||||
None,
|
||||
@ -176,8 +173,7 @@ fn make_hunk_styles<'a>(opt: &'a cli::Opt, styles: &'a mut HashMap<&str, StyleRe
|
||||
Some(Style::from_colors(
|
||||
None,
|
||||
Some(color::get_plus_background_color_default(
|
||||
is_light_mode,
|
||||
true_color,
|
||||
color_mode, true_color,
|
||||
)),
|
||||
)),
|
||||
None,
|
||||
@ -190,8 +186,7 @@ fn make_hunk_styles<'a>(opt: &'a cli::Opt, styles: &'a mut HashMap<&str, StyleRe
|
||||
Some(Style::from_colors(
|
||||
None,
|
||||
Some(color::get_plus_emph_background_color_default(
|
||||
is_light_mode,
|
||||
true_color,
|
||||
color_mode, true_color,
|
||||
)),
|
||||
)),
|
||||
None,
|
||||
@ -214,8 +209,7 @@ fn make_hunk_styles<'a>(opt: &'a cli::Opt, styles: &'a mut HashMap<&str, StyleRe
|
||||
Some(Style::from_colors(
|
||||
None,
|
||||
Some(color::get_plus_background_color_default(
|
||||
is_light_mode,
|
||||
true_color,
|
||||
color_mode, true_color,
|
||||
)),
|
||||
)),
|
||||
None,
|
||||
|
@ -1,8 +1,9 @@
|
||||
use crate::cli;
|
||||
use crate::color::{ColorMode, ColorMode::*};
|
||||
use crate::config;
|
||||
use crate::delta;
|
||||
use crate::env::DeltaEnv;
|
||||
use crate::options::theme::is_light_syntax_theme;
|
||||
use crate::options::theme::color_mode_from_syntax_theme;
|
||||
use crate::utils;
|
||||
use crate::utils::bat::output::{OutputType, PagingMode};
|
||||
use clap::Parser;
|
||||
@ -41,19 +42,19 @@ pub fn show_syntax_themes() -> std::io::Result<()> {
|
||||
let opt = make_opt();
|
||||
|
||||
if !(opt.dark || opt.light) {
|
||||
_show_syntax_themes(opt, false, &mut writer, stdin_data.as_ref())?;
|
||||
_show_syntax_themes(make_opt(), true, &mut writer, stdin_data.as_ref())?;
|
||||
_show_syntax_themes(opt, Dark, &mut writer, stdin_data.as_ref())?;
|
||||
_show_syntax_themes(make_opt(), Light, &mut writer, stdin_data.as_ref())?;
|
||||
} else if opt.light {
|
||||
_show_syntax_themes(opt, true, &mut writer, stdin_data.as_ref())?;
|
||||
_show_syntax_themes(opt, Light, &mut writer, stdin_data.as_ref())?;
|
||||
} else {
|
||||
_show_syntax_themes(opt, false, &mut writer, stdin_data.as_ref())?
|
||||
_show_syntax_themes(opt, Dark, &mut writer, stdin_data.as_ref())?
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn _show_syntax_themes(
|
||||
mut opt: cli::Opt,
|
||||
is_light_mode: bool,
|
||||
color_mode: ColorMode,
|
||||
writer: &mut dyn Write,
|
||||
stdin: Option<&Vec<u8>>,
|
||||
) -> std::io::Result<()> {
|
||||
@ -80,14 +81,14 @@ index f38589a..0f1bb83 100644
|
||||
}
|
||||
};
|
||||
|
||||
opt.computed.is_light_mode = is_light_mode;
|
||||
opt.computed.color_mode = color_mode;
|
||||
let mut config = config::Config::from(opt);
|
||||
let title_style = ansi_term::Style::new().bold();
|
||||
let assets = utils::bat::assets::load_highlighting_assets();
|
||||
|
||||
for syntax_theme in assets
|
||||
.themes()
|
||||
.filter(|t| is_light_syntax_theme(t) == is_light_mode)
|
||||
.filter(|t| color_mode_from_syntax_theme(t) == color_mode)
|
||||
{
|
||||
writeln!(
|
||||
writer,
|
||||
@ -121,7 +122,7 @@ mod tests {
|
||||
let opt = integration_test_utils::make_options_from_args(&[]);
|
||||
|
||||
let mut writer = Cursor::new(vec![0; 1024]);
|
||||
_show_syntax_themes(opt, true, &mut writer, None).unwrap();
|
||||
_show_syntax_themes(opt, Light, &mut writer, None).unwrap();
|
||||
let mut s = String::new();
|
||||
writer.rewind().unwrap();
|
||||
writer.read_to_string(&mut s).unwrap();
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::io::{self, ErrorKind, IsTerminal, Read};
|
||||
|
||||
use crate::cli;
|
||||
use crate::color::ColorMode;
|
||||
use crate::config;
|
||||
use crate::delta;
|
||||
use crate::env::DeltaEnv;
|
||||
@ -8,7 +9,7 @@ use crate::git_config;
|
||||
use crate::options::get::get_themes;
|
||||
use crate::utils::bat::output::{OutputType, PagingMode};
|
||||
|
||||
pub fn show_themes(dark: bool, light: bool, computed_theme_is_light: bool) -> std::io::Result<()> {
|
||||
pub fn show_themes(dark: bool, light: bool, color_mode: ColorMode) -> std::io::Result<()> {
|
||||
use std::io::BufReader;
|
||||
|
||||
use bytelines::ByteLines;
|
||||
@ -58,8 +59,8 @@ pub fn show_themes(dark: bool, light: bool, computed_theme_is_light: bool) -> st
|
||||
let is_light_theme = opt.light;
|
||||
let config = config::Config::from(opt);
|
||||
|
||||
if (!computed_theme_is_light && is_dark_theme)
|
||||
|| (computed_theme_is_light && is_light_theme)
|
||||
if (color_mode == ColorMode::Dark && is_dark_theme)
|
||||
|| (color_mode == ColorMode::Light && is_light_theme)
|
||||
|| (dark && light)
|
||||
{
|
||||
writeln!(writer, "\n\nTheme: {}\n", title_style.paint(theme))?;
|
||||
|
@ -103,7 +103,7 @@ pub fn wrap(text: &str, width: usize, indent_with: &str, no_indent: &str, no_wra
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
if result.find("no-sanity").is_none() {
|
||||
if !result.contains("no-sanity") {
|
||||
// sanity check
|
||||
let stripped_input = text
|
||||
.replace(" ", "")
|
||||
|
@ -598,6 +598,7 @@ pub mod tests {
|
||||
With(usize, Rc<Vec<T>>),
|
||||
None,
|
||||
Invalid,
|
||||
ErrorAlreadyHandled,
|
||||
}
|
||||
|
||||
// When calling `FakeParentArgs::get()`, it can return `Some(values)` which were set earlier
|
||||
@ -648,24 +649,39 @@ pub mod tests {
|
||||
TlsState::With(n, args) => TlsState::With(*n + 1, Rc::clone(args)),
|
||||
TlsState::None => TlsState::None,
|
||||
TlsState::Invalid => TlsState::Invalid,
|
||||
TlsState::ErrorAlreadyHandled => TlsState::ErrorAlreadyHandled,
|
||||
});
|
||||
|
||||
match old_value {
|
||||
TlsState::Once(args) | TlsState::Scope(args) => Some(args),
|
||||
TlsState::With(n, args) if n < args.len() => Some(args[n].clone()),
|
||||
TlsState::None => None,
|
||||
TlsState::Invalid | TlsState::With(_, _) => Self::error("get"),
|
||||
TlsState::Invalid | TlsState::With(_, _) | TlsState::ErrorAlreadyHandled => {
|
||||
Self::error("get");
|
||||
None
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
pub fn are_set() -> bool {
|
||||
FAKE_ARGS.with(|a| *a.borrow() != TlsState::None)
|
||||
FAKE_ARGS.with(|a| {
|
||||
*a.borrow() != TlsState::None && *a.borrow() != TlsState::ErrorAlreadyHandled
|
||||
})
|
||||
}
|
||||
fn error(where_: &str) -> ! {
|
||||
panic!(
|
||||
"test logic error (in {}): wrong FakeParentArgs scope?",
|
||||
where_
|
||||
);
|
||||
fn error(where_: &str) {
|
||||
FAKE_ARGS.with(|a| {
|
||||
let old_value = a.replace(TlsState::ErrorAlreadyHandled);
|
||||
|
||||
match old_value {
|
||||
TlsState::ErrorAlreadyHandled => (),
|
||||
_ => {
|
||||
panic!(
|
||||
"test logic error (in {}): wrong FakeParentArgs scope?",
|
||||
where_
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
impl Drop for FakeParentArgs {
|
||||
@ -680,7 +696,7 @@ pub mod tests {
|
||||
}
|
||||
}
|
||||
TlsState::Once(_) | TlsState::None => Self::error("drop"),
|
||||
TlsState::Scope(_) | TlsState::Invalid => {}
|
||||
TlsState::Scope(_) | TlsState::Invalid | TlsState::ErrorAlreadyHandled => {}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -838,7 +854,7 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[should_panic(expected = "test logic error (in get): wrong FakeParentArgs scope?")]
|
||||
fn test_process_testing_assert() {
|
||||
let _args = FakeParentArgs::once("git blame do.not.panic");
|
||||
assert_eq!(
|
||||
@ -850,13 +866,23 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_process_testing_assert_never_used() {
|
||||
#[should_panic(expected = "test logic error (in drop): wrong FakeParentArgs scope?")]
|
||||
fn test_process_testing_assert_once_never_used() {
|
||||
let _args = FakeParentArgs::once("never used");
|
||||
}
|
||||
|
||||
// causes a panic while panicking, so can't test:
|
||||
// let _args = FakeParentArgs::for_scope(&"never used");
|
||||
// let _args = FakeParentArgs::once(&"never used");
|
||||
#[test]
|
||||
#[should_panic(expected = "test logic error (in once): wrong FakeParentArgs scope?")]
|
||||
fn test_process_testing_assert_for_scope_never_used() {
|
||||
let _args = FakeParentArgs::for_scope(&"never used");
|
||||
let _args = FakeParentArgs::once(&"never used");
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "test logic error (in for_scope): wrong FakeParentArgs scope?")]
|
||||
fn test_process_testing_assert_once_never_used2() {
|
||||
let _args = FakeParentArgs::once(&"never used");
|
||||
let _args = FakeParentArgs::for_scope(&"never used");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -879,13 +905,13 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[should_panic(expected = "test logic error (in drop with): wrong FakeParentArgs scope?")]
|
||||
fn test_process_testing_n_times_unused() {
|
||||
let _args = FakeParentArgs::with(&["git blame once", "git blame twice"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[should_panic(expected = "test logic error (in drop with): wrong FakeParentArgs scope?")]
|
||||
fn test_process_testing_n_times_underused() {
|
||||
let _args = FakeParentArgs::with(&["git blame once", "git blame twice"]);
|
||||
assert_eq!(
|
||||
@ -895,15 +921,13 @@ pub mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
#[ignore]
|
||||
#[should_panic(expected = "test logic error (in get): wrong FakeParentArgs scope?")]
|
||||
fn test_process_testing_n_times_overused() {
|
||||
let _args = FakeParentArgs::with(&["git blame once"]);
|
||||
assert_eq!(
|
||||
calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename),
|
||||
Some("once".into())
|
||||
);
|
||||
// ignored: dropping causes a panic while panicking, so can't test
|
||||
calling_process_cmdline(ProcInfo::new(), guess_git_blame_filename);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user