?

Log in

No account? Create an account

емакс, часть 4: ретроспектива - Excelsior — LiveJournal

Dec. 10th, 2011

03:05 pm - емакс, часть 4: ретроспектива

Previous Entry Share Next Entry

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

Вдохновленный сегодняшним выступлением @alexott на митапе scala.by, я тоже решил поделиться наблюдениями из своего опыта. Экспы у меня не то чтобы много, но постараюсь быть максимально адекватным. Если я чего-то не догоняю, это не со зла - вы меня поправьте, ладно?

1) Емакс действительно крут. Главные его плюсы, на мой взгляд - неинтрузивность, программируемость и естественная интеграция с консолью. Например, недавно я соорудил наколенную билд-систему, с помощью которой застримлайнил свою работу над абсолютно разнородными проектами в универе. Она прекрасно заинтегрировалась в фар, и не менее замечательно - в емакс. Чтобы из емакса запустить какой-нибудь процесс и вбросить аутпут в буфер, нужны буквально пару телодвижений. Повесить на это все хоткеи и сделать гиперлинки на ошибки - еще немного работы. Пару обтачиваний и вуаля: myke-backend.el. Страшно представить, как что-то похожее сделать в Эклипсе.

2) Практически все можно пилить самому. Это прекрасно и очень вдохновляет (например, одним телодвижением можно посмотреть, на какой именно код забинджен тот или иной ключик), но есть и обратная сторона. Практически все придется допиливать самому. Даже банальную ширину таба нужно настраивать секретным образом (см. отдельную настройку для tab-stop-list), что уж говорить про такие вещи как копипасту, анду или прокрутку (кстати, у меня до сих пор через раз работает выделение мышкой). Это не то что бы уж очень плохо, но надо иметь ввиду, что первые пару недель емакс будет отнимать колоссальное количество времени.

3) Лисп не античеловечный, но и не простой в освоении. Довольно быстро я научился колбасить говнокод (что, наверняка, уже увидели уважаемые гуру емакса, пробежавшись по моему конфигу), но что-либо сложное я предпочитаю писать на чем-нибудь другом. Например, билд-система, упоминавшаяся выше, естественным образом выросла из ад-хок сниппетов на елиспе, но попытки превратить ее в что-то более-менее стройное успехом не увенчались, поэтому я по-быструхе переписал все с нуля на сишарпе. Наверняка, проблемы с удобством стандартной библиотеки и структур данных - всего лишь следствие моего несистемного подхода к изучению елиспа, но что вижу, то и пою. В любом случае, крайне помог бложек Стива Йегги, например, вот этот пост: Emergency Elisp.

4) Емакс - не панацея, что бы не писали в инете (по крайней мере для меня). Для разработки компилятора Скалы я юзаю Эклипс (контрол + клик на дефинишен и дебаг слишком важны, чтобы от них отказываться), для коммитов и истории я юзаю TortoiseGit (magit работает через раз + для чего-то нетривиального в VCS тупо нужен гуй). Вначале я думал, что это я такой нехардкорный, а потом увидел, что все в команде делают то же самое (только гуй к гиту другой, ибо никто не сидит на венде). Даже Мартин, который юзает емакс уже лет двадцать.

5) И все же я очень доволен емаксом. За денек я интегрировал в него греп по проектам с персональными свистелками, после чего выкинул поиск эклипса. Для сложных сессий репла Скалы я тоже юзаю емакс (идея консоли в буфере просто прелестна!). Да и домашки по алгоритмам в латеке я тоже фигачу в емаксе, ибо там подсветка синтаксиса и вручную прикрученный side-by-side превью.

Вот так и живем. Браузинг кода и дебаг в эклипсе, компиляция в фаре, текстовый поиск и реплы в емаксе. Use the right tools for the right job. Искренне ваш, кэп.

Comments:

From:(Anonymous)
Date:December 10th, 2011 03:42 pm (UTC)

M-.

(Link)
А контрол + клик - это переход на определение функции в эклипсе? Если так, то в имасксе это M-., но надо вначале сгенерировать TAGS файл. Почитай про ctags, там всё вроде ровно.

По поводу выделений мышки и прочих. M-x cua-mode. Будет выделение шифт + стрелочки, C-c/v и т.д.
(Reply) (Thread)
[User Picture]
From:xeno_by
Date:December 10th, 2011 11:55 pm (UTC)

Re: M-.

(Link)
Тагсы для навигации по скале, к сожалению, не катят - слишком много всяких перегрузок. Особенно для нашего кодебейза.

Ага, юзаю куа-мод. Но вещи вроде выделить что-то мышкой, а потом сделать копипаст, работают через раз.
(Reply) (Parent) (Thread)
[User Picture]
From:sorhed
Date:December 10th, 2011 03:50 pm (UTC)
(Link)
Браузинг кода и дебаг в IDEA, компиляция в IDEA, текстовый поиск и реплы в IDEA.

Use the right tool for the right job indeed. ;)
(Reply) (Thread)
From:Oleg Aleshko
Date:December 10th, 2011 10:07 pm (UTC)
(Link)
плюсую
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:December 10th, 2011 11:11 pm (UTC)
(Link)
К сожалению, идея на нашем кодебейзе ложится. Может, с недавним релизом стало получше, но пока что нет времени проверять. Хотя, действительно, надо бы.
(Reply) (Parent) (Thread)
[User Picture]
From:sorhed
Date:December 11th, 2011 04:42 pm (UTC)
(Link)
Попробуй, только непременно 11-ю.

Впрочем, я и сам могу попробовать.
(Reply) (Parent) (Thread)
[User Picture]
From:Дмитрий Макаров
Date:December 11th, 2011 04:39 pm (UTC)
(Link)
ну да, не подскажешь как засунуть в IDEA проект, в котором генерируется java code и этот код imported в других частях проекта?
(Reply) (Parent) (Thread)
[User Picture]
From:sorhed
Date:December 11th, 2011 04:41 pm (UTC)
(Link)
Сделать нормальный билд.

1) Сгенерировать код.
2) Скомпилировать сгенерированный код, упаковать его в jar-ы, в идеале — выложить maven-артефакт;
3) Подключить джары к идеевскому проекту.

Всё это делается антом или мавеном на раз-два. При чём здесь IDEA?
(Reply) (Parent) (Thread)
From:Oleg Aleshko
Date:December 11th, 2011 05:02 pm (UTC)
(Link)
идея нормально поддерживает generated-sources в мавене (без сборки дополнительных артефактов)
например всякие плагины для генерации вебсервис стабов работают без проблем
не думаю что будут проблемы и с sbt

по теме - с год назад идея вполне справлялась с сорсами скалы (на ноуте 2007 года выпуска), я постоянно во всех проектах подключаю сорсы ко всем либам (в том числе и scala-library)
(Reply) (Parent) (Thread)
[User Picture]
From:alexott
Date:December 12th, 2011 08:42 am (UTC)
(Link)
а ты ensime пользуешься?
Для Scala EBNF существует вообще? может стоит написать парсер для Semantic/CEDET?

По поводу myke-backend.el - лучше вынести mode-map & define-key за пределы myke-invoke, и оформить все в виде пакета - по крайней мере добавить (provide 'myke-backend). Да и (interactive) не нужен в lambda, которые ты засовываешь в define-key. Вместо (let .. (let ..)) лучше использовать (let* - тогда можно ссылаться на предыдущие объявления
(Reply) (Thread)
[User Picture]
From:xeno_by
Date:December 12th, 2011 08:30 pm (UTC)
(Link)
Надо посмотреть в сторону энсайма, точнее, в сторону его сервера, который абсолютно независим от емакса: https://github.com/aemoncannon/ensime/blob/scala-2.9/src/main/scala/org/ensime/protocol/SwankProtocol.scala.

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

Спасибо за код-ревью. Может, глянешь весь мой конфиг? А то пишу как голоса из розетки скажут, а, наверняка, где-то есть гуд практисы и все такое.
(Reply) (Parent) (Thread)
[User Picture]
From:alexott
Date:December 12th, 2011 08:38 pm (UTC)
(Link)
ты мне напомни про конфиг на той неделе, я посмотрю как стенфордские курсы кончатся...
(Reply) (Parent) (Thread)
[User Picture]
From:alexott
Date:December 15th, 2011 08:48 am (UTC)
(Link)
кстати, а в каких случаях вы используете графический интерфейс для Git?
(Reply) (Thread)
[User Picture]
From:xeno_by
Date:December 15th, 2011 09:04 am (UTC)
(Link)
Ясное дело, clone/push/pull/remote я делаю в командной строке (в гуи слишком много мышкокликов для этого). Мерж, ресет, ребейз запускаю тоже иногда из ком. строки, но далеко не всегда - только когда понятно, какой будет результат.

Коммичу обычно из GUI, чтобы иметь возможность два раза проверить каждый коммит и, если необходимо, на месте подредактировать/черрипикнуть/разделить на несколько коммитов коммитаемые файлы. Историю смотрю тоже в GUI: а) больше влазит на экран, б) более удобная визуализация, чем в magit. Поэтому операции с историей тоже часто делаю из GUI - глазами нашел, например, коммит, к которому откатиться, райт-клик, reset to (вместо того, чтобы мучительно вбивать хэш коммита в консоль).

За всех я говорить не могу, но то, что я наблюдал, совпадает со средней температурой по больнице. Есть народ, который юзает консоль практически для всего (но все равно иногда пользуется, например, gitk). Есть ребята, которые перелезли с SmartSVN на SmartGit и все делают из гуи. Я где-то посередине. upd. Мой критерий - где меньше телодвижений, то и юзать (поэтому, например, клоны я делаю исключительно из консоли).

Недавно я честно пробовал делать все из консоли, но необходимость вручную добавлять/удалять файлики в/из staging area (пусть даже с вайлдкардами) здорово напрягает. Если я где-то неправ (т.е. для описанной/описанных задач консоль эффективнее, чем GUI), пожалуйста, поправь меня. Интересно повысить эффективность своей работы.

Edited at 2011-12-15 09:05 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:alexott
Date:December 15th, 2011 09:05 am (UTC)
(Link)
я консоль тоже редко использую, но у меня все в основном идет через magit...
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:December 15th, 2011 09:20 am (UTC)
(Link)
я бы рад закрыть глаза на то, что в магите на экран влазит меньше информации, и на то, что не всегда способ представления инфы мне приятен (тот же лог - или это стандартная фича емакса, хз).

но есть две серьезные проблемы. то ли с вендой, то ли с магитом, то с радиусом кривизны моих рук. 1) магит жестоко тупит на винде (нажал s на коммите - тормоз на пару секунд - отпустило), 2) весьма часто просто отваливается (т.е. до переоткрытия емакса перестает работать). с этим я жить не могу, а пилить самому не хватает ни времени, ни желания общаться с елиспом.
(Reply) (Parent) (Thread)
[User Picture]
From:alexott
Date:December 15th, 2011 09:22 am (UTC)
(Link)
а, я все забываю про винду :-) может быть там так и есть...
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:December 15th, 2011 09:20 am (UTC)
(Link)
кстати вот про елисп. меня он напрягает не только, гхм, неординарностью стдлиба, но и отсутствием тулов для дебага (или я про эти тулы не знаю).

скажем, надо что-то допилить в конфиге. написал, закрыл/открыл емакс (уже неудобно), при загрузке что-то отвалилось, вижу стектрейс без номеров строчек или тело здоровенной лямбды (тоже без указания, где именно). начинаются гадания. как ставить брейкпоинты тоже непонятно, поэтому приходится дебагать на ручной тяге через принты. здорово помогает ielm, но не всегда.

почти 100% я что-то упускаю, поэтому просвети меня, плиз.

Edited at 2011-12-15 09:21 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:alexott
Date:December 15th, 2011 09:27 am (UTC)
(Link)
Ну во первых, если что-то дописывается в конфиге, то не нужно выходить из емакс - ставишь на последнюю скобку выражения и жмешь C-x C-e, и вычисляешь его (или M-x eval-defun для тела функции или M-x eval-buffer - для всего буфера). Обычно при отладке ставишь флажок "Debug on Error" - он при ошибке вываливает стектрейс, в котором названия функций - гиперссылки на исходник.

Есть еще и tracing выполнения функций и т.п. В Emacs Lisp Manual есть целый раздел про дебаггинг. вот тут еще есть полезные советы
(Reply) (Parent) (Thread)
[User Picture]
From:Дмитрий Бушенко
Date:January 2nd, 2012 10:48 am (UTC)
(Link)
Насчет сложности освоения elisp-а, мне кажется, ты не совсем прав. Он очень простой, гораздо проще Scala, C/C++ или Java. И функций там море, а чего нету -- легко доделать самому.
Кстати, последнее свойство -- главное преимущество Emacs. Расширяемость редактора -- главная фишка Emacs, которая и делает его таким гибким. В Eclipse мне приходится мириться с массой недостатков. В Emacs, напротив, если что-то сильно раздражает -- садишься и исправляешь или делаешь свое. Причем это настолько просто, что лично я зачастую пишу плагины емакса под каждый проект в отдельности.
Сам по себе Emacs не обеспечивает такого же удобства, как IDE. Если не будешь его допиливать под себя, делать плагины, которые будут писать за тебя код, то врядли получишь существенную пользу от Emacs.
Еше рекомендую посмотреть в сторону проекта emacs-eclim. Он прозрачно интегрируется с eclipse и обеспечивает такую же поддержку проектов и языков программирования, как сам Eclipse. Например, он умеет делать контекстно-зависимое автодополнение, рефакторинг и т.д. -- всё то, что умеет сам eclipse. Единственное, для чего я всё еще использую Eclipse -- для дебага, а код пишу только в Emacs.
(Reply) (Thread)
[User Picture]
From:xeno_by
Date:January 2nd, 2012 07:44 pm (UTC)
(Link)
Ага, я совсем немного поколбасил емакс и уже с тяжелым сердцем юзаю эклипс, ибо есть недостатки, с которыми я ничего не могу поделать. Дебаг, да - страшная беда. Самое лучшее, что есть в скаловском IDE-моде (ENSIME) для дебага - это комманд лайн.

Касательно языка. Из фич мне совсем неочевидны скоупы. Иногда переменные, локальные для буфера работают, иногда нет - все попытки понять, что к чему, фейлились. Также перемешивание локальных переменных и адвайсов тоже ни к чему хорошему не приводило. С моего единственного сложного адвайса я сдуваю пылинки - если сломается, мне капут. Плюс, стдлиб мне пока на душу не лег. Для многих несложных вещей нужно писать дофига кода. Может, это от недостатка опыта с лиспами.
(Reply) (Parent) (Thread)
[User Picture]
From:Дмитрий Бушенко
Date:January 2nd, 2012 10:23 pm (UTC)
(Link)
Думаю, всё дело в том, что ты понимаешь под "несложными" вещами. Emacs Lisp предназначен в первую очередь для обработки текста и кастомизации Emacs. Все, что в пределах этих задач -- делается достаточно просто.
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:January 3rd, 2012 09:15 am (UTC)
(Link)
Да ладно. В стандартной библиотеке, например, нет замены в строке без регексов. То же самое с startsWith, endsWith, trim, mkString. Или вот как сделать slurp одной строкой (я в курсе про временный буфер, но это не одна строка)? А как получить список всех файлов в папке стандартной функцией? Я понимаю, что все можно запилить самому, но, согласись, в некоторых важных областях стандартная библиотека весьма аскетична.

Плюс, структуры данных и общая многословность синтаксиса. Это отдельная песня, но это специфика лиспа, поэтому я не жалуюсь, но, опять же, стоит признать, что для большинства программистов, которые не являются фанатами лиспов, это неудобно и замедляет работу.
(Reply) (Parent) (Thread)
[User Picture]
From:Дмитрий Бушенко
Date:January 3rd, 2012 09:38 am (UTC)
(Link)
Slurp через временный буфер -- это и есть идиоматичное решение. Строку из него можно получить через (buffer-substring 1 (point-max)). Список всех файлов получить можно через (split-string (shell-command-to-string "ls")).

Edited at 2012-01-03 09:39 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:January 3rd, 2012 09:52 am (UTC)
(Link)
Я не говорю про невозможность сделать что-то, а именно про удобство стандартной библиотеки. Это одна из немногих вещей дотнета, по которым я скучаю в Скале.
(Reply) (Parent) (Thread)
[User Picture]
From:xeno_by
Date:January 3rd, 2012 09:52 am (UTC)
(Link)
Список файлов через ls? А как же пробелы?
(Reply) (Parent) (Thread)
[User Picture]
From:Дмитрий Бушенко
Date:January 3rd, 2012 10:05 am (UTC)
(Link)
Выведи по одному файлу на строку и сплитай по \n
(Reply) (Parent) (Thread)