mirror of
https://github.com/sharkdp/bat.git
synced 2025-02-16 17:51:31 +01:00
Added tab expansion preprocessing step.
This commit is contained in:
parent
8b4abb03db
commit
b23ff24ebc
18
src/app.rs
18
src/app.rs
@ -41,6 +41,9 @@ pub struct Config<'a> {
|
||||
/// The character width of the terminal
|
||||
pub term_width: usize,
|
||||
|
||||
/// The width of tab characters.
|
||||
pub tab_width: usize,
|
||||
|
||||
/// Whether or not to simply loop through all input (`cat` mode)
|
||||
pub loop_through: bool,
|
||||
|
||||
@ -276,6 +279,15 @@ impl App {
|
||||
'unbuffered'). The output is always unbuffered - this option \
|
||||
is simply ignored.",
|
||||
),
|
||||
).arg(
|
||||
Arg::with_name("tabs")
|
||||
.long("tabs")
|
||||
.short("t")
|
||||
.takes_value(true)
|
||||
.value_name("width")
|
||||
.help("Sets the tab width.")
|
||||
.long_help("Sets the tab width. Use a width of 0 to pass tabs through \
|
||||
directly"),
|
||||
).arg(
|
||||
Arg::with_name("terminal-width")
|
||||
.long("terminal-width")
|
||||
@ -393,6 +405,12 @@ impl App {
|
||||
|| self.matches.value_of("color") == Some("always")
|
||||
|| self.matches.value_of("decorations") == Some("always")),
|
||||
files,
|
||||
tab_width: self
|
||||
.matches
|
||||
.value_of("tabs")
|
||||
.and_then(|w| w.parse().ok())
|
||||
.or_else(|| env::var("BAT_TABS").ok().and_then(|w| w.parse().ok()))
|
||||
.unwrap_or(8),
|
||||
theme: self
|
||||
.matches
|
||||
.value_of("theme")
|
||||
|
@ -24,6 +24,7 @@ mod decorations;
|
||||
mod diff;
|
||||
mod line_range;
|
||||
mod output;
|
||||
mod preprocessor;
|
||||
mod printer;
|
||||
mod style;
|
||||
mod terminal;
|
||||
|
35
src/preprocessor.rs
Normal file
35
src/preprocessor.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use console::AnsiCodeIterator;
|
||||
|
||||
/// Expand tabs like an ANSI-enabled expand(1).
|
||||
pub fn expand(line: &str, width: usize) -> String {
|
||||
let mut buffer = String::with_capacity(line.len() * 2);
|
||||
let mut cursor = 0;
|
||||
|
||||
for chunk in AnsiCodeIterator::new(line) {
|
||||
match chunk {
|
||||
(text, true) => buffer.push_str(text),
|
||||
(mut text, false) => {
|
||||
while let Some(index) = text.find('\t') {
|
||||
// Add previous text.
|
||||
if index > 0 {
|
||||
cursor += index;
|
||||
buffer.push_str(&text[0..index]);
|
||||
}
|
||||
|
||||
// Add tab.
|
||||
let spaces = width - (cursor % width);
|
||||
cursor += spaces;
|
||||
buffer.push_str(&*" ".repeat(spaces));
|
||||
|
||||
// Next.
|
||||
text = &text[index + 1..text.len()];
|
||||
}
|
||||
|
||||
cursor += text.len();
|
||||
buffer.push_str(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer
|
||||
}
|
@ -16,6 +16,7 @@ use decorations::{Decoration, GridBorderDecoration, LineChangesDecoration, LineN
|
||||
use diff::get_git_diff;
|
||||
use diff::LineChanges;
|
||||
use errors::*;
|
||||
use preprocessor::expand;
|
||||
use style::OutputWrap;
|
||||
use terminal::{as_terminal_escaped, to_ansi_color};
|
||||
|
||||
@ -200,9 +201,17 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
||||
line_number: usize,
|
||||
line_buffer: &[u8],
|
||||
) -> Result<()> {
|
||||
let line = String::from_utf8_lossy(&line_buffer);
|
||||
let mut line = String::from_utf8_lossy(&line_buffer).to_string();
|
||||
|
||||
// Preprocess.
|
||||
if self.config.tab_width > 0 {
|
||||
line = expand(&line, self.config.tab_width);
|
||||
}
|
||||
|
||||
// Highlight.
|
||||
let regions = self.highlighter.highlight(line.as_ref());
|
||||
|
||||
// Print.
|
||||
if out_of_range {
|
||||
return Ok(());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user