1
0
mirror of https://github.com/sharkdp/bat synced 2026-06-09 10:03:18 +00:00

Add --fallback-syntax for undetected files (#3617)

* feat(cli): add fallback syntax option

Expose a new fallback syntax CLI option so users can opt into syntax highlighting only when auto-detection fails.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* feat(syntax): apply fallback only after detection fails

Use the fallback syntax only when path and first-line detection fail, preserving existing behavior for detected files and explicit language selection.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* test(cli): cover fallback syntax behavior

Add integration coverage for fallback syntax usage, precedence with --language, and no-op behavior when syntax is already detected; update help snapshots for the new option.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* docs(changelog): document fallback syntax option

Record the new fallback syntax feature in the unreleased changelog section.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
Rizky Mirzaviandy Priambodo
2026-03-08 10:18:29 +07:00
committed by GitHub
parent ab80bd9717
commit 844bfded50
9 changed files with 166 additions and 9 deletions
+115
View File
@@ -2470,6 +2470,121 @@ fn no_first_line_fallback_when_mapping_to_invalid_syntax() {
.stderr(predicate::str::contains("unknown syntax: 'InvalidSyntax'"));
}
#[test]
fn fallback_syntax_is_used_when_no_syntax_is_detected() {
let content = "# comment\nfoo=bar\n";
let fallback_output = bat()
.arg("--color=always")
.arg("--style=plain")
.arg("--file-name=unknown.fallbacksyntax")
.arg("--fallback-syntax=bash")
.write_stdin(content)
.assert()
.success()
.get_output()
.stdout
.clone();
let explicit_output = bat()
.arg("--color=always")
.arg("--style=plain")
.arg("--language=bash")
.arg("--file-name=unknown.fallbacksyntax")
.write_stdin(content)
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(
from_utf8(&fallback_output).expect("output is valid utf-8"),
from_utf8(&explicit_output).expect("output is valid utf-8")
);
}
#[test]
fn fallback_syntax_does_not_override_detected_syntax() {
let content = "fn main() { println!(\"hello\"); }\n";
let with_fallback = bat()
.arg("--color=always")
.arg("--style=plain")
.arg("--file-name=test.rs")
.arg("--fallback-syntax=json")
.write_stdin(content)
.assert()
.success()
.get_output()
.stdout
.clone();
let without_fallback = bat()
.arg("--color=always")
.arg("--style=plain")
.arg("--file-name=test.rs")
.write_stdin(content)
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(
from_utf8(&with_fallback).expect("output is valid utf-8"),
from_utf8(&without_fallback).expect("output is valid utf-8")
);
}
#[test]
fn fallback_syntax_does_not_override_explicit_language() {
let content = "{\"a\": 1}\n";
let with_fallback = bat()
.arg("--color=always")
.arg("--style=plain")
.arg("--language=json")
.arg("--fallback-syntax=rust")
.arg("--file-name=unknown.fallbacksyntax")
.write_stdin(content)
.assert()
.success()
.get_output()
.stdout
.clone();
let without_fallback = bat()
.arg("--color=always")
.arg("--style=plain")
.arg("--language=json")
.arg("--file-name=unknown.fallbacksyntax")
.write_stdin(content)
.assert()
.success()
.get_output()
.stdout
.clone();
assert_eq!(
from_utf8(&with_fallback).expect("output is valid utf-8"),
from_utf8(&without_fallback).expect("output is valid utf-8")
);
}
#[test]
fn invalid_fallback_syntax_returns_error() {
bat()
.arg("--color=always")
.arg("--style=plain")
.arg("--file-name=unknown.fallbacksyntax")
.arg("--fallback-syntax=InvalidSyntax")
.write_stdin("foo\n")
.assert()
.failure()
.stderr(predicate::str::contains("unknown syntax: 'InvalidSyntax'"));
}
#[test]
fn show_all_mode() {
bat()