?

Log in

No account? Create an account

емакс, часть 3: windows - Excelsior — LiveJournal

Aug. 22nd, 2011

12:18 am - емакс, часть 3: windows

Previous Entry Share Next Entry

емакс, часть 1: первый взгляд
емакс, часть 2: восторг
емакс, часть 3: windows
емакс, часть 4: ретроспектива

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

Сразу после запуска емакс встретил меня сообщением об ошибке в скриптах инициализации и антиалиаснутым курьером. "Окей, в принципе никто и не предполагал, что сразу все заработает" - подумал я и нажал Alt+F4, чтобы перезапустить емакс в режиме отладки. В ответ последовало: "<M-f4> is undefined", что в переводе на русский обозначает, что Alt+F4 по умолчанию ни на что не забинджен. Да, поездочка будет долгой...

Сегодняшний пост будет содержать большое количество технических деталей, поэтому нетерпеливым читателям спешу сообщить, что все заработало (в том числе и шелл-скрипты с участием coreutils), но пришлось немного повозиться. Недоволен я остался лишь гитом - он и, как следствие, интеграция с ним работают раздражающе медленно, но, к счастью, общение с ними удалось свести к минимуму. В любом случае, все траблы, через которые пришлось пройти, перекрываются тем фактом, что под линухой и виндой у меня теперь практически идентичное окружение. А, благодаря дропбоксу, перезагрузка в другую операционку всего лишь меняет визуальную тему окошек, но не их содержимое.

upd. Также я столкнулся с проблемой тормозов. Часть из них была вызвана гитом (см. ниже по тексту), часть из них имела другие причины. Хорошая новость в том, что все удалось починить. Детали см. вот тут: http://xeno-by.livejournal.com/57626.html.

***

Первым делом я обдумал вопрос программного окружения. Так как емакс неслабо использует возможности стандартных юниксовых тулов (например, поиск по пачке файлов (читай, проекту) проще всего реализовать через find+grep), нужно было где-то достать эти самые тулы. Можно было просто вытащить греп и файнд из mingw, но отказываться от шелла тоже не хотелось, ибо писать дакт-тейп на елиспе - удовольствие ниже среднего. В итоге, остались два варианта: 1) запускать емакс из-под цигвина или чего-то подобного (к сожалению, я плохо разбираюсь в теме эмуляции юникса под виндой, поэтому не в курсе, как еще можно поступить в рамках этой опции), 2) юзать NT Emacs (т.е. емакс, скомпилированный в виде нативного виндового приложения), но при этом использовать bash и gnu utils от цигвина.

После чтения емакс-вики и статейки Стива Йегги я решил остановиться на второй возможности. Кроме общефилософского мнения о том, что предпочтительнее юзать нативную прилагу, немаловажным был тот фактор, что цигвин я видел первый раз в жизни, поэтому непонятно, какие косяки меня могли ожидать. В любом случае, и баш, и корные юниксовые утилиты доступны в обоих случаях, поэтому, выбрав NT Emacs, концептуально я ничего не терял. В итоге я поставил цигвин, добавил его bin в виндовый PATH, установил переменную окружения SHELL в c:\cygwin\bin\bash.exe (это все, что нужно для того, чтобы емакс проинтегрировался с цигвиновскими coreutils) и смело пошел навстречу граблям.

Самым первым делом я пофиксил шрифты. Если к сглаживанию как таковому я со временем привык, то сглаженный курьер меня продолжает удивлять и по сей день. Впрочем, оказалось, что установкой одной-единственной переменной можно сразу изменить шрифт для всего окна емакса. Для полноты картины отмечу два нюанса: 1) формат значений этой переменной нетривиален, 2) переменная локальна для фрейма, т.е. для новых окон нужно ее устанавливать заново. За деталями смотрим сюда.

Следующей на очереди была унификация формата сохраненной сессии емакса между виндой и линуксом. Винда успешно поддерживает симлинки, но никакими симлинками не превратить путь типа X:\ в путь типа /foo/bar. И это даже несмотря на то, что емакс прекрасно переваривает прямые слеши вместо обратных и наоборот. Проблема решилась при помощи цигвина. В папке c:\cygwin я воспроизвел структуру рабочего окружения линукса и забросил оттуда симлинки на папки с реальным контентом. А дальше всего лишь осталось заюзать библиотеку cygwin-mount, которая умеет маппить виртуальные юниксовые пути на реальные виндовые пути внутри папки цигвина.

Пришлось также неслабо поисследовать вопрос с хоткеями. В линуксе проблема гвоздями прибитых хоткеев отсутствует - и в метасити, и в компизе можно перебиндить что угодно, включая вещи вроде alt+tab. В винде все несколько грустнее. Во-первых, из коробки емакс не обрабатывал кнопки Win, отдавая их системе. Если в убунте я мог изображать любые сочетания клавиш с участием Win, то в винде эти штучки уже не работали. К счастью, нашлось простое решение. Для того, чтобы Win превратить в super (или во любой другой модификатор), нужно всего лишь установить парочку переменных.

Дальше - интереснее. Если проблемы с win+tab и win+цифры я ожидал, то увидеть занятыми ctrl+esc и даже win+= было удивительно. Вначале я пытался разрулить проблему, копаясь в реестре, но это были просто припарки - там заработало, тут отвалилось. Ситуацию переломил бесплатный тул AutoHotkey. С помощью несложного вида скриптов он позволяет перекрыть и обработать большой спектр хоткеев (я подозреваю, что все, что угодно, кроме ctrl+alt+del), а также даже скомпилировать свои скрипты в standalone икзешники. Кроме того, я перемаппил Caps Lock на Ctrl - это делается регедитом, без всяких тулов.

Конечно, мои изыскания не могли пройти мимо проблемы с разделителями строк. Вначале я подумал, что эту проблему удастся избежать, т.к. емакс достаточно смартовый редактор для того, чтобы автоматически понимать, где \n, а где \r\n. Но после того, как скрипт, отредактированный под виндой, отвалился в линуксе по причине лишнего символа \r, мне стало не до шуток. Была введена политика огораживания, по которой все новосозданные файлы, несмотря на текущую операционку, кодируются с разделителями в стиле юникса. Исключение - бат-файлы, которые без \r\n виндовый интерпретатор не съест. Интуитивно чувствую, что это решение слишком жестко, чтобы быть практичным, но будущее покажет.

Кстати, по концовке оказалось, что проблема была не в емаксе. Символы окончания строки испортил кое-кто другой. Некоторые из вас, вероятно, уже догадались. В честь этого все вместе передадим привет гиту и его core.autocrlf. Впрочем, тема гита на винде выходит за пределы и так уже большого поста.

Последняя грабля была связана снова с гитом. В интернетах много кто жалуется на неторопливость его виндового порта. Как я понял, это связано с тем, что гит юзает идиомы линукса, которые невозможно эффективно замаппить на виндовый апи, в честь чего и тормоза. На горьком опыте я выяснил, для дефолтного сетапа msysgit 1.7.2 операции вида git XXX выполняются минимум 0.3 секунды каждая (ssd, core i7, loads of ram). Все бы ничего, но при открытии каждого файла емаксовая инфраструктура сорс-контроля выполняет более 10 таких операций. Путем красноглазия удалось сократить время до 0.1 секунды на операцию, но это все равно баттхёрт! Пришлось отрубать, но, на счастье, получилось чисто - отключился только хук, но не остальной функционал вроде диффов.

***

tl;dr. Поставлено тулов: 1) Cygwin, 2) NT Emacs. Пришлось подпилить: 1) фонты, 2) имена файлов в сессиях, 3) системные хоткеи винды, 4) политику разделителей строк, 5) интеграцию с гитом. В результате под виндой: 1) gnu тулы из емакса работают, 2) шелл-скрипты из емакса (например, grep+find по проекту) работают, 3) сессии емакса, сохраненные в одной операционке, открываются в другой, 4) функциональность и хоткеи емакса в пределах моего воркфлова одинаковы - и в линухе, и в винде.