From 904cec3c4a329cf89fc3219d359239910d61f3f6 Mon Sep 17 00:00:00 2001 From: thing1 Date: Tue, 28 Jan 2025 09:14:32 +0000 Subject: init commit --- autoload/tools/patch.kak | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 autoload/tools/patch.kak (limited to 'autoload/tools/patch.kak') diff --git a/autoload/tools/patch.kak b/autoload/tools/patch.kak new file mode 100644 index 0000000..a481ff4 --- /dev/null +++ b/autoload/tools/patch.kak @@ -0,0 +1,63 @@ +define-command patch -params .. -docstring %{ + patch []: apply selections in diff to a file + + Given some selections within a unified diff, apply the changed lines in + each selection by piping them to "patch 1>&2" + (or " 1>&2" if starts with a non-option argument). + If successful, the in-buffer diff will be updated to reflect the applied + changes. + For selections that contain no newline, the entire enclosing diff hunk + is applied (unless the cursor is inside a diff header, in which case + the entire diff is applied). + To revert changes, must contain "--reverse" or "-R". +} %{ + evaluate-commands -draft -itersel -save-regs aes|^ %{ + try %{ + execute-keys \n + } catch %{ + # The selection contains no newline. + execute-keys -save-regs '' Z + execute-keys ^diff + try %{ + execute-keys ^@@ + # If the cursor is in a diff hunk, stage the entire hunk. + execute-keys z + execute-keys /.*?(?:(?=\n@@)|(?=\ndiff)|(?=\n\n)|\z)x^@@ + } catch %{ + # If the cursor is in a diff header, stage the entire diff. + execute-keys ?.*?(?:(?=\ndiff)|(?=\n\n)|\z) + } + } + # We want to apply only the selected lines. Remember them. + execute-keys + set-register s %val{selection_desc} + # Select forward until the end of the last hunk. + execute-keys H?.*?(?:(?=\n@@)|(?=\ndiff)|(?=\n\n)|\z)x + # Select backward to the beginning of the first hunk's diff header. + execute-keys ^diff + # Move cursor to the beginning so we know the diff's offset within the buffer. + execute-keys + set-register a %arg{@} + set-register e nop + set-register | %{ + # The selected range to apply. + IFS=' .,' read min_line _ max_line _ <<-EOF + $kak_reg_s + EOF + min_line=$((min_line - kak_cursor_line + 1)) + max_line=$((max_line - kak_cursor_line + 1)) + + # Since registers are never empty, we get an empty arg even if + # there were no args. This does no harm because we pass it to + # a shell where it expands to nothing. + eval set -- "$kak_quoted_reg_a" + + perl "${kak_runtime}"/rc/tools/patch-range.pl $min_line $max_line "$@" || + echo >$kak_command_fifo "set-register e fail 'patch: failed to apply selections, see *debug* buffer'" + } + execute-keys | + %reg{e} + } +} + +provide-module patch %ยงยง -- cgit v1.2.3