mirror of
https://github.com/sharkdp/bat
synced 2024-11-18 15:26:16 +00: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
|
/// The character width of the terminal
|
||||||
pub term_width: usize,
|
pub term_width: usize,
|
||||||
|
|
||||||
|
/// The width of tab characters.
|
||||||
|
pub tab_width: usize,
|
||||||
|
|
||||||
/// Whether or not to simply loop through all input (`cat` mode)
|
/// Whether or not to simply loop through all input (`cat` mode)
|
||||||
pub loop_through: bool,
|
pub loop_through: bool,
|
||||||
|
|
||||||
@ -276,6 +279,15 @@ impl App {
|
|||||||
'unbuffered'). The output is always unbuffered - this option \
|
'unbuffered'). The output is always unbuffered - this option \
|
||||||
is simply ignored.",
|
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(
|
||||||
Arg::with_name("terminal-width")
|
Arg::with_name("terminal-width")
|
||||||
.long("terminal-width")
|
.long("terminal-width")
|
||||||
@ -393,6 +405,12 @@ impl App {
|
|||||||
|| self.matches.value_of("color") == Some("always")
|
|| self.matches.value_of("color") == Some("always")
|
||||||
|| self.matches.value_of("decorations") == Some("always")),
|
|| self.matches.value_of("decorations") == Some("always")),
|
||||||
files,
|
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
|
theme: self
|
||||||
.matches
|
.matches
|
||||||
.value_of("theme")
|
.value_of("theme")
|
||||||
|
@ -24,6 +24,7 @@ mod decorations;
|
|||||||
mod diff;
|
mod diff;
|
||||||
mod line_range;
|
mod line_range;
|
||||||
mod output;
|
mod output;
|
||||||
|
mod preprocessor;
|
||||||
mod printer;
|
mod printer;
|
||||||
mod style;
|
mod style;
|
||||||
mod terminal;
|
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::get_git_diff;
|
||||||
use diff::LineChanges;
|
use diff::LineChanges;
|
||||||
use errors::*;
|
use errors::*;
|
||||||
|
use preprocessor::expand;
|
||||||
use style::OutputWrap;
|
use style::OutputWrap;
|
||||||
use terminal::{as_terminal_escaped, to_ansi_color};
|
use terminal::{as_terminal_escaped, to_ansi_color};
|
||||||
|
|
||||||
@ -200,9 +201,17 @@ impl<'a> Printer for InteractivePrinter<'a> {
|
|||||||
line_number: usize,
|
line_number: usize,
|
||||||
line_buffer: &[u8],
|
line_buffer: &[u8],
|
||||||
) -> Result<()> {
|
) -> 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());
|
let regions = self.highlighter.highlight(line.as_ref());
|
||||||
|
|
||||||
|
// Print.
|
||||||
if out_of_range {
|
if out_of_range {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user