tig icon indicating copy to clipboard operation
tig copied to clipboard

A new substitution special string %(sh {shell-command}) that substitutes external command's output

Open psprint opened this issue 3 years ago • 7 comments

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)'

psprint avatar Aug 31 '22 18:08 psprint

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.

krobelus avatar Aug 31 '22 19:08 krobelus

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.

psprint avatar Sep 01 '22 02:09 psprint

@koutcher ping

psprint avatar Sep 08 '22 15:09 psprint

@krobelus ping?

psprint avatar Sep 17 '22 13:09 psprint

The patch is precious also because %(prompt %(commit)) works as expected…

psprint avatar Sep 17 '22 13:09 psprint

@koutcher @krobelus merge?

psprint avatar Oct 01 '22 05:10 psprint

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…

psprint avatar Oct 06 '22 07:10 psprint