kakoune
kakoune copied to clipboard
[REQUEST] Make <ret> do git show when on a hash in git log output
Feature
The rc/tools/git.kak
is really helpful to quickly interact with git on a project.
For example, if you :git log
, you see the history that appears in the *git*
buffer. This is super handy. If you add the -p
option (:git log -p
), you directly see the patch for each commit. And if you do <ret>
when the cursor is on one of the lines of the diff, you jump there. This is awesome.
To improve even more the experience, I think that doing <ret>
while on a hash (a short hash such as when doing :git log --oneline
or a long hash in regular :git log
) could do a :git show <the_selected_hash>
. This way, one could really rapidly navigate the history to check a previous change with :git log
and <ret>
.
Of course, if :git show
is called while within :git log
, it means that the user won't be able to go back to the log while seeing the patch, as they are using the same scratch buffer *git*
. This could be mitigated if another scratch buffer is used so that the user could use ^O
to jump back. But maybe it is not worth it to go that far.
Usecase
Navigate quickly the git history and see patches.
Yeah. I use this, mapped to a different key than <ret>
though.
define-command -override my-git-enter %{ evaluate-commands -save-regs c %{
try %{
evaluate-commands -draft %{
execute-keys s\S+<ret>
try %{
evaluate-commands %sh{
[ "$(git rev-parse --revs-only "$kak_selection")" ] || echo fail
}
} catch %{
try %{ execute-keys <a-i>w }
evaluate-commands %sh{
[ "$(git rev-parse --revs-only "$kak_selection")" ] || echo fail
}
}
set-register c %val{selection}
}
git show %reg{c} --
} catch %{
git-diff-goto-source
}
}}
Nice, thank you for sharing.
According to you, would it be worth it to integrate this behavior directly to rc/tools/git.kak
?
To improve even more the experience, I think that doing
while on a hash (a short hash such as when doing :git log --oneline or a long hash in regular :git log) could do a :git show <the_selected_hash>. This way, one could really rapidly navigate the history to check a previous change with :git log and .
One problem with overloading <ret>
with two different behaviors (well,
three, we already map it to blame-jump
while blame annotations are
shown) is that we have to second-guess the user in edge cases where
it's not clear whether we are in a diff / whether the thing at cursor
is an object ID.
It's probably still worth adding. Here's a rough attempt:
diff --git a/rc/tools/git.kak b/rc/tools/git.kak
index 1a1e8d81e..594e54a4a 100644
--- a/rc/tools/git.kak
+++ b/rc/tools/git.kak
@@ -41,10 +41,10 @@ hook -group git-diff-highlight global WinSetOption filetype=(git-diff|git-log) %
}
}
-hook global WinSetOption filetype=(?:git-diff|git-log) %{
- map buffer normal <ret> %exp{:git-diff-goto-source # %val{hook_param}<ret>} -docstring 'Jump to source from git diff'
+hook global WinSetOption filetype=git-(?:commit|diff|log|notes|rebase) %{
+ map buffer normal <ret> %exp{:git-jump # %val{hook_param}<ret>} -docstring 'Jump to source from git diff'
hook -once -always window WinSetOption filetype=.* %exp{
- unmap buffer normal <ret> %%{:git-diff-goto-source # %val{hook_param}<ret>}
+ unmap buffer normal <ret> %%{:git-jump # %val{hook_param}<ret>}
}
}
@@ -776,3 +776,30 @@ define-command git-diff-goto-source \
fi
}
}
+
+define-command git-jump -docstring %{
+ If inside a diff, run git-diff-goto-source,
+ Else show the Git object at cursor.
+} %{ evaluate-commands -save-regs c %{
+ try %{
+ execute-keys -draft l[px<a-k>^diff<ret>
+ set-register c git-diff-goto-source
+ } catch %{
+ evaluate-commands -draft %{
+ try %{
+ execute-keys <a-i>w # TODO this should include characters like -.@# etc
+ } catch %{
+ fail git-jump: no word at cursor
+ }
+ try %{
+ evaluate-commands %sh{
+ [ "$(git rev-parse --revs-only "$kak_selection")" ] || echo fail
+ }
+ } catch %{
+ fail "git-jump: bad revision '%val{selection}'"
+ }
+ set-register c git show %val{selection} --
+ }
+ }
+ %reg{c}
+}}
Of course, if :git show is called while within :git log, it means that the user won't be able to go back to the log while seeing the patch, as they are using the same scratch buffer git. This could be mitigated if another scratch buffer is used so that the user could use ^O to jump back. But maybe it is not worth it to go that far.
I keep a stack of all git buffers - look for git-stack
here