Tales of Power.

Фрагменты записной книжки.

17 Апрель 2008

Краткое содержание предыдущих серий.

Должен признать, что предыдущие сообщения в большей мере представляли собой попытку объять необъятное.

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

Вторым фактором было состояние двоичных сборок emacs для платформы Windows. Например, поддержка latex-preview была доступна только в особой сборке, скачиваемой с особого сайта. Некоторые пакеты можно было собрать только через automake, который невозможно было заставить работать сколько-нибудь вменяемо под Windows.

Все перечисленное, а так же последствия экспериментов с очередным Новым Интересным Пакетом привели к тому, что запуск обожаемого редактора стал напоминать запуск стратегической ракеты средней дальности [1].

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

Такое пафосное начало омрачалось старой памятью о часах мучений с жизненно-важными пакетами и прочими радостями жизни конца 20-столетия.

Однако, как оказалось, прогресс не стоял на месте. Чего мне всегда не хватало в моей Windows-жизни - так это unix-подобного окружения. Скрестив пальцы, я скачал Cygwin с одноименного ресурса. О чудо! Это уже не тот кривобокий монстр, дело с которым я имел почти 8 лет назад. Кроме того, я проигнорировал рекомендацию "не устанавливать Cygwin" в корневой раздел, и таки установил, правда, в специально отведенный диск. emacs занял свое место в /usr/local/ и после перезагрузки отлично видел пути ко всем нужным утилитам[3].

Версия 23.0.0.1 имеет достаточно приятных новшеств (вполне вероятно, что они появились ранее, но лично я отметил их в версии 23), например, обновлены привязки клавиш, делающие часть моих комбинаций ненужными.

Следующим шагом была плановая ревизия начальных настроек. Они у меня хранятся в двух файлах, традиционном ~/.emacs и менее традиционном ~/.custom.

Последний файл был отредактирован кардинально: оттуда были вырезаны все значение, относящиеся к внешним модулям. Небольшой трюк: перед сохранением этого файла выполните eval-buffer (ведь вы же редактируете в emacs, верно?). Нет ошибок - сохраняем.

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

Итак, что же осталось тут? На свалку безжалостно отправлены строки, расширяющие load-path - сегодня emacs самостоятельно включает туда все каталоги в site-lisp. Особо сложной системы вложений я избегаю: названия каталогов различных пакетов не совпадают, а пакеты из одного файла я копирую прямо в site-lisp.

Не менее безжалостно вырезаны вызовы всех библиотек, ну, кроме самых необходимых. Такими для меня являются ibuffer, ido, hideshow и yasnippet[4]. Из остальных модулей я установил cedet, slime, nxml-mode, jabber.el, ipython и несколько режимов подсветки. Эти модули загружаются только тогда, когда требуются

Отдельно стоит изрядно похудевшая секция привязки клавиш, в основном на функции, не имеющие привязок вообще. Например, есть такой фрагмент:

(global-set-key (kbd "C-x C-b") (lambda () (interactive) (ibuffer :shrink) (switch-to-buffer (get-buffer "*Ibuffer*"))))

(define-key ibuffer-mode-map (kbd "RET") 'ibuffer-visit-buffer-1-window)

Этот фрагмент заменяет стандартное поведение: вместо стандартного списка буферов открывается ibuffer, который занимает ровно столько места, сколько требуется для отображения списка, а по команде RET открывается выбраный буфер во все окно. Лично мне так удобно.

А так я сворачиваю-разворачиваю блоки кода или разметки.

(global-set-key [(control kp-subtract)] (lambda () (interactive)(hs-toggle-hiding) (beginning-of-line)))

В общем, теперь файл настроек занимает 50 строк (из 11 пустых и 6 - комментарии), а сам emacs загружается практически мгновенно.

[1] Вообще-то, я не знаю, как стартуют любые ракеты. Но думаю, что развертывание комплекса происходит долго.

[2] Это не опечатка, слово "гигабайты" написано дважды. Пока печатал фразу, постоянно исправлял приставку "мега" на "гига". Черт возьми, а ведь приставка "мега" может исчезнуть окончательно!

[3] Полная строка версии - "GNU Emacs 23.0.0.1 (i386-mingw-nt5.1.2600) of 2007-08-18 on TPAD", то есть мой emacs не из поставки cygwin.

[4] Этот модуль достоен всяческой похвалы и внимания. Из всех перепробованных, соотношение настройка\скорость\возможности - оптимальное.

07 Июнь 2007

Секретное оружие

Ок, теперь мы можем загружать модули. А какие модули стоит загружать?

Ответ на такой вопрос сугубо индивидуален. Конечно же, все зависит от того, чем вы занимаетесь.

Я приглашаю вас посмотреть внутрь моего .emacs. Если хотите, попробуйте угадать, чем я чаще всего занимаюсь. Итак, добро пожаловать.

;;загрузить сedet и включить semantic
(load-file "../site-lisp/cedet/common/cedet.el")
(setq semantic-load-turn-useful-things-on t)
(semantic-load-enable-code-helpers)
(require 'ecb)
Так загружается модуль ecb - Emacs Code Browser. Это очень мощный модуль, превращающий emacs в полноценную интегрированную среду разработки для множества языков. Этот модуль позволит вам перемещаться между файлами вашего проекта, двигаться от функции к функции, предлагает улучшенные средства работы с компилятором (точнее, с буфером компиляции1). ecb, как видно из первой и второй строки, зависит от модуля cedet, который включает в себя несколько других. Ознакомившись с документацией, вы получите мощный инструмент для программирования.

ecb - наиболее сложный модуль из всех, которыми я пользуюсь. Остальные значительно проще. Впрочем, к этому мы еще вернемся.

;;Загрузка nxml-mode
(load "../site-lisp/nxml/rng-auto.el")

Так загружается nxml-mode - мощный и легковесный режим для работы со структурированными языками разметки, например, с xml или html.

Этот режим умеет производить валидацию разметки, подсвечивать синтаксис, имеет собственный режим автодополнения, может быть настроен на различные схемы.

У nxml-mode есть аналог, называется psgml-mode. Судя по его описанию, он является еще более мощным, хоть и более тяжеловесным, чем nxml-mode. К сожалению, мне не удалось за полиномиальное время заставить его работать на Windows, так что пришлось отложить этот вопрос на неопределенный срок. Это вдвойне обидно, т.к. на сайте IBM, где описана инструкция по его применению, видно, что автору удалось заставить работать psgml-mode именно на WinXP.

Не будем отвлекаться и продолжим:

(require 'gnuserv)
(require 'tabbar)
(require 'ido)
Это сразу три модуля. gnuserv заставляет emacs работать в режиме сервера. Это значит, что у вас всегда будет один процесс emacs-а. Это удобно в случае, когда emacs является ассоциированным редактором для определенных типов файлов. Если не включать этот режим, то при открытии файлов такого типа будет создан еще один экземпляр emacs-а. Лично мне так неудобно, предпочитаю, чтобы файлы открывались в работающей сессии редактора.

tabbar добавляет в буфер строку с закладками на открытые буферы и определяет сочетания клавиш для переключения на видимые закладки.

Стандартный модуль ido должен быть вам знаком. Можно сказать, что ido - противоположность модулю tabbar. Почему я использую оба модуля? Потому, что иногда все же приходится брать мышь в руки.

(require 'erc)
(require 'jabber)
(require 'socks)
(require 'emms-setup)
Модуль erc служит для общения по протоколу irc, это мощный и удобный irc-клиент. Загрузите его, дайте команду M-x erc-select, ответьте на вопросы и готово - вы на любимом канале.

Модуль jabber говорит сам за себя. Крайне гибкий и настраиваемый модуль. Если вам стало интересно, то в Интернете есть множество статей с описанием настройки и установки2.

Модуль socks позволяет использовать socks-proxy. Прокси можно использовать для любых сетевых соединений, например, для irc, почты3, модуля прозрачного доступа к удаленным файлам3 и так далее.

emms - emacs multimedia mode. Это front-end к трем консольным проигрывателям. Из этих трех я использую mplayer, его легко найти и установить. Модуль поддерживает списки воспроизведения, поиск музыки в папках и еще много различных функций. Когда я слушаю музыку и болтаю с друзьями, то вставка проигрывающейся песни - вопрос пары нажатий.

(require 'jam-mode)
(require 'php-mode)
Jam - это система сборки, аналог make, учитывающий все недостатки предшественика и добавляющая новые возможности. Библиотека boost использует свою модификацию этой утилиты - bjam. Если вы пользуетесь первым или вторым, то этот модуль будет вам удобен.

Php-mode - ничего особого не добавляет, не считая подсветки синтаксиса. Однако, в сочетании с модулем mmm-mode можно добиться впечатляющих результатов.

(require 'hideshow)
Этот модуль является стандартным и позволяет скрывать или показывать блоки кода. Такой возможностью обладает Visual Studio от Microsoft и множество других редакторов, платных и бесплатных. Примечательно, что такая возможность существует в emacs с незапамятных времен (не хочу врать без нужды, но в исходном файле первый copyright датирован 94-ым годом. Windows тогда еще не существовал как таковой).

Мне редко приходится пользоваться сверткой исходных текстов при программировании, но свертка структурированной разметки жутко удобна. Для nxml-mode я включил ее так:

;; hideshow
(add-hook 'c++-mode-hook (lambda () (hs-minor-mode 1)))
(add-hook 'nxml-mode-hook (lambda () (hs-minor-mode 1)))

(add-to-list 'hs-special-modes-alist
'(nxml-mode
"\\|<[^/>]&>\\|<[^/][^>]*[^/]>"

""
" ;; won't work on its own; uses syntax table
nxml-forward-element
nil))

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



05.03.2007 11:55 <DIR> haskell
09.11.2006 15:51 <DIR> jde
05.03.2007 11:55 <DIR> slime
05.03.2007 11:57 <DIR> slime48

Эти модули предназначены для поддержки языков программирования Haskell, Java, Lisp и Scheme соответстсвенно. Откровенно говоря, каждый из них требует отдельного рассмотрения. Чтобы представить себе их мощь хоть приблизительно, можете задуматься над занимательными фактами: вводное видео от создателя slime длится более часа, jde успешно выполняет те же задачи, что и Eclipse в плане редактирования java-кода (да остальному легко обучить), а haskell-mode является предметом зависти программирующих на Erlang.

Кроме этих режимов у меня установлены quack-mode - режим, поддерживающий большинство реализаций Scheme, erlang-mode и еще ряд режимов, в основном, для подсветки синтаксиса.

Будем надеяться, что у меня будут возможности и способности рассказать о каждом из режимов в будущем.


01.05.2007 22:20 <DIR> auctex
25.05.2007 23:26 <DIR> imaxima
25.05.2007 23:26 <DIR> maxima

Auctex - режим для создания ТеХ-документов, содержит модуль preview, который способен показывать сгенерированные формулы и рисунки в буфере документа. Для работы этого модуля требуется установленный пакет TeX, как минимум две реализации которого свободно доступны для скачивания.

Maxima и imaxima - модули поддержки одноименной программы символьных вычислений. Эта программа свободно заменяет сложные коммерческие программы типа Mathcad, по крайней мере, в том объеме, котором это требуется студенту или инженеру. Кстати, попробуйте на досуге разузнать, что такое "символьные вычисления", думаю, расширите свой кругозор...

Благодаря настроенному модулю auctex, модули поддержки maxima могут отображать формулы в буфере оболочки maxima, или, проще говоря, вы будете видеть красивые рисунки в буфере, в котором вы вводите команды maxima.


21.03.2007 17:11 <DIR> mmm-mode
25.05.2007 23:26 <DIR> muse

Модуль mmm позволяет вам скомбинировать несколько режимов в одном буфере. Например, вы свободно можете скомбинировать php-mode и html-mode, или же html-mode с любым другим режимом, очень удобно, если вы используете систему автодокументирования и в комментариях используется разметка.

Muse - среда публикаций для emacs, легковесный режим с впечатляющими возможностями. Удобен, когда вы создаете несколько связанных между собой документов, например, что-то вроде подшивки. Позволяет выводить результаты в различных форматах, например, LaTeX, html, xhtml и им подобным. Обладает собственным простым (если не сказать рудиментарным) языком разметки. По большому счету, тех же результатов можно добиться, используя LaTeX, однако, используя muse, можно начать буквально в течении минут, чего не скажешь о LaTeX - объем зависимостей и порог вхождения достаточно велик. Я бы сказал, что они находятся в различных весовых категориях.

Уф. Хоть это не все, но все же на этом я решил остановиться. Дело в том, что информации по затронутым предметам более, чем достаточно: либо это освещено кем-то ранее, либо имеется исчерпывающая документация по нужному предмету. Лично я порекомендовал бы обратить внимание на следующие материалы: Emacs+MinGw+Qt HOWTO, Точки Emacs.


На этом краткое введение в emacs заканчивается, думаю, пищи для размышлений более, чем достаточно. Посмотрим, что можно сделать, используя emacs?

1. Буфер компиляции - буфер, в который выводятся все сообщения компилятора. Он создается, когда вы выполняете команду M-x compile. emacs спросит, какую команду выполнять для компиляции и запустит ее как подчиненный процесс. Обычно это make, но вполне можно указать и другую, например python.exe myscript.py

2. Вводная информация есть на http://xtalk.msk.su/~ott/ru/emacs/emacs-im/emacs-im.ru.html, небольшая заметка есть на http://blog.romanlagunov.ru/2006/10/27/jabber-client-for-emacs.html

3. К этому модулю я еще вернусь.

28 Май 2007

Набираем обороты.

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

Как указать emacs, где искать файл инициализации? В Unix это каталог c таким же именем, .emacs, в домашней директории пользователя. В Windows чуть сложнее, но не намного. Домашней директорией считается директория, на которую указвает переменная окружения %HOME%. Если она не задана, то emacs пытается прочесть ветку реестра HKLM\Software\Gnu\Emacs\HOME. Обычно эта ветка создается при запуске утилиты addpm.exe, которая есть в emacs\bin. Однако, если ветки нет - создайте ее сами.

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

Итак, вам известно, как сохранять изменения ваших настроек и как указать emacs, где искать файл инициализации.

Настало время рассказать о том, что делает emacs еще мощнее. Это модули, большое количество которых поставляется с emacs, и еще большее количество, доступных для скачивания.

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

Посмотрите в структуру каталогов внутри вашей директории emacs. Сейчас нас интересуют два каталога: /lisp и /site-lisp1. Первый содержит модули, распространяемые с системой. Лично я в отношении этого каталога придерживаюсь правила "можно читать, по возможности не писать". Посмотрите файлы внутри каталога. По традиции emacs, в начале каждого модуля идет большой комментарий (да, совершенно верно, точка с запятой означает начало комментария), это описание модуля, с пояснениями работы этого модуля.

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

Из стандартных модулей можно отметить ido, который позволяет переключаться в нужный буфер быстрее, чем обычно.

Модуль ido очень простой, поэтому подключить его очень просто. Достаточно вписать строку (require 'ido). Как только вы перезапустите emacs, переключение буферов и файлов будет использовать автодополнение, то есть вам будет достаточно набрать несколько букв из имени буфера, а emacs предложит вам подходящие варианты.2

Что происходит, когда мы даем команду require? Как загружается модуль, ведь мы не указывали путь к файлу модуля?

emacs обладает понятием "путь загрузки". Это список каталогов, в которых emacs ищет исходные тексты (или уже скомпилированные) модулей. Путь загрузки регулируется значением переменной3 load-path. Эта переменная имеет тип "список", то есть что-то типа '("../lisp" "../site-lisp" "../some/dir").

Самый простой способ - воспользоваться функцией (push). Например, чтобы добавить нужный вам каталог, можно добавить в .emacs нечто вроде:

(push "../path/to/mydir" load-path)

Обратите внимание на то, что пути являются относительными. Так проще, если вам приходится переносить файл конфигурации с компьютера на компьютер. Трюк в том, что в момент загрузки emacs текущим является Каталог с исполняемым файлом emacs. В какой-то момент трюк может перестать работать, поэтому умнее будет завести переменную, указвающую на базовый каталог, и сцеплять относительный путь с базовым каталогом. Следовательно, можно записать вот что:

(setf base-path "c:/gnu/emacs")
(push (concat base-path "/path/to/dir") load-path)

Сначала мы создаем переменную base-path, устанавливая ее значением строку "c:/gnu/emacs", а функция (concat) сцепляет вместе две строки и возвращает результат. Обратите внимание, что слэши - прямые, а не обратные, как это принято в Windows4.

Когда вам может потребоваться добавлять свой каталог в путь загрузки? Например тогда, когда модуль состоит из более чем одного файла, в таком случае удобно поместить его в отдельный каталог. Возможен вариант, когда вы создали модуль для персонального использования и хотите разместить его в своем домашнем каталоге. Вариантов множество.

После того, как нужный каталог добавлен в путь загрузки, воспользуйтесь функцией require, чтобы загрузить нужный модуль. Иногда того же результата можно добиться использованием функции load-library или load-file. Чем они отличаются от require - можно выяснить в документации.

Зачем нам это все? Конечно же, чтобы загружать модули. А какие модули нам интересны? Об этом читайте далее...

1. В Unix site-lisp обычно располагается /usr/share или /usr/var. Команда find или whereis помогут узнать точнее.

2. Существует способ включить модуль без перезагрузки, но пока не будем забегать вперед.

3. Здесь и далее я использую термин "переменная" только для простоты.

4. Признаться, я все время путаю, какой из них прямой, а какой обратный.


09 Май 2007

Быстрый старт.

Emacs - настоящая виртуальная машина lisp. Поэтому, процесс восстановления настроек очень прост. Существует понятие "стартовый файл инициализации", в Unix их называют по шаблону ".имяпрограммы" (для emacs файл называется .emacs, точка-emacs). При старте программа читает и разбирает сохраненные в файле настройки, затем выставляет соответствующие значения во внутренних ячейках стостояния. Но точка-emacs - ни что иное, как настоящая lisp-программа. elisp-программа, если быть точным, в которой установка значений происходит присваиванием значений переменным.

Этот файл можно открыть любым ascii-редактором, тогда вы увидите удивительный синтаксис lisp-а, с его причудливыми именами функций и скобками. Не знаю, как у вас, но лично я ощущаю различные языки и стили почти как на ощупь. Ощущать lisp приятно.

Хранить настройки программы в виде программы - очень старая идея в мире интерпретируемых языков. Конечно, подобное возможно и в мире компилируемых языков, но для интерпретаторов это естественно, а для компилируемого языка требуется магия.

Итак, как только процесс emacs-a запускается на выполнение, то сначала запускается lisp-машина, которая отыскивает файл инициализации и исполняет его. Заметье, в точка-emacs возможно выполнять не только присвоения, а вообще любые команды языка lisp. После исполнения .emacs lisp-машина переходит в режим ожидания команд пользователя. То есть ваших.

Ранее я говорил, что по комбинации М-х вы исполняете lisp-команды, по другому - вызываете функции. Функции написаны так, что если им требуются аргументы, но вы их не задали, то функция будет ожидать ввода команд с клавиатуры. Все функции, которые возможно вызвать через комбинацию М-х, являются интерактивными, если потребуется, то они сами запросят аргументы.

Следовательно, при вызове этих функций из файла инициализации вам обязательно придется указать требуемые аргументы. Но для начала небольшой экскурс в мир lisp.

Программа на lisp состоит из так назваемых s-выражений (вы так же можете встретить сокращенное название: s-exp) или форм. Форма - это выражение в скобках. Lisp считает, что первым в скобках идет имя вызываемой функции, а все остальное - аргументы. Если в аргументах встретится форма - она будет вычислена. Самые простые функции - арифметические: сложение, вычитание, умножение и деление. Их имена могут быть вам знакомы, вот они: +, -, *, /. А теперь - примеры, слева выражения lisp, справа их аналоги на псевдо-С:

(+ 3 4)                           3 + 4
(+ 3 5 6) 3 + 5 + 6
(* (+ 3 4) (/ 10 2)) (3 + 4) * (10 / 2)
(function x y) function(x,y)
(function1 'function2 x y) function(function2, x,y)
Обратите внимание на последний пример. В функцию в качестве аргумента передается другая функция. А ваш язык такое может?

Любой язык имеет некоторые типы данных. Основной тип данных в lisp - список. Чтобы указать интерпретатору, что следующее выражение данные, перед скобкой необходимо поставить апостроф. Тогда результатом будет список, тот самый связный список, без которого не обходится ни один учебник по С. А чтобы получить массив, он же вектор, скобочки надо заменить на квадратные, апостроф в таком случае не потребуется. Примеры:

        (1 2 3 4) - вызовет ошибку, интерпретатор будет искать функцию по имени 1.
'(1 2 3 4) - список. Каждое значение - это не просто число, это атом, особая структура, нечто вроде элемента связного списка.
[1 2 3 4] - массив.
[1 3 5 (1 3 4)] - массив, последний элемент которого список. Апостроф не требуется, но если его поставить - эффект такой же.
'(1 2 [1 3 4] 5) - список, один из элементов - массив. Апостроф требуется.
Как несложно догадаться, существуют функции, принимающие в качестве аргументов списки. Но вернемся к нашему первоначальному вопросу: как сохранить привязки клавиш между сессиями emacs-a? Вот как теперь звучит ответ: необходимо при старте emacs-a вызывать функцию привязки. Функция привязки называется (global-set-key), это нам уже известно. Чтобы вызвать ее при старте emacs-a, вызов необходимо поместить в файл инициализации. Осталось выяснить, во-первых, где должен находиться файл инициализации, во-вторых, как передать параметры функции (global-set-key).

С первым все достаточно просто. Файл инициализации в первую очередь ищется в домашней директории пользователя. В Unix с этим вопросов нет, а в Windows нет домашней директории у пользователя, поэтому в Windows домашней считается директория, на которую указывает переменная окружения %HOME% или директория, на которую указывает строковой параметр реестра HOME в ветке HKLM\Software\Gnu\Emacs. Если ни переменная окружения, ни параметр реестра не существуют, то файл инициализации будет, скорее всего, в корне системного диска, то есть диска, на который установлена ОС Windows. Чтобы файл наверняка существовал, зайдите в меню Options, и выберите Save options.

Со вторым нам поможет еще одна функция elisp - describe-function. Это интерактивная функция, вызовите ее и она предложит вам ввести имя функции, описание которой вас интересует. Сейчас нас интересует (global-set-key), значит... M-x describe-function RET global-set-key (можете воспользоваться автодополнением строки ввода, нажимая на Tab). Emacs ответит следующее:
"""
global-set-key is an interactive compiled Lisp function in `subr.el'.
(global-set-key key command)

Give key a global binding as command.
command is the command definition to use; usually it is
a symbol naming an interactively-callable function.
key is a key sequence; noninteractively, it is a string or vector
of characters or event types, and non-ASCII characters with codes
above 127 (such as ISO Latin-1) can be included if you use a vector.
"""
Итак, теперь мы знаем, что (global-set-key) ожидает два параметра. Первый - клавиша (или комбинация клавиш), второй - команда, то есть еще одна функция (помните пример?). Далее сообщается, что тип первого аргумента - или строка (если нас интересует всего одна клавиша), или массив (если нас интересует *последовательность* нажатых клавиш). Комбинация клавиш представляется как список.

Примеры: "x" - клавиша "x", (control x) - комбинация С-x, [Esc x (control x)] - последовательность из Esc, x, Ctrl-x. Еще можно добавить, что "x" эквивалентно [x].Суммируя все, сказанное выше получаем, что если мы хотим привязать сохранение текущего буфера на комбинацию Ctrl-f2, то вызов команды будет иметь вид: (global-set-key [(control f2)] 'save-buffer)

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

Если же вы где-то допустили ошибку, то диагностическое сообщение будет выведено в специальный буфер *Messages*. Наиболее вероятные ошибки - не нашелся файл инициализации или досадные опечатки.

Что дальше? Дальше - обзор средств, облегчающих программирование и жизнь в emacs.

15 Апрель 2007

Рычаги управления

Как-то на одном из форумов я прочел, что emacs жутко привередлив в выборе друзей. Фраза запала в память потому, что внутренне я тоже так считаю. Немудрено. По самой своей сути он не может быть дружелюбен к каждому. Впрочем, он и не должен. Такой подход важен для коммерческой программы, так как каждый потерянный пользователь - это не полученные деньги. Emacs бесплатен, ему нечего бояться, поэтому он один из немногих программ, могущих позволить себе выбирать своего пользователя. Звучит захватывающе, верно? Похоже на сюжет научно-фантастического романа (в тот момент, когда я жму на клавиши своего компьютера, весь мир скорбит о смерти Курта Воннегута... да, того самого Воннегута, доставившего немало волнующих переживаний своими романами мне-подростку, Воннегута, печатавшего их на обычной печатной машинке, Писателя, по сравнению с которым я навсегда останусь жалким графоманом), или какого-то фильма о разумных компьютерах. Однако, не все так фантастично. Точнее, в этой аллегории есть небольшая доля реальности.

Emacs обладает зачатками искуственного интеллекта. Чтобы не вдаваться в полемику, отыщите трактовку термина "искусственный интеллект" в современной computer science (извините, я не знаю соответствующего русского термина). Для краткости скажу, что лично я подразумеваю под ИИ различные решения проблем вроде проблемы распознаваня образов и ей подобных. Так вот, emacs обладает зачатками ИИ. Emacs представляет собой настоящую виртуальную lisp-машину. Как это понимать? Понимать примерно так: есть особый диалект языка lisp, он называется elisp, от слов emacs и lisp. Это более или менее стандартный lisp, который был расширен дополнительными сущностями (такими как буфер, файл, окно) и функциями для манипуляции этими сущностями. Кстати, такие функции называются "примитивными" (или "базовыми").

Если вы все еще не верите в ИИ в emacs, то зайдите в меню "Помощь" и выберите "Emacs Psychoterapist" - пообщаетесь с роботом. После того, как Элиза (робота зовут Элиза) решит все ваши психологические проблемы, можете поискать в интернете информацию по ключевому слову "eliza". Поверьте, вы узнаете немало занимательных фактов из истории развития искусственного интеллекта.

Я думаю, мне удалось убедить вас насчет ИИ. Или хотя бы заронить искру интереса. Таким образом мне хотелось подвести вас к мысли, что emacs потенциально может гораздо больше, чем другие программы могут в принципе. Во-первых, emacs может быть обучен в прямом смысле этого слова. Существует проект, использующий именно такую возможность для построения крайне "умной" системы рефакторинга исходных текстов на языке С++. Во-вторых, lisp - крайне высокоуровневый язык программирования, и это тоже дает значительное преимущество перед другими программами. Все модули расширения, с которыми вы так или иначе столкнетесь, являются макросами в терминах других сред разработки. Программист на lisp более продуктивен, чем программисты на других языках, поэтому небольшими усилиями такие программисты добиваются больших результатов.

Мы еще вернемся к этому вопросу позже, а пока скажу вот что: не переживайте, если emacs не делает того, что вам нужно. Просто пока вы не можете его попросить об этом. Немного терпения, и у вас все получится.

Чтобы управлять мощным механизмом и не попасть в катастрофу необходимо удобное управление. Если вы проходили интерактивный курс обучения, то уже успели узнать основные сочетания для открытия, сохранения и закрытия файлов, а так же еще ряд полезных функций. Однако, я сомневаюсь, что вы находите эти сочетания удобными. Кроме того, ряд функций не имеет сочетаний вообще, и единственный путь ими воспользоваться - вызывать их напрямую. Не слишком-то удобно, не так ли? Конечно же, emacs предоставляет возможность решить эти проблемы.

В терминах emacs сочетание клавиш называется привязкой. Каждый раз, когда вы набираете определенную комбинацию клавиш, вызывается определенная функция elisp. Говорят, что функция привязана к комбинации, отсюда и название. А как узнать, какая функция вызывается по каждой привязке? Надо воспользоваться особой функцией describe-key.

Все функции elisp можно вызвать, набрав "М-х", затем напечатать имя интересующей вас функции. Префикс "М-х" и все, что вы напечатаете после, будет отображаться внизу, в так называемом мини-буфере. Префикс "М-х" можно ввести двумя способами: или нажав "Alt-x", или нажав "Esc", а затем х, это вы должны знать из курса обучения.

Остался еще один момент. Это обратное действие: как привязать функцию к комбинации клавиш? Требуемая в этом случае функция называется global-set-key. Когда вы ее вызовете, emacs предложит ввести нужную вам комбинацию (или просто клавишу), после чего спросит, какую функцию привязать к указанной комбинации.

Я начинал работать еще в те времена, когда про блоки бесперебойного питания писали в журналах "Наука и жизнь" и "Техника - молодежи" в рубрике "Прогнозы на следующее столетие", так что привычка сохранять работу как можно чаще уже вошла в генетическую память и, скорее всего, перейдет к моим потомкам. Постоянно нажимать "C-x C-s" - медленно, хочется быстрее и удобнее. В качестве примера я покажу, как привязать операцию сохранения к моей любимой клавише.

Сначала, как уже и говорилось, я хочу выяснить, какая функция вызывается по "C-x C-s". Клик-клик-клик, "M-x describe-key". Emacs с готовностью сообщает, что по этой привязке вызывается функция save-buffer. Замечательно. Продолжим: "M-x global-set-key". Хочу, чтобы сохранение происходило по клавише '<f2>'. Ее и нажимаю, затем набираю "save-buffer". Нажимаю Enter (он же Return, он же RET). Осталось проверить... Нажимаю '<f2>', и emacs в мини-буфере говорит, что файл успешно сохранен.

Подобным способом вы можете сделать любые привязки так, как вам удобно. Но вот беда: все изменения будут потеряны, как только вы выйдете из emacs. Как сделать, чтобы emacs запомнил ваши привязки? Об этом - далее...

11 Апрель 2007

Голубая пилюля.

Моей голубой пилюлей стал самый обыкновенный расширяемый настраиваемый самодокументирующийся экранный редактор реального времени (здорово звучит, не правда ли?). В простонародье он известен как emacs.

Конечно же, emacs не заменил мне 100% программ, однако, их количество уменьшилось до пяти (или около того). Все же я оставил файловый менеджер (если быть честным, я пользуюсь и emacs, и far), остался браузер, остался набор консольных утилит... Остальное не беру во внимание, так как суть их примерно одинаковая. В остальном же emacs полностью устраивает мои нужды.

Не пугайтесь. Все, что вы слышали про emacs раньше - или неправда, или искажение, или неверное толкование. Любое лекарство, в том числе и голубую пилюлю, надо принимать по предписанию и под наблюдением врача. Должен быть кто-то, кто проведет вас по новому и неизведанному миру, в противном случае шансы пережить bad experience очень велики.

Здесь, наверное, я должен вам кое-что сказать. Не пользуйтесь emacs. Даже не пробуйте им пользоваться. Потому что через некоторое время вы осознаете, что ваша жизнь изменилась коренным образом.

Ну вот. Я вас предупредил. Все последствия на вашей совести, я тут ни причем.

Emacs стар. Очень стар. Первая версия увидела свет в конце 70х двадцатого века, примерно за год (или в год) моего рождения. Соответственно, emacs несет традиции Древних, традиции, многие из которых могли быть забыты. Они кажутся странными, но это потому, что вам приходится переучиваться. Попробуйте представить, что вы вообще не имеете привычек - тогда новое не покажется вам необычным.

По-моему, нет смысла рассказывать очевидное. Так же нет смысла повторять рассказанное. Поэтому сейчас я ограничусь советами общего плана. Хотя слово "общие" немного не подходит. И тем не менее...

Первое: пройдите интерактивный курс обучения. Это первое, что советует сам emacs. Запустите emacs (если до сего момента вам не хватило сообразительности найти и скачать его - дальше не читайте, только зря потратите время), нажмите Ctrl+h, затем сразу же t. Дальнейшие указания начинаются с верхней строчки. Кстати, в терминологии emacs клавиша Control обозначается просто C, следовательно, вы нажали C-h. Видимо, старинные клавиатуры имели меньшее число клавиш, чем современные, поэтому комбинации нередко бывают длинными - три или четыре нажатия подряд, настоящие аккорды (cамое время подыскать клавиатуру с педалями... или что-то вроде этого). Ну а полностью эта комбинация пишется как C-h t. То есть, сначала Ctrl+h, следом t. Видите, все просто.

То, что должно было открыться у вас на экране - интерактивный курс обучения редактора emacs. На английском, естественно. Точнее, если бы для вас это было естественно, то эту статью вы бы не читали. Вы бы читали какого-нибудь Клементса, или Армстронга, или еще кого... Так что если вам затруднительно, то лучше пройдите курс обучения на родном языке. Или на том, который понимаете без проблем. Не стесняйтесь, мозг должен работать над курсом, а не над переводом. Возьмите мышь, зайдите в "Помощь" (надеюсь, затруднений нет?), второй пункт сверху - "Emacs Tutorial (choose language)". Пройдите курс. Не спешите. Относитесь к этому как к таблице умножения - пока неясно, зачем ее учат, но в дальнейшем без нее трудно.

Прошли? Замечательно. Все запомнили? Если да, то дальше тоже не читайте, т.к. с вашими способностями можно найти гораздо более полезное занятие. Ну, а если нет - тоже не беспокойтесь, в конце концов, вы не переносной накопитель, есть вещи и поважнее. Поэтому мой второй совет: скачайте справочную таблицу по emacs. Распечатайте и держите на столе или где-то под рукой - еще пригодится.

Совет номер три: не сдавайтесь. Всегда легче отказаться, чем бороться. Поверьте, бороться придется недолго. И вам воздастся.

Камо грядеши?

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

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

Рядовой субъект заявит: "Нельзя сделать X без программы У". После чего без всякого зазрения совести найдет пиратскую программу "У" и сделает необходимый ему "Х". Небольшое зло, в общем-то, особенно по сравнению с бомбардировками стран третьего мира или спекуляций на рынке недвижимости. Но с точки зрения философии, зло кроется в самом подходе. Рядовой субъект не желает переформулировать свое утверждение в виде "Я не знаю, как сделать Х без программы У", более того он не собирается осмысливать факт того, что зачастую преобразование Х->Y не является конечной целью.

Поясню на примере: студент должен сдать курсовой проект в соответствии с ГОСТ-ом. У большинства в голове всплывает огненная надпись MS-Word, у немногих - MathCad, еще у единиц - TeX. И совсем ничтожно малое количество осознает, что чаще всего вполне хватит обычного ASCII-файла. Ок, чуть подыграем: ASCII-файла с минимальной HTML-разметкой. Повторюсь - "чаще всего", а не "всегда". Та часть, которая выбрала общеизвестный текстовый процессор (далеко не худший, надо сказать), будет пользоваться пиратским. Оно и понятно. В нашей стране студенты не могут позволить себе отдать приличные деньги за эту программу.

Вторая сторона медали: в этом же ВУЗе наверняка есть готовые шаблоны для работ. Угадайте, в каком формате они доступны? В какой-то мере, многие шаблоны инженерной мысли являются навязанными, например, теми же преподавателями института или общественным мнением (одногруппник, коллега по работе, сосед по подъезду). Ради интереса, я поспрашивал знакомых студентов про программы, которые они используют для учебы. Джентльменский набор: ПО для текстовой обработки, иногда табличный процессор, компилятор некоего языка. Все пиратское, даже компилятор, у которого есть бесплатная версия.

И вот, проучившись все курсы, наш студент приходит на работу. Мне кажется, он не будет особо беспокоиться о лицензионнности программ, которыми пользуется его предприятие. Это становится плохой традицией. Это уже стало плохой традицией. Однажды я работал в лаборатории небольшого колледжа. Мой коллега читал курс алгоритмических языков программирования. Ни секунды не задумываясь, он выбрал пиратский компилятор и идущую в комплекте среду программирования. Попытавшись объяснить, что поощрять студентов пользоваться пиратскими программами - это нехорошо, что есть другие способы, я увидел, что он меня просто не понимает. Так, как будто я в один момент начал говорить на неизвестном ему диалекте. Позже я понял в чем дело: он никогда не видел иного способа, он никогда не думал про иные способы, он не верил в существование иных способов писать программы.

Конечно же, я не призываю вас изменить или спасти мир. Я не ратую за отмену платных лицензионных программ: в этом мире всему есть своя роль. Я предлагаю взглянуть на ваш мир с другой точки, это поможет вам рассмотреть его всесторонне. И еще: ведь вы же не хотите быть похожим на моего коллегу?

Не слишком обольщайтесь на мой счет: когда-то я был таким же. Однако, мой основной козырь - обучаемость и критический склад ума. Это позволяло двигаться мне вперед. Однако, временами, я слишком долго топчусь на месте, а потом, сдвинувшись, понимаю, что маленький импульс со стороны мог бы сэкономить мне множество сил и времени. И мне хочется верить, что в нужное время я окажусь тем самым маленьким импульсом со стороны.