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

1

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:

emacsclient --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")'

However, emacsclient returns instantly (as it would do when given plain files and the --no-wait option). Of course, unison then complains that no files have been edited.

Is there a way to let emacsclient wait until I'm finished with the merge?

Florian Jenn

Posted 2009-12-11T16:59:46.693

Reputation: 524

Answers

1

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

Darren Hall

Posted 2009-12-11T16:59:46.693

Reputation: 6 354

1

Emacsclient will wait if you ask it to create a new frame. Hence, use either:

emacsclient -c --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")' if you want to create a graphical frame or

emacsclient -t --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")' if you want a terminal frame.

purple_arrows

Posted 2009-12-11T16:59:46.693

Reputation: 231

0

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.]

jkp

Posted 2009-12-11T16:59:46.693

Reputation: 305