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_flags
|
||||||
|
declare-option -hidden line-specs git_blame_index
|
||||||
declare-option -hidden str git_blame
|
declare-option -hidden str git_blame
|
||||||
declare-option -hidden str git_blob
|
declare-option -hidden str git_blob
|
||||||
declare-option -hidden line-specs git_diff_flags
|
declare-option -hidden line-specs git_diff_flags
|
||||||
|
@ -180,6 +181,7 @@ define-command -params 1.. \
|
||||||
hide_blame() {
|
hide_blame() {
|
||||||
printf %s "
|
printf %s "
|
||||||
set-option buffer git_blame_flags $kak_timestamp
|
set-option buffer git_blame_flags $kak_timestamp
|
||||||
|
set-option buffer git_blame_index $kak_timestamp
|
||||||
set-option buffer git_blame %{}
|
set-option buffer git_blame %{}
|
||||||
remove-highlighter window/git-blame
|
remove-highlighter window/git-blame
|
||||||
unmap window normal <ret> %{:git blame-jump<ret>}
|
unmap window normal <ret> %{:git blame-jump<ret>}
|
||||||
|
@ -272,6 +274,7 @@ define-command -params 1.. \
|
||||||
cd_bufdir
|
cd_bufdir
|
||||||
printf %s "evaluate-commands -client '$kak_client' %{
|
printf %s "evaluate-commands -client '$kak_client' %{
|
||||||
set-option buffer=$kak_bufname git_blame_flags '$kak_timestamp'
|
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 ''
|
set-option buffer=$kak_bufname git_blame ''
|
||||||
}" | kak -p ${kak_session}
|
}" | kak -p ${kak_session}
|
||||||
git blame --incremental "$@" <${contents_fifo} | perl -wne '
|
git blame --incremental "$@" <${contents_fifo} | perl -wne '
|
||||||
|
@ -297,9 +300,11 @@ define-command -params 1.. \
|
||||||
}
|
}
|
||||||
open CMD, "|-", "kak -p $ENV{kak_session}";
|
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_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;
|
print CMD "set-option -add buffer=$ENV{kak_bufname} git_blame " . quote $raw_blame;
|
||||||
close(CMD);
|
close(CMD);
|
||||||
$flags = "";
|
$flags = "";
|
||||||
|
$index = "";
|
||||||
$raw_blame = "";
|
$raw_blame = "";
|
||||||
$last_sent = $now;
|
$last_sent = $now;
|
||||||
}
|
}
|
||||||
|
@ -310,6 +315,9 @@ define-command -params 1.. \
|
||||||
$sha = $1;
|
$sha = $1;
|
||||||
$line = $3;
|
$line = $3;
|
||||||
$count = $4;
|
$count = $4;
|
||||||
|
for ( my $i = 0; $i < $count; $i++ ) {
|
||||||
|
$index .= " " . ($line+$i) . "|$.,$i";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m/^author /) {
|
if (m/^author /) {
|
||||||
$authors{$sha} = substr($_,7);
|
$authors{$sha} = substr($_,7);
|
||||||
|
@ -483,11 +491,16 @@ define-command -params 1.. \
|
||||||
blame_jump() {
|
blame_jump() {
|
||||||
echo >${kak_command_fifo} "echo -to-file ${kak_response_fifo} -- %opt{git_blame}"
|
echo >${kak_command_fifo} "echo -to-file ${kak_response_fifo} -- %opt{git_blame}"
|
||||||
blame_info=$(cat < ${kak_response_fifo})
|
blame_info=$(cat < ${kak_response_fifo})
|
||||||
|
blame_index=
|
||||||
cursor_column=${kak_cursor_column}
|
cursor_column=${kak_cursor_column}
|
||||||
cursor_line=${kak_cursor_line}
|
cursor_line=${kak_cursor_line}
|
||||||
if [ -z "$blame_info" ] && {
|
if [ -n "$blame_info" ]; then {
|
||||||
[ "${kak_opt_filetype}" = git-diff ] || [ "${kak_opt_filetype}" = git-log ]
|
echo >${kak_command_fifo} "
|
||||||
}; then {
|
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 '
|
printf >${kak_command_fifo} %s '
|
||||||
evaluate-commands -draft %{
|
evaluate-commands -draft %{
|
||||||
try %{
|
try %{
|
||||||
|
@ -528,7 +541,7 @@ define-command -params 1.. \
|
||||||
cursor_line=$3
|
cursor_line=$3
|
||||||
cursor_column=$4
|
cursor_column=$4
|
||||||
blame_info=$(git blame --porcelain "$starting_commit" -L"$cursor_line,$cursor_line" -- "$file")
|
blame_info=$(git blame --porcelain "$starting_commit" -L"$cursor_line,$cursor_line" -- "$file")
|
||||||
} elif [ -z "$blame_info" ]; then {
|
} else {
|
||||||
set --
|
set --
|
||||||
eval "$prepare_git_blame_args"
|
eval "$prepare_git_blame_args"
|
||||||
blame_info=$(git blame --porcelain -L"$cursor_line,$cursor_line" "$@" <${contents_fifo})
|
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)
|
rm -r $(dirname $contents_fifo)
|
||||||
fi
|
fi
|
||||||
} fi
|
} fi
|
||||||
eval "$(printf %s "$blame_info" |
|
eval "$(printf '%s\n---\n%s' "$blame_index" "$blame_info" |
|
||||||
client=${kak_opt_docsclient:-$kak_client} \
|
client=${kak_opt_docsclient:-$kak_client} \
|
||||||
cursor_line=$cursor_line cursor_column=$cursor_column \
|
cursor_line=$cursor_line cursor_column=$cursor_column \
|
||||||
perl -wne '
|
perl -wne '
|
||||||
|
@ -562,8 +575,28 @@ define-command -params 1.. \
|
||||||
return "$SQ$token$SQ";
|
return "$SQ$token$SQ";
|
||||||
}
|
}
|
||||||
$target = $ENV{"cursor_line"};
|
$target = $ENV{"cursor_line"};
|
||||||
|
$state = "index";
|
||||||
}
|
}
|
||||||
chomp;
|
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 (m/^([0-9a-f]+) ([0-9]+) ([0-9]+) ([0-9]+)/) {
|
||||||
if ($done) {
|
if ($done) {
|
||||||
last;
|
last;
|
||||||
|
@ -572,16 +605,27 @@ define-command -params 1.. \
|
||||||
$old_line = $2;
|
$old_line = $2;
|
||||||
$new_line = $3;
|
$new_line = $3;
|
||||||
$count = $4;
|
$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) {
|
if ($new_line <= $target and $target < $new_line + $count) {
|
||||||
$old_line += $target - $new_line;
|
$old_line += $target - $new_line;
|
||||||
$done = 1;
|
$done = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (m/^filename /) { $old_filenames{$sha} = substr($_,9) }
|
if (m/^filename /) { $old_filenames{$sha} = substr($_,9) }
|
||||||
if (m/^author /) { $authors{$sha} = substr($_,7) }
|
if (m/^author /) { $authors{$sha} = substr($_,7) }
|
||||||
if (m/^author-time ([0-9]*)/) { $dates{$sha} = strftime("%F", localtime $1) }
|
if (m/^author-time ([0-9]*)/) { $dates{$sha} = strftime("%F", localtime $1) }
|
||||||
if (m/^summary /) { $summaries{$sha} = substr($_,8) }
|
if (m/^summary /) { $summaries{$sha} = substr($_,8) }
|
||||||
END {
|
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) {
|
if (not defined $sha) {
|
||||||
print "echo fail git blame-jump: missing blame info";
|
print "echo fail git blame-jump: missing blame info";
|
||||||
exit;
|
exit;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user