Как заставить 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.]