Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move AmbiguousDiffMinusCounter to hunk_header #1825

Merged
merged 1 commit into from
Aug 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 1 addition & 57 deletions src/delta.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::convert::TryInto;
use std::io::{self, BufRead, IsTerminal, Write};

use bytelines::ByteLines;
Expand All @@ -11,7 +10,7 @@ use crate::config::Config;
use crate::config::GrepType;
use crate::features;
use crate::handlers::grep;
use crate::handlers::hunk_header::ParsedHunkHeader;
use crate::handlers::hunk_header::{AmbiguousDiffMinusCounter, ParsedHunkHeader};
use crate::handlers::{self, merge_conflict};
use crate::paint::Painter;
use crate::style::DecorationStyle;
Expand Down Expand Up @@ -78,61 +77,6 @@ pub enum Source {
Unknown,
}

// The output of `diff -u file1 file2` does not contain a header before the
// `--- old.lua` / `+++ new.lua` block, and the hunk can of course contain lines
// starting with '-- '. To avoid interpreting '--- lua comment' as a new header,
// count the minus lines in a hunk (provided by the '@@ -1,4 +1,3 @@' header).
// `diff` itself can not generate two diffs in this ambiguous format, so a second header
// could just be ignored. But concatenated diffs exist and are accepted by `patch`.
#[derive(Debug)]
pub struct AmbiguousDiffMinusCounter(isize);

impl AmbiguousDiffMinusCounter {
// The internal isize representation avoids calling `if let Some(..)` on every line. For
// nearly all input the counter is not needed, in this case it is decremented but ignored.
// [min, COUNTER_RELEVANT_IF_GT] unambiguous diff
// (COUNTER_RELEVANT_IF_GT, 0] handle next '--- ' like a header, and set counter in next @@ block
// [1, max] counting minus lines in ambiguous header
const COUNTER_RELEVANT_IF_GREATER_THAN: isize = -4096; // -1 works too, but be defensive
const EXPECT_DIFF_3DASH_HEADER: isize = 0;
pub fn not_needed() -> Self {
Self(Self::COUNTER_RELEVANT_IF_GREATER_THAN)
}
pub fn count_from(lines: usize) -> Self {
Self(
lines
.try_into()
.unwrap_or(Self::COUNTER_RELEVANT_IF_GREATER_THAN),
)
}
pub fn prepare_to_count() -> Self {
Self(Self::EXPECT_DIFF_3DASH_HEADER)
}
pub fn three_dashes_expected(&self) -> bool {
if self.0 > Self::COUNTER_RELEVANT_IF_GREATER_THAN {
self.0 <= Self::EXPECT_DIFF_3DASH_HEADER
} else {
true
}
}
#[allow(clippy::needless_bool)]
pub fn must_count(&mut self) -> bool {
let relevant = self.0 > Self::COUNTER_RELEVANT_IF_GREATER_THAN;
if relevant {
true
} else {
#[cfg(target_pointer_width = "32")]
{
self.0 = Self::COUNTER_RELEVANT_IF_GREATER_THAN;
}
false
}
}
pub fn count_line(&mut self) {
self.0 -= 1;
}
}

// Possible transitions, with actions on entry:
//
//
Expand Down
66 changes: 60 additions & 6 deletions src/handlers/hunk_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,18 @@
// src/hunk_header.rs:119: fn write_to_output_buffer( │
// ───────────────────────────────────────────────────┘
// ```

use std::convert::TryInto;
use std::fmt::Write as FmtWrite;

use lazy_static::lazy_static;
use regex::Regex;

use super::draw;
use crate::config::{
Config, HunkHeaderIncludeCodeFragment, HunkHeaderIncludeFilePath, HunkHeaderIncludeLineNumber,
};
use crate::delta::{self, DiffType, InMergeConflict, MergeParents, State, StateMachine};
use crate::paint::{self, BgShouldFill, Painter, StyleSectionSpecifier};
use crate::style::{DecorationStyle, Style};
use lazy_static::lazy_static;
use regex::Regex;

#[derive(Clone, Default, Debug, PartialEq, Eq)]
pub struct ParsedHunkHeader {
Expand All @@ -43,6 +42,62 @@ pub enum HunkHeaderIncludeHunkLabel {
No,
}

// The output of `diff -u file1 file2` does not contain a header before the
// `--- old.lua` / `+++ new.lua` block, and the hunk can of course contain lines
// starting with '-- '. To avoid interpreting '--- lua comment' as a new header,
// count the minus lines in a hunk (provided by the '@@ -1,4 +1,3 @@' header).
// `diff` itself can not generate two diffs in this ambiguous format, so a second header
// could just be ignored. But concatenated diffs exist and are accepted by `patch`.
#[derive(Debug)]
pub struct AmbiguousDiffMinusCounter(isize);

impl AmbiguousDiffMinusCounter {
// The internal isize representation avoids calling `if let Some(..)` on every line. For
// nearly all input the counter is not needed, in this case it is decremented but ignored.
// [min, COUNTER_RELEVANT_IF_GT] unambiguous diff
// (COUNTER_RELEVANT_IF_GT, 0] handle next '--- ' like a header, and set counter in next @@ block
// [1, max] counting minus lines in ambiguous header
const COUNTER_RELEVANT_IF_GREATER_THAN: isize = -4096; // -1 works too, but be defensive
const EXPECT_DIFF_3DASH_HEADER: isize = 0;

pub fn not_needed() -> Self {
Self(Self::COUNTER_RELEVANT_IF_GREATER_THAN)
}
pub fn prepare_to_count() -> Self {
Self(Self::EXPECT_DIFF_3DASH_HEADER)
}
pub fn three_dashes_expected(&self) -> bool {
if self.0 > Self::COUNTER_RELEVANT_IF_GREATER_THAN {
self.0 <= Self::EXPECT_DIFF_3DASH_HEADER
} else {
true
}
}
pub fn count_line(&mut self) {
self.0 -= 1;
}
fn count_from(lines: usize) -> Self {
Self(
lines
.try_into()
.unwrap_or(Self::COUNTER_RELEVANT_IF_GREATER_THAN),
)
}
#[allow(clippy::needless_bool)]
fn must_count(&mut self) -> bool {
let relevant = self.0 > Self::COUNTER_RELEVANT_IF_GREATER_THAN;
if relevant {
true
} else {
#[cfg(target_pointer_width = "32")]
{
self.0 = Self::COUNTER_RELEVANT_IF_GREATER_THAN;
}
false
}
}
}

impl<'a> StateMachine<'a> {
#[inline]
fn test_hunk_header_line(&self) -> bool {
Expand Down Expand Up @@ -77,8 +132,7 @@ impl<'a> StateMachine<'a> {
if let &[(_, minus_lines), (_, _plus_lines), ..] =
parsed_hunk_header.line_numbers_and_hunk_lengths.as_slice()
{
self.minus_line_counter =
delta::AmbiguousDiffMinusCounter::count_from(minus_lines);
self.minus_line_counter = AmbiguousDiffMinusCounter::count_from(minus_lines);
}
}

Expand Down
Loading