Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@altsem
Copy link
Owner

@altsem altsem commented Oct 19, 2025

No description provided.

@altsem altsem requested a review from Copilot October 19, 2025 08:52
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR enhances diff and status parsing to correctly handle filenames without a/b prefixes and quoted/unicode paths, and improves parse error diagnostics. Key updates include a new FilePath type with quoting support, a revamped parser error model with richer context, and updates across ops and UI to use the new path formatting. Tests were added for non-ASCII filenames, quoted escapes, and ambiguous cases.

  • Add FilePath with fmt() to unescape quoted paths (using smashquote) and switch DiffHeader to use FilePath.
  • Overhaul parser errors to accumulate ThinParseError with contextual formatting and logging; support headers without prefixes and robust newline-or-EOF handling.
  • Update ops, UI rendering, and status parsing to use Strings/Cow for paths; add tests for non-ASCII and quoted filenames.

Reviewed Changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/tests/snapshots/gitu__tests__non_ascii_filename.snap Adds snapshot to validate UI with non-ASCII filenames.
src/tests/mod.rs Adds test to exercise non-ASCII filename handling.
src/screen/status.rs Switches untracked paths to String-based flow and PathBuf conversion.
src/ops/unstage.rs Uses FilePath::fmt() for path resolution in unstage.
src/ops/stage.rs Uses FilePath::fmt() for path resolution in stage.
src/ops/show.rs Uses FilePath::fmt() for editor paths.
src/ops/discard.rs Uses FilePath::fmt() for paths; adjusts discard behavior for Added/Renamed/Other.
src/items.rs Formats displayed filenames using FilePath::fmt().
src/highlight.rs Uses FilePath::fmt() for syntax highlight path discrimination.
src/gitu_diff.rs Major parser refactor: FilePath, improved errors, support for quoted/unprefixed paths.
src/git/status.rs Changes StatusFile path types to String.
src/git/parse/status/mod.rs Parses status paths as Strings and unescapes quoted paths (for path; not yet for new_path).
Cargo.toml Adds tinyvec and smashquote dependencies.

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +26 to +30
ItemData::Delta { diff, file_i } => {
let file_path = &diff.file_diffs[*file_i].header.new_file;
let path: &str = &file_path.fmt(&diff.text);
editor(Path::new(path), None)
}
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This takes a reference to a temporary Cow returned by fmt(), resulting in a dangling reference. Bind the Cow (or an owned String) to a local variable so it lives through the call.

Copilot uses AI. Check for mistakes.
Comment on lines +35 to +42
} => {
let file_path = &diff.file_diffs[*file_i].header.new_file;
let path: &str = &file_path.fmt(&diff.text);
editor(
Path::new(path),
Some(diff.file_line_of_first_diff(*file_i, *hunk_i) as u32),
)
}
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same temporary reference issue as above; path borrows from a temporary Cow. Store the Cow or an owned String in a local variable before passing a reference to Path::new.

Copilot uses AI. Check for mistakes.
let old_mask = diff.mask_old_hunk(file_index, hunk_index);
let old_file_range = file_diff.header.old_file.clone();
let old_path = &diff.text[old_file_range];
let old_path = &old_file_range.fmt(&diff.text);
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both lines take references to temporary Cow values returned by fmt(), which will drop immediately, leaving dangling references. Assign the Cow to a local variable and pass a reference to its contents.

Copilot uses AI. Check for mistakes.
let new_mask = diff.mask_new_hunk(file_index, hunk_index);
let new_file_range = file_diff.header.new_file.clone();
let new_path = &diff.text[new_file_range];
let new_path = &new_file_range.fmt(&diff.text);
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both lines take references to temporary Cow values returned by fmt(), which will drop immediately, leaving dangling references. Assign the Cow to a local variable and pass a reference to its contents.

Copilot uses AI. Check for mistakes.
// TODO Need to handle invalid unicode
let line_start = self.input[..cursor].rfind('\n').unwrap_or(0);
let line_end = self.input[line_start..]
.find('\n')
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line_end is computed as an offset within the slice self.input[line_start..] but then used as an absolute index, which can cause slicing panics. Convert the relative offset to an absolute index.

Suggested change
.find('\n')
.find('\n')
.map(|offset| line_start + offset)

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +29
let file_path = &diff.file_diffs[*file_i].header.new_file;
let path: &str = &file_path.fmt(&diff.text);
editor(Path::new(path), None)
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested fix: bind the Cow to a local variable to avoid borrowing a temporary. For example: let path = file_path.fmt(&diff.text); editor(Path::new(path.as_ref()), None).

Copilot uses AI. Check for mistakes.
Comment on lines +36 to +41
let file_path = &diff.file_diffs[*file_i].header.new_file;
let path: &str = &file_path.fmt(&diff.text);
editor(
Path::new(path),
Some(diff.file_line_of_first_diff(*file_i, *hunk_i) as u32),
)
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested fix: let path = file_path.fmt(&diff.text); editor(Path::new(path.as_ref()), Some(...)). This ensures the referent outlives the call.

Copilot uses AI. Check for mistakes.
let old_mask = diff.mask_old_hunk(file_index, hunk_index);
let old_file_range = file_diff.header.old_file.clone();
let old_path = &diff.text[old_file_range];
let old_path = &old_file_range.fmt(&diff.text);
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested fix: store the Cow in locals so their lifetimes cover the call: let old = old_file_range.fmt(&diff.text); let newp = new_file_range.fmt(&diff.text); then pass old.as_ref(), newp.as_ref() to iter_syntax_highlights.

Copilot uses AI. Check for mistakes.
let new_mask = diff.mask_new_hunk(file_index, hunk_index);
let new_file_range = file_diff.header.new_file.clone();
let new_path = &diff.text[new_file_range];
let new_path = &new_file_range.fmt(&diff.text);
Copy link

Copilot AI Oct 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested fix: store the Cow in locals so their lifetimes cover the call: let old = old_file_range.fmt(&diff.text); let newp = new_file_range.fmt(&diff.text); then pass old.as_ref(), newp.as_ref() to iter_syntax_highlights.

Copilot uses AI. Check for mistakes.
@altsem altsem force-pushed the improve-filename-parsing branch from 21610ed to ba69ec4 Compare October 19, 2025 09:07
@altsem altsem merged commit e40cfc8 into master Oct 19, 2025
3 checks passed
@altsem altsem deleted the improve-filename-parsing branch October 19, 2025 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants