rc tools git: blame-jump to handle buffer modifications since blame
If I run git blame execute-keys 10o<esc>,j git blame-jump that'll jump to the wrong commit. Use a flag-lines option to tell if a line still has blame information cached. Closes #5084
This commit is contained in:
parent
7cea09d327
commit
c97add7f5a
|
@ -74,6 +74,7 @@ hook -group git-show-branch-highlight global WinSetOption filetype=git-show-bran
|
|||
}
|
||||
|
||||
declare-option -hidden line-specs git_blame_flags
|
||||
declare-option -hidden line-specs git_blame_index
|
||||
declare-option -hidden str git_blame
|
||||
declare-option -hidden str git_blob
|
||||
declare-option -hidden line-specs git_diff_flags
|
||||
|
@ -180,6 +181,7 @@ define-command -params 1.. \
|
|||
hide_blame() {
|
||||
printf %s "
|
||||
set-option buffer git_blame_flags $kak_timestamp
|
||||
set-option buffer git_blame_index $kak_timestamp
|
||||
set-option buffer git_blame %{}
|
||||
remove-highlighter window/git-blame
|
||||
unmap window normal <ret> %{:git blame-jump<ret>}
|
||||
|
@ -272,6 +274,7 @@ define-command -params 1.. \
|
|||
cd_bufdir
|
||||
printf %s "evaluate-commands -client '$kak_client' %{
|
||||
set-option buffer=$kak_bufname git_blame_flags '$kak_timestamp'
|
||||
set-option buffer=$kak_bufname git_blame_index '$kak_timestamp'
|
||||
set-option buffer=$kak_bufname git_blame ''
|
||||
}" | kak -p ${kak_session}
|
||||
git blame --incremental "$@" <${contents_fifo} | perl -wne '
|
||||
|
@ -297,9 +300,11 @@ define-command -params 1.. \
|
|||
}
|
||||
open CMD, "|-", "kak -p $ENV{kak_session}";
|
||||
print CMD "set-option -add buffer=$ENV{kak_bufname} git_blame_flags $flags;";
|
||||
print CMD "set-option -add buffer=$ENV{kak_bufname} git_blame_index $index;";
|
||||
print CMD "set-option -add buffer=$ENV{kak_bufname} git_blame " . quote $raw_blame;
|
||||
close(CMD);
|
||||
$flags = "";
|
||||
$index = "";
|
||||
$raw_blame = "";
|
||||
$last_sent = $now;
|
||||
}
|
||||
|
@ -310,6 +315,9 @@ define-command -params 1.. \
|
|||
$sha = $1;
|
||||
$line = $3;
|
||||
$count = $4;
|
||||
for ( my $i = 0; $i < $count; $i++ ) {
|
||||
$index .= " " . ($line+$i) . "|$.,$i";
|
||||
}
|
||||
}
|
||||
if (m/^author /) {
|
||||
$authors{$sha} = substr($_,7);
|
||||
|
@ -483,11 +491,16 @@ define-command -params 1.. \
|
|||
blame_jump() {
|
||||
echo >${kak_command_fifo} "echo -to-file ${kak_response_fifo} -- %opt{git_blame}"
|
||||
blame_info=$(cat < ${kak_response_fifo})
|
||||
blame_index=
|
||||
cursor_column=${kak_cursor_column}
|
||||
cursor_line=${kak_cursor_line}
|
||||
if [ -z "$blame_info" ] && {
|
||||
[ "${kak_opt_filetype}" = git-diff ] || [ "${kak_opt_filetype}" = git-log ]
|
||||
}; then {
|
||||
if [ -n "$blame_info" ]; then {
|
||||
echo >${kak_command_fifo} "
|
||||
update-option buffer git_blame_index
|
||||
echo -to-file ${kak_response_fifo} -- %opt{git_blame_index}
|
||||
"
|
||||
blame_index=$(cat < ${kak_response_fifo})
|
||||
} elif [ "${kak_opt_filetype}" = git-diff ] || [ "${kak_opt_filetype}" = git-log ]; then {
|
||||
printf >${kak_command_fifo} %s '
|
||||
evaluate-commands -draft %{
|
||||
try %{
|
||||
|
@ -528,7 +541,7 @@ define-command -params 1.. \
|
|||
cursor_line=$3
|
||||
cursor_column=$4
|
||||
blame_info=$(git blame --porcelain "$starting_commit" -L"$cursor_line,$cursor_line" -- "$file")
|
||||
} elif [ -z "$blame_info" ]; then {
|
||||
} else {
|
||||
set --
|
||||
eval "$prepare_git_blame_args"
|
||||
blame_info=$(git blame --porcelain -L"$cursor_line,$cursor_line" "$@" <${contents_fifo})
|
||||
|
@ -536,7 +549,7 @@ define-command -params 1.. \
|
|||
rm -r $(dirname $contents_fifo)
|
||||
fi
|
||||
} fi
|
||||
eval "$(printf %s "$blame_info" |
|
||||
eval "$(printf '%s\n---\n%s' "$blame_index" "$blame_info" |
|
||||
client=${kak_opt_docsclient:-$kak_client} \
|
||||
cursor_line=$cursor_line cursor_column=$cursor_column \
|
||||
perl -wne '
|
||||
|
@ -562,8 +575,28 @@ define-command -params 1.. \
|
|||
return "$SQ$token$SQ";
|
||||
}
|
||||
$target = $ENV{"cursor_line"};
|
||||
$state = "index";
|
||||
}
|
||||
chomp;
|
||||
if ($state eq "index") {
|
||||
if ($_ eq "---") {
|
||||
$state = "blame";
|
||||
next;
|
||||
}
|
||||
@blame_index = split;
|
||||
next unless @blame_index;
|
||||
shift @blame_index;
|
||||
foreach (@blame_index) {
|
||||
$_ =~ m{(\d+)\|(\d+),(\d+)} or die "bad blame index flag: $_";
|
||||
my $buffer_line = $1;
|
||||
if ($buffer_line == $target) {
|
||||
$target_in_blame = $2;
|
||||
$target_offset = $3;
|
||||
last;
|
||||
}
|
||||
}
|
||||
defined $target_in_blame and next, or last;
|
||||
}
|
||||
if (m/^([0-9a-f]+) ([0-9]+) ([0-9]+) ([0-9]+)/) {
|
||||
if ($done) {
|
||||
last;
|
||||
|
@ -572,16 +605,27 @@ define-command -params 1.. \
|
|||
$old_line = $2;
|
||||
$new_line = $3;
|
||||
$count = $4;
|
||||
if (defined $target_in_blame) {
|
||||
if ($target_in_blame == $. - 2) {
|
||||
$old_line += $target_offset;
|
||||
$done = 1;
|
||||
}
|
||||
} else {
|
||||
if ($new_line <= $target and $target < $new_line + $count) {
|
||||
$old_line += $target - $new_line;
|
||||
$done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m/^filename /) { $old_filenames{$sha} = substr($_,9) }
|
||||
if (m/^author /) { $authors{$sha} = substr($_,7) }
|
||||
if (m/^author-time ([0-9]*)/) { $dates{$sha} = strftime("%F", localtime $1) }
|
||||
if (m/^summary /) { $summaries{$sha} = substr($_,8) }
|
||||
END {
|
||||
if (@blame_index and not defined $target_in_blame) {
|
||||
print "echo fail git blame-jump: line has no blame information;";
|
||||
exit;
|
||||
}
|
||||
if (not defined $sha) {
|
||||
print "echo fail git blame-jump: missing blame info";
|
||||
exit;
|
||||
|
|
Loading…
Reference in New Issue
Block a user