Using jEdit as diff/merge tool
Рубрика: Development, Java | 7 December 2007, 12:02 |
Vadim Voituk
… или о пользе встраиваемых скриптовых языков
Уже лет так 5, для разработки, я пользуюсь редактором jEdit. Почти все это время c ним активно использовался плагин для сравнения файлов jDiff.
А вчера решил использовать jEdit+jDiffPlugin для diff-а и merge-а в системе контроля версий StarTeam.
Кто использовал StarTeam, для контроля версионности кода – могут только посочуствовать, так как наверняка знают что пользоваться встроенным diff-ом/merge-ом – невозможно.
Указать просто запуск jEdit вместо diff – мне показазалось мало – хотелось чтоб 2 файла открывались в левой и правой панелях редактора, с уже “подсвеченными” изменениями, дабы не приходилось проводить дополнительные действия.
Для этого я написал небольшой BeanShell-скрипт для jEdit (BeanShell-единственный скриптовый язык, который им поддерживается) и добавил его в параметр -run=… при старте редактора:
[java]
void doDiff() {
void run() {
// Получаем текущее view, ипользуется для всех вызовов связанных с UI
view = jEdit.getLastView();
// Проверяем наличие JDiff-плагина
if (jEdit.getPlugin("jdiff.JDiffPlugin") == null) {
Macros.message(view, "Please install jDiff plugin");
return;
}
// Получаем имена файлов для сравнения из параметров коммандной строки
String file1 = args[1];
String file2 = args[2];
if (file1==null || file2==null || file1.equals("") || file2.equals("")) {
Macros.message(view, "Usage: jdiff file1 file2");
return;
}
File f1 = new File(file1);
if (!f1.exists() || !f1.canRead()) {
Macros.message(view, "Cant read file " + file1);
return;
}
File f2 = new File(file2);
if (!f2.exists() || !f2.canRead()) {
Macros.message(view, "Cant read file " + file2);
return;
}
// Сворачиваем все разделения окон в текущем view
// (мало ли сколько там их было открыто)
while (view.getEditPanes().length > 1)
view.unsplit();
// делим рабочую область вертикально пополам
EditPane fPane = view.getEditPane();
EditPane sPane = view.splitVertically();
// открываем нужные файлы
Buffer fBuf = jEdit.openFile(view, file1);
Buffer sBuf = jEdit.openFile(view, file2);
// выставляем один в левой панели, второй - в правой
fPane.setBuffer(fBuf, true);
sPane.setBuffer(sBuf, true);
// Запускаем diff
jdiff.DualDiff.toggleIgnoreWhitespaceFor(view);
jdiff.DualDiff.toggleFor(view);
jdiff.DualDiff.refreshFor(view);
// Устанавливаем разделитель между областями редактирования посредине
view.getSplitPane().setDividerLocation(0.5);
}
// Этот хак связан с тем, что при старте jEdit текущий view ещё не создан
// потому вызов jEdit.getLastView(); (см. выше) вернет null
// Чтоб выполнить вызов скрипта уже после создания view - цепляем его запуск к AWT-потоку
if(jEdit.getLastView() == null)
VFSManager.runInAWTThread(this);
else
run();
}
doDiff();
[/java]
Надеюсь из комментариев в коде, принцип работы скрипта понятен, потому отдельно описывать не буду.
Запуск нужно проводить таким образом:
javaw -jar D:\jEdit\jedit.jar -norestore -run=D:\jEdit\extra\jdiff.bsh %1 %2
Вуаля! Теперь могу использовать любимый и привычный редактор как полноценный diff/merge инструмент в StarTeam!
Ссылки в тему:
JEdit sFTP: Authentication has not been completed
My JEdit plugins

Спасибо, очень пригодилось.
Только пришлось поменять строчки с аргументами, т.к. номера 1 и 2 не соответствовали именам файлов.
String file1 = args[args.length - 2];
String file2 = args[args.length - 1];
Петр,
В таком случае нужно не забыть проверить размер args.length, дабы не наступить на ArrayOutOfBoundsException
Что верно, то верно :)
Но php, знаете ли, расслабляет и позволяет безнаказанно писать разные глупости вроде отрицательных индексов :)