I have a few git svn related functions that see if I have to pull/push from/to the repository.
My problem is that the functions I've written to gather this information are too slow. I'd like to make them async so that PS1
shows a default, if though the data produced by the functions is ready I want it printed.
I'd like to have these information in my prompt – so that, for example, I know if I have to pull – without doing a git svn fetch
everytime.
This is the function I call to add a ↑ to my PS1 if I have to push my changes.
function hasToPush {
(($1 == 0)) &&
(git svn dcommit --dry-run 2>/dev/null | grep -q "diff-tree" && echo "↑")
}
These are the functions I call to add a ↓ if I have to pull. The first is used to refresh my index every 2 minutes so that I can do the (($latest > $current))
check.
function loopingGitSvnFetch {
sleep 120
git svn fetch &>/dev/null
}
loopingGitSvnFetch &
function hasToPull {
(($1 == 0)) && (
latest=$(git svn log | awk 'NR==2' | cut -d ' ' -f1 | tr -d 'r')
current=$2
(($latest > $current)) && echo "↓"
)
}
To make them async, I've tried to put them together like this:
function async {
{
git diff-index --quiet --cached HEAD &>/dev/null
dirty=$(echo $?)
push=$(hasToPush $dirty)
gitsvn=$(git svn info 2> /dev/null | grep Revision)
gitsvn=${gitsvn#Revision: }
pull=$(hastoPull $dirty $gitsvn)
callback $push $pull
} &
}
But that produces the same slow behaviour.
I've tried to put results in a file and then read it after, but I don't like that approach.
I've thought about using PROMPT_COMMAND
. But that would not be async; it would be on demand.
Could you shed some light on how PS1
behaves or on what I'm doing wrong?
Thank you in advance.
PS: Could someone with 300 rep add the async and ps1 tags?
EDIT:
I added these line to my .bashrc as a simple test, it seemed to work, so having rewrote them (I reverted my previous attempt) seems was a good thing 🙂
while true;
do
discoverScmInfo &>~/.ps1
sleep 1
done &
PS1='$(customW)$(cat ~/.ps1)\$ '
I'll put this in a function and check if the job is already running before calling it.
Sorry about this, after all it seems that all I needed was to write about it. 🙂
Best Answer
re: your solution of a loop every second: you could write to a file in /tmp, instead of in your home directory. And
PS1=$(customW)$(< ~/.ps1)\$ '
would save a fork/exec ofcat
.re: the original question: how to get an async update to
PS1
: To start an async write toPS1
:PROMPT_COMMAND
to a function that checks if the data is available.PS1
and unsetPROMPT_COMMAND
PS1
with the old or placeholder value.Use a file in
/tmp
for the async IO to write to, andPROMPT_COMMAND
to read from.I think this should work.