Home » Questions » Computers [ Ask a new question ]

How to make emacsclient wait when using the --eval option?

How to make emacsclient wait when using the --eval option?

I'd like to invoke emacs' ediff-merge-files function for merging files with the unison file synchronizer. To avoid starting a new instance, I prefer using emacsclient:

Asked by: Guest | Views: 377
Total answers/comments: 2
bert [Entry]

"I see 2 ways to do this.

wrap your call to ediff-merge-files around another emacs function that will wait for the call to finish, can play around with doing some hacks into the startup hooks, but this could get very messy
wrap your call to emacsclient with a script that waits for the new file to be created before returning, if the temporary file is created on demand then this is an easier solution, if the new file may already exist, then you'll need to use a placeholder file

Example script - ediff-wait, it's hacked up and has minimal sanity checks
#!/bin/sh

[ -f $3 ] && exit 1 # merge file exists?

emacsclient --eval ""( ediff-merge-files \""$1\"" \""$2\"" nil \""$3\"" )""
while /bin/true; do
[ -f $3 ] && exit 0
sleep 1
done"
bert [Entry]

"It seems that the problem with using emacsclient as a diff tool is that it always returns 0 as status code making it impossible for git to decide if the merge succeeded or not.

A solution was proposed on the Mercurial wiki:

#!/bin/bash

if [ $# -lt 1 ]; then
echo 1>&2 ""Usage: $0 local other base output""
exit 1
fi

local=$1
other=$2
base=$3
output=$4

OUTPUT=`emacsclient --no-wait --eval ""(ediff-merge-with-ancestor \""$local\"" \""$other\"" \""$base\"" nil \""$output\"")"" 2>&1`
echo $OUTPUT | grep -v ""Ediff Control Panel""

if echo ""$OUTPUT"" | grep -q '^*ERROR*'; then
exit 1
fi

Put this in a shell script in your path and things should be dandy.

[NOTE: This issue has been fixed in the emacs trunk.]"