Background:
I’m currently working on some code in which there’s an if/else statement in which I’m pretty sure the body of the if was copy-pasted into the body of the else. Since a small difference can be hard to catch with the naked eye, I thought it would be great if I could diff the 2 sections just as I might diff 2 files.
While I haven’t really used it, I’m aware that there’s a utility included on many unix systems called diff that can diff 2 files or even raw text.
Some searches yielded me to this example:
diff <(echo "$sometext") <(echo "$someothertext")
Kakoune provides great mechanisms for sending selections through shell commands. There seems a good opportunity to achieve my goal here.
Question(s):
Does anyone know or have some ideas on how to diff [let’s start with] 2 selections from within Kakoune? Is this doable without any scripting, or what would be a minimal command implementation to accomplish this?
I think there’s great plugin or rc script opportunities here (like the git integration script), but would like to know if anyone knows or could come up with a quick-n-dirty way of using diff from kak in this way.
Not so much a pointer for implementation (since Vim has its internal diff engine and windowing utilities) but in terms of ideas and interface linediff-vim is probably looking into. Very occasionally (once or twice a year) I need such a tool and I usually go back to Vim to use the above plugin. However it probably wouldn’t be hard to implement such a tool in Kakoune, at least to display a unified format diff in a scratch buffer. It would be trickier to be able to edit the snippet and reflect the changes to the original buffer though.
It wouldn’t be too difficult to write a plugin that used RegisterModified hooks to automatically update a buffer with the diff of two registers. That way you could do something like :new diff-regs a b to open a new window containing a diff buffer comparing the a and b registers, then "ay one one piece of text and "by on the other to fill in the regsiters and watch the diff buffer update.
It would be more work than just using temporary files manually, though.
Based on @Screwtapello’s input, I threw this together, which works well. Kakoune even has built-in syntax highlighting for diffs.
define-command -docstring 'Diff the current selections and display result in a new buffer.' \
diff-selections %{
evaluate-commands %sh{
eval set -- "$kak_quoted_selections"
if [ $# -gt 1 ]; then
echo "$1" > /tmp/a.txt
echo "$2" > /tmp/b.txt
diff -uw /tmp/a.txt /tmp/b.txt > /tmp/diff-result.diff
echo 'edit -existing -readonly /tmp/diff-result.diff'
else
echo "echo -debug 'You must have at least 2 selections to compare.'"
fi
}
}
I was hoping to avoid creating tmp files, but it works, is easy, and I couldn’t figure out a more elegant way to do it my limited time and knowledge. I don’t think process substitution <(...) from the original example diff command I posted is available when executing via /bin/sh.