summaryrefslogtreecommitdiff
path: root/rc/tools/patch-range.pl
diff options
context:
space:
mode:
authorJohannes Altmanninger <aclopte@gmail.com>2024-09-14 12:25:02 +0200
committerMaxime Coste <mawww@kakoune.org>2024-09-16 15:23:18 +1000
commit54992c08aecb2fc91aecacccc15d3a17ae7390dc (patch)
treefb8cc822bb2105111b93bb1f1ad96759ac22262f /rc/tools/patch-range.pl
parentaac32e0f5ad3332775a4f3e3092a4fd8a6c0db62 (diff)
rc git: teach "git apply" to work on content, not just diffs
Staging/unstaging/reverting (parts of) the current buffer's file can be a common use case. Today "git apply" can do that based on a selection within a diff. When the selection is on uncommitted content, we can probably assume that the intent is to use the part of the selection that overlaps with the +-side of "git diff" (or "git diff --cached" for "git apply --cached"). Make "git apply" treat selections as content if the buffile is tracked by Git. This differentiator is not perfect but I don't know why anyone would want to use the existing "git apply" semantics on a tracked file. Maybe we should pick a different name. This feature couples well with "git show-diff", which shows all lines with unstaged changes (in future it should probably show staged changes as well). Whereas on diffs, "git apply" stages the entire hunk if the selection contains no newline, this does not happen when operating on content. I didn't yet try implementing that. I guess the hunks are not as explicit here. Closes #5225
Diffstat (limited to 'rc/tools/patch-range.pl')
-rwxr-xr-xrc/tools/patch-range.pl20
1 files changed, 15 insertions, 5 deletions
diff --git a/rc/tools/patch-range.pl b/rc/tools/patch-range.pl
index 2d54ab26..01611abe 100755
--- a/rc/tools/patch-range.pl
+++ b/rc/tools/patch-range.pl
@@ -9,6 +9,12 @@ if ($ARGV[0] eq "-print-remaining-diff") {
shift @ARGV;
}
+my $line_number_kind = "diff";
+if ($ARGV[0] eq "-line-numbers-from-new-file") {
+ $line_number_kind = "new-file";
+ shift @ARGV;
+}
+
my $min_line = $ARGV[0];
shift @ARGV;
my $max_line = $ARGV[0];
@@ -22,7 +28,7 @@ if (defined $ARGV[0] and $ARGV[0] =~ m{^[^-]}) {
}
my $reverse = grep /^(--reverse|-R)$/, @ARGV;
-my $lineno = 0;
+my $lineno = $line_number_kind eq "diff" ? 0 : undef;
my $original = "";
my $diff_header = "";
my $wheat = "";
@@ -63,9 +69,9 @@ sub finish_hunk {
}
while (<STDIN>) {
- ++$lineno;
+ ++$lineno if $line_number_kind eq "diff";
$original .= $_;
- if (m{^diff}) {
+ if (m{^diff} || (not defined $state and m{^---})) {
finish_hunk();
$state = "diff header";
$diff_header = "";
@@ -74,7 +80,8 @@ while (<STDIN>) {
$signature .= $_ if $print_remaining;
next;
}
- if (m{^@@ -\d+(?:,(\d)+)? \+\d+(?:,\d+)? @@}) {
+ if (m{^@@ -\d+(?:,(\d)+)? \+(\d+)(?:,\d+)? @@}) {
+ $lineno = $2 - 1 if $line_number_kind eq "new-file";
$hunk_remaining_lines = $1 or 1;
finish_hunk();
$state = "diff hunk";
@@ -96,8 +103,11 @@ while (<STDIN>) {
$signature .= $_ if $print_remaining;
next;
}
+ ++$lineno if $line_number_kind eq "new-file" && m{^[ +]};
--$hunk_remaining_lines if m{^[ -]};
- my $include = m{^ } || ($lineno >= $min_line && $lineno <= $max_line);
+ my $include = m{^ } ||
+ ($lineno >= $min_line && $lineno <= $max_line) ||
+ ($line_number_kind eq "new-file" && m{^-} && $lineno == $min_line - 1);
if ($include) {
$hunk_wheat .= $_;
if ($print_remaining) {