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

Комментариев: 3

3 Responses to “Using jEdit as diff/merge tool”

Комментарии:

  1. Petr

    Спасибо, очень пригодилось.
    Только пришлось поменять строчки с аргументами, т.к. номера 1 и 2 не соответствовали именам файлов.
    String file1 = args[args.length - 2];
    String file2 = args[args.length - 1];

  2. Vadim Voituk

    Петр,
    В таком случае нужно не забыть проверить размер args.length, дабы не наступить на ArrayOutOfBoundsException

  3. Petr

    Что верно, то верно :)
    Но php, знаете ли, расслабляет и позволяет безнаказанно писать разные глупости вроде отрицательных индексов :)

Leave a Reply