mirror of
https://github.com/sharkdp/bat.git
synced 2024-11-21 15:23:19 +01:00
Merge pull request #2998 from eth-p/improve-preprocessor
Update bat's tab expansion preprocessor to use bat's ANSI escape sequence iterator.
This commit is contained in:
commit
10a1b24191
@ -38,6 +38,7 @@
|
||||
- Display which theme is the default one in colored output, see #2838 (@sblondon)
|
||||
- Add aarch64-apple-darwin ("Apple Silicon") binary tarballs to releases, see #2967 (@someposer)
|
||||
- Update the Lisp syntax, see #2970 (@ccqpein)
|
||||
- Use bat's ANSI iterator during tab expansion, see #2998 (@eth-p)
|
||||
|
||||
## Syntaxes
|
||||
|
||||
|
@ -1,17 +1,18 @@
|
||||
use std::fmt::Write;
|
||||
|
||||
use console::AnsiCodeIterator;
|
||||
|
||||
use crate::nonprintable_notation::NonprintableNotation;
|
||||
use crate::{
|
||||
nonprintable_notation::NonprintableNotation,
|
||||
vscreen::{EscapeSequenceOffsets, EscapeSequenceOffsetsIterator},
|
||||
};
|
||||
|
||||
/// Expand tabs like an ANSI-enabled expand(1).
|
||||
pub fn expand_tabs(line: &str, width: usize, cursor: &mut usize) -> String {
|
||||
let mut buffer = String::with_capacity(line.len() * 2);
|
||||
|
||||
for chunk in AnsiCodeIterator::new(line) {
|
||||
match chunk {
|
||||
(text, true) => buffer.push_str(text),
|
||||
(mut text, false) => {
|
||||
for seq in EscapeSequenceOffsetsIterator::new(line) {
|
||||
match seq {
|
||||
EscapeSequenceOffsets::Text { .. } => {
|
||||
let mut text = &line[seq.index_of_start()..seq.index_past_end()];
|
||||
while let Some(index) = text.find('\t') {
|
||||
// Add previous text.
|
||||
if index > 0 {
|
||||
@ -31,6 +32,10 @@ pub fn expand_tabs(line: &str, width: usize, cursor: &mut usize) -> String {
|
||||
*cursor += text.len();
|
||||
buffer.push_str(text);
|
||||
}
|
||||
_ => {
|
||||
// Copy the ANSI escape sequence.
|
||||
buffer.push_str(&line[seq.index_of_start()..seq.index_past_end()])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ fn join(
|
||||
|
||||
/// A range of indices for a raw ANSI escape sequence.
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum EscapeSequenceOffsets {
|
||||
pub enum EscapeSequenceOffsets {
|
||||
Text {
|
||||
start: usize,
|
||||
end: usize,
|
||||
@ -320,6 +320,32 @@ enum EscapeSequenceOffsets {
|
||||
},
|
||||
}
|
||||
|
||||
impl EscapeSequenceOffsets {
|
||||
/// Returns the byte-index of the first character in the escape sequence.
|
||||
pub fn index_of_start(&self) -> usize {
|
||||
use EscapeSequenceOffsets::*;
|
||||
match self {
|
||||
Text { start, .. } => *start,
|
||||
Unknown { start, .. } => *start,
|
||||
NF { start_sequence, .. } => *start_sequence,
|
||||
OSC { start_sequence, .. } => *start_sequence,
|
||||
CSI { start_sequence, .. } => *start_sequence,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the byte-index past the last character in the escape sequence.
|
||||
pub fn index_past_end(&self) -> usize {
|
||||
use EscapeSequenceOffsets::*;
|
||||
match self {
|
||||
Text { end, .. } => *end,
|
||||
Unknown { end, .. } => *end,
|
||||
NF { end, .. } => *end,
|
||||
OSC { end, .. } => *end,
|
||||
CSI { end, .. } => *end,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over the offests of ANSI/VT escape sequences within a string.
|
||||
///
|
||||
/// ## Example
|
||||
@ -327,7 +353,7 @@ enum EscapeSequenceOffsets {
|
||||
/// ```ignore
|
||||
/// let iter = EscapeSequenceOffsetsIterator::new("\x1B[33mThis is yellow text.\x1B[m");
|
||||
/// ```
|
||||
struct EscapeSequenceOffsetsIterator<'a> {
|
||||
pub struct EscapeSequenceOffsetsIterator<'a> {
|
||||
text: &'a str,
|
||||
chars: Peekable<CharIndices<'a>>,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user