use std::borrow::Cow;
use lazy_static::lazy_static;
use regex::Regex;
use serde::Deserialize;
use crate::ansi;
use crate::config::{
delta_unreachable, GrepType, HunkHeaderIncludeCodeFragment, HunkHeaderIncludeFilePath,
HunkHeaderIncludeLineNumber,
};
use crate::delta::{State, StateMachine};
use crate::handlers::{self, ripgrep_json};
use crate::paint::{self, BgShouldFill, StyleSectionSpecifier};
use crate::style::Style;
use crate::utils::{process, tabs};
use super::hunk_header::HunkHeaderIncludeHunkLabel;
#[derive(Debug, PartialEq, Eq)]
pub struct GrepLine<'b> {
pub grep_type: GrepType,
pub path: Cow<'b, str>,
pub line_number: Option<usize>,
pub line_type: LineType,
pub code: Cow<'b, str>,
pub submatches: Option<Vec<(usize, usize)>>,
}
impl<'b> GrepLine<'b> {
fn expand_tabs(&mut self, tab_cfg: &tabs::TabCfg) {
let old_len = self.code.len();
self.code = tabs::expand(&self.code, tab_cfg).into();
let shift = self.code.len().saturating_sub(old_len);
// HACK: it is not necessarily the case that all submatch coordinates
// should be shifted in this way. It should be true in a common case of:
// (a) the only tabs were at the beginning of the line, and (b) the user
// was not searching for tabs.
self.submatches = self.submatches.as_ref().map(|submatches| {
submatches
.iter()
.map(|(a, b)| (a + shift, b + shift))
.collect()
});
}
}
#[deriv