A new substitution special string %(sh {shell-command}) that substitutes external command's output
On gitter, in a discussion there has been an idea from user @krobelus:
<krobelus> I don't thikn this is possible, we should add that feature
10:17 maybe like :goto %sh{git rev-list %(commit) | head -1
– it was an idea of a %(…)-like substitution string that would substitute the given external command's output. I have implemented the idea in this PR, as %(sh …) special string, similar to %(prompt …).
This PR implements a new substitution special string %(sh {shell-command}) that runs an external command, captures its output and substitutes it in place of the %-string. It can be used as follows:
bind generic T :echo '%(sh printf "Home dir is $HOME")'
As it can be seen, the command is run via sh -c '{command}', so environment variable substitutions can be used.
The implementation works OK with limitation inherited from %(prompt ) – in the argument there shouldn't be any other substitutions like %(commit), because they will not be substituted. Any ideas were in the code to implement this? It would be needed for e.g.:
bind generic T :goto '%(sh git rev-list %(commit)~..|head -1)'
I agree the expansion system could use some love.
The current one is inspired by Git's format strings that allow things like %(refname:strip=3).
Obviously Git doesn't need shell expansions but we probably do.
bind generic T :goto '%(sh git rev-list %(commit)~..|head -1)'
I feel like it's a bad idea to substitute %(commit) here.
I'd rather make users write
bind generic T :goto '%(sh git rev-list "$tig_commit"~..|head -1)'
then the contents of the %(sh) block is pure shell, no other funny syntax.
Another potential problem is that you have single quotes around the shell expansion. How does that interact with single quotes inside the shell expansion? They should not affect each other. Not sure if this is the case.
Patch 4301605 contains handling of embedded, recursive %()-substitutions. Even %(sh printf %(sh printf $HOME)) is possible, and also the needed %(sh printf %(commit)). @krobelus review?I've read your previous review and I'm taking it into account.
@koutcher ping
@krobelus ping?
The patch is precious also because %(prompt %(commit)) works as expected…
@koutcher @krobelus merge?
If the delay is because the (↔) matching fancy function then I can quickly provide a better one (that would just count incr. ( and decr. on ), super easy).
Isn't it welcomed to provide flexible %(sh …) and to allow %(commit) inside a %(prompt)? Even %(prompt %(sh printf %.7s %(commit))) is finally possible…