summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml5
-rw-r--r--README.md4
-rw-r--r--etc/completion/completion.bash7
-rw-r--r--manual/src/choosing-colors-styles.md9
-rw-r--r--src/cli.rs8
-rw-r--r--src/config.rs5
-rw-r--r--src/delta.rs2
-rw-r--r--src/env.rs10
-rw-r--r--src/handlers/blame.rs10
-rw-r--r--src/handlers/diff_header.rs79
-rw-r--r--src/handlers/diff_header_diff.rs6
-rw-r--r--src/handlers/diff_header_misc.rs3
-rw-r--r--src/handlers/git_show_file.rs4
-rw-r--r--src/handlers/grep.rs8
-rw-r--r--src/options/get.rs2
-rw-r--r--src/options/set.rs6
-rw-r--r--src/options/theme.rs2
-rw-r--r--src/paint.rs49
-rw-r--r--src/subcommands/show_colors.rs2
-rw-r--r--src/tests/ansi_test_utils.rs12
-rw-r--r--src/tests/test_example_diffs.rs58
-rw-r--r--src/utils/process.rs143
-rw-r--r--src/wrapping.rs2
23 files changed, 255 insertions, 181 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c44aaef1..a9ccb415 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -14,6 +14,9 @@ jobs:
matrix:
job:
- os: macos-latest
+ target: aarch64-apple-darwin
+ use-cross: false
+ - os: macos-12 # Should be Intel macOS, macos-latest is arm since ~2024-04
target: x86_64-apple-darwin
use-cross: false
- os: windows-latest
@@ -63,7 +66,7 @@ jobs:
os: [macos-latest, ubuntu-latest]
include:
- os: macos-latest
- target: x86_64-apple-darwin
+ target: aarch64-apple-darwin
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
steps:
diff --git a/README.md b/README.md
index b880542b..d2bff458 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,10 @@
[delta]
navigate = true # use n and N to move between diff sections
+ # delta detects terminal colors automatically; set one of these to disable auto-detection
+ # dark = true
+ # light = true
+
[merge]
conflictstyle = diff3
diff --git a/etc/completion/completion.bash b/etc/completion/completion.bash
index 5c7de994..124f73c3 100644
--- a/etc/completion/completion.bash
+++ b/etc/completion/completion.bash
@@ -375,4 +375,9 @@ _delta() {
esac
}
-complete -F _delta -o nosort -o bashdefault -o default delta
+# nosort isn't supported for bash less than < 4.4
+if [[ ${BASH_VERSINFO[0]} -lt 4 || ( ${BASH_VERSINFO[0]} -eq 4 && ${BASH_VERSINFO[1]} -lt 4 ) ]]; then
+ complete -F _delta -o bashdefault -o default delta
+else
+ complete -F _delta -o bashdefault -o default -o nosort delta
+fi
diff --git a/manual/src/choosing-colors-styles.md b/manual/src/choosing-colors-styles.md
index 37c95635..2b053d6b 100644
--- a/manual/src/choosing-colors-styles.md
+++ b/manual/src/choosing-colors-styles.md
@@ -1,5 +1,14 @@
# Choosing colors (styles)
+Delta detects your terminal background color automatically and chooses appropriate default colors.
+To override automatic detection use `dark` or `light`, e.g.
+
+```gitconfig
+[delta]
+ dark = true
+```
+This is necessary when running delta in some contexts such as `lazygit` or `zellij`.
+
All options that have a name like `--*-style` work in the same way. It is very similar to how
colors/styles are specified in a gitconfig file:
<https://git-scm.com/docs/git-config#Documentation/git-config.txt-color>
diff --git a/src/cli.rs b/src/cli.rs
index 4cddd6fb..723ea42c 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -287,12 +287,12 @@ pub struct Opt {
/// For more control, see the style options and --syntax-theme.
pub dark: bool,
- #[arg(long = "default-language", value_name = "LANG")]
+ #[arg(long = "default-language", value_name = "LANG", default_value = "txt")]
/// Default language used for syntax highlighting.
///
- /// Used when the language cannot be inferred from a filename. It will typically make sense to
- /// set this in per-repository git config (.git/config)
- pub default_language: Option<String>,
+ /// Used as a fallback when the language cannot be inferred from a filename. It will
+ /// typically make sense to set this in the per-repository config file '.git/config'.
+ pub default_language: String,
/// Detect whether or not the terminal is dark or light by querying for its colors.
///
diff --git a/src/config.rs b/src/config.rs
index 7d3d442d..76789289 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -31,6 +31,9 @@ use crate::wrapping::WrapConfig;
pub const INLINE_SYMBOL_WIDTH_1: usize = 1;
+// Used if an invalid default-language was specified.
+pub const SYNTAX_FALLBACK_LANG: &str = "txt";
+
#[cfg_attr(test, derive(Clone))]
pub struct Config {
pub available_terminal_width: usize,
@@ -49,7 +52,7 @@ pub struct Config {
pub cwd_of_user_shell_process: Option<PathBuf>,
pub cwd_relative_to_repo_root: Option<String>,
pub decorations_width: cli::Width,
- pub default_language: Option<String>,
+ pub default_language: String,
pub diff_stat_align_width: usize,
pub error_exit_code: i32,
pub file_added_label: String,
diff --git a/src/delta.rs b/src/delta.rs
index 3bce32a1..9890b9b2 100644
--- a/src/delta.rs
+++ b/src/delta.rs
@@ -192,7 +192,7 @@ impl<'a> StateMachine<'a> {
self.config.max_line_length,
);
self.raw_line = raw_line[..truncated_len].to_string();
- self.line = self.raw_line.clone();
+ self.line.clone_from(&self.raw_line);
}
}
}
diff --git a/src/env.rs b/src/env.rs
index 978c4881..8c169bcc 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -62,10 +62,17 @@ impl DeltaEnv {
#[cfg(test)]
pub mod tests {
use super::DeltaEnv;
+ use lazy_static::lazy_static;
use std::env;
+ use std::sync::{Arc, Mutex};
+
+ lazy_static! {
+ static ref ENV_ACCESS: Arc<Mutex<()>> = Arc::new(Mutex::new(()));
+ }
#[test]
fn test_env_parsing() {
+ let _guard = ENV_ACCESS.lock().unwrap();
let feature = "Awesome Feature";
env::set_var("DELTA_FEATURES", feature);
let env = DeltaEnv::init();
@@ -74,6 +81,7 @@ pub mod tests {
#[test]
fn test_env_parsing_with_pager_set_to_bat() {
+ let _guard = ENV_ACCESS.lock().unwrap();
env::set_var("PAGER", "bat");
let env = DeltaEnv::init();
assert_eq!(
@@ -86,6 +94,7 @@ pub mod tests {
#[test]
fn test_env_parsing_with_pager_set_to_more() {
+ let _guard = ENV_ACCESS.lock().unwrap();
env::set_var("PAGER", "more");
let env = DeltaEnv::init();
assert_eq!(env.pagers.1, Some("less".into()));
@@ -93,6 +102,7 @@ pub mod tests {
#[test]
fn test_env_parsing_with_pager_set_to_most() {
+ let _guard = ENV_ACCESS.lock().unwrap();
env::set_var("PAGER", "most");
let env = DeltaEnv::init();
assert_eq!(env.pagers.1, Some("less".into()));
diff --git a/src/handlers/blame.rs b/src/handlers/blame.rs
index e8c2e435..fc3d6d1c 100644
--- a/src/handlers/blame.rs
+++ b/src/handlers/blame.rs
@@ -77,13 +77,9 @@ impl<'a> StateMachine<'a> {
// Emit syntax-highlighted code
if matches!(self.state, State::Unknown) {
- if let Some(lang) = utils::process::git_blame_filename_extension()
- .as_ref()
- .or(self.config.default_language.as_ref())
- {
- self.painter.set_syntax(Some(lang));
- self.painter.set_highlighter();
- }
+ self.painter
+ .set_syntax(utils::process::git_blame_filename().as_deref());
+ self.painter.set_highlighter();
}
self.state = State::Blame(key);
self.painter.syntax_highlight_and_paint_line(
diff --git a/src/handlers/diff_header.rs b/src/handlers/diff_header.rs
index 3c71a61a..24ecc9d5 100644
--- a/src/handlers/diff_header.rs
+++ b/src/handlers/diff_header.rs
@@ -95,10 +95,10 @@ impl<'a> StateMachine<'a> {
if self.source == Source::DiffUnified {
self.state = State::DiffHeader(DiffType::Unified);
self.painter
- .set_syntax(get_file_extension_from_marker_line(&self.line));
+ .set_syntax(get_filename_from_marker_line(&self.line));
} else {
self.painter
- .set_syntax(get_file_extension_from_diff_header_line_file_path(
+ .set_syntax(get_filename_from_diff_header_line_file_path(
&self.minus_file,
));
}
@@ -129,7 +129,7 @@ impl<'a> StateMachine<'a> {
.unwrap_or(path_or_mode);
self.plus_file_event = file_event;
self.painter
- .set_syntax(get_file_extension_from_diff_header_line_file_path(
+ .set_syntax(get_filename_from_diff_header_line_file_path(
&self.plus_file,
));
self.current_file_pair = Some((self.minus_file.clone(), self.plus_file.clone()));
@@ -142,7 +142,8 @@ impl<'a> StateMachine<'a> {
{
self.painter.emit()?;
self._handle_diff_header_header_line(self.source == Source::DiffUnified)?;
- self.handled_diff_header_header_line_file_pair = self.current_file_pair.clone();
+ self.handled_diff_header_header_line_file_pair
+ .clone_from(&self.current_file_pair);
}
Ok(handled_line)
}
@@ -255,7 +256,8 @@ impl<'a> StateMachine<'a> {
&& self.handled_diff_header_header_line_file_pair != self.current_file_pair
{
self._handle_diff_header_header_line(self.source == Source::DiffUnified)?;
- self.handled_diff_header_header_line_file_pair = self.current_file_pair.clone();
+ self.handled_diff_header_header_line_file_pair
+ .clone_from(&self.current_file_pair);
Ok(())
} else {
Ok(())
@@ -300,30 +302,23 @@ pub fn write_generic_diff_header_header_line(
#[allow(clippy::tabs_in_doc_comments)]
/// Given input like
-/// "--- one.rs 2019-11-20 06:16:08.000000000 +0100"
-/// Return "rs"
-fn get_file_extension_from_marker_line(line: &str) -> Option<&str> {
+/// "--- a/zero/one.rs 2019-11-20 06:16:08.000000000 +0100"
+/// Return "one.rs"
+fn get_filename_from_marker_line(line: &str) -> Option<&str> {
line.split('\t')
.next()
.and_then(|column| column.split(' ').nth(1))
- .and_then(|file| file.split('.').last())
+ .and_then(get_filename_from_diff_header_line_file_path)
}
-fn get_file_extension_from_diff_header_line_file_path(path: &str) -> Option<&str> {
- if path.is_empty() || path == "/dev/null" {
- None
- } else {
- get_extension(path).map(|ex| ex.trim())
- }
-}
-
-/// Attempt to parse input as a file path and return extension as a &str.
-pub fn get_extension(s: &str) -> Option<&str> {
- let path = Path::new(s);
- path.extension()
- .and_then(|e| e.to_str())
- // E.g. 'Makefile' is the file name and also the extension
- .or_else(|| path.file_name().and_then(|s| s.to_str()))
+fn get_filename_from_diff_header_line_file_path(path: &str) -> Option<&str> {
+ Path::new(path).file_name().and_then(|filename| {
+ if path != "/dev/null" {
+ filename.to_str()
+ } else {
+ None
+ }
+ })
}
fn parse_diff_header_line(line: &str, git_diff_name: bool) -> (String, FileEvent) {
@@ -477,51 +472,49 @@ mod tests {
use super::*;
#[test]
- fn test_get_file_extension_from_marker_line() {
+ fn test_get_filename_from_marker_line() {
assert_eq!(
- get_file_extension_from_marker_line(
- "--- src/one.rs 2019-11-20 06:47:56.000000000 +0100"
- ),
- Some("rs")
+ get_filename_from_marker_line("--- src/one.rs 2019-11-20 06:47:56.000000000 +0100"),
+ Some("one.rs")
);
}
#[test]
- fn test_get_file_extension_from_diff_header_line() {
+ fn test_get_filename_from_diff_header_line() {
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("a/src/parse.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("a/src/parse.rs"),
+ Some("parse.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("b/src/pa rse.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("b/src/pa rse.rs"),
+ Some("pa rse.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("src/pa rse.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("src/pa rse.rs"),
+ Some("pa rse.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("wat hello.rs"),
- Some("rs")
+ get_filename_from_diff_header_line_file_path("wat hello.rs"),
+ Some("wat hello.rs")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("/dev/null"),
+ get_filename_from_diff_header_line_file_path("/dev/null"),
None
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("Dockerfile"),
+ get_filename_from_diff_header_line_file_path("Dockerfile"),
Some("Dockerfile")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("Makefile"),
+ get_filename_from_diff_header_line_file_path("Makefile"),
Some("Makefile")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("a/src/Makefile"),
+ get_filename_from_diff_header_line_file_path("a/src/Makefile"),
Some("Makefile")
);
assert_eq!(
- get_file_extension_from_diff_header_line_file_path("src/Makefile"),
+ get_filename_from_diff_header_line_file_path("src/Makefile"),
Some("Makefile")
);
}
diff --git a/src/handlers/diff_header_diff.rs b/src/handlers/diff_header_diff.rs
index f8a007e2..d8c53196 100644
--- a/src/handlers/diff_header_diff.rs
+++ b/src/handlers/diff_header_diff.rs
@@ -25,7 +25,7 @@ impl<'a> StateMachine<'a> {
};
self.handle_pending_line_with_diff_name()?;
self.handled_diff_header_header_line_file_pair = None;
- self.diff_line = self.line.clone();
+ self.diff_line.clone_from(&self.line);
// Pre-fill header fields from the diff line. For added, removed or renamed files
// these are updated precisely on actual header minus and header plus lines.
@@ -33,8 +33,8 @@ impl<'a> StateMachine<'a> {
// are no minus and plus lines. Without the code below, in such cases the file names
// would remain unchanged from the previous diff, or empty for the very first diff.
let name = get_repeated_file_path_from_diff_line(&self.line).unwrap_or_default();
- self.minus_file = name.clone();
- self.plus_file = name.clone();
+ self.minus_file.clone_from(&name);
+ self.plus_file.clone_from(&name);
self.minus_file_event = FileEvent::Change;
self.plus_file_event = FileEvent::Change;
self.current_file_pair = Some((self.minus_file.clone(), self.plus_file.clone()));
diff --git a/src/handlers/diff_header_misc.rs b/src/handlers/diff_header_misc.rs
index c9404d6c..b120fb2f 100644
--- a/src/handlers/diff_header_misc.rs
+++ b/src/handlers/diff_header_misc.rs
@@ -23,7 +23,8 @@ impl<'a> StateMachine<'a> {
// This can happen in output of standalone diff or git diff --no-index.
if self.minus_file.is_empty() && self.plus_file.is_empty() {
self.emit_line_unchanged()?;
- self.handled_diff_header_header_line_file_pair = self.current_file_pair.clone();
+ self.handled_diff_header_header_line_file_pair
+ .clone_from(&self.current_file_pair);
return Ok(true);
}
diff --git a/src/handlers/git_show_file.rs b/src/handlers/git_show_file.rs
index a9e1358e..ff670eb9 100644
--- a/src/handlers/git_show_file.rs
+++ b/src/handlers/git_show_file.rs
@@ -9,11 +9,11 @@ impl<'a> StateMachine<'a> {
self.painter.emit()?;
let mut handled_line = false;
if matches!(self.state, State::Unknown) {
- if let process::CallingProcess::GitShow(_, Some(extension)) =
+ if let process::CallingProcess::GitShow(_, Some(filename)) =
&*process::calling_process()
{
self.state = State::GitShowFile;
- self.painter.set_syntax(Some(extension));
+ self.painter.set_syntax(Some(filename));
} else {
return Ok(handled_line);
}
diff --git a/src/handlers/grep.rs b/src/handlers/grep.rs
index b7f2dc53..63cc1a3e 100644
--- a/src/handlers/grep.rs
+++ b/src/handlers/grep.rs
@@ -132,12 +132,8 @@ impl<'a> StateMachine<'a> {
self.painter.set_highlighter()
}
if new_path {
- if let Some(lang) = handlers::diff_header::get_extension(&grep_line.path)
- .or(self.config.default_language.as_deref())
- {
- self.painter.set_syntax(Some(lang));
- self.painter.set_highlighter();
- }
+ self.painter.set_syntax(Some(grep_line.path.as_ref()));
+ self.painter.set_highlighter();
}
match &self.state {
State::Grep(GrepType::Ripgrep, _, _, _) => {
diff --git a/src/options/get.rs b/src/options/get.rs
index fcea8c5a..40f3d581 100644
--- a/src/options/get.rs
+++ b/src/options/get.rs
@@ -38,7 +38,7 @@ where
T::get_option_value(option_name, builtin_features, opt, git_config)
}
-static GIT_CONFIG_THEME_REGEX: &str = r#"^delta\.(.+)\.(light|dark)$"#;
+static GIT_CONFIG_THEME_REGEX: &str = r"^delta\.(.+)\.(light|dark)$";
pub fn get_themes(git_config: Option<git_config::GitConfig>) -> Vec<String> {
let mut themes: Vec<String> = Vec::new();
diff --git a/src/options/set.rs b/src/options/set.rs
index cfb42987..f6d293e9 100644
--- a/src/options/set.rs
+++ b/src/options/set.rs
@@ -79,7 +79,7 @@ pub fn set_options(
}
opt.navigate = opt.navigate || opt.env.navigate.is_some();
if opt.syntax_theme.is_none() {
- opt.syntax_theme = opt.env.bat_theme.clone();
+ opt.syntax_theme.clone_from(&opt.env.bat_theme);
}
let option_names = cli::Opt::get_argument_and_option_names();
@@ -632,7 +632,7 @@ fn set_true_color(opt: &mut cli::Opt) {
// It's equal to its default, so the user might be using the deprecated
// --24-bit-color option.
if let Some(_24_bit_color) = opt._24_bit_color.as_ref() {
- opt.true_color = _24_bit_color.clone();
+ opt.true_color.clone_from(_24_bit_color);
}
}
@@ -735,7 +735,7 @@ pub mod tests {
assert_eq!(opt.commit_decoration_style, "black black");
assert_eq!(opt.commit_style, "black black");
assert!(!opt.dark);
- assert_eq!(opt.default_language, Some("rs".to_owned()));
+ assert_eq!(opt.default_language, "rs".to_owned());
// TODO: should set_options not be called on any feature flags?
// assert_eq!(opt.diff_highlight, true);
// assert_eq!(opt.diff_so_fancy, true);
diff --git a/src/options/theme.rs b/src/options/theme.rs
index f53a0821..7c1dbce8 100644
--- a/src/options/theme.rs
+++ b/src/options/theme.rs
@@ -141,7 +141,7 @@ fn detect_light_mode() -> bool {
#[cfg(test)]
pub(crate) mod test_utils {
thread_local! {
- pub(super) static DETECT_LIGHT_MODE_OVERRIDE: std::cell::Cell<Option<bool>> = std::cell::Cell::new(None);
+ pub(super) static DETECT_LIGHT_MODE_OVERRIDE: std::cell::Cell<Option<bool>> = const { std::cell::Cell::new(None) };
}
pub(crate) struct DetectLightModeOverride {
diff --git a/src/paint.rs b/src/paint.rs
index ee2fefec..4b487ea3 100644
--- a/src/paint.rs
+++ b/src/paint.rs
@@ -70,9 +70,7 @@ pub enum StyleSectionSpecifier<'l> {
impl<'p> Painter<'p> {
pub fn new(writer: &'p mut dyn Write, config: &'p config::Config) -> Self {
- let default_syntax =
- Self::get_syntax(&config.syntax_set, None, config.default_language.as_deref());
-
+ let default_syntax = Self::get_syntax(&config.syntax_set, None, &config.default_language);
let panel_width_fix = ansifill::UseFullPanelWidth::new(config);
let line_numbers_data = if config.line_numbers {
@@ -104,27 +102,50 @@ impl<'p> Painter<'p> {
}
}
- pub fn set_syntax(&mut self, extension: Option<&str>) {
+ pub fn set_syntax(&mut self, filename: Option<&str>) {
self.syntax = Painter::get_syntax(
&self.config.syntax_set,
- extension,
- self.config.default_language.as_deref(),
+ filename,
+ &self.config.default_language,
);
}
fn get_syntax<'a>(
syntax_set: &'a SyntaxSet,
- extension: Option<&str>,
- fallback_extension: Option<&str>,
+ filename: Option<&str>,
+ fallback: &str,
) -> &'a SyntaxReference {
- for extension in [extension, fallback_extension].iter().flatten() {
- if let Some(syntax) = syntax_set.find_syntax_by_extension(extension) {
- return syntax;
+ if let Some(filename) = filename {
+ let path = std::path::Path::new(filename);
+ let file_name = path.file_name().and_then(|n| n.to_str()).unwrap_or("");
+ let extension = path.extension().and_then(|x| x.to_str()).unwrap_or("");
+
+ // Like syntect's `find_syntax_for_file`, without inspecting the file content, plus:
+ // If the file has NO extension then look up the whole filename as a
+ // syntax definition (if it is longer than 4 bytes).
+ // This means file formats like Makefile/Dockerfile/Rakefile etc. will get highlighted,
+ // but 1-4 short filenames will not -- even if they, as a whole, match an extension:
+ // 'rs' will not get highlighted, while 'x.rs' will.
+ if !extension.is_empty() || file_name.len() > 4 {
+ if let Some(syntax) = syntax_set
+ .find_syntax_by_extension(file_name)
+ .or_else(|| syntax_set.find_syntax_by_extension(extension))
+ {
+ return syntax;
+ }
}
}
- syntax_set
- .find_syntax_by_extension("txt")
- .unwrap_or_else(|| delta_unreachable("Failed to find any language syntax definitions."))
+
+ // Nothing found, try the user provided fallback, or the internal fallback.
+ if let Some(syntax) = syntax_set.find_syntax_for_file(fallback).unwrap_or(None) {
+ syntax
+ } else {
+ syntax_set
+ .find_syntax_by_extension(config::SYNTAX_FALLBACK_LANG)
+ .unwrap_or_else(|| {
+ delta_unreachable("Failed to find any language syntax definitions.")
+ })
+ }
}
pub fn set_highlighter(&mut self) {
diff --git a/src/subcommands/show_colors.rs b/src/subcommands/show_colors.rs
index 8ad9fc35..2898dd97 100644
--- a/src/subcommands/show_colors.rs
+++ b/src/subcommands/show_colors.rs
@@ -28,7 +28,7 @@ pub fn show_colors() -> std::io::Result<()> {
let writer = output_type.handle().unwrap();
let mut painter = paint::Painter::new(writer, &config);
- painter.set_syntax(Some("ts"));
+ painter.set_syntax(Some("a.ts"));
painter.set_highlighter();
let title_style = ansi_term::Style::new().bold();
diff --git a/src/tests/ansi_test_utils.rs b/src/tests/ansi_test_utils.rs
index 5e60223b..8bb2dbcb 100644
--- a/src/tests/ansi_test_utils.rs
+++ b/src/tests/ansi_test_utils.rs
@@ -122,15 +122,19 @@ pub mod ansi_test_utils {
line_number: usize,
substring_begin: usize,
expected_substring: &str,
- language_extension: &str,
+ filename_for_highlighting: &str,
state: State,
config: &Config,
) {
+ assert!(
+ filename_for_highlighting.contains('.'),
+ "expecting filename, not just a file extension"
+ );
let line = output.lines().nth(line_number).unwrap();
let substring_end = substring_begin + expected_substring.len();
let substring = &ansi::strip_ansi_codes(line)[substring_begin..substring_end];
assert_eq!(substring, expected_substring);
- let painted_substring = paint_line(substring, language_extension, state, config);
+ let painted_substring = paint_line(substring, filename_for_highlighting, state, config);
// remove trailing newline appended by paint::paint_lines.
assert!(line.contains(painted_substring.trim_end()));
}
@@ -163,7 +167,7 @@ pub mod ansi_test_utils {
pub fn paint_line(
line: &str,
- language_extension: &str,
+ filename_for_highlighting: &str,
state: State,
config: &Config,
) -> String {
@@ -174,7 +178,7 @@ pub mod ansi_test_utils {
is_syntax_highlighted: true,
..Style::new()
};
- painter.set_syntax(Some(language_extension));
+ painter.set_syntax(Some(filename_for_highlighting));
painter.set_highlighter();
let lines = vec![(line.to_string(), state)];
let syntax_style_sections = paint::get_syntax_style_sections_for_lines(
diff --git a/src/tests/test_example_diffs.rs b/src/tests/test_example_diffs.rs
index 104807a7..c686924f 100644
--- a/src/tests/test_example_diffs.rs
+++ b/src/tests/test_example_diffs.rs
@@ -111,7 +111,7 @@ mod tests {
12,
1,
" rsync -avu --delete $src/ $dst",
- "bash",
+ "abc.bash",
State::HunkZero(DiffType::Unified, None),
&config,
);
@@ -126,18 +126,50 @@ mod tests {
"bash",
]);
let output = integration_test_utils::run_delta(MODIFIED_BASH_AND_CSHARP_FILES, &config);
+ eprintln!("{}", &output);
ansi_test_utils::assert_line_has_syntax_highlighted_substring(
&output,
19,
1,
" static void Main(string[] args)",
- "cs",
+ "abc.cs",
State::HunkZero(DiffType::Unified, None),
&config,
);
}
#[test]
+ fn test_full_filename_used_to_detect_language() {
+ let config = integration_test_utils::make_config_from_args(&[
+ "--color-only",
+ "--default-language",
+ "txt",
+ ]);
+ let output = integration_test_utils::run_delta(MODIFIED_DOCKER_AND_RS_FILES, &config);
+ let ansi = ansi::explain_ansi(&output, false);
+
+ // Ensure presence