use std::borrow::Cow;
use lazy_static::lazy_static;
use regex::Regex;
use serde::Deserialize;
use crate::ansi;
use crate::config::{
delta_unreachable, GrepType, 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);
self.submatches = self.submatches.as_ref().map(|submatches| {
submatches
.iter()
.map(|(a, b)| (a + shift, b + shift))
.collect()
});
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum LineType {
ContextHeader,
Context,
FileHeader,
Match,
Ignore,
}