Как заставить emacsclient ждать при использовании опции --eval?

Я хотел бы вызвать Emacs ediff-merge-files функция объединения файлов с синхронизатором файлов unison. Чтобы избежать запуска нового экземпляра, я предпочитаю использовать emacsclient:

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

Тем не мение, emacsclient возвращается мгновенно (как это было бы, когда даны простые файлы и --no-wait опция). Конечно, тогда unison жалуется, что файлы не были отредактированы.

Есть ли способ позволить emacsclient подождать, пока я не закончу слияние?

3 ответа

Решение

Я вижу 2 способа сделать это.

Оберните ваш вызов в ediff-merge-files вокруг другой функции emacs, которая будет ждать завершения вызова, может поиграться с некоторыми хаки в ловушках запуска, но это может стать очень грязным

Оберните ваш вызов в emacsclient сценарием, который ожидает создания нового файла перед возвратом. Если временный файл создается по требованию, то это более простое решение, если новый файл может уже существовать, тогда вам нужно будет использовать файл заполнителя

Пример скрипта - ediff-wait, он взломан и имеет минимальные проверки работоспособности

#!/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

Emacsclient будет ждать, если вы попросите его создать новый фрейм. Следовательно, используйте либо:

emacsclient -c --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")' если вы хотите создать графическую рамку или

emacsclient -t --eval '(ediff-merge-files "CURRENT1" "CURRENT2" nil "NEW")' если вы хотите терминальную рамку.

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

Другие вопросы по тегам