Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question

3 Answers 3

up vote 1 down vote accepted

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
share|improve this answer

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.

share|improve this answer

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

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.