Добавить в избранное | Сделать стартовой страницей

Большая Linux библиотека для пользователей OS Linux и ПО для нее
Есть что сказать? Нужен совет? Посети наш форум.




Руководство по GNU Emacs. часть 4

Использование множества буферов

Текст, который вы редактируете в Emacs, находится в объекте, называемом буфером. Каждый раз, когда вы обращаетесь к файлу, для хранения его текста создается буфер. Каждый раз, когда вы запускаете Dired, создается буфер, содержащий список каталога. Если вы посылаете сообщение с помощью C-x m, то для текста этого сообщения используется буфер с именем `*mail*'. Когда вы запрашиваете документацию команды, она появится в буфере с именем `*Help*'.

В любой момент один и только один буфер является выбранным. Он также называется текущим буфером. Часто мы говорим, что команда действует в "буфере", как если бы он был только один; но на самом деле это означает, что команда действует в выбранном буфере (большинство команд так и делают).

Когда Emacs создает множество окон, каждое окно имеет свой выбранный буфер, но в любой момент времени только одно из окон является выбранным, и его буфер -- это выбранный буфер. Строка режима каждого окна показывает имя буфера, который в нем отображен (смотрите раздел Множество окон).

У каждого буфера есть имя, которое может быть произвольной длины, и вы можете выбрать любой буфер по имени. Большинство буферов создаются при обращении к файлам, и их имена производятся из имени файла. Но вы можете также создать пустой буфер с любым именем, каким захотите. Только что запущенный Emacs несет один буфер с именем `*scratch*', который может быть использован для вычисления выражений Лиспа в Emacs. В именах буферов имеет значение различие между верхним и нижним регистрами.

Каждый буфер записывает отдельно, к какому файлу он обращается, изменен ли он, и какие основной и второстепенные режимы в нем действуют (смотрите раздел Основные режимы). Любая переменная Emacs может быть сделана локальной для конкретного буфера; имеется в виду, что ее значение в этом буфере может отличаться от ее значения в других буферах. Смотрите раздел Локальные переменные.

Создание и выбор буферов

C-x b буфер RET
Выбрать или создать буфер с именем буфер (switch-to-buffer).
C-x 4 b буфер RET
Аналогично, но выбирает буфер в другом окне (switch-to-buffer-other-window).
C-x 5 b буфер RET
Аналогично, но выбирает буфер в другом фрейме (switch-to-buffer-other-frame).

Чтобы выбрать буфер с именем имя-буфера, наберите C-x b имя-буфера RET. Это запустит команду switch-to-buffer с аргументом имя-буфера. Вы можете применить завершение сокращенного имени желаемого буфера (смотрите раздел Завершение). Пустой аргумент для C-x b задает последний выбранный буфер, который не отображен ни в одном окне.

Большинство буферов создаются при обращении к файлам или же командами Emacs, которые хотят показать некоторый текст, но вы также можете явно создать буфер, набрав C-x b имя-буфера RET. Эта команда создает новый, пустой буфер, который не обращется ни к какому файлу, и выберет его для редактирования. Такие буферы создаются для заметок. Если вы попытаетесь сохранить этот буфер, то у вас спросят имя файла для записи. Основной режим в новом буфере определяется значением переменной default-major-mode (смотрите раздел Основные режимы).

Отметим, что C-x C-f и любая другая команда для обращения к файлу также могут использоваться для переключения к существующему буферу, обращающемуся к файлу. Смотрите раздел Обращение к файлам.

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

Перечисление существующих буферов

C-x C-b
Перечисляет существующие буферы (list-buffers).

Чтобы напечатать список всех существующих буферов, наберите C-x C-b. Каждая строка в списке показывает имя одного буфера, его основной режим и файл, к которому он обращается. Буферы перечисляются в том порядке, в котором они были текущими; буферы, которые были текущими недавно, идут первыми.

Знак `*' в начале строки указывает, что буфер "модифицирован". Если модифицированы несколько буферов, то может быть пора записать некоторые из них при помощи C-x s (смотрите раздел Сохранение файлов). Знаком `%' обозначаются буферы, доступные только для чтения. Знак `.' отмечает выбранный буфер. Вот пример перечня буферов:

 MR Buffer         Size  Mode           File
 -- ------         ----  ----           ----
.*  emacs.tex      383402 Texinfo       /u2/emacs/man/emacs.tex
    *Help*         1287  Fundamental
    files.el       23076 Emacs-Lisp     /u2/emacs/lisp/files.el
  % RMAIL          64042 RMAIL          /u/rms/RMAIL
 *% man            747   Dired          /u2/emacs/man/
    net.emacs      343885 Fundamental   /u/rms/net.emacs
    fileio.c       27691 C              /u2/emacs/src/fileio.c
    NEWS           67340 Text           /u2/emacs/etc/NEWS
    *scratch*      0     Lisp Interaction

Отметим, что буфер `*Help*' создается при запросе справки, и это не является обращением к какому-либо файлу. Буфер `man' был создан Dired для каталога `/u2/emacs/man/'.

Разнообразные операции над буфером

C-x C-q
Переключить доступ на запись в буфер (vc-toggle-read-only).
M-x rename-buffer RET имя RET
Изменить имя текущего буфера.
M-x rename-uniquely
Переименовать буфер добавлением `<числа>' в конец имени.
M-x view-buffer RET буфер RET
Просмотреть буфер.

Буфер может быть доступен только для чтения, что означает, что команды для изменения его содержимого не разрешены. Строка режима указывает на то, что буфер доступен только для чтения, знаками `%%' или `%*' около левого края. Буферы только для чтения обычно создаются подсистемами вроде Dired и Rmail, которые имеют специальные команды для действий над текстом; буфер только для чтения создается также, если вы обращаетесь к файлу, для которого у вас нет доступа на запись.

Если вы хотите сделать изменения в буфере, предназначенном только для чтения, используйте команду C-x C-q (vc-toggle-read-only). Она делает буфер, доступный только для чтения, доступным для записи, а буфер, доступный для записи -- доступным только для чтения. В большинстве случаев эта команда работает, устанавливая переменную buffer-read-only, которая имеет локальное значение в каждом буфере и делает буфер закрытым для записи, если ее значение не nil. Если этот файл сопровождается с контролем версий, то C-x C-q работает через систему управления версиями и изменяет состояния доступа на запись как для файла, так и для буфера. Смотрите раздел Управление версиями.

M-x rename-buffer изменяет имя текущего буфера. Новое имя задается как аргумент минибуфера. Значения по умолчанию нет. Если вы напишете имя, которое используется для какого-то другого буфера, то происходит ошибка, и переименование не делается.

M-x rename-uniquely переименовывает текущий буфер в похожее имя с добавленным числовым окончанием и делает это имя одновременно уникальным и отличным от других. Этой команде не нужен аргумент. Она полезна для создания нескольких буферов с оболочкой: если вы переименуете буфер `*Shell*' и снова сделаете M-x shell, то создастся новый буфер оболочки с именем `*Shell*'; тем временем старый буфер оболочки продолжает существовать под своим новым именем. Этот метод также полезен для буферов почтовых сообщений, буферов компиляции и большинства программ в Emacs, которые создают специальные буферы с конкретными именами.

M-x view-buffer очень похожа на M-x view-file (смотрите раздел Разнообразные действия над файлами), за исключением того, что она показывает уже существующий буфер Emacs. Режим View предусматривает команды для удобной прокрутки буфера, но не для его изменения. Когда вы выходите из режима View с помощью q, вы переключаетесь назад к тому буферу (и позиции), который прежде отображался в этом окне. Или вы можете выйти из режима View с помощью e, в результате после прочтения сохранятся буфер и значение точки.

Команды M-x append-to-buffer and M-x insert-buffer можно использовать для копирования текста из одного буфера в другой. Смотрите раздел Накопление текста.

Уничтожение буферов

Если вы продолжаете работу в Emacs довольно долго, вы можете накопить большое количество буферов. Тогда вы можете посчитать удобным уничтожить те из них, в которых вы больше не нуждаетесь. В большинстве операционных систем уничтожение буфера освобождает занимаемое им пространство, так что его смогут использовать другие процессы. Вот несколько команд для уничтожения буферов:

C-x k имя-буфера RET
Уничтожает буфер имя-буфера (kill-buffer).
M-x kill-some-buffers
Предлагает уничтожить каждый буфер один за другим.

C-x k (kill-buffer) уничтожает один буфер, чье имя задано в минибуфере. По умолчанию, если вы наберете в минибуфере просто RET, уничтожится текущий буфер. Если уничтожается текущий буфер, то выбранным становится другой буфер -- тот, который выбрали недавно, но сейчас он не виден ни в одном окне. Если вы попросили уничтожить буфер, который обращается к файлу и был модифицирован (содержит несохраненные изменения), тогда вас спросят о подтверждении с yes перед тем, как буфер будет уничтожен.

Команда M-x kill-some-buffers спрашивает о каждом буфере, один за другим. Ответ y означает уничтожить буфер. Уничтожение текущего буфера или буфера, содержащего незаписанные изменения, выбирает новый буфер или требует такого же подтверждения, как и kill-buffer.

Меню буферов (смотрите раздел Действия над несколькими буферами) также предоставляет удобный способ уничтожения различных буферов.

Если вы хотите делать что-то особенное каждый раз, когда уничтожается буфер, вы можете добавить свои функции в ловушку kill-buffer-hook (смотрите раздел Ловушки).

Если вы продолжаете один сеанс Emacs в течении многих дней, как делают многие, он может наполниться буферами, которые вы использовали несколько дней назад. Команда M-x clean-buffer-list -- это удобный способ очистить их; она уничтожает все неизмененные буферы, которые вы не использовали долгое время. Обычные буферы уничтожаются, если они не отображались в течении трех дней; однако, вы можете указать определенные буферы, которые никогда не должны уничтожаться автоматически, и другие, которые нужно уничтожать, если их не использовали хотя бы час.

Вы также можете сделать так, чтобы эти буферы очищались для вас сами ежедневно в полночь, включив режим Midnight. Режим Midnight работает каждый день в полночь; в это время он запускает clean-buffer-list или другие функции, которые вы поместите в обычную ловушку midnight-hook (смотрите раздел Ловушки).

Чтобы включить режим Midnight, используйте буфер Customization для установки переменной midnight-mode в значение t. Смотрите раздел Интерфейс для простой настройки.

Действия над несколькими буферами

Меню буферов похоже на "Dired для буферов". Оно позволяет вам запрашивать действия для различных буферов Emacs при помощи редактирования буфера, содержащего их список. Вы можете сохранять буферы, уничтожать их (здесь это называется удалением для согласования с Dired) или показывать их.

M-x buffer-menu
Начать редактирование буфера, содержащего список всех буферов Emacs.

Команда buffer-menu записывает список всех буферов Emacs в буфер с именем `*Buffer List*' и выбирает этот буфер в режиме Buffer Menu. Этот буфер предназначен только для чтения и может быть изменен только при помощи специальных команд, описанных в этом разделе. В буфере `*Buffer List*' могут использоваться обычные команды Emacs для движения курсора. Следующие специальные команды применяются к буферу, описанному в текущей строке:

d
Запросить удаление (уничтожение) буфера, и затем сдвинуться вниз. Запрос показывается как `D' на строке перед именем буфера. Затребованные удаления происходят, когда вы печатаете команду x.
C-d
Как d, но сдвигает вверх, а не вниз.
s
Запросить сохранение буфера. Запрос показывается как `S' на строке. Требуемые сохранения происходят, когда используется команда x. Вы можете запросить и запись, и удаление для одного и того же буфера.
x
Выполнить ранее запрошенные удаления и сохранения.
u
Уничтожить любой запрос, сделанный для текущей строки, и сдвинуть курсор вниз.
DEL
Сдвинуть курсор к предыдущей строке и уничтожить любой запрос, сделанный для этой строки.

Команды d, C-d, s и u для добавления или сброса флагов также перемещают вниз (или вверх) на одну строку. Они принимают числовой аргумент в качестве счетчика повторов.

Эти команды действуют сразу на буфер, перечисленный в текущей строке:

~
Пометить буфер как "неизмененный". Команда ~ делает это немедленно после того, как вы ее ввели.
%
Переключает флаг доступности на запись для буфера. Команда % действует сразу после ввода.
t
Обратиться к буферу как к таблице тегов. Смотрите раздел Выбор таблицы тегов.

Есть также команды для выбора другого буфера или нескольких буферов:

q
Выйти из меню буферов -- сразу отобразить последний буфер, бывший прежде видимым на его месте.
RET
f
Немедленно выбрать буфер на этой строке на место буфера `*Buffer List*'.
o
Немедленно выбрать буфер на этой строке в другом окне, как если бы это было сделано при помощи C-x 4 b, оставляя `*Buffer List*' видимым.
C-o
Немедленно отобразить буфер на этой строке в другом окне, но не выбирать это окно.
1
Немедленно выбрать буфер на этой строке в полноэкранном окне.
2
Немедленно создать два окна, одно с буфером на этой строке, а второе с предыдущим выбранным буфером (помимо буфера `*Buffer List*').
b
Спрятать буфер, перечисленный в текущей строке.
m
Пометить этот буфер для показа в другом окне, если вы выйдите с помощью команды q. Такой запрос показывается как `>' в начале строки. (Один и тот же буфер не может иметь и запрос на показ, и запрос на удаление.)
v
Немедленно выбрать буфер на этой строке, а также показать в других окнах любые буферы, прежде помеченные с помощью команды m. Если таких буферов нет, то эта команда эквивалентна 1.

Все, что buffer-menu делает непосредственно, -- это создает и выбирает подходящий буфер и включает режим Buffer Menu. Все остальное из описанного выше осуществляется при помощи специальных команд, предоставляемых в режиме Buffer Menu. Одним из следствий этого является то, что вы можете переключиться из буфера `*Buffer List*' в другой буфер Emacs и редактировать там. Вы можете выбрать заново буфер `*Buffer List*' позже, чтобы исполнить уже запрошенные действия, или вы можете уничтожить его или больше не обращать на него внимания.

Существует только одно различие между buffer-menu и list-buffers -- это то, что buffer-menu выбирает буфер `*Buffer List*' в текущем окне, а list-buffers отображает его в другом окне. Если вы запускаете list-buffers (это происходит при наборе C-x C-b) и выбираете список буферов вручную, то вы можете использовать все описанные здесь команды.

Буфер `*Buffer List*' не обновляется автоматически, когда создаются или уничтожаются буферы; его содержимое -- это просто текст. Если вы создавали, удаляли или переименовывали буферы, вы можете обновить `*Buffer List*', чтобы он показывал то, что вы сделали, напечатав g (revert-buffer) или повторив команду buffer-menu.

Косвенные буферы

Косвенный буфер разделяет текст с каким-то другим буфером, называемым базовым буфером косвенного буфера. Это своего рода аналог символьных ссылок на файлы, но для буферов.

M-x make-indirect-buffer базовый-буфер RET косвенное-имя RET
Создает косвенный буфер с именем косвенное-имя, чей базовый буфер --- это базовый-буфер.

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

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

Один из способов применения косвенных буферов -- отображение нескольких различных видов схемы текста. Смотрите раздел Просмотр одной схемы в нескольких видах

Множество окон

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

Понятие окна в Emacs

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

В любой момент одно из окон является выбранным окном; буфер, отображаемый этим окном, является текущим буфером. Курсор терминала показывает позицию точки в этом окне. Все другие окна также имеют позицию точки, но так у терминала есть только один курсор, нельзя показать, где находятся эти позиции. Когда есть несколько видимых фреймов в X Windows, в каждом фрейме изображается один курсор, находящийся в выбранном окне этого фрейма. Курсор в выбранном фрейме закрашен; курсоры в других фреймах выглядят как пустые клетки.

Команды движения точки действуют только на значение точки для выбранного окна Emacs. Они не изменяют значение точки в каком-либо другом окне Emacs, даже в показывающем тот же самый буфер. Это верно и для таких команд, как C-x b для изменения выбранного буфера в выбранном окне, на другие окна они не действуют вообще. Однако, существуют другие команды, например C-x 4 b, которые выбирают другое окно и переключают буферы в нем. Также, все команды, которые показывают информацию в окне, включая (например) C-h f (discribe-function) и C-x C-b (list-bufers), работают при помощи переключения буферов в невыбранном окне, не затрагивая выбранное.

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

Каждое окно имеет свою собственную строку режима, которая показывает имя буфера, статус модификации и основной и второстепенные режимы буфера, который отражен в данном окне. Смотрите раздел Строка режима, для более подробной информации о строке режима.

Разделение окон

C-x 2
Разделить выбранное окно на два, находящихся одно под другим (split-window-vertically).
C-x 3
Разделить выбранное окно на два окна, находящихся одно рядом с другим (split-window-horizontally).
C-Mouse-2
В строке режима или полосе прокрутки, разделяет это окно.

Команда C-x 2 (split-window-vertically) разбивает выбранное окно на два, одно под другим. Оба окна cначала показывают один и тот же буфер с одним и тем же значением точки. По умолчанию каждое из двух окон получает половину высоты окна, которое было разделено; числовой аргумент определяет количество строк, которое необходимо дать верхнему окну.

C-x 3 (split-window-horizontally) разбивает выбранное окно на два рядом стоящих окна. Числовой аргумент определяет, сколько столбцов дать левому окну. Окна разделяются строкой вертикальных штрихов. Окна, которые не занимают всю ширину фрейма, имеют строки режима, но они усечены. На терминалах, где Emacs не поддерживает подсветку, усеченные строки режима иногда появляются не в инверсном изображении.

Вы можете разделить окно горизонтально, щелкнув C-Mouse-2 на строке режима или полосе прокрутки. Линия раздела проходит от места, где вы щелкнули: если вы щелкнули на строке режима, от этого места отойдет новая полоса прокрутки; если вы щелкнули на полосе прокрутки, в месте вашего щелчка появится строка режима нового окна.

Когда окно меньше полной ширины экрана, часто встречаются слишком длинные строки текста, которые не помещаются в окне. Продолжение всех этих строк может привести к путанице. Переменная truncate-partial-width-windows может быть установлена не равной nil, это принудительно делает во всех окнах усечение строк до меньшего, чем полная ширина окна, размера независимо от отображаемого буфера и значения переменной truncate-lines в нем. Смотрите раздел Строки продолжения.

Горизонтальная прокрутка часто используется в окнах, расположенных рядом вертикально. Смотрите раздел Управление изображением.

Если split-window-keep-point не равна nil, как по умолчанию, то оба окна, получающиеся после C-x 2, наследуют значение точки от разделяемого окна. Это означает, что необходима прокрутка. Если эта переменная равна nil, то C-x 2 пытается избежать сдвига текста на экране, помещая точку в каждом окне в уже видимом месте. Она также выбирает то окно, которое содержит строку текста, на которой курсор был раньше. Некоторые пользователи предпочитают такой режим на медленных терминалах.

Использование других окон

C-x o
Выбрать другое окно (other-window). Это буква o, не ноль.
C-M-v
Прокрутить следующее окно (scroll-other-window).
M-x compare-windows
Найти следующее место, где текст выбранного окна не совпадает с текстом в следующем окне.
Mouse-1
Mouse-1 на строке режима какого-нибудь окна выбирает это окно, но не перемещает в нем точку (mouse-select-window).

Чтобы выбрать другое окно, щелкните Mouse-1 на его строке режима. С помощью клавиатуры вы можете переключать окна, набирая C-x o (other-window). Это буква о, от слова `other' (`другое'), а не ноль. Когда имеется более двух окон, эта команда продвигается через все окна по кругу, обычно сверху вниз и слева направо. От самого правого нижнего окна она идет обратно в то, которое находится в верхнем левом углу. Числовой аргумент означает движение на несколько шагов по круговому порядку окон. Отрицательный аргумент продвигает по кругу в обратном порядке. Когда минибуфер активен, он является последним окном в кольце; вы можете переключиться из окна минибуфера в одно из других окон и позже переключиться обратно и завершить в минибуфере запрашиваемый аргумент. Смотрите раздел Редактирование в минибуфере.

Обычные команды прокрутки (смотрите раздел Управление изображением) относятся только к выбранному окну, но существует одна команда для прокрутки следующего окна. C-M-v (scroll-other-window) прокручивает окно, которое выбрала бы C-x o. Она принимает положительные и отрицательные аргументы так же, как и C-v. (В минибуфере, C-M-v прокручивает окно, содержащее справку для минибуфера, если оно есть, а не следующее окно в стандартном круговом порядке.)

Команда M-x compare-windows позволяет вам сравнить два файла или буфера, видимые в двух окнах, продвигаясь по ним до следующего несовпадения. Смотрите раздел Сравнение файлов, для подробностей.

Изображение в другом окне

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

C-x 4 b имя-буфера RET
Выбрать буфер имя-буфера в другом окне. При этом запускается switch-to-buffer-other-window.
C-x 4 C-o имя-буфера RET
Отобразить буфер имя-буфера в другом окне, но не выбирать в нем этот буфер. Это запускает display-buffer.
C-x 4 f имя-файла RET
Обратиться к файлу имя-файла и выбрать его буфер в другом окне. При этом запускается find-file-other-window. Смотрите раздел Обращение к файлам.
C-x 4 d каталог RET
Выбрать буфер Dired для каталога в другом окне. При этом запускается dired-other-window. Смотрите раздел Dired, редактор каталогов.
C-x 4 m
Начать составление почтового сообщения в другом окне. При этом запускается mail-other-window; аналог этой команды, работающий в том же окне -- C-x m (смотрите раздел Посылка почты).
C-x 4 .
Найти тег в текущей таблице тегов в другом окне. При этом запускается find-tag-other-window, многооконный вариант M-. (смотрите раздел Таблицы тегов).
C-x 4 r имя-файла RET
Обратиться к файлу имя-файла в режиме только для чтения и выбрать его буфер в другом окне. Этот ключ запускает команду find-file-read-only-other-window. Смотрите раздел Обращение к файлам.

Принудительное изображение в том же окне

Некоторые команды Emacs переключают в определенный буфер с особым содержимым. Например, M-x shell переключает в буфер, называемый `*Shell*'. По соглашению, все эти команды написаны так, чтобы выдавать этот буфер в отдельном окне. Но вы можете указать, что некоторые из этих буферов должны появляться в выбранном окне.

Если вы добавляете имя буфера в список same-window-buffer-names, то в результате такие команды отображают этот буфер, переключаясь к нему в том же окне. Например, если вы добавите в этот список элемент "*grep*", то команда grep будет показывать буфер с выводом в текущем окне.

Значение same-window-buffer-names по умолчанию не равно nil: оно задает имена буферов `*info*', `*mail*' и `*shell*' (а также других буферов, используемых более туманными пакетами Emacs). Поэтому M-x shell обычно переключает в буфер `*shell*' в выбранном окне. Если вы удалите этот элемент из списка same-window-buffer-names, поведение M-x shell изменится --- вместо этого она будет выдавать буфер в другом окне.

Вы можете задать эти буферы в более общей форме с помощью переменной same-window-regexps. Установите ее равной списку регулярных выражений; теперь любой буфер, чье имя совпадает с одним из этих регулярных выражений, будет отображаться с переключением к нему в выбранном окне. (Еще раз, это относится только к тем буферам, которые обычно показываются вам в отдельном окне.) Значение этой переменной по умолчанию задает буферы Telnet и rlogin.

Аналогичная возможность позволяет вам задать буферы, которые должны отображаться в принадлежащих только им фреймах. Смотрите раздел Фреймы специальных буферов.

Удаление и переупорядочение окон

C-x 0
Удалить выбранное окно (delete-window). Последний знак в этой последовательности ключей -- ноль.
C-x 1
Удалить в выбранном фрейме все окна, кроме выбранного (delete-other-windows).
C-x 4 0
Удалить выбранное окно и уничтожить буфер, который был в нем показан (kill-buffer-and-window). Последний знак в этой последовательности ключей -- ноль.
C-x ^
Сделать выбранное окно выше (enlarge-window).
C-x }
Расширить выбранное окно (enlarge-window-horizontally).
C-x {
Сузить выбранное окно (shrink-window-horizontally).
C-x -
Уменьшить это окно, если буфер в нем не требует столько строк (shrink-window-if-larger-than-buffer).
C-x +
Выровнять высоты всех окон (balance-windows).
Drag-Mouse-1
Перемещение строки режима окна с помощью mouse-1 изменяет высоту окон.
Mouse-2
Mouse-2 на строке режима окна удаляет все остальные окна в этом фрейме (mouse-delete-other-windows).
Mouse-3
Mouse-3 на строке режима какого-нибудь окна удаляет это окно (mouse-delete-window).

Чтобы удалить окно, наберите C-x 0 (delete-window). (Это ноль). Пространство, занимаемое удаленным окном, достается соседнему окну (но не окну минибуфера, даже если оно активно в этот момент). Как только окно удалено, его атрибуты забываются; их может вернуть только восстановление конфигурации окна. Удаление окна не влияет на буфер, который оно отображало; этот буфер продолжает существовать, и вы можете выбрать его в любом окне командой C-x b.

C-x 4 0 (kill-buffer-and-window) -- более сильная команда, чем C-x 0; она уничтожает текущий буфер и затем удаляет выбранное окно.

C-x 1 (delete-other-windows) -- более мощная в другом смысле; она удаляет все окна за исключением выбранного (и минибуфера). Выбранное окно расширяется, чтобы использовать весь фрейм, за исключением эхо-области.

Вы также можете удалить окно, щелкнув на его строке режима Mouse-2, и удалить все окна во фрейме, кроме одного, щелкнув на строке режима этого окна Mouse-3.

Простейший способ настроить высоту окон -- сделать это с помощью мыши. Если вы нажмете Mouse-1 на строке режима, вы можете перетащить ее вверх или вниз, изменяя высоту окон сверху и снизу от нее.

Чтобы перенастроить деление пространства между вертикально соседними окнами, используйте C-x ^ (enlarge-window). Она делает текущее выбранное окно больше на одну строку или на столько строк, сколько определено числовым аргументом. С отрицательным аргументом, она делает выбранное окно меньше. C-x } (enlarge-window-horizontally) делает выбранное окно шире, а C-x { (shrink-window-horizontally) -- уже на заданное число столбцов.

Когда вы увеличиваете окно, оно забирает пространство от одного из своих соседей. Если это делает какие-то окна слишком маленькими, то эти окна удаляются и их пространство делится между соседними окнами. Минимальный размер определяется переменными window-min-height и window-min-width.

Команда C-x - (shrink-window-if-larger-than-buffer) уменьшает высоту выбранного окна, если оно выше, чем необходимо для показа всего текста отображаемого в нем буфера. Она передает освободившиеся строки другим окнам в этом фрейме.

Вы также можете использовать C-x + (balance-windows), чтобы выровнять высоты всех окон в выбранном фрейме.

Смотрите раздел Редактирование в минибуфере, подробное описание режима Resize-Minibuffer, который автоматически изменяет размер окна минибуфера, чтобы в нем вмещался текст минибуфера.

Фреймы и X Windows

При использовании X Window System вы можете создавать в одном сеансе Emacs несколько окон уровня оконной системы. Каждое принадлежащее Emacs X-окно показывает один фрейм, который может содержать одно или несколько окон Emacs. Изначально фрейм содержит одно окно Emacs общего назначения, которое вы можете поделить вертикально или горизонтально на меньшие. Обычно фрейм имеет собственную эхо-область и минибуфер, но вы можете сделать фреймы без них -- они будут использовать эхо-область и минибуфер другого фрейма.

Редактирование в одном фрейме затрагивает и другие фреймы. К примеру, если вы поместите текст в список уничтожений в одном фрейме, вы можете восстановить его в другом. Если вы выходите из Emacs через C-x C-c в одном фрейме, это удалит все фреймы. Чтобы удалить только один фрейм, используйте C-x 5 0.

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

Emacs, скомпилированный для MS-DOS, эмулирует некоторые аспекты оконной системы, так что вы сможете использовать многие возможности из описанных в этой главе. Смотрите раздел Клавиатура и мышь в MS-DOS, для дальнейшей информации.

Команды мыши для редактирования

Команды мыши для выделения и копирования области в основном совместимы с командами программы xterm. Вы можете пользоваться одними и теми же командами мыши для обмена текстом между Emacs другими X-клиентами.

Если вы выделите область с помощью любой из этих команд и сразу же после этого нажмете функциональную клавишу DELETE, она удалит выделенную область. Функциональная клавиша BACKSPACE или ASCII-знак DEL не делают этого; и если вы нажмете между командой мыши и DELETE какую-то другую клавишу, DELETE не подействует таким образом.

Mouse-1
Перемещает точку туда, где вы щелкнули (mouse-set-point). Обычно это левая кнопка.
Drag-Mouse-1
Устанавливает область вокруг текста, по которому вы провели, и копирует этот текст в список уничтожений (mouse-set-region). С помощью этой команды вы можете указать оба конца области. Если при проведении мышью вы переместите ее за верхний или нижний предел окна, это окно непрерывно прокручивается, пока вы не вернете в него мышь. Таким способом вы можете выделять области, не умещающиеся на экране. Число прокручиваемых за один шаг строк зависит от того, насколько далеко за край окна ушла мышь; минимальный размер шага определяет переменная mouse-scroll-min-lines.
Mouse-2
Восстанавливает последний уничтоженный текст в том месте, где вы щелкнули (mouse-yank-at-click). Обычно это средняя кнопка.
Mouse-3
Эта команда, mouse-save-then-kill, имеет несколько назначений в зависимости от того, где вы щелкнули, и от состояния области. Самый основной случай -- это когда вы щелкаете Mouse-1 в одном месте, а затем Mouse-3 в другом. Это выделяет текст между двумя этими позициями в качестве области. Это также копирует новую область в список уничтожений, чтобы вы могли скопировать его в другое место. Если вы щелкните в тексте Mouse-1, прокрутите окно с помощью полоски прокрутки и затем щелкните Mouse-3, Emacs запомнит, где была точка перед прокруткой (где вы поместили ее с помощью Mouse-1), и использует эту позицию как другой конец области. Это сделано, чтобы вы могли выделять области, которые не умещаются полностью на экране. В более общем виде, если у вас нет подсвеченной области, Mouse-3 выделяет в качестве области текст между точкой и местом щелчка. Она делает это, устанавливая метку там, где была точка, и перемещая точку к той позиции, где вы щелкнули. Если у вас есть подсвеченная область, или если область была установлена непосредственно перед этим с помощью проведения кнопкой 1, Mouse-3 подстраивает ближайший конец области, перемещая его к месту щелчка. Также, текст подстроенной области замещает в списке уничтожений текст старой области. Если вы изначально задали область, используя двойной или тройной щелчок Mouse-1, чтобы определить область как состоящую из целых слов или строк, то подстройка области с помощью Mouse-3 также проходит по целым словам или строкам. Если вы примените Mouse-3 два раз подряд на одном месте, вы уничтожите уже выделенную область.
Double-Mouse-1
Этот ключ устанавливает область вокруг слова, на котором вы щелкнули. Если вы щелкнули на знаке с синтаксической категорией "symbol" (например, на подчерке в режиме C), он устанавливает область вокруг символа, которому принадлежит этот знак. Если вы щелкнули на знаке с синтаксической категорией открывающей или закрывающей круглой скобки, область устанавливается вокруг группы (s-выражения), которая завершается или начинается на этом знаке. Если вы щелкнули на знаке с синтаксической категорией разделителя строк (таком как кавычка или двойные кавычки в Си), область будет установлена вокруг этой строковой константы (с использованием эвристики, чтобы выяснить, является ли этот знак начинающим или завершающим).
Double-Drag-Mouse-1
Этот ключ выделяет область, состоящую из слов, по которым вы провели.
Triple-Mouse-1
Этот ключ устанавливает область вокруг строки, на которой вы щелкнули.
Triple-Drag-Mouse-1
Этот ключ выделяет область, состоящую из строк, по которым вы провели.

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

Чтобы восстановить уничтоженный или скопированный текст в другое место, переведите туда мышь и нажмите Mouse-2. Смотрите раздел Восстановление. Однако, если mouse-yank-at-point не равна nil, Mouse-2 восстанавливает в точке. Тогда не имеет значения, где вы щелкаете, или даже в каком из окон фрейма вы щелкаете. Значение по умолчанию равно nil. Эта переменная влияет также на восстановление вторичного выделения.

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

Чтобы скопировать текст из другого X-окна, используйте в программе, работающей в другом окне, команды "вырезать" или "копировать", чтобы выделить нужный вам текст. Затем восстановите его в Emacs с помощью C-y или Mouse-2.

Эти команды вырезания и вставки работают также и в MS-Windows.

Когда Emacs помещает текст в список уничтожений или перекладывает текст на вершину списка уничтожений, он устанавливает первичное выделение X-сервера. Именно таким образом другие X-клиенты могут получить доступ к этому тексту. Emacs также сохраняет текст в буфере вырезок, но только если этот текст достаточно короткий (x-cut-buffer-max задает максимальное число знаков); помещение в буфер вырезок длинных строк может быть медленным.

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

Вторичное выделение

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

M-Drag-Mouse-1
Устанавливает вторичное выделение с одним концом в том месте, где вы нажали кнопку, и другим -- в том, где вы ее отпустили (mouse-set-secondary). Когда вы проводите мышью, появляется и изменяется подсветка. Если при проведении мышью вы сдвинете ее за верхний или нижний предел окна, это окно непрерывно прокручивается, пока вы не вернете в него мышь. Таким способом вы можете выделять области, не умещающиеся на экране.
M-Mouse-1
Устанавливает одну из граничных точек вторичного выделения (mouse-start-secondary).
M-Mouse-3
Создает вторичное выделение, используя место, указанное с помощью M-Mouse-1 как его второй конец (mouse-secondary-save-then-kill). Второй щелчок на этом же месте уничтожает только что сделанное вторичное выделение.
M-Mouse-2
Вставляет в месте щелчка вторичное выделение (mouse-yank-secondary). Это помещает точку в конец восстановленного текста.

Двойные и тройные щелчки M-Mouse-1 действуют на слова и строки, во многом как для Mouse-1.

Если mouse-yank-at-point не равна nil, M-Mouse-2 восстанавливает в точке. Тогда не имеет значения, где вы щелкнули; главное, в каком окне. Смотрите раздел Команды мыши для редактирования.

Следование по ссылкам с помощью мыши

Некоторые буферы Emacs показывают различного рода перечни. Это перечни файлов, буферов, возможных завершений, совпадений с образцом и так далее.

Поскольку восстановление в этих буферах бессмысленно, в большинстве из них Mouse-2 определена особо, как команда для использования или просмотра пункта, на котором вы щелкнули.

Например, если вы щелкните Mouse-2 на имени файла в буфере Dired, вы обратитесь к этому файлу. Если вы щелкните Mouse-2 на сообщении об ошибке в буфере `*Compilation*', вы перейдете к исходному коду для этого сообщения. Если вы щелкните Mouse-2 на завершении в буфере `*Completions*', вы выберете это завершение.

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

Щелчки мыши для меню

Щелчки мыши, модифицированные с помощью клавиш CTRL и SHIFT, выводят меню.

C-Mouse-1
Это меню для выбора буфера.
C-Mouse-2
Это меню для задания начертаний и других свойств текста для редактирования форматированного текста. Смотрите раздел Редактирование форматированного текста.
C-Mouse-3
Это меню определяется режимом. Для большинства режимов данное меню имеет те же пункты, что содержатся во всех определяемых режимом меню из полоски меню. Некоторые режимы могут определять для этой кнопки другое меню.(3)
S-mouse-1
Это меню для задания основного шрифта фрейма.

Команды мыши для строки режима

Вы можете использовать мышь на строке режима для выбора окон и манипуляций с ними.

Mouse-1
Mouse-1 на строке режима выбирает окно сверху. Проводя мышью с нажатой на строке режима Mouse-1, вы можете перемещать эту строку режима, изменяя таким образом высоту окон сверху и снизу.
Mouse-2
Mouse-2 на строке режима раскрывает окно на весь фрейм.
Mouse-3
Mouse-3 на строке режима удаляет окно сверху.
C-Mouse-2
C-Mouse-2 на строке режима разбивает окно сверху по вертикали в том месте, где вы щелкнули.

C-Mouse-2 на полоске прокрутки разбивает соответствующее окно по горизонтали. Смотрите раздел Разделение окон.

Создание фреймов

Префиксный ключ C-x 5 аналогичен C-x 4, и на них определены параллельные подкоманды. Разница между ними в том, что команды с C-x 5 создают новый фрейм, а не просто новое окно в выбранном фрейме (смотрите раздел Изображение в другом окне). Если запрошенный материал уже показывается в существующем видимом или минимизированном фрейме, эти команды используют существующий фрейм после его поднимания или деминимизации по необходимости.

Команды на C-x 5 различаются по тому, как они находят или создают буфер для выбора:

C-x 5 2
Создает новый фрейм (make-frame-command).
C-x 5 b имя-буфера RET
Выбирает буфер имя-буфера в другом фрейме. Это запускает switch-to-buffer-other-frame.
C-x 5 f имя-файла RET
Обращается к файлу имя-файла и выбирает его буфер в другом фрейме. Это запускает find-file-other-frame. Смотрите раздел Обращение к файлам.
C-x 5 d каталог RET
Выбирает буфер Dired для каталога каталог в другом фрейме. Это запускает dired-other-frame. Смотрите раздел Dired, редактор каталогов.
C-x 5 m
Позволяет начать составление почтового сообщения в другом фрейме (mail-other-frame). Это вариант C-x m, работающий в другом фрейме. Смотрите раздел Посылка почты.
C-x 5 .
Обращается к тегу из текущей таблицы тегов в другом фрейме. Это запускает find-tag-other-frame, вариант M-., работающий с несколькими фреймами. Смотрите раздел Таблицы тегов.
C-x 5 r имя-файла RET
Обращается к файлу имя-файла в режиме только для чтения и выбирает его буфер в другом фрейме. Это запускает find-file-read-only-other-frame. Смотрите раздел Обращение к файлам.

Вы можете управлять видом вновь создаваемых фреймов, устанавливая параметры фрейма в default-frame-alist. Для задания параметров, относящихся только к начальному фрейму, вы можете использовать переменную initial-frame-alist. Смотрите раздел `Initial Parameters' в The Emacs Lisp Reference Manual, для дальнейшей информации.

Простейший способ указать основной шрифт для всех фреймов Emacs --- через X-ресурс (смотрите раздел Ключи для задания шрифта), но вы также можете сделать это, изменив default-frame-alist так, чтобы в нем задавался параметр font, как показано здесь:

(add-to-list 'default-frame-alist '(font . "10x20"))

Создание и использование фрейма Speedbar

Фрейм Emacs может иметь speedbar, то есть вертикальное окно, служащее как меню с возможностью прокрутки для файлов, к которым вы можете обратиться, и тегов внутри этих файлов. Чтобы создать speedbar, введите M-x speedbar; это создает окно speedbar для выбранного фрейма. После этого вы можете щелкнуть в speedbar на имени файла, чтобы обратиться к нему в соответствующем фрейме Emacs, или щелкнуть на имени тега, чтобы перескочить к нему соответствующем фрейме.

Изначально speedbar перечисляет непосредственное содержание текущего каталога по одному файлу на строке. В каждой строке также есть кнопка, `[+]' или `<+>', на которой вы можете щелкнуть Mouse-2, чтобы "открыть" содержимое данного элемента. Если на этой строке перечислен каталог, то при открытии к показанному в speedbar добавляется содержание этого каталога под его собственной строкой. Если на строке перечислен обычный файл, при его открытии к содержимому speedbar добавляется список тегов из этого файла. Когда файл открывается, `[+]' заменяется на `[-]'; вы можете щелкнуть на этой кнопке, чтобы "закрыть" этот файл (скрыть его содержание).

Некоторые основные режимы, включая режим Rmail, Info и GUD, имеют специализированные способы поместить в speedbar другие полезные вещи. Например, в режиме Rmail speedbar показывает перечень Rmail-файлов и позволяет вам перенести текущее сообщение в другой Rmail-файл, щелкнув на кнопке `'.

Speedbar принадлежит одному фрейму Emacs и всегда работает с этим фреймом. Если вы используете несколько фреймов, вы можете сделать speedbar для некоторых или для всех из них; чтобы сделать speedbar для любого данного фрейма, наберите в нем M-x speedbar.

Множество дисплеев

Один Emacs может общаться более чем с одним дисплеем X Windows. Изначально Emacs использует только один дисплей -- тот, что указан в переменной среды `DISPLAY' или с помощью ключа --display (смотрите раздел Ключи запуска). Чтобы подсоединиться к другому дисплею, воспользуйтесь командой make-frame-on-display:

M-x make-frame-on-display RET дисплей RET
Создает новый фрейм на дисплее дисплей.

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

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

Несмотря на это, люди, использующие одно и то же задание Emacs с разных дисплеев, все же могут вмешиваться в дела друг друга, если будут неосторожны. Например, если любой их них напечатает C-x C-c, это прекратит задание Emacs для всех!

Фреймы специальных буферов

Вы можете сделать так, чтобы определенные буферы, для которых Emacs обычно создает второе окно, если у вас есть только одно, появлялись в особых собственных фреймах. Чтобы сделать это, установите переменную special-display-buffer-names равной списку имен буферов; любой буфер, чье имя содержится в этом списке, автоматически получает специальный фрейм, когда какая-нибудь команда Emacs хочет показать его "в другом окне".

Например, если вы установите эту переменную таким образом:

(setq special-display-buffer-names
      '("*Completions*" "*grep*" "*tex-shell*"))

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

В более общем случае вы можете установить special-display-regexps равной списку регулярных выражений; тогда буфер получает собственный фрейм, если его имя совпадает в любым из них. (Еще раз, это относится только к буферам, которые обычно отображаются в отдельном окне.)

Переменная special-display-frame-alist задает параметры для этих фреймов. У нее есть значение по умолчанию, поэтому вам необязательно устанавливать ее.

Те, кто знает Лисп, могут также сделать элемент special-display-buffer-names или special-display-regexps списком. Тогда первый элемент -- это имя буфера или регулярное выражение, а остальные указывают, как создавать фрейм. Это может быть ассоциативный список, задающий значения параметров фрейма; эти значения имеют приоритет перед значениями параметров, указанных в special-display-frame-alist. Или же остальные элементы могут иметь такую форму:

(функция аргументы...)

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

Аналогичными средствами вы можете указать буферы, которые должны отображаться в выбранном окне. Смотрите раздел Принудительное изображение в том же окне. Показ в том же окне обладает приоритетом перед показом в специальном фрейме; следовательно, если вы добавили имя буфера к special-display-buffer-names, но это не возымело никакого эффекта, проверьте, не используется ли для этого же имени буфера средство показа в том же окне.

Установка параметров фрейма

Этот раздел описывает команды для изменения стиля отображения выбранного фрейма и его поведения в оконной среде.

M-x set-foreground-color RET цвет RET
Задает цвет для текста в выбранном фрейме.
M-x set-background-color RET цвет RET
Задает цвет для фона в выбранном фрейме. Также изменяет цвет текста в начертании modeline, чтобы оно оставалось инверсией начертания по умолчанию.
M-x set-cursor-color RET цвет RET
Задает цвет курсора в выбранном фрейме.
M-x set-mouse-color RET цвет RET
Задает цвет указателя мыши, когда он находится над выбранным фреймом.
M-x set-border-color RET цвет RET
Задает цвет рамки выбранного фрейма.
M-x list-colors-display
Выводит определенные имена цветов и показывает, как эти цвета выглядят. Это несколько медленная команда.
M-x auto-raise-mode
Переключает автоматическое поднятие выбранного фрейма. Автоматическое поднятие означает, что всякий раз, когда вы передвигаете мышь в этот фрейм, он поднимается. Обратите внимание, это средство автоматического поднятия реализовано самим Emacs. Некоторые программы управления окнами также реализуют автоподнятие. Если вы включите автоподнятие для фреймов Emacs в вашей программе управления X-окнами, это будет работать, но не под контролем Emacs, и следовательно, auto-raise-mode не будет играть роли.
M-x auto-lower-mode
Переключает автоматическое опускание выбранного фрейма. Автоматическое опускание означает, что всякий раз, когда вы передвигаете мышь за пределы этого фрейма, он переносится вниз стека X-окон. Команда auto-lower-mode не влияет на автоопускание, реализованное программой управления X-окнами. Чтобы контролировать это, вы должны использовать соответствующие средства своей программы управления окнами.
M-x set-frame-font RET шрифт RET
Определяет шрифт как основной шрифт в выбранном фрейме. Основной шрифт используется для всего отображаемого в этом фрейме текста, кроме случаев, когда для какого-то текста с помощью начертания (смотрите раздел Использование разных начертаний) определен другой шрифт. Смотрите раздел Ключи для задания шрифта, чтобы узнать о способах перечисления доступных в вашей системе шрифтов. Вы также можете установить основной шрифт фрейма через всплывающее меню. Чтобы вызвать это меню, нажмите S-Mouse-1.

В версиях Emacs, которые используют X toolkit, функции для установки цвета и шрифтов не влияют на меню, так как меню отображаются со своими собственными классами виджетов. Чтобы сменить вид меню, вы должны использовать X-ресурсы (смотрите раздел X-ресурсы). Смотрите раздел Параметры для задания цветов, сведения о цветах, а также раздел Ключи для задания шрифта, касающийся вопросов о выборе шрифта.

Для получения информации о параметрах и настройках фреймов смотрите раздел `Frame Parameters' в The Emacs Lisp Reference Manual.

Полоски прокрутки

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

Вы можете использовать на полоске прокрутки Mouse-2 (обычно это средняя кнопка), чтобы передвинуть или перетащить внутренний прямоугольник вверх или вниз. Если вы переместите его к верху полоски прокрутки, вы увидите начало буфера. Если вы переместите его к низу полоски прокрутки, то увидите конец буфера.

Правая и левая кнопки мыши прокручивают на контролируемое число строк. Mouse-1 (обычно левая кнопка) перемещает строку, на уровне которой вы щелкнули, к верхнему краю окна. Mouse-3 (обычно правая кнопка) перемещает верхнюю строку окна вниз к тому уровню, где вы щелкнули. Щелкая последовательно на одном месте, вы можете прокручивать на одно и то же расстояние еще и еще.

Помимо прокрутки, вы также можете щелкнуть на полоске прокрутки с помощью C-Mouse-2, чтобы разбить окно по горизонтали. Разбиение делается в той строке, где вы щелкнули.

Вы можете включить или выключить режим Scroll Bar командой M-x scroll-bar-mode. Без аргумента, она переключает использование полосок прокрутки. С аргументом, она включает использование полосок прокрутки тогда и только тогда, когда аргумент положителен. Эта команда применяется ко всем фреймам, включая те, что еще будут созданы. Для управления начальной установкой режима Scroll Bar вы можете использовать X-ресурс `verticalScrollBars'. Смотрите раздел X-ресурсы.

Чтобы включить или выключить полоски прокрутки только для выбранного фрейма, воспользуйтесь командой M-x toggle-scroll-bar.

Полоски меню

Вы можете включить или выключить показ полосок меню с помощью команды M-x menu-bar-mode. Без аргументов, эта команда переключает режим Menu Bar; это второстепенный режим. С аргументом, эта команда включает режим Menu Bar, если аргумент положителен, и выключает, если аргумент неположителен. Для управления начальной установкой режима Menu Bar вы можете использовать X-ресурс `menuBarLines'. Смотрите раздел X-ресурсы. Профессиональные пользователи часто выключают полоску меню, особенно на текстовых терминалах, где это освобождает одну дополнительную строку для текста.

Смотрите раздел Полоска меню, для получения информации о том, как вызывать команды с помощью полоски меню.

Использование разных начертаний

Когда вы используете Emacs с системой X, вы можете настроить несколько стилей отображения знаков. Вы можете контролировать такие аспекты стиля: шрифт, цвет текста, цвет фона и подчеркивание. Emacs частично поддерживает начертания в MS-DOS, позволяя вам контролировать для каждого начертания цвета текста и фона (смотрите раздел Emacs и MS-DOS).

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

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

Режим Enriched, предназначенный для редактирования форматированного текста, включает несколько команд и меню для задания начертаний. Смотрите раздел Начертания в форматированном тексте, чтобы узнать, как указать шрифт для текста в буфере. Смотрите раздел Цвета в форматированном тексте, о задании цветов текста и фона.

Для изменения внешнего вида начернания используйте буфер настройки. Смотрите раздел Настройка начертаний. Для определения атрибутов конкретных начертаний вы также можете использовать X-ресурсы (смотрите раздел X-ресурсы).

Чтобы узнать, какие начертания определены в данный момент, и как они выглядят, наберите M-x list-faces-display. Одно начертание может выглядеть по-разному в разных фреймах; данная команда показывает его вид в том фрейме, где вы ее набрали. Вот перечень стандартных определенных начертаний:

default
Это начертание используется для обычного текста, для которого не определено другое начертание.
modeline
Это начертание используется для строк режима. По умолчанию оно устанавливается как инверсия начертания default. Смотрите раздел Переменные управления изображением.
highlight
Это начертание используется в различных режимах для подсветки частей текста.
region
Это начертание применяется для отображения выделенной области (когда включен режим Transient Mark -- смотрите ниже).
secondary-selection
Это начертание используется для отображения вторичного выделения (смотрите раздел Вторичное выделение).
bold
Это начертание использует жирный вариант шрифта по умолчанию, если он есть.
italic
Это начертание использует курсивный вариант шрифта по умолчанию, если он есть.
bold-italic
Это начертание использует жирный курсивный вариант шрифта по умолчанию, если он есть.
underline
Это начертание подчеркивает текст.

Если включен режим Transient Mark, текст области подсвечивается, когда метка активна. Для этого используется начертание с именем region; вы можете управлять стилем подсветки, меняя стиль этого начертания (смотрите раздел Настройка начертаний). Смотрите раздел Режим Transient Mark, для получения большей информации о режиме Transient Mark и активизации и деактивизации метки.

Один простой способ использовать разные начертания -- включить режим Font Lock. Этот второстепенный режим, всегда локальный для конкретного буфера, подбирает начертания в соответствии с синтаксисом редактируемого текста. Он может распознавать комментарии и строки в большинстве языков; в некоторых языках он умеет даже распознавать и правильно подсвечивать различные другие важные конструкции. Смотрите раздел Режим Font Lock, для получения большей информации о режиме Font Lock и синтаксической подсветке.

Вы можете распечатать буфер с подсветкой, какую вы видите на экране, с помощью команды ps-print-buffer-with-faces. Смотрите раздел Печать через Postscript.

Режим Font Lock

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

Команда M-x font-lock-mode включает и выключает режим Font Lock в соответствии с аргументом и переключает, если аргумент не задан. Функция turn-on-font-lock безусловно включает режим Font Lock. Это полезно в функциях-ловушках режима. Например, чтобы задействовать режим Font Lock всякий раз, когда вы редактируете файл на Си, вы можете сделать так:

(add-hook 'c-mode-hook 'turn-on-font-lock)

Чтобы включить режим Font Lock автоматически во всех режимах, которые его поддерживают, используйте функцию global-font-lock-mode, как показано здесь:

(global-font-lock-mode 1)

Когда вы редактируете текст в режиме Font Lock, подсветка в измененной строке обновляется автоматически. Чаще всего изменения не оказывают влияния на подсветку последующих строк, но иногда все же влияют. Чтобы обновить подсветку нескольких строк, используйте команду M-g M-g (font-lock-fontify-block).

В некоторых основных режимах M-g M-g обновляет подсветку всей текущей функции. (Как именно можно найти текущую функцию, указывает переменная font-lock-mark-block-function.) В других основных режимах M-g M-g обновляет подсветку 16-ти строк над и под точкой.

С числовым аргументом n, M-g M-g обновляет подсветку n строк над и под точкой, независимо от режима.

Чтобы получить все преимущества режима Font Lock, вам придется выбрать такой шрифт по умолчанию, у которого есть жирный, курсивный и жирный курсивный варианты; или вам понадобится цветной монитор или монитор, отображающий много градаций серого.

Переменная font-lock-maximum-decoration задает предпочтительный уровень оформления для режимов, которые предоставляют несколько уровней. Уровень 1 -- это минимальное оформление; некоторые режимы поддерживают до трех уровней. Обычное значение по умолчанию обозначает "как можно больше". Вы можете указать целое число, которое применяется ко всем режимам, или задать разные числа для конкретных режимов; например, чтобы использовать уровень 1 для режимов C/C++ и уровень по умолчанию в остальных случаях, напишите так:

(setq font-lock-maximum-decoration
      '((c-mode . 1) (c++-mode . 1)))

В больших буферах подсветка может быть слишком медленной, поэтому вы можете подавить ее. Переменная font-lock-maximum-size задает размер буфера, сверх которого подсветка не делается.

Подсветка комментариев и строк (или "синтаксическая" подсветка) основывается на анализе синтаксической структуры текста буфера. В целях увеличения скорости некоторые режимы, включая режим C и режим Lisp полагаются на особое соглашение: открывающая скобка в самом левом столбце всегда обозначает начало определения функции и, таким образом, всегда находится вне любой строки или комментария. (Смотрите раздел Определения функций.) Если вы не следуете этому соглашению, режим Font Lock может сделать неправильную подсветку текста после открывающей скобки в левом столбце, которая попадает в строку или комментарий.

Переменная font-lock-beginning-of-syntax-function (всегда локальная для буфера) указывает, каким образом режим Font Lock может найти позицию, которая гарантированно находится вне любого комментария или строки. В режимах, использующих соглашение об открывающей скобке в левом столбце, значение этой переменной по умолчанию -- это beginning-of-defun, что велит режиму Font Lock применять это соглашение. Если вы установите эту переменную в nil, Font Lock больше не станет полагаться на это соглашение. Это позволяет избежать неверных результатов, но ценой этого будет то, что в некоторых случаях для подсветки придется проходить текст буфера с самого начала.

Образцы подсветки Font Lock уже существуют для многих режимов, но вы можете захотеть раскрасить что-то дополнительно. Чтобы добавить свои собственные образцы подсветки для определенного режима, вы можете использовать функцию font-lock-add-keywords. К примеру, чтобы выделить в комментариях Си слова `FIXME:', используйте это:

(font-lock-add-keywords
 'c-mode
 '(("\\<\\(FIXME\\):" 1 font-lock-warning-face t)))

Режимы поддержки Font Lock

Режимы поддержки убыстряют режим Font Lock в больших буферах. Есть два режима поддержки: режим Fast Lock и режим Lazy Lock. Они используют два разных метода ускорения режима Font Lock.

Режим Fast Lock

Чтобы сделать режим Font Lock более быстрым для буферов, обращающихся к большим файлам, вы можете использовать режим Fast Lock. Режим Fast Lock сохраняет информацию о шрифтах для каждого файла в отдельном файле кеша; всякий раз, когда вы обращаетесь к файлу, он заново считывает информацию о шрифтах из файла кеша вместо того, чтобы вычислять шрифты для текста с нуля.

Команда M-x fast-lock-mode включает и выключает режим Fast Lock в соответствии с аргументом (без аргумента, режим переключается). Вы также можете сделать так, чтобы режим Fast Lock включался всякий раз, когда вы используете режим Font Lock, следующим образом:

(setq font-lock-support-mode 'fast-lock-mode)

Записывать файл кеша для маленьких буферов не имеет смысла. Поэтому есть переменная, fast-lock-minimum-size, задающая наименьший размер файла, для которого информация о шрифтах кешируется.

Переменная fast-lock-cache-directories указывает, где нужно размещать файлы кеша. Ее значение -- это список каталогов, которые будут испробованы; "." означает тот же каталог, где файл редактируется. Значение по умолчанию равно ("." "~/.emacs-flc"), что велит использовать тот же каталог, если это возможно, иначе использовать каталог `~/.emacs-flc'.

Переменная fast-lock-save-others указывает, должен ли режим Fast Lock сохранять файлы кеша для файлов, чьим владельцем являетесь не вы. Отличное от nil значение говорит, что должен (и это значение по умолчанию).

Режим Lazy Lock

Чтобы ускорить режим Font Lock для больших буферов, вы можете использовать режим Lazy Lock, который уменьшает количество текста, подлежащего подсветке. В режиме Lazy Lock подсветка буфера делается по необходимости; она производится только для тех частей буфера, которые должны появиться на экране. И подсветка ваших изменений замедлена; она производится, только когда Emacs бездействовал определенный небольшой промежуток времени.

Команда M-x lazy-lock-mode включает и выключает режим Lazy Lock в соответствии с аргументом (без аргумента, режим переключается). Вы также можете сделать так, чтобы режим Lazy Lock включался всякий раз, когда вы используете режим Font Lock, следующим образом:

(setq font-lock-support-mode 'lazy-lock-mode)

Избегать подсветки маленьких буферов не имеет смысла. Минимальный размер буфера, для которого подсветка делается по необходимости, определяется переменной lazy-lock-minimum-size. Меньшие буферы расцвечиваются сразу, как в простом режиме Font Lock.

Когда вы изменяете буфер, режим Lazy Lock откладывает подсветку измененного текста. Переменная lazy-lock-defer-time задает число секунд, которое Emacs должен оставаться незанятым, прежде чем начать подсветку ваших изменений. Если ее значение равно 0, изменения подсвечиваются незамедлительно, как в простом режиме Font Lock.

Обычно режим Lazy Lock подсвечивает ставшие видимыми фрагменты буфера перед тем, как они впервые показываются на экране. Однако, если значение lazy-lock-defer-on-scrolling не равно nil, вновь видимый текст подсвечивается только после того, как Emacs бездействовал lazy-lock-defer-time секунд.

В некоторых режимах, включая режим C и режим Emacs Lisp, изменение содержимого одной строки изменяет контекст последующих строк и, следовательно, ту подсветку, которая должна для них использоваться. Обычно вы должны набрать M-g M-g, чтобы обновить подсветку последующих строк. Однако, если вы установите переменную lazy-lock-defer-contextually не равной nil, режим Lazy Lock делает это автоматически по истечении lazy-lock-defer-time секунд.

Когда Emacs бездействует продолжительное время, Lazy Lock подсвечивает дополнительные фрагменты буфера, которые еще не показаны, на случай, если вы вынесете их на экран позднее. Это называется скрытой подсветкой.

Переменная lazy-lock-stealth-time определяет, сколько минут Emacs должен оставаться незанятым, прежде чем начать скрытую подсветку. Значение nil означает отсутствие скрытой подсветки. Переменные lazy-lock-stealth-lines и lazy-lock-stealth-verbose задают диапазон и подробность скрытой подсветки.

Fast Lock или Lazy Lock?

Вот простые указания, которые помогут вам выбрать один из режимов поддержки Font Lock.

  • Режим Fast Lock играет роль только при обращении к файлам и уничтожении буферов (и связанных событий); следовательно, редактирование буфера и прокрутка окна не быстрее и не медленнее, чем в простом режиме Font Lock.
  • Режим Fast Lock медленнее при считывании файлов кеша, чем режим Lazy Lock при подсветке буфера; следовательно, режим Fast Lock медленнее при обращении к файлам, чем режим Lazy Lock.
  • Режим Lazy Lock работает во время прокрутки окна, чтобы раскрасить текст, выносимый на экран; следовательно, прокрутка медленнее, чем в простом режиме Font Lock.
  • Режим Lazy Lock не подсвечивает буфер в процессе редактирования (он откладывает подсветку изменений); следовательно, редактирование в нем быстрее, чем в простом режиме Font Lock.
  • Режим Fast Lock может быть сбит с толку файлом, находящимся под контролем системы управления версиями; следовательно, подсветка буфера может производиться, даже если для этого файла есть файл кеша.
  • Режим Fast Lock работает только с буферами, обращающимися к файлам; режим Lazy Lock работает с любыми буферами.
  • Режим Fast Lock создает файлы кеша; режим Lazy Lock не создает.

Переменная font-lock-support-mode указывает, какой из этих режимов поддержки следует использовать; например, чтобы сказать, что в режимах C/C++ используется режим Fast Lock, а в остальных случаях --- режим Lazy Lock, установите эту переменную так:

(setq font-lock-support-mode
      '((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode)
        (t . lazy-lock-mode)))

Режим Highlight Changes

Используйте M-x highlight-changes-mode, чтобы включить второстепенный режим, который показывает с помощью разных начертаний (в основном цветов), какие части текста буфера изменялись недавно.

Другие возможности X Windows

Следующие команды позволяют вам создавать и удалять фреймы, а также делать другие операции над ними:

C-z
Минимизирует выбранный фрейм (iconify-or-deiconify-frame). Обычное значение C-z, приостановка Emacs, бесполезно под оконной системой, поэтому в данном случае у этого ключа другая привязка. Если вы введете эту команду в пиктограмме фрейма Emacs, она деминимизирует этот фрейм.
C-x 5 0
Удаляет выбранный фрейм (delete-frame). Это не допускается, если есть только один фрейм.
C-x 5 o
Выбирает другой фрейм, поднимает его и переносит в него мышь, чтобы он оставался выбранным. Если вы повторяете эту команду, она циклически проходит по всем фреймам на вашем терминале.

Неоконные терминалы

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

Чтобы создать новый фрейм и переключиться в него, используйте C-x 5 2; для кругового прохода по существующим фреймам используйте C-x 5 o; чтобы удалить текущий фрейм, используйте C-x 5 0.

Каждый фрейм имеет отличительный номер. Если ваш терминал может показывать в одно время только один фрейм, то около начала строки режима появляется номер n текущего фрейма в форме `Fn'.

`Fn' на самом деле -- это имя фрейма. Вы также можете указать другое имя, если хотите, и вы можете выбирать фреймы по именам. Чтобы задать новое имя для текущего фрейма, используйте команду M-x set-frame-name RET имя RET, а для выбора фрейма в соответствии с его именем используйте M-x select-frame-by-name RET имя RET. Указанное вами имя появляется в строке режима, когда этот фрейм становится выбранным.

Поддержка разных языков

Emacs поддерживает широкий спектр наборов знаков разных языков, включая европейские варианты латинского алфавита, а также китайскую, девангари (хинди и маратхи), эфиопскую, греческую, IPA, японскую, корейскую, лаосскую, русскую, тайскую, тибетскую и вьетнамскую письменности. Эти возможности были внесены из измененной версии Emacs, известной как MULE (от "MULti-lingual Enhancement to GNU Emacs".(4))

Введение в наборы знаков разных языков

Пользователи этих систем письма выработали много более или менее стандартных систем кодирования для хранения файлов. Внутренне Emacs использует единую многобайтную кодировку, так что в ней можно перемешивать знаки из всех этих систем письма в одном буфере или строке. Эта кодировка представляет каждый знак, не входящий в ASCII, как последовательность байт в промежутке от 0200 до 0377. Emacs переводит из этой многобайтной кодировки в различные другие системы кодирования при считывании и записи файлов, при обмене данными с подпроцессами и (в некоторых случаях) в команде C-q (смотрите раздел Однобайтные и многобайтные не-ASCII-знаки).

Команда C-h h (view-hello-file) выводит файл `etc/HELLO', который показывает, как сказать "здравствуйте" на разных языках. Это иллюстрирует различные виды письменности.

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

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

Включение поддержки многобайтных знаков

Вы можете включить или выключить поддержку многобайтных знаков либо для всего Emacs, либо для отдельного буфера. Когда в буфере выключены многобайтные знаки, каждый байт в нем представляет один знак, даже коды от 0200 до 0377. Старые средства для поддержки европейских наборов знаков, ISO Latin-1 и ISO Latin-2, работают так же, как они работали в Emacs 19, и кроме того, работают для других наборов знаков ISO 8859.

Однако, чтобы использовать ISO Latin, необязательно выключать поддержку многобайтных знаков; многобайтный набор знаков Emacs включает все эти знаки, и Emacs может автоматически переводить из него в коды ISO и наоборот.

Чтобы отредактировать определенный файл в однобайтном представлении, обратитесь к нему через find-file-literally. Смотрите раздел Обращение к файлам. Чтобы превратить буфер в многобайтном представлении в однобайтное представление тех же знаков, проще всего сохранить содержимое этого буфера в файле, уничтожить его и снова обратиться к этому файлу с помощью find-file-literally. Вы также можете использовать C-x RET c (universal-coding-system-argument) и указать `raw-text' в качестве системы кодирования для обращения к файлу или для его сохранения. Смотрите раздел Задание системы кодирования. Обращение к файлу как к `raw-text' не выключает преобразование формата, декомпрессию и автоматический выбор режима, в отличие от find-file-literally.

Чтобы выключить поддержку многобайтных знаков по умолчанию, запустите Emacs с ключом --unibyte (смотрите раздел Ключи запуска) или установите переменную среды `EMACS_UNIBYTE'. Вы также можете настроить параметр enable-multibyte-characters или, что эквивалентно, прямо установить переменную default-enable-multibyte-characters в вашем файле инициализации, это дает в основном тот же эффект, что и --unibyte.

Во время инициализации не создаются многобайтные строки из значений переменных среды, вхождений файла `/etc/passwd', etc., которые содержат не входящие в ASCII восьмибитные знаки. Однако, файл инициализации обычно считывается как многобайтный -- как все файлы на Лиспе -- даже если задан ключ --unibyte. Чтобы избежать создания многобайтных строк из находящихся в этом файле строк с не-ASCII-знаками, поместите в его первой строке комментарий с текстом `-*-unibyte: t;-*-'. Для файлов инициализации других пакетов, вроде Gnus, нужно сделать то же самое.

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

Языковые среды

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

Языковая среда определяет, какие системы кодирования распознаются при считывании текста (смотрите раздел Распознавание систем кодирования). Это относится к файлам, приходящей почте, сетевым новостям и любому другому тексту, который вы считываете в Emacs. Она также может задавать систему кодирования, используемую по умолчанию для создания файла. Каждая языковая среда также указывает принимаемый по умолчанию метод ввода.

Языковая среда выбирается командой M-x set-language-environment. Не имеет значения, какой буфер является текущим во время запуска этой команды, потому что ее действия применяются глобально ко всему сеансу Emacs. Поддерживаемые языковые среды включают:

Chinese-BIG5, Chinese-CNS, Chinese-GB, Cyrillic-Alternativnyj, Cyrillic-ISO, Cyrillic-KOI8, Devanagari, English, Ethiopic, Greek, Hebrew, Japanese, Korean, Lao, Latin-1, Latin-2, Latin-3, Latin-4, Latin-5, Thai, Tibetan и Vietnamese.

Некоторые операционные системы позволяют вам указать используемый вами язык путем установки переменных среды, определяющих вашу местность. Emacs может обрабатывать один распространенный частный случай: если название вашей региональной установки для типов знаков содержит строку `8859-n', Emacs автоматически выбирает соответствующую языковую среду.

Чтобы получить сведения об эффектах определенной языковой среды яз-среда, используйте команду C-h L яз-среда RET (describe-language-environment). Это сообщит вам, для каких языков полезна данная языковая среда, и перечислит приходящие с ней наборы знаков, системы кодирования и методы ввода. Эта команда также показывает образцы текста, которые иллюстрируют используемые в этой языковой среде системы письма. По умолчанию она описывает выбранную языковую среду.

Вы можете настроить для себя любую языковую среду с помощью обычной ловушки set-language-environment-hook. Команда set-language-environment запускает эту ловушку после подготовки новой языковой среды. Функции этой ловушки могут определить текущую языковую среду по значению переменной current-language-environment.

До начала подготовки новой языковой среды, команда set-language-environment запускает ловушку exit-language-environment-hook. Эта ловушка полезна для отмены настроек, сделанных с помощью set-language-environment-hook. К примеру, если вы установили с использованием set-language-environment-hook особые привязки ключей для конкретной языковой среды, вам стоит сделать так, чтобы exit-language-environment-hook восстанавливала нормальные привязки.

Методы ввода

Метод ввода -- это разновидность преобразования знаков, разработанная специально для интерактивного ввода. В Emacs, как правило, каждый язык имеет свой метод ввода; иногда несколько языков, в которых используются одни и те же знаки, могут разделять один метод ввода. Есть немного языков, которые поддерживают несколько методов ввода.

В простейшем случае метод ввода работает через отображение ASCII-букв в другой алфавит. Таким способом действуют методы ввода для греческого и русского.

Более мощный способ -- составление: преобразование последовательности знаков в одну букву. Составление используется во многих европейских методах ввода для сознания одной не-ASCII-буквы из последовательности, состоящей из буквы, за которой идет знак акцента (или наоборот). Например, некоторые методы ввода преобразуют последовательность a' в одну букву с акцентом. В этих методах ввода нет собственных специальных команд; всё, что они делают, -- компонуют последовательности печатных знаков.

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

Для китайского и японского требуются более сложные методы. В китайских методах ввода вы сначала вводите фонетическое написание китайского слова (в методе ввода chinese-py, помимо прочих) или последовательность частей знака (методы ввода chinese-4corner, chinese-sw и другие). Поскольку одно фонетическое написание обычно соответствует многим различным китайским знакам, вы должны выбрать одну из альтернатив с помощью особых команд Emacs. Такие ключи, как C-f, C-b, C-n, C-p, и цифры имеют в этой ситуации особые определения, используемые для выбора среди альтернатив. TAB выводит буфер, показывающий все возможные варианты.

В японских методах ввода вы сначала вводите целое слово, используя фонетическое написание; потом, когда это слово уже в буфере, Emacs преобразует его в один или несколько знаков, используя большой словарь. Одно фонетическое написание соответствует многим по-разному записанным японским словам, поэтому вы должны выбрать один из них; для циклического прохода по альтернативам используйте C-n и C-p.

Иногда полезно остановить действие метода ввода, чтобы только что введенные вами знаки не сливались с последующими. Например, в методе ввода latin-1-postfix последовательность e ' комбинируется в `e' с акцентом. Что если вы хотели ввести их как раздельные знаки?

Один способ -- набрать акцент дважды; это специальное средство для ввода буквы и акцента раздельно. Например, e ' ' дает два знака `e''. Другой способ -- набрать после `e' еще одну букву, которая не скомбинируется с ней, и сразу удалить ее. Например, вы могли бы набрать e e DEL ', чтобы получить раздельные `e' и `''.

Еще один способ, более общий, но не такой легкий для набора, --- использовать между двумя знаками C-\ C-\, чтобы предотвратить их комбинирование. Это команда C-\ (toggle-input-method), примененная дважды.

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

Переменные input-method-highlight-flag и input-method-verbose-flag управляют тем, как методы ввода поясняют происходящее. Если input-method-highlight-flag не равна nil, частичная последовательность подсвечивается в буфере. Если input-method-verbose-flag не равна nil, в эхо-области показывается список возможных следующих знаков (но не в том случае, когда вы находитесь в минибуфере).

Выбор метода ввода

C-\
Включает или выключает использование выбранного метода ввода.
C-x RET C-\ метод RET
Выбирает новый метод ввода для текущего буфера.
C-h I метод RET
C-h C-\ метод RET
Описывает метод ввода метод (describe-input-method). По умолчанию, она описывает текущий метод ввода (если он есть). Такое описание должно давать вам все подробности о том, как использовать любой конкретный метод ввода.
M-x list-input-methods
Выводит перечень всех поддерживаемых методов ввода.

Чтобы выбрать метод ввода для текущего буфера, используйте C-x RET C-\ (set-input-method). Эта команда считывает имя метода ввода из минибуфера; имя обычно начинается с языковой среды, для которой этот метод предназначался. В переменной current-input-method записывается, какой метод ввода был выбран.

Методы ввода используют для обозначения знаков, не входящих в ASCII, различные последовательности ASCII-знаков. Иногда бывает полезно временно выключить метод ввода. Чтобы сделать это, наберите C-\ (toggle-input-method). Чтобы опять задействовать метод ввода, наберите C-\ снова.

Если вы напечатаете C-\, но метод ввода пока не выбран, вас попросят указать его. Это имеет тот же эффект, что и использование C-x RET C-\ для задания метода ввода.

Выбор языковой среды определяет метод ввода, используемый по умолчанию. Тогда вы можете выбрать его в текущем буфере, набирая C-\. Переменная default-input-method задает метод ввода, принимаемый по умолчанию (nil означает, что такого нет).

Некоторые методы ввода для алфавитных систем письма работают путем отображения клавиатуры для эмуляции различных раскладок, часто используемых для этих систем письма. Как правильно сделать это отображение, зависит от действительной раскладки вашей клавиатуры. Чтобы указать ее, используйте команду M-x quail-set-keyboard-layout.

Чтобы просмотреть перечень всех поддерживаемых методов ввода, наберите M-x list-input-methods. Перечень сообщает сведения о каждом методе ввода, включая строку, обозначающую этот метод ввода в строке режима.

Однобайтные и многобайтные не-ASCII-знаки

Когда включены многобайтные знаки, знаки с кодами от 0240 (восьмиричное) до 0377 (восьмиричное) на самом деле недопустимы в буфере. Допустимые печатные знаки, не входящие в ASCII, имеют коды, начинающиеся от 0400.

Если вы набираете самовставляющийся знак в недопустимом диапазоне от 0240 до 0377, Emacs предполагает, что вы намеревались использовать один из наборов знаков Latin-n, и преобразует его в код Emacs, представляющий этот знак Latin-n. Вы указываете, какой набор знаков ISO нужно для этого применять, своим выбором языковой среды (смотрите выше). Если вы не указали свой выбор, по умолчанию используется Latin-1.

То же происходит, когда вы используете C-q для ввода восьмиричного кода в этом диапазоне.

Системы кодирования

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

Emacs присваивает каждой системе кодирования свое имя. Большинство систем кодирования используются для одного языка, и имя такой системы кодирования начинается с имени языка. Некоторые системы кодирования используются для нескольких языков; их имена обычно начинаются с `iso'. Есть также специальные системы кодирования no-conversion, raw-text и emacs-mule, которые не делают преобразования печатных знаков вообще.

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

C-h C кодирование RET
Описывает систему кодирования кодирование.
C-h C RET
Описывает систему кодирования, используемую в данный момент.
M-x list-coding-systems
Выводит перечень всех поддерживаемых систем кодирования.

Команда C-h C (describe-coding-system) выводит сведения о конкретной системе кодирования. Вы можете задать имя системы кодирования в качестве аргумента; иначе, с пустым аргументом, она опишет системы кодирования, выбранные в данный момент для различных целей как в текущем буфере, так и принимаемые по умолчанию, а также перечень приоритетов для распознавания систем кодирования (смотрите раздел Распознавание систем кодирования).

Чтобы вывести перечень всех поддерживаемых систем кодирования, наберите M-x list-coding-systems. Этот перечень дает информацию о каждой системе кодирования, включая букву, обозначающую ее в строке режима (смотрите раздел Строка режима).

Каждая система кодирования из перечисленных в этом списке -- кроме no-conversion, что означает не делать никаких преобразований --- указывает, как преобразовывать печатные знаки и нужно ли это делать, но оставляет выбор преобразования конца-строки до решения, основанном на содержимом файла. Например, если оказалось, что в файле для разделения строк используется последовательность возврат каретки-перевод строки, будет использовано преобразование из конца-строки DOS.

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

...-unix
Не производить преобразования конца-строки; предполагается, что в файле для разделения строк используется перевод строки. (Это соглашение обычно используется в системах Unix и GNU.)
...-dos
Предполагать, что в файле для разделения строк используется возврат каретки-перевод строки, и делать соответствующее преобразование. (Это соглашение обычно используется в системах Microsoft.(5))
...-mac
Предполагать, что в файле для разделения строк используется возврат каретки, и делать соответствующее преобразование. (Это соглашение обычно используется в системе Macintosh.)

Эти варианты систем кодирования опускаются для краткости в выводе list-coding-systems, поскольку они полностью предсказуемы. Например, система кодирования iso-latin-1 имеет варианты iso-latin-1-unix, iso-latin-1-dos и iso-latin-1-mac.

Система кодирования raw-text хороша для файлов, которые содержат в основном ASCII-текст, но могут включать байты со значениями выше 127, которые не предназначались для кодирования не-ASCII-знаков. С raw-text, Emacs копирует эти байты без изменений и, чтобы они интерпретировались правильно, устанавливает в текущем буфере enable-multibyte-characters равной nil. raw-text обрабатывает преобразование конца-строки обычным способом, основываясь на увиденных данных, и имеет три обычных варианта для указания нужного преобразования конца-строки.

В противоположность этому, система кодирования no-conversion не задает никакого преобразования кодов знаков вообще -- ни для значений байт, выходящих за пределы ASCII, ни для конца-строки. Это полезно для считывания и записи двоичных файлов, tar-файлов и других, которые нужно просматривать буквально. Она тоже устанавливает enable-multibyte-characters в значение nil.

Простейший способ отредактировать файл без любых преобразований --- воспользоваться командой M-x find-file-literally. Она использует no-conversion, а также подавляет другие средства Emacs, которые могли бы преобразовать содержимое файла до того, как вы его увидите. Смотрите раздел Обращение к файлам.

Система кодирования emacs-mule полагает, что файл содержит не-ASCII-знаки во внутренней кодировке Emacs. Она обрабатывает преобразование конца-строки, основываясь на увиденных данных, и имеет три обычных варианта для указания нужного преобразования конца-строки.

Распознавание систем кодирования

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

Некоторые системы кодирования могут быть распознаны или выделены по тому, какие последовательности знаков появляются среди данных. Однако, есть системы кодирования, которые не могут быть различены, даже потенциально. Например, нет способа отличить Latin-1 от Latin-2; они используют одни и те же значения байт с разными смыслами.

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

Список приоритетов систем кодирования зависит от выбранной языковой среды (смотрите раздел Языковые среды). Например, если вы используете французский, вы, вероятно, захотите, чтобы Emacs предпочитал Latin-1, а не Latin-2; а если вы используете чешский -- чтобы предпочтение отдавалось Latin-2. Это одна из причин задавать языковую среду.

Однако, вы можете детально изменять список приоритетов с помощью команды M-x prefer-coding-system. Эта команда считывает имя системы кодирования в минибуфере и добавляет ее в начало списка приоритетов, так, чтобы ей отдавалось предпочтение среди остальных. Если вы применяете эту команду несколько раз, при каждом использовании в начало списка приоритетов добавляется один элемент.

Если вы используете систему кодирования, которая определяет тип преобразования последовательности конец-строки, такую как iso-8859-1-dos, то это означает, что Emacs должен попытаться распознать предпочтительно iso-8859-1 и использовать преобразование конца-строки DOS, если iso-8859-1 была распознана.

Иногда имя файла указывает на то, какая система кодирования должна для него использоваться. Это соответствие задает переменная file-coding-system-alist. Для добавления элементов к этому списку есть особая функция, modify-coding-system-alist. К примеру, чтобы все `.txt'-файлы считывались и записывались с использованием системы кодирования china-iso-8bit, вы можете выполнить следующее лисповское выражение:

(modify-coding-system-alist 'file "\\.txt\\'" 'china-iso-8bit)

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

Emacs узнаёт, какой вид преобразования конца-строки следует использовать, основываясь на содержимом файла: если он видит только возвраты каретки или только последовательности возврат каретки-перевод строки, то выбирает соответствующее преобразование. Вы можете подавить автоматическое использование преобразования конца-строки, установив переменную inhibit-eol-conversion в значение nil.

Вы можете указать систему кодирования для конкретного файла, применяя конструкцию `-*-...-*-' в начале этого файла или в списке локальных переменных в его конце (смотрите раздел Локальные переменные в файлах). Вы делаете это, определяя значение для "переменной" с именем coding. На самом деле в Emacs нет переменной coding; вместо установки переменной он использует заданную систему кодирования для этого файла. Например, `-*-mode: C; coding: latin-1;-*-' велит использовать систему кодирования Latin-1 и режим C. Если вы явно указали систему кодирования в файле, она перекрывает file-coding-system-alist.

Переменная auto-coding-alist -- это самый сильный способ указать систему кодирования для определенных образцов имен файлов; эта переменная даже перекрывает теги `-*-coding:-*-' в самом файле. Emacs использует это средство для tar-файлов и архивов, чтобы избежать ошибочной интерпретации тега `-*-coding:-*-' в элементе архива как относящегося ко всему архивному файлу.

Когда Emacs выбрал систему кодирования для буфера, он сохраняет ее в buffer-file-coding-system и по умолчанию использует эту систему кодирования для операций, которые записывают этот буфер в файл. Это включает команды save-buffer и write-region. Если вы хотите записывать файлы из этого буфера, используя другую систему кодирования, вы можете указать для этого файла новую систему кодирования с помощью set-buffer-file-coding-system (смотрите раздел Задание системы кодирования).

Когда вы посылаете сообщение с помощью режима Mail (смотрите раздел Посылка почты), у Emacs есть четыре разных способа узнать систему кодирования для текста сообщения. Он пробует значение buffer-file-coding-system, собственное для этого буфера, если оно не равно nil. Иначе, он использует значение sendmail-coding-system, если оно не равно nil. Третий способ -- использовать систему кодирования, принимаемую по умолчанию для новых файлов, которая управляется вашей языковой средой, если она не nil. Если все три эти значения равны nil, Emacs кодирует исходящую почту, используя систему кодирования Latin-1.

Когда вы получаете новую почту в Rmail, каждое сообщение автоматически переводится из той системы кодирования, в которой оно было написано --- как если бы оно было отдельным файлом. При этом используется заданный вами список приоритетов систем кодирования. Если в сообщении в формате MIME указан набор знаков, Rmail подчиняется этому указанию, если rmail-decode-mime-charset не равна nil.

Для считывания и сохранения самих Rmail-файлов Emacs использует систему кодирования, задаваемую переменной rmail-file-coding-system. Значение по умолчанию равно nil, что означает, что Rmail-файлы не переводятся (они считываются и сохраняются во внутренней кодировке Emacs).

Задание системы кодирования

В случаях, когда Emacs не может автоматически подобрать правильную систему кодирования, вы можете указать ее явно с помощью таких команд:

C-x RET f кодирование RET
Использовать систему кодирования кодирование для файла, к которому обращается текущий буфер.
C-x RET c кодирование RET
Задает систему кодирования кодирование для непосредственно следующей команды.
C-x RET k кодирование RET
Использовать систему кодирования кодирование для ввода с клавиатуры.
C-x RET t кодирование RET
Использовать систему кодирования кодирование для вывода на терминал.
C-x RET p код-ввода RET код-вывода RET
Использовать системы кодирования код-ввода и код-вывода для ввода и вывода подпроцесса текущего буфера.
C-x RET x кодирование RET
Использовать систему кодирования кодирование для передачи выделений другим программам и получения их из других программ через оконную систему.
C-x RET X кодирование RET
Использовать систему кодирования кодирование для передачи или получения одного выделения -- следующего -- в оконную систему или из нее.

Команда C-x RET f (set-buffer-file-coding-system) задает систему кодирования файла для текущего буфера -- другими словами, указывает, какую систему кодирования следует использовать для сохранения или повторного считывания этого файла. Вы задаете систему кодирования в минибуфере. Так как эта команда применяется только к файлу, к которому вы уже обратились, она влияет лишь на способ сохранения этого файла.

Другой способ указать систему кодирования для файла -- сделать это во время обращения. Сначала используйте команду C-x RET c (universal-coding-system-argument); эта команда считывает в минибуфере имя системы кодирования. После выхода из минибуфера заданная система кодирования применяется для непосредственно следующей команды.

Таким образом, если непосредственно следующей командой будет, скажем, C-x C-f, то она считает файл, используя указанную систему кодирования (и запоминает эту систему кодирования для последующей записи файла). Или, если следующей командой будет C-x C-w, она запишет файл, используя эту систему кодирования. Другие команды работы с файлами, на которые действует заданная система кодирования, включают C-x C-i и C-x C-v, а также варианты C-x C-f с показом в другом окне.

C-x RET c также влияет на программы, начинающие подпроцессы, включая M-x shell (смотрите раздел Запуск команд оболочки из Emacs).

Однако, если непосредственно следующая команда не использует систему кодирования, то C-x RET c в результате не имеет эффекта.

Простой способ обратиться к файлу без преобразования предоставляет команда M-x find-file-literally. Смотрите раздел Обращение к файлам.

Переменная default-buffer-file-coding-system определяет выбор системы кодирования для вновь создаваемых файлов. Она применяется, когда вы обращаетесь к новому файлу или создаете буфер и затем сохраняете его в файл. При выборе языковой среды эта переменная как правило устанавливается в подходящее значение по умолчанию.

Команда C-x RET t (set-terminal-coding-system) задает систему кодирования для терминального вывода. Если вы зададите систему кодирования для терминального вывода, все выводимые на терминал знаки переводятся в эту систему.

Это средство полезно для некоторых текстовых терминалов, сделанных с поддержкой какого-то конкретного языка или набора знаков -- например, европейских терминалов, поддерживающих один из наборов знаков ISO Latin. При использовании многобайтного текста вам нужно указать систему кодирования, чтобы Emacs знал, какие знаки этот терминал может на самом деле обработать.

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

Команда C-x RET k (set-keyboard-coding-system) задает систему кодирования для ввода с клавиатуры. Перевод кодов вводимых с клавиатуры знаков полезен для терминалов, клавиши которых посылают графические не-ASCII-знаки, например, для некоторых терминалов, разработанных для кодировки ISO Latin-1 или ее подмножеств.

По умолчанию ввод с клавиатуры не переводится.

Между использованием системы кодирования для перевода ввода с клавиатуры и использованием метода ввода есть некое сходство: в обоих случаях определяются вводимые с клавиатуры последовательности, превращающиеся с один знак. Однако, методы ввода разработаны для удобного интерактивного использования людьми, и переводимые ими последовательности обычно являются последовательностями печатных ASCII-знаков. Системы кодирования как правило переводят последовательности неграфических знаков.

Команда C-x RET x (set-selection-coding-system) задает систему кодирования для передачи выделенного текста оконной системе и для получения текста выделений, сделанных в других приложениях. Эта команда относится ко всем будущим выделениям, пока вы не отмените это, снова применив эту команду. Команда C-x RET X (set-next-selection-coding-system) задает систему кодирования для следующего выделения, сделанного в Emacs или считанного Emacs.

Команда C-x RET p (set-buffer-process-coding-system) задает систему кодирования для ввода и вывода подпроцесса. Эта команда относится к текущему буферу; как правило, каждый подпроцесс имеет собственный буфер, следовательно, вы можете указывать перекодировку ввода и вывода процесса, давая эту команду в соответствующем буфере.

По умолчанию ввод и вывод процессов не переводится совсем.

Переменная file-name-coding-system задает систему кодирования, используемую для кодирования имен файлов. Если вы установите ее равной имени системы кодирования (это лисповский символ или строка), Emacs станет кодировать имена файлов при всех файловых операциях, используя эту систему кодирования. Это позволяет использовать в именах файлов не-ASCII-знаки, или по крайней мере те не-ASCII-знаки, которые могут быть закодированы текущей системой кодирования.

Если file-name-coding-system равна nil, Emacs использует систему кодирования по умолчанию, определяемую языковой средой. В языковой среде, принимаемой по умолчанию, любые знаки в именах файлов, не входящие в ASCII, никак особенно не кодируются; они появляются в файловой системе во внутреннем представлении Emacs.

Внимание: если вы измените file-name-coding-system (или языковую среду) в середине сеанса Emacs, вы можете столкнуться с проблемами, если вы уже обратились к файлам, чьи имена были закодированы с использованием старой системы кодирования и не могут быть представлены (или кодируются иначе) в новой системе кодирования. Если вы попытаетесь сохранить один из таких буферов под именем файла, к которому он обращается, может быть использовано неправильное имя или может возникнуть ошибка. Если случается такая проблема, используйте C-x C-w, чтобы задать для этого буфера новое имя файла.

Наборы шрифтов

Шрифт X Windows обычно определяет начертание для одного алфавита или письменности. Поэтому для отображения полного спектра всех систем письма, которые поддерживает Emacs, необходимо множество шрифтов. В Emacs такое множество называется набором шрифтов. Набор шрифтов определяется как список шрифтов, каждый из которых предназначается для работы с одним диапазоном кодов знаков.

Каждый набор шрифтов имеет имя, как и отдельный шрифт. Доступные шрифты определяются X-сервером; наборы шрифтов определяются внутри самого Emacs. Как только вы определили набор шрифтов, вы можете использовать его в Emacs, указывая его имя в любом контексте, где вы могли бы написать один шрифт. Разумеется, наборы шрифтов Emacs могут содержать только те шрифты, которые поддерживаются X-сервером; если некоторые знаки появляются на экране как пустые прямоугольники, это означает, что в используемом наборе шрифтов нет шрифта для этих знаков.

Emacs создает два набора шрифтов автоматически: стандартный набор шрифтов и стартовый набор шрифтов. Стандартный набор шрифтов скорее всего содержит шрифты для широкого спектра знаков, не входящих в ASCII; однако, по умолчанию Emacs использует не его. (По умолчанию Emacs старается найти шрифт, которые имеет жирный и курсивный варианты.) Вы можете указать, что нужно использовать стандартный набор шрифтов, с помощью ключа -fn или с помощью X-ресурса `Font' (смотрите раздел Ключи для задания шрифта). Например,

emacs -fn fontset-standard

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

Высота и ширина набора шрифтов определяются ASCII-знаками (то есть шрифтами, используемыми в этом наборе для ASCII-знаков). Если другой шрифт в этом наборе имеет иную высоту или ширину, то знаки, приписанные к этому шрифту, обрезаются до размера набора шрифтов. Если highlight-wrong-size-font отлична от nil, то вокруг знаков с неправильным размером еще выводится прямоугольник.

Определение наборов шрифтов

Emacs создает стандартный набор шрифтов автоматически в соответствии с standard-fontset-spec. Именем этого набора является

-*-fixed-medium-r-normal-*-16-*-*-*-*-*-fontset-standard

или просто `fontset-standard' для краткости.

Жирный, курсивный и жирный курсивный варианты стандартного набора шрифтов создаются автоматически. Их имена имеют `bold' вместо `medium', или `i' вместо `r' или и то, и другое.

Если вы задали ASCII-шрифт по умолчанию с помощью ресурса `Font' или аргумента -fn, Emacs автоматически генерирует из него набор шрифтов. Это стартовый набор шрифтов, и его имя --- fontset-startup. Emacs делает это, заменяя в имени шрифта поля foundry, family, add_style и average_width на `*', заменяя charset_registry на `fontset', а поле charset_encoding -- на `startup' и используя затем полученную строку для задания набора шрифтов.

К примеру, если вы запустили Emacs таким образом:

emacs -fn "*courier-medium-r-normal--14-140-*-iso8859-1"

Emacs генерирует следующий набор шрифтов и использует его для первого фрейма:

-*-*-medium-r-normal-*-14-140-*-*-*-*-fontset-startup

В X-ресурсе `Emacs.Font' вы можете указывать набор шрифтов, точно так же, как и обычное имя шрифта. Но будьте внимательны и не задавайте набор шрифтов в ресурсе с символами подстановки, как `Emacs*Font', -- такая спецификация применяется для различных целей, например для меню, а меню не может обращаться с наборами шрифтов.

Вы можете определить дополнительные наборы шрифтов, используя X-ресурсы с именами `Fontset-n', где n -- число, отсчитываемое от нуля. Значение этого ресурса должно иметь такую форму:

шаблон-шрифта, [имя-кодировки:имя-шрифта]...

шаблон-шрифта, кроме двух последних полей, должен иметь форму стандартного имени X-шрифта. Два последних поля должны иметь вид `fontset-псевдоним'.

У набора шрифтов есть два имени, одно длинное, а другое короткое. Длинное имя -- это шаблон-шрифта. Короткое имя -- это `fontset-псевдоним'. Вы можете ссылаться на набор шрифтов по любому из этих имен.

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

Для остальных наборов знаков Emacs выбирает шрифт, основываясь на шаблоне-шрифта. Он заменяет `fontset-псевдоним' на значения, описывающие набор знаков. Для шрифта знаков ASCII, `fontset-псевдоним' заменяется на `ISO8859-1'.

Кроме того, когда несколько последовательных полей являются символами подстановки, Emacs сжимает их в один символ. Это делается для предотвращения использования автоматически масштабированных шрифтов. Шрифты, получаемые масштабированием более крупного шрифта, непригодны для редактирования, а масштабирование мелкого шрифта бессмысленно, потому что мелкий шрифт лучше использовать с его собственным размером, что Emacs и делает.

Таким образом, если шаблон-шрифта задан так:

-*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24

то спецификация шрифта для ASCII-знаков была бы такой:

-*-fixed-medium-r-normal-*-24-*-ISO8859-1

а спецификация шрифта для китайских знаков GB2312 такой:

-*-fixed-medium-r-normal-*-24-*-gb2312*-*

У вас может не оказаться китайских шрифтов, соответствующих приведенной выше спецификации. Большинство дистрибутивов X Windows включают только китайские шрифты с `song ti' или `fangsong ti' в поле family. В таком случае `Fontset-n' можно задать таким образом:

Emacs.Fontset-0: -*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24,\
        chinese-gb2312:-*-*-medium-r-normal-*-24-*-gb2312*-*

Тогда спецификации всех шрифтов, кроме китайских GB2312, будут иметь `fixed' в поле family, а спецификации для китайских знаков GB2312 несут в поле family символ подстановки `*'.

Функция, которая обрабатывает значение ресурса, определяющего набор шрифтов, и создает этот набор, называется create-fontset-from-fontset-spec. Вы также можете вызывать эту функцию явно, чтобы сгенерировать набор шрифтов.

Смотрите раздел Ключи для задания шрифта, для большей информации об именовании шрифтов в X.

Поддержка однобайтных европейских знаков

Наборы знаков ISO 8859 Latin-n определяют коды знаков в диапазоне от 160 до 255 для обращения с акцентированными буквами и знаками препинания, необходимыми в различных европейских языках. Если вы выключите поддержку многобайтных знаков, Emacs все же сможет работать с одной из этих кодировок. Чтобы указать, какие из этих кодов следует использовать, вызовите M-x set-language-environment и задайте подходящую языковую среду, такую как `Latin-n'.

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

Emacs может также отображать такие знаки, при условии, что они поддерживаются терминалом или шрифтом. Это работает автоматически. Или, если вы используете оконную систему, Emacs может отображать однобайтные знаки через наборы шрифтов, показывая в действительности эквивалентные многобайтные знаки в соответствии с языковой средой. Чтобы затребовать это, установите переменную unibyte-display-via-language-environment в отличное от nil значение.

Если ваш терминал не поддерживает набор знаков Latin-1, Emacs может отображать их как ASCII-последовательности, которые по крайней мере дают вам ясное представление о том, что это за знаки. Чтобы сделать так, загрузите библиотеку iso-ascii. Могут быть реализованы похожие библиотеки и для других наборов знаков Latin-n, но пока их у нас нет.

Обычно не входящие в ISO-8859 знаки (между 128 и 159 включительно) отображаются как восьмиричные управляющие последовательности. Вы можете изменить это для нестандартных `расширенных' версий наборов знаков ISO-8859, используя функцию standard-display-8bit из библиотеки disp-table.

Есть три разных способа вводить однобайтные не-ASCII-знаки:

  • Если ваша клавиатура может генерировать коды знаков от 128 и выше, представляющие знаки, не входящие в ASCII, выполните следующее выражение, чтобы Emacs смог их понимать:
    (set-input-mode (car (current-input-mode))
                    (nth 1 (current-input-mode))
                    0)
    
  • Вы можете использовать метод ввода для выбранной языковой среды. Смотрите раздел Методы ввода. Когда вы используете метод ввода в однобайтном буфере, задаваемые с его помощью знаки переводятся в однобайтное представление.
  • Для ввода печатных знаков Latin-1 вы можете использовать C-x 8 как префикс "составления". C-x 8 удобен для вставки (в минибуфере, а также в остальных буферах), для поиска и во всех других контекстах, где допускаются последовательности знаков. C-x 8 работает путем загрузки библиотеки iso-transl. Когда эта библиотека загружена, клавиша-модификатор ALT, если она у вас есть, служит для той же цели, что и C-x 8; используйте ALT вместе со знаком акцента, чтобы модифицировать следующую букву. Кроме того, если у вас есть залипающие клавиши для генерации акцентов Latin-1, то они тоже определены для компоновки со следующим знаком, если iso-transl загружена.

Основные режимы

Emacs предоставляет много различных основных режимов, каждый из которых настраивает Emacs на редактирование текста определенного вида. Основные режимы являются взаимоисключающими, и каждый буфер находится в каждый момент времени в одном основном режиме. Строка режима обычно содержит имя текущего основного режима в круглых скобках (смотрите раздел Строка режима).

Наименее специализированный основной режим называется Fundamental. Этот режим не имеет специальных режимных переопределений или устанавливаемых переменных, так что каждая команда Emacs ведет себя самым обычным образом и каждый параметр находится в своем состоянии по умолчанию. Для редактирования некоторого текста определенного типа, такого как код на Лиспе или английский текст, вы должны переключить Emacs в соответствующий основной режим, такой как режим Lisp или режим Text.

Выбор основного режима изменяет значение нескольких ключей таким образом, чтобы они стали более приспособленным к редактируемому языку. Одни из наиболее часто изменяемых ключей -- это TAB, DEL и C-j. Префиксный ключ C-c обычно содержит команды, специфичные для режима. Помимо этого, команды для управления комментариями используют режим для определения того, каким образом комментарии должны ограничиваться. Многие основные режимы переопределяют синтаксические свойства знаков, появляющихся в буфере. Смотрите раздел Синтаксическая таблица.

Основные режимы делятся на три основных группы. Режим Lisp (который имеет несколько вариантов), режим C и режим Fortran -- для специфических языков программирования. Режим Text, режим Nroff, режим TeX и режим Outline -- для редактирования текста на естественном языке. Остальные основные режимы не предназначены для использования с файлами пользователей; они используются в буферах, создаваемых Emacs для специальных целей, это такие режимы, как режим Dired для буферов, созданных Dired (смотрите раздел Dired, редактор каталогов), режим Mail для буферов, созданных при помощи C-x m (смотрите раздел Посылка почты), и режим Shell для буферов, используемых для связи с подчиненным процессом оболочки (смотрите раздел Интерактивная подчиненная оболочка).

Большинство основных режимов для языков программирования указывают, что только пустые строки разделяют абзацы. Таким образом, команды работы с абзацами остаются удобными. (Смотрите раздел Абзацы.) Они так же заставляют режим Auto Fill использовать определение TAB для создания отступа во вновь создаваемых им строках. Это далется, поскольку большинство строк в программе обычно начинаются с отступа. (Смотрите раздел Отступы.)

Как выбираются основные режимы

Вы можете выбрать основной режим для текущего буфера явно, но чаще Emacs сам определяет, какой режим использовать, основываясь на имени файла или на специальном тексте в файле.

Явный выбор нового основного режима делается при помощи команды M-x. Чтобы получить имя команды для выбора режима, добавьте к имени основного режима окончание -mode. Таким образом, вы можете войти в режим Lisp, выполнив команду M-x lisp-mode.

Когда вы обращаетесь к файлу, Emacs обычно выбирает правильный основной режим, основываясь на имени этого файла. Например, файлы, чьи имена оканчиваются на `.с', редактируются в режиме С. Соответствие между именем файла и основным режимом контролируется переменной auto-mode-alist. Ее значение -- это список, каждый элемент которого имеет такой вид:

(регулярное-выражение . функция-режима)

или такой:

(регулярное-выражение функция-режима флаг)

Например, один элемент, обычно находящийся в этом списке, имеет вид ("\\.c\\'" . c-mode), и это является сигналом для выбора режима С для файлов, чьи имена кончаются на `.с'. (Отметим, что `\\' необходимо по синтаксису Лиспа для того, чтобы включить в эту строку знак `\', а он нужен для подавления специального значения `.' в регулярном выражении.) Если этот элемент имеет форму (регулярное-выражение функция-режима флаг), и флаг не nil, то после вызова функции-режима суффикс, совпавший с регулярным-выражением, отбрасывается, и в списке производится повторный поиск другого совпадения.

Вы можете указать, какой основной режим должен использоваться для редактирования определенного файла, с помощью текста специального вида в первой непустой строке файла. В этой строке должно появиться имя режима, до и после него должны стоять строки `-*-'. В этой строке также может появиться другой текст. Например,

;-*-Lisp-*-

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

Другой формат определения режима:

-*- mode: имя-режима;-*-

что позволяет вам также задать локальные переменные, как здесь:

-*- mode: имя-режима; пер: значение; ... -*-

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

Если содержимое файла начинается с `#!', он может служить в качестве выполняемой команды оболочки, которая работает путем запуска интерпретатора, названного в первой строке этого файла. Остальная часть файла подается на вход интерпретатора.

Когда вы обращаетесь к подобному файлу в Emacs, если имя файла не задает основной режим, Emacs использует для выбора режима имя интерпретатора в первой строке. Если первая строка -- это имя поддерживаемой программы-интерпретатора, такой как `perl' или `tcl', Emacs использует режим, подходящий для программ для этого интерпретатора. Переменная interpreter-mode-alist задает соответствие между именами программ-интерпретаторов и основными режимами.

Когда первая строка начинается с `#!', вы не можете (на многих системах) использовать в ней `-*-', поскольку при запуске интерпретатора это ввело бы в заблуждение систему. Поэтому в таких файлах Emacs ищет `-*-' на второй строке, а не только на первой. Когда вы обращаетесь к файлу, который не указывает, какой основной режим использовать, или когда вы создаете новый буфер при помощи C-x b, то используемым основным режимом является тот, что определен переменной default-major-mode. Обычно ее значение --- это символ fundamental-mode, который задает режим Fudamental. Если default-major-mode равна nil, то основной режим берется из ранее выбранного буфера.

Если вы изменили основной режим буфера, вы можете вернуться к тому основному режиму, который Emacs выбрал бы автоматически: используйте для этого команду M-x normal-mode. Это та же функция, которую вызывает find-file для выбора основного режима. Она также обрабатывает список локальных переменных файла, если он есть.

Команды C-x C-w и set-visited-file-name переключают в новый основной режим, если новое имя файла подразумевает выбор режима (смотрите раздел Сохранение файлов). Однако, это не происходит, если содержимое буфера задает основной режим; и некоторые "специальные" основные режимы не допускают изменения режима. Вы можете выключить эту возможность переключения режимов, установив change-major-mode-with-file-name в значение nil.

Отступы

Эта глава описывает команды Emacs, которые создают, убирают или настраивают отступы.

TAB
Сделать отступ текущей строки, "соответствующий" режиму.
C-j
Выполнить RET, за которым следует TAB (newline-and-indent).
M-^
Слить две строки (delete-indentation). Это отменяет действие C-j.
C-M-o
Разбить строку в точке; текст на строке после точки становится новой строкой с отступом до того столбца, с которого он начинается сейчас (split-line).
M-m
Передвинуться (вперед или назад) к первому непустому знаку на текущей строке (back-to-indetation).
C-M-\
Сделать отступ нескольких строк до одного и того же столбца (indent-region).
C-x TAB
Жестко сдвинуть блок строк влево или вправо (indent-rigidly).
M-i
Сделать отступ от точки к следующему предопределенному столбцу позиции табуляции (tab-to-tab-stop).
M-x indent-relative
Сделать отступ от точки к месту под точкой отступа в предыдущей строке.

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

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

В режиме Text, TAB запускает команду tab-to-tab-stop, которая делает отступ к следующему столбцу позиции табуляции. Вы можете установить позиции табуляции с помощью M-x edit-tab-stops.

Способы и команды отступа

Чтобы передвинуться через отступ на строке, сделайте M-m (back-to-indentation). Эта команда, данная где угодно на строке, помещает точку на первый непустой знак в этой строке.

Чтобы вставить строку с отступом перед текущей строкой, сделайте C-a C-o TAB. Чтобы сделать строку с отступом после текущей строки, используйте C-e C-j.

Если вы просто хотите вставить в буфер символ табуляции, то вы можете набрать C-q TAB.

C-M-o (split-line) сдвигает текст от точки до конца строки вертикально вниз, так что текущая строка становится двумя строками. C-M-o сначала передвигает точку вперед через любое количество пробелов и табуляций. Затем она вставляет после точки ограничитель строки и достаточное количество отступов, чтобы достичь того же столбца, на котором находится точка. Точка остается перед вставляемым переводом строки; с этой точки зрения C-M-o напоминает C-o.

Чтобы начисто соединить две строки, используйте команду M-^ (delete-indentation). Она удаляет отступ в начале текущей строки, а так же ограничитель строки, заменяя их одиночным пробелом. В особом случае (полезном для кода на Лиспе) одиночный пробел опускается, если соединяемыми знаками являются последовательные открывающие или закрывающие круглые скобки, или если после слияния идет еще одна новая строка. Чтобы удалить просто отступ строки, перейдите в начало строки и используйте M-\ (delete-horizontal-space), которая удаляет все пробелы и табуляции около курсора.

Если есть префикс заполнения, M-^ убирает его, если он находится после удаляемого перевода строки. Смотрите раздел Префикс заполнения.

Имеются также команды для изменения отступов нескольких строк сразу. C-M-\ (indent-region) применяется для всех строк, которые начинаются в данной области; она делает для каждой из этих строк "обычный" отступ, как если бы вы напечатали TAB в начале строки. Числовой аргумент определяет столбец для отступа, и каждая строка сдвигается влево или вправо так, что ее первый непустой знак появляется в этом столбце. C-x TAB (indent-rigidly) cдвигает все строки в области вправо в соответствии со своим аргументом (влево при отрицательном аргументе). Вся группа строк жестко сдвигается в одну сторону, именно поэтому эта команда получила такое имя.

M-x indent-relative выполняет отступ точки, основываясь на предыдущей строке (фактически, по последней непустой строке). Она вставляет пробел в точке, двигая точку до тех пор, пока она не встанет под точкой отступа в предыдущей строке. Точка отступа является концом последовательности пробелов или концом строки. Если точка находится дальше вправо, чем любая точка отступа в предыдущей строке, то все пробельные знаки перед точкой удаляются, и используется первая применимая теперь точка отступа. Если даже после этого нет пригодной точки отступа, indent-relative запускает tab-to-tab-stop (смотрите следующий раздел).

indent-relative -- это определение TAB в режиме Indented Text. Смотрите раздел Команды для естественных языков.

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

Позиции табуляции

Для набора таблиц вы можете использовать определение TAB в режиме Text, tab-to-tab-stop. Эта команда вставляет перед точкой отступ, достаточный для того, чтобы достичь следующего столбца позиции табуляции. Если вы находитесь не в режиме Text, эту функцию можно найти по ключу M-i.

Вы можете произвольно установить используемые в M-i позиции табуляции. Они запоминаются в переменной с именем tab-stop-list как список номеров столбцов в возрастающем порядке.

Удобный способ установить позиции табуляции -- воспользоваться командой M-x edit-tab-stops, которая создает и выбирает буфер, содержащий описание установленных позиций табуляции. Вы можете отредактировать этот буфер для определения других позиций табуляции и затем набрать C-c C-c, чтобы сделать эти новые позиции табуляции действующими. edit-tab-stops запоминает, какой буфер был текущим, когда вы запускали ее, и записывает позиции табуляции обратно в этот буфер; обычно все буферы разделяют одни и те же позиции табуляции, и изменение их в одном буфере влияет на все, но если вам случится сделать tab-stop-list локальной в одном буфере, то edit-tab-stops будет редактировать локальные установки.

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

        :       :       :       :       :       :
0         1         2         3         4
0123456789012345678901234567890123456789012345678
To install changes, type C-c C-c

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

Заметим, что позиции табуляции, которые управляют tab-to-tab-stop, не имеют ничего общего с показанными символами табуляции в буфере. Смотрите раздел Переменные управления изображением, для более подробной информации на этот счет.

Табуляция по сравнению с пробелами

Обычно Emacs использует для отступа строк как табуляцию, так и пробелы. Если вы захотите, то все отступы будут делаться только при помощи пробелов. Чтобы потребовать это, установите переменную indent-tab-mode равной nil. Это переменная буфера; изменение ее влияет только на текущий буфер, но имеется и значение по умолчанию, которое вы тоже можете изменить. Смотрите раздел Локальные переменные.

Существуют также команды для превращения табуляции в пробелы и наоборот, всегда сохраняющие столбцы всего непустого текста. M-x tabify находит в области последовательности пробелов и преобразует в табуляцию любую последовательность, состоящую по меньшей мере из трех пробелов, если это можно сделать без изменения отступа. M-x untabify заменяет все табуляции в области на соответствующее число пробелов.

Команды для естественных языков

Термин текст имеет два широко распространенных значения в нашей области компьютерной науки. Одно -- это данные, которые являются последовательностью знаков. Любой файл, который вы редактируете при помощи Emacs, -- это текст в этом смысле слова. Другое значение более узкое: последовательность знаков на естественном языке, предназначенная для чтения людьми (возможно после обработки форматированием), в противоположность программам или командам для программы.

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

Emacs имеет несколько основных режимов для редактирования текста на естественном языке. Если файл содержит несложный чистый текст, используйте режим Text, который быстро настраивает Emacs на синтаксические условности текста. Режим Outline предоставляет особые команды для действий с со структурированным текстом. Смотрите раздел Режим Outline.

Для текста, который содержит встроенные команды для программ форматирования, Emacs имеет другие основные режимы, свой для каждого формата. Таким образом, для ввода в TeX вы должны использовать режим TeX (смотрите раздел Режим TeX). Для ввода в nroff -- режим Nroff.

Вместо использования программы форматирования, вы можете редактировать форматированный текст в стиле WYSIWYG ("what you see is what you get")(6) с помощью режима Enriched. Тогда форматирование появляется на экране в Emacs во время редактирования. Смотрите раздел Редактирование форматированного текста.

Слова

В Emacs существуют команды для передвижения по словам или воздействия на них. По соглашению, все ключи для этого являются Meta-знаками.

M-f
Перейти вперед через слово (forward-word).
M-b
Перейти назад через слово (backward-word).
M-d
Уничтожить вперед все вплоть до конца слова (kill-word).
M-DEL
Уничтожить назад все вплоть до начала слова (backward-kill-word).
M-@
Пометить конец следующего слова (mark-word).
M-t
Переставить два слова или перенести одно слово через другие слова (transpose-words).

Заметьте, как эти ключи образуют ряд, который соответствует ключам, работающим со знаками: C-f, C-b, C-d, DEL и C-t. M-@ соответствует C-@, которая иначе называется C-SPC.

Команды M-f (forward-word) and M-b (backward-word) передвигают вперед или назад через слова. Таким образом, эти Meta-знаки аналогичны C-f и C-b, которые передвигают через одиночные знаки в тексте. Аналогия распространяется на числовые аргументя, которые служат счетчиками повторов. M-f с отрицательным аргументом передвигает назад, а M-b с отрицательным аргументом передвигает вперед. Движение вперед останавливается сразу после последней буквы слова, тогда как движение назад останавливается сразу перед первой буквой.

M-d (kill-word) уничтожает слово после точки. Точнее, она уничтожает все от точки до того места, куда переместила бы команда M-f. Таким образом, если точка находится в середине слова, M-d уничтожает только часть слова после точки. Если между точкой и следующим словом находятся какие-то знаки препинания, то они уничтожаются вместе со словом. (Если вы хотите уничтожить только следующее слово, но не уничтожать знаки препинания перед ним, то просто сделайте M-f, чтобы перейти на конец, и уничтожьте слово в обратном направлении при помощи M-DEL.) M-d трактует аргументы точно так же, как M-f.

M-DEL (backward-kill-word) уничтожает слово перед точкой. Она уничтожает все от точки назад к тому месту, куда передвинула бы M-b. Если точка находится после пробела в `FOO, BAR', то уничтожается `FOO, '. (Если вы хотите уничтожить просто `FOO', сделайте M-b M-d вместо M-DEL.)

M-t (transpose-words) меняет местами слово, стоящее перед точкой или содержащее ее, со следующим словом. Разграничительные знаки между словами не сдвигаются. Например, `FOO, BAR' превращается в `BAR, FOO', а не в `BAR FOO,'. Для более подробной информации о перестановках и аргументах команд перестановки смотрите раздел Перестановка текста.

Чтобы подействовать на следующие n слов с помощью операции, которая применяется между точкой и меткой, вы можете либо установить метку в точке и затем передвинуть точку через слова, либо использовать команду M-@ (mark-word), которая не перемещает точку, но устанавливает метку туда, куда ее передвинула бы команда M-f. M-@ принимает числовой аргумент, который говорит, через сколько слов нужно поместить метку. В режиме Transient Mark эта команда активизирует метку.

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

Предложения

Команды Emacs для действий над предложениями и абзацами в большинстве своем приданы Meta-ключам, чтобы они были подобны командам работы со словами.

M-a
Перейти назад к началу предложения (backward-sentence).
M-e
Перейти вперед к концу предложения (forward-sentence).
M-k
Уничтожить вперед до конца предложения (kill-sentence).
C-x DEL
Уничтожить все в обратном направлении до начала предложения (backward-kill-sentence).

Команды M-a и M-e (backward-sentence и forward-sentence) передвигают точку к началу и к концу текущего предложения, соответственно. Они выбраны так, чтобы напоминать C-a и C-e, которые сдвигают к концу и началу строки. В отличие от них, M-a и M-e при повторении или с заданными числовыми аргументами передвигают через последовательные предложения.

Перемещение назад через предложение помещает точку непосредственно перед первым знаком этого предложения; перемещение вперед помещает точку сразу после знака препинания, завершающего предложение. Ни одна из этих команд не перемещает через пропуски на границах предложений.

Точно так же, как C-a и C-e имеют соответствующую им команду уничтожения C-k, так и M-a и M-e имеют соответствующую команду уничтожения M-k (kill-sentence), которая уничтожает все от точки до конца предложения. С аргументом, равным минус единице, она уничтожает в обратном направлении до начала предложения. Большие аргументы служат для подсчета повторов. Есть также особая команда C-x DEL (backward-kill-sentence) для уничтожения в обратном направлении к началу предложения. Она удобна, когда вы меняете свое решение в процессе сочинения текста.

Команды работы с предложениями предполагают, что вы следуете соглашению американских машинисток -- ставить в конце предложения два пробела; они считают предложение оконченным, если там есть знаки `.', `?' или `!', за которыми следует конец строки или два пробела; в середине допустимо любое число знаков `)', `]' или `"'. Предложение также начинается или кончается, если начинается или кончается абзац.

Переменная sentence-end управляет распознаванием конца предложения. Это регулярное выражение, которое соответствует последним нескольким знакам предложения вместе с пробелами, следующими за предложением. Его нормальное значение таково:

"[.?!][]\"')]*\\($\\|\t\\|  \\)[ \t\n]*"

Этот пример объясняется в разделе о регулярных выражениях. Смотрите раздел Синтаксис регулярных выражений.

Если вы хотите использовать между предложениями только один пробел, вам нужно установить sentence-end в такое значение:

"[.?!][]\"')]*\\($\\|\t\\| \\)[ \t\n]*"

Вам нужно также установить переменную sentence-end-double-space равной nil, чтобы команды заполнения ожидали и оставляли в конце предложений только один пробел. Заметьте, что при этом невозможно отличить точки, завершающие предложения, и точек в сокращениях.

Абзацы

Команды Emacs для работы с абзацами -- это также Meta-ключи.

M-{
Перейти назад к началу предыдущего абзаца (backward-paragraph).
M-}
Переместиться вперед к концу следующего абзаца (forward-paragraph).
M-h
Поставить точку и метку вокруг этого или следующего абзаца (mark-paragraph).

M-{ двигает точку в начало текущего или предыдущего абзаца, в то время как M-} двигает ее к концу текущего или следующего абзаца. Абзацы разделяются пустыми строками и строками команд форматирования текста, которые в свою очередь не являются частью какого-либо абзаца. В режиме Fundamental, но не в режиме Text, строка с отступом также начинает новый абзац. (Если перед абзацем стоит пустая строка, данные команды считают эту пустую строку началом абзаца.)

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

Когда имеется префикс заполнения, абзацы ограничиваются всеми строками, которые не начинаются с этого префикса. Смотрите раздел Заполнение текста.

Когда вы захотите оперировать с абзацем, вы можете использовать команду M-h (mark-paragraph), чтобы установить вокруг него область. Таким образом, например, M-h C-w уничтожает абзац вокруг или после точки. Команда M-h ставит точку в начале абзаца, содержащего точку, и метку в его конце. В режиме Transient Mark она активизирует метку. Если точка находится между абзацами (в области пустых строк или на границе), то точкой и меткой окружается абзац, следующий за точкой. Если первой строке абзаца предшествуют пустые строки, то одна из этих пустых строк включается в область.

Точным определением границ абзаца управляют две переменные: paragraph-separate и paragraph-start. Значение paragraph-start -- это регулярное выражение, которое должно соответствовать любой строке, которая либо начинает, либо разделяет абзацы. Значение paragraph-separate -- это еще одно регулярное выражение, которое должно соответствовать только строкам, которые разделяют абзац, но не являются частью какого-либо абзаца (например, пустые строки). Строки, которые начинают новый абзац и содержатся в нем, должны соответствовать только paragraph-start, но не paragraph-separate. Например, в режиме Fundamental, paragraph-start равна "[ \t\n\f]", а paragraph-separate -- это "[ \t\f]*$".

Обычно желательно, чтобы границы страниц разделяли абзацы. Значения по умолчанию этих переменных распознают обычный разделитель страниц.

Страницы

Очень часто файлы представляются разделенными на страницы с помощью знаков прогона (или перевода) страницы (ASCII Control-L, восьмиричный код 014). Когда вы печатаете файл, этот знак принудительно разбивает страницу; таким образом, каждая страница файла будет начинаться на новом листе бумаги. Большинство команд Emacs рассматривают знак-разделитель страниц точно так же, как любые другие знаки: вы можете вставить их при помощи C-q C-l или удалить с помощью DEL. Таким образом, вы свободны в выборе, делить на страницы ваш файл или нет. Однако, из-за того, что деление на страницы часто является смысловым делением файла, то предусмотрены команды для перемещения по страницам и для действий над ними.

C-x [
Сместить точку к предыдущей странице (backward-page).
C-x ]
Сместить точку к следующей странице (forward-page).
C-x C-p
Поставить точку и метку по краям этой (или другой) страницы (mark-page).
C-x l
Сосчитать строки в этой странице (count-lines-page).

Команда C-x [ (backward-page) двигает точку к позиции непосредственно после предыдущего разделителя страницы. Если точка уже находится сразу после разделителя, то команда пропускает эту страницу и останавливается на предшествующей ей. Числовой аргумент служит в качестве счетчика повторов. Команда C-x ] (forward-page) передвигает точку вперед, пропуская следующий разделитель страниц.

Команда C-x C-p (mark-page) ставит точку в начале текущей страницы, а метку в ее конце. Разделитель страниц в конце включается в область (метка следует за ним). Разделитель страниц в начале не включается (точка следует за ним). C-x C-p C-w дает удобный способ уничтожить страницу или переместить ее в другое место. Если вы сдвинитесь к разделителю еще одной страницы с помощью C-x [ и C-x ], а затем восстановите уничтоженную страницу, все страницы будут снова правильно разграничины. C-x C-p включает в область только разделитель следующей страницы именно для этого.

Числовой аргумент для C-x C-p используется для указания страницы, к которой необходимо отправиться, относительно текущей. Ноль означает текущую страницу. Единица означает следующую страницу, а -1 -- предыдущую.

Команда C-x l (count-lines-page) хороша для принятия решения, где разорвать страницу на две. Она печатает в эхо-области общее число строк в текущей странице и затем делит ее на те, которые предшествуют текущей строке, и на те, что следуют за ней, как в примере:

Page has 96 (72+25) lines(7)

Заметьте, что значение суммы на единицу меньше; это верно, если точка не стоит в начале строки.

Переменная page-delimiter говорит, где начинается страница. Ее значение -- это регулярное выражение, соответствующее началу строки, которая разделяет страницы. Обычное значение этой переменной равно "^\f", что соответствует знаку перевода страницы в начале строки.

Заполнение текста

Заполнение текста означает разбиение его на строки определенной длины. Emacs может делать заполнение двумя способами. В режиме Auto Fill, вставка текста с помощью самовставляющихся знаков также автоматически заполняет его. Есть также явные команды для заполнения, которые вы можете использовать, когда редактирование текста оставляет его незаполненным. Когда вы редактируете форматированный текст, вы можете задать стиль заполнения каждого фрагмента (смотрите раздел Редактирование форматированного текста).

Режим Auto Fill

Режим Auto Fill -- это второстепенный режим, в котором строки обрываются автоматически, когда становятся слишком длинными. Разрыв происходит только тогда, когда вы набираете SPC или RET.

M-x auto-fill-mode
Включение и выключение режима Auto Fill.
SPC
RET
В режиме Auto Fill прерывает строку, если это нужно.

M-x auto-fill-mode включает режим Auto Fill, если он был отключен, или выключает, если он был включен. С положительным аргументом она всегда включает режим Auto Fill, а отрицательным --- всегда отключает. Вы можете видеть, когда режим Auto Fill действует, по присутствию слова `Fill' в строке режима внутри круглых скобок. Режим Auto Fill -- второстепенный режим, включаемый или выключаемый для каждого буфера отдельно. Смотрите раздел Второстепенные режимы.

В режиме Auto Fill строки автоматически разрываются на пробелах, когда они становятся длиннее желаемой величины. Прерывание и перерасположение строки происходит, только когда вы набираете SPC или RET. Если вы хотите вставить пробел или знак новой строки с запретом прерывания строки, наберите C-q SPC или C-q C-j (напомним, что знак новой строки -- это на самом деле control-J). C-o также вставляет новую строку без прерывания строки.

Режим Auto Fill хорошо работает с режимами для языков программирования, так как он делает в новых строках отступ с помощью TAB. Если строка, заканчивающаяся комментарием, получилась слишком длинной, то текст комментария разбивается на две строки. Возможно, в конце первой строки и в начале второй вставятся новые ограничители комментариев, таким образом, чтобы каждая строка стала отдельным комментарием; этим выбором управляет переменная comment-multi-line (смотрите раздел Управление комментариями).

Адаптивное заполнение (смотрите следующий раздел) работает с режимом Auto Fill так же, как с явными командами заполнения. Оно автоматически берет префикс заполнения из второй или первой строки абзаца.

Режим Auto Fill не перезаполняет целые абзацы; он может прерывать строки, но не может их объединять. Таким образом, редактирование в середине абзаца может привести к созданию абзаца, который неправильно заполнен. Простейшим способом сделать абзац снова правильно заполненным обычно служит применение явных команды заполнения.

Многие пользователи любят режим Auto Fill и хотят использовать его во всех текстовых файлах. Раздел о файлах инициализации рассказывает, как устроить, чтобы это было для вас постоянным. Смотрите раздел Файл инициализации, `~/.emacs'.

Явные команды заполнения

M-q
Заполнить текущий абзац (fill-paragraph).
C-x f
Установить столбец заполнения (set-fill-column).
M-x fill-region
Заполнить каждый абзац в области (fill-region).
M-x fill-region-as-paragraph
Заполнить область, рассматривая ее как один абзац.
M-s
Отцентрировать строку.

Чтобы перезаполнить один абзац, используйте команду M-q (fill-paragraph). Она действует на абзац, в котором находится точка, или на абзац после точки, если она стоит между абзацами. Перезаполнение работает путем удаления всех разрывов строк и вставки новых в тех местах, где это требуется.

Чтобы перезаполнить много абзацев, используйте M-x fill-region, которая делит область на абзацы и заполняет каждый из них.

Команды M-q и fill-region используют для нахождения границ абзаца тот же самый критерий, что и M-h (смотрите раздел Абзацы). Для большего контроля, вы можете использовать M-x fill-region-as-paragraph, которая перезаполняет все между точкой и меткой. Эта команда удаляет в области все пустые строки, поэтому отдельные блоки текста в результате объединяются в один блок.

Числовой аргумент для M-q приводит к тому, что помимо заполнения, текст еще и выравнивается. Это значит, что вставляются дополнительные пробелы, чтобы правый край строки попадал точно в столбец заполнения. Чтобы уничтожить дополнительные пробелы, используйте M-q без аргумента. (Аналогично и для fill-region.) Другой способ управлять выравниванием или выбрать другие стили заполнения состоит в применении свойства текста justification; смотрите раздел Выравнивание в форматированном тексте.

Команда M-s (center-line) центрирует текущую строку в пределах текущего столбца заполнения. С аргументом n, она центрирует несколько строк отдельно и переходит через них.

Максимальная ширина строки для заполнения содержится в переменной fill-column. Изменение значения fill-column делает ее локальной для текущего буфера; до этого момента действует значение по умолчанию. Изначально оно равно 70. Смотрите раздел Локальные переменные. Наилегчайший способ установить fill-column -- использовать команду C-x f (set-fill-column). Запущенная с числовым аргументом, она использует его в качестве нового столбца заполнения. Просто с C-u в качестве аргумента, она устанавливает fill-column соответственно текущей горизонтальной позиции точки.

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

Если переменная sentence-end-double-space равна nil, то команды заполнения ожидают и оставляют в конце предложений только один пробел. Обычно эта переменная равна t, поэтому команды заполнения настаивают на постановке двух пробелах в конце предложения, как объяснено выше. Смотрите раздел Предложения.

Если переменная colon-double-space не равна nil, команды заполнения ставят после двоеточия два пробела.

Префикс заполнения

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

C-x .
Установить префикс заполнения (set-fill-prefix).
M-q
Заполнить абзац с текущим префиксом заполнения (fill-paragraph).
M-x fill-individual-paragraphs
Заполнить область, рассматривая каждое изменение отступа как начало нового абзаца.
M-x fill-nonuniform-paragraphs
Заполнить область, считая началом нового абзаца только строки-разделители абзацев.

Чтобы задать префикс заполнения, передвиньтесь к строке, которая начинается с желаемого префикса, поставьте точку в конец префикса и дайте команду C-x . (set-fill-prefix). После C-x стоит точка. Чтобы выключить префикс заполнения, определите пустой префикс: наберите C-x ., когда точка находится в начале строки.

Когда префикс заполнения в действии, команды заполнения уничтожают его в каждой строке перед заполнением и вставляют его в каждую строку после заполнения. Режим Auto Fill также автоматически вставляет в каждую вновь созданную строку префикс заполнения. Команда C-o вставляет в созданные ей строки префикс заполнения, когда вы используете ее в начале строки (смотрите раздел Пустые строки). С другой стороны, команда M-^ уничтожает префикс (если он есть) после удаляемого перевода строки (смотрите раздел Отступы).

Например, если fill-column равна 40 и вы установили префикс заполнения равным `;; ', то M-q в таком тексте:

;; Это пример
;; абзаца внутри
;; комментария в стиле Лиспа.

дает следующее:

;; Это пример абзаца внутри комментария
;; в стиле Лиспа.

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

Вы можете использовать M-x fill-individual-paragraphs, чтобы установить префикс заполнения для каждого абзаца автоматически. Эта команда делит область на абзацы, считая любое изменение величины отступа началом нового абзаца, и заполняет каждый из этих абзацев. Таким образом, все строки одного "абзаца" имеют одинаковый отступ. Именно этот отступ служит префиксом заполнения для каждого абзаца.

M-x fill-nonuniform-paragraphs -- это похожая команда, которя делит область на абзацы другим способом. Она рассматривает только строки-разделители абзацев (как определено paragraph-separate) в качестве начинающих новый абзац. Поскольку это означает, что строки одного абзаца могут иметь разный отступ, в качестве префикса заполнения используется отступ наименьшего среди всех строк этого абзаца размера. Это дает хорошие результаты для стилей, в которых первая строка абзаца имеет больший или меньший отступ, чем остальная часть абзаца.

Префикс заполнения хранится в переменной fill-prefix. Ее значение -- это либо строка, либо nil, когда префикса заполнения нет. В каждом буфере для этой переменной есть свое значение; ее изменение воздействует только на текущий буфер, но имеется и значение по умолчанию, которое вы также можете изменить. Смотрите раздел Локальные переменные.

Свойство текста indentation предоставляет другой способ управления величиной отступа абзаца. Смотрите раздел Отступы в форматированном тексте.

Адаптивное заполнение

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

Если в абзаце есть две или более строки, префикс заполнения берется из второй, но только если он также появляется и в первой.

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

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

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

Если префикс, обнаруженный на первой строке, соответствует регулярному выражению adaptive-fill-first-line-regexp, или он оказался последовательностью, начинающей комментарий (это зависит от основнего режима), то для заполнения абзаца используется этот найденный префикс, при условии, что он не будет действовать как начало абзаца в следующих строках.

Иначе, найденный префикс преобразуется в эквивалентное число пробелов, и в качестве префикса заполнения для оставшихся строк используются эти пробелы, при условии, что они не будут действовать как начало абзаца в следующих строках.

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

Переменная adaptive-fill-regexp определяет, какие виды начала строки могут служить префиксом заполнения: используются любые знаки в начале строки, соответствующие этому регулярному выражению. Если вы установите переменную adaptive-fill-mode равной nil, префикс заполнения никогда не выбирается автоматически.

Вы можете задать более сложные методы автоматического выбора префикса заполнения, установив переменную adaptive-fill-function в значение функции. Эта функция вызывается, когда точка находится с левого края строки, и она должна вернуть подходящий префикс заполнения. Если она возвращет nil, это означает, что она не увидела в этой строке префикс заполнения.

Команды преобразования регистра

В Emacs есть команды для перевода одиночных слов или любого произвольного текста в верхний или в нижний регистр.

M-l
Перевести следующее слово в нижний регистр (downcase-word).
M-u
Перевести следующее слово в верхний регистр (upcase-word).
M-c
Сделать первую букву следующего слова заглавной, а остальные --- строчными (capitalize-word).
C-x C-l
Перевести область в нижний регистр (downcase-region).
C-x C-u
Перевести область в верхний регистр (upcase-region).

Команды преобразования слов наиболее полезны. M-l (downcase-word) переводит слово после точки в нижний регистр, передвигая точку за него. Таким образом, повторение M-l переводит последующие слова. M-u (upcase-word) переводит все слово в прописные буквы, в то время как M-c (capitalize-word) ставит первую букву слова в верхнем регистре, а остальные -- в нижнем регистре. Все эти команды переводят несколько слов за один раз, если им придать аргумент. Они особенно удобны для перевода большого объема текста, набранного полностью в верхнем регистре, в смешанный регистр, потому что вы можете двигаться по тексту, используя M-l, M-u или M-c, когда это необходимо, и используя иногда M-f, чтобы пропустить слово.

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

Если команда перевода регистра в словах дается в середине слова, то она применяется только к части слова, которая следует за точкой. Это очень похоже на то, что делает M-d (kill-word). С отрицательным аргументом, перевод регистра применяется только к части слова перед точкой.

Другие команды перевода регистра -- это C-x C-u (upcase-region) и C-x C-l (downcase-region), которые переводят все между точкой и меткой в заданный регистр. Точка и метка не сдвигаются.

Команды перевода регистра в области, upcase-region и downcase-region, обычно заблокированы. Это означает, что они запрашивают подтверждение, если вы пытаетесь их использовать. При подтверждении вы можете включить эти команды, тогда они больше не будут запрашивать подтверждения. Смотрите раздел Блокирование команд.

Режим Text

Когда вы редактируете текстовые файлов на естественном языке, вам будет удобнее воспользоваться режимом Text, а не Fundamental. Чтобы войти в режим Text, наберите M-x text-mode.

В режиме Text абзацы разделяются только пустыми строками и разделителями страниц. В результате абзацы могут иметь отступ, и адаптивное заполнение может определить, какой отступ должен использоваться для заполнения абзаца. Смотрите раздел Адаптивное заполнение.

В режиме Text TAB запускает функцию indent-relative (смотрите раздел Отступы), чтобы вам было удобно делать отступ как в предыдущей строке. Когда в предыдущей строке нет отступа, indent-relative запускает tab-to-tab-stop, которая использует устанавливаемые вами позиции табуляции (смотрите раздел Позиции табуляции).

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

Если вы делаете отступ в первой строке абзаца, вам нужно использовать режим Paragraph-Indent Text вместо режима Text. В этом режиме вам не обязательно ставить между абзацами пустые строки, потому что отступа в первой строке достаточно для начала нового абзаца; однако, абзацы, в которых каждая строка имеет отступ, не поддерживаются. Чтобы войти в этот режим, используйте M-x paragraph-indent-text-mode.

Режим Text и все режимы, основанные на нем, определяют M-TAB как команду ispell-complete-word, которая производит завершение части слова перед точкой в данном буфере, используя орфографический словарь как пространство возможных слов. Смотрите раздел Поиск и исправление орфографических ошибок.

Вход в режим Text запускает ловушку text-mode-hook. Другие основные режимы, родственные с режимом Text, также запускают эту ловушку и потом свои ловушки; к ним относятся режим Paragraph-Indent Text, режим Nroff, режим TeX, режим Outline и режим Mail. Функции ловушки text-mode-hook могут проверить значение major-mode, чтобы узнать, в какой из этих режимов вы на самом деле входите. Смотрите раздел Ловушки.

Режим Outline

Режим Outline -- это основной режим, очень похожий на режим Text, но предназначенный для редактирования структурированного текста. Он позволяет вам делать части текста временно невидимыми, так что вы можете видеть просто просмотреть структуру текста. Наберите M-x outline-mode, чтобы включить режим Outline в текущем буфере.

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

Команды редактирования, работающие со строками, такие как C-n и C-p, трактуют текст невидимой строки как часть предыдущей видимой. Уничтожение полной видимой строки, включая ограничивающий ее знак новой строки, на самом деле уничтожает вместе с ней все следующие невидимые строки.

Второстепенный режим Outline предоставляет те же команды, что и основной режим Outline, но вы можете использовать его совместно с другими основными режимами. Чтобы включить второстепенный режим Outline в текущем буфере, наберите M-x outline-minor-mode. Вы также можете указать это в тексте файла с помощью локальной переменной в форме `mode: outline-minor' (смотрите раздел Локальные переменные в файлах).

Основной режим, режим Outline, предоставляет особые привязки ключей на префиксе C-c. Второстепенный режим Outline предоставляет похожие привязки с C-c @ в качестве префикса; это нужно, чтобы уменьшить риск конфликта со специальными командами основного режима. (Используемый префикс управляется переменной outline-minor-mode-prefix.)

При входе в режим Outline запускается ловушка text-mode-hook сразу после ловушки outline-mode-hook (смотрите раздел Ловушки).

Формат схем текста

Режим Outline предполагает, что строки в буфере делятся на два типа: строки заголовка и строки тела. Строки заголовка представляет тему в схеме текста. Они начинаются с одной или более звездочек; число звездочек определяет глубину заголовка в структуре текста. Таким образом, строка заголовка с одной звездочкой -- это основная тема; все строки заголовка с двумя звездочками между этой строкой и следующей строкой заголовка с одной звездочкой являются ее подтемами и так далее. Любая строка, которая не является строкой заголовка, -- это строка тела. Строки тела относятся к предшествующей строке заголовка. Вот пример:

* Еда
Это тело, которое
говорит что-то о еде.

** Вкусная еда
Это тело заголовка второго уровня.

** Противная еда
Здесь тоже могло бы
быть тело на
нескольких строках.

*** Общепит

* Приют
Еще одна тема первого уровня со своей строкой заголовка.

Строка заголовка вместе со всеми последующими строками тела в совокупности называются вхождением. Строка заголовка вместе со всеми следующими более глубокими заголовками и их строками тела называется поддеревом.

Вы можете настроить критерий для различения строк заголовка, установив переменную outline-regexp. Любая строка, чье начало содержит совпадение с этим регулярным выражением, рассматривается как строка заголовка. Соответствия, которые начинаются с середины строки (не в начале), не рассматриваются. Длина текста соответствия определяет уровень заголовка: более длинное соответствие создает глубже вложенный уровень. Например, если программа форматирования имеет команды `@chapter', `@section' и `@subsection' для деления документа на главы и разделы, вы можете сделать эти строки воспринимаемыми в качестве строк заголовка, установив outline-regexp равной `"@chap\\|@\\(sub\\)*section"'. Обратите внимание на хитрость: слова `chapter' и `section' имеют равную длину, но определив регулярное выражение как совпадающее только с `chap', мы гарантируем, что длина текста, соответствующего заголовку главы, будет короче; таким образом, режим Outline будет знать, что разделы содержатся в главах. Это работает, если никакая другая команда не начинается с `@chap'.

Есть возможность изменить правило подсчета уровня строк заголовка, путем установки переменной outline-level. Значение outline-level должно быть функцией, не принимающей аргументов и возвращающей номер уровня текущего заголовка. Некоторые основные режимы, например режимы C, Nroff и Emacs Lisp, устанавливают эту переменную, чтобы ими можно было пользоваться со второстепенным режимом Outline.

Команды перемещения по структуре

Режим Outline предоставляет особые команды перемещения, которые передвигают назад и вперед по строкам заголовков.

C-c C-n
Передвинуть точку к следующей видимой строке заголовка (outline-next-visible-heading).
C-c C-p
Передвинуть точку к предыдущей видимой строке заголовка (outline-previous-visible-heading).
C-c C-f
Передвинуть точку к следующей видимой строке заголовка того же уровня, что и строка, на которой находится точка (outline-forward-same-level).
C-c C-b
Передвинуть точку к предыдущей видимой строке заголовка этого же уровня (outline-backward-same-level).
C-c C-u
Передвинуть точку назад к видимой строке заголовка более низкого уровня (outline-up-heading).

C-c C-n (outline-next-visible-heading) переходит вниз на следующую строку заголовка. C-c C-p (outline-previous-visible-heading) передвигает аналогично, но назад. Обе принимают числовой аргумент как счетчик повторов. Имена этих команд подчеркивают, что невидимые заголовки пропускаются, но это на самом деле не специальная особенность. Все команды редактирования, которые просматривают строки, игнорируют невидимые строки автоматически.

Более мощные команды движения понимают уровневую структуру заголовков. C-c C-f (outline-forward-same-level) и C-c C-b (outline-backward-same-level) передвигают от одной строки заголовка к другой видимой строке заголовка той же самой глубины в структуре. C-c C-u (outline-up-heading) передвигает назад к другому заголовку, который имеет меньшую глубину вложенности.

Команды управления видимостью структуры

Чтобы сделать строки видимыми или невидимыми, используются другие специальные команды режима Outline. Все их имена начинаются либо с hide, либо с show. Большинство из них составляют пары противоположностей. Они не могут быть отменены; вместо этого вы можете произвести отмену безотносительно к видимости текста. Изменение видимости строк просто не записывается механизмом отмены.

C-c C-t
Сделать все строки тела в буфере невидимыми (hide-body).
C-c C-a
Сделать все строки в буфере видимыми (show-all).
C-c C-d
Сделать все под этим заголовком невидимым, но не сам этот заголовок (hide-subtree).
C-c C-s
Сделать все под этим заголовком видимым, включая тело, подзаголовки и их тела (show-subtree).
C-c C-l
Сделать тело этой строки заголовка и все его подзаголовки невидимыми (hide-leaves).
C-c C-k
Сделать все подзаголовки этого заголовка видимыми на всех уровнях (show-branches).
C-c C-i
Сделать непосредственные подзаголовки (на один уровень вниз) этого заголовка видимыми (show-children).
C-c C-c
Сделать тело этого заголовка невидимым (hide-entry).
C-c C-e
Сделать тело этого заголовка видимым (show-entry).
C-c C-q
Скрыть все, кроме n верхних уровней строк заголовков (hide-sublevels).
C-c C-o
Скрыть все, кроме заголовка или тела, в котором находится точка, и заголовков, ведущих отсюда к верхнему уровню структуры (hide-other).

Две команды, которые строго противоположны, -- это C-c C-c (hide-entry) и C-c C-e (show-entry). Они применяются, когда точка расположена на заголовке, и относятся только к строкам тела этого заголовка. Подтемы и их тела не затрагиваются.

Две более мощные противоположности -- это C-c C-d (hide-subtree) и C-c C-s (show-subtree). Обе предполагают использование, когда точка находится на заголовке, и обе применяются ко всем строкам поддерева этого заголовка: его телу, всем его подзаголовкам, как прямым, так и косвенным, и всем их телам. Другими словами, поддерево содержит все, что следует за этим заголовком, вплоть до (но не включая) следующего заголовка того же самого или более высокого ранга.

Промежуточное состояние между видимым и невидимым поддеревом -- это когда видимы все подзаголовки, но не видимо ни одно тело. Для осуществления этого есть две команды, в зависимости от того, хотите ли вы скрыть тела или сделать видимыми подзаголовки. Это C-c C-l (hide-leaves) и C-c C-k (show-branches).

Команда C-c C-i (show-children) немного слабее show-branches. Она делает видимыми только непосредственные подзаголовки -- те, что на один уровень ниже. Более глубокие подзаголовки остаются невидимыми, если они были таковыми.

Две команды производят действие, охватывающее весь файл. C-c C-t (hide-body) делает все строки тела невидимыми, так что вы видите просто схему текста. C-c C-a (show-all) делает все строки видимыми. Эти команды могут рассматриваться как пара противоположных, хотя C-c C-a применяется не только к строкам тела.

Команда C-c C-q (hide-sublevels) скрывает все заголовки, кроме заголовков верхнего уровня. С числовым аргументом n, она скрывает все, кроме строк заголовков n верхних уровней.

Команда C-c C-o (hide-other) скрывает все, кроме заголовка или текста тела, в котором находится точка, и их родителей (заголовков, ведущих отсюда к верхнему уровню структуры).

Использование многоточий в конце видимых строк может быть отключено путем установки selective-display-ellipses равной nil. Тогда не будет явного указания на существование невидимых строк.

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

Просмотр одной схемы в нескольких видах

Вы можете просмотреть два вида одной схемы одновременно в разных окнах. Чтобы сделать так, вы должны создать косвенный буфер, используя M-x make-indirect-buffer. Первый аргумент этой команды -- это имя существующего буфера Outline, а второй аргумент -- это имя, которое будет использоваться для нового косвенного буфера. Смотрите раздел Косвенные буферы.

Когда косвенный буфер создан, вы можете показать его в окне, как обычно, с помощью C-x 4 b или других команд Emacs. Команды режима Outline для показа или скрывания частей текста действуют в каждом буфере независимо; в результате каждый буфер может иметь свой вид. Если вы хотите получить более двух видов одной и той же схемы, создайте дополнительные косвенные буферы.

Режим TeX

TeX -- это мощная программа компьютерного набора, написанная Дональдом Кнутом. Он также является свободным программным продуктом, как и GNU Emacs. LaTeX -- это упрощенный формат ввода для TeX, реализованный на макросах TeX. Он распространяется вместе с TeX. SliTeX -- это особая форма LaTeX.

В Emacs есть специальный режим TeX для редактирования входных TeX-файлов. Он предусматривает средства для проверки сбалансированности ограничителей и для вызова TeX для всего файла или его части.

Режим TeX имеет три варианта: режим Plain TeX, режим LaTeX и режим SliTeX (три этих основных режима отличающихся друг от друга лишь слегка). Они предназначены для редактирования трех различных входных форматов. Команда M-x tex-mode проверяет содержимое буфера, чтобы определить, не является ли это входом для LaTeX или SliTeX; если это так, она выбирает подходящий режим. Если содержимое файла не оказалось ни LaTeX, ни SliTeX, она выбирает режим TeX. Если содержимого файла оказалось недостаточно для определения формата, то используется режим, задаваемый переменной tex-default-mode.

Когда M-x tex-mode делает неправильное предположение, вы можете использовать команды M-x plain-tex-mode, M-x latex-mode и M-x slitex-mode для явного выбора конкретного варианта режима TeX.

Команды редактирования режима TeX

Здесь перечислены специальные команды, предусмотренные в режиме TeX для редактирования текста файла.

"
Вставить согласно контексту либо `"', либо `"', либо `"' (tex-insert-quote).
C-j
Вставить разрыв абзаца (два перевода строки) и проверить предыдущий абзац на несбалансированные фигурные скобки или знаки доллара (tex-terminate-paragraph).
M-x tex-validate-region
Проверить каждый абзац в буфере на несбалансированные фигурные скобки или знаки доллара.
C-c {
Вставить `{}' и расположить точку между ними (tex-insert-braces).
C-c }
Перейти вперед за следующую непарную закрывающую фигурную скобку (up-list).

Знак `"' обычно не используется в TeX; мы используем `"', чтобы открыть кавычки, и `"', чтобы закрыть. Чтобы облегчить редактирование с учетом этого соглащения о форматировании, режим TeX заменяет обычное значение клавиши " на команду, вставляющую пару одиночных простых или обратных кавычек (tex-insert-quote). Если говорить точно, эта команда вставляет `"' после пропуска или открывающей фигурной скобки, `"' после обратной косой черты и `"' после всех остальных знаков.

Если вам нужен знак `"' сам по себе в необычном контексте, используйте для его вставки C-q. Также, " c числовым аргументом всегда вставляет указанное число знаков `"'. Вы можете выключить средство раскрытия ", убрав эту привязку из локальной раскладки (смотрите раздел Настройка привязок ключей).

Знак `$' имеет в режиме TeX особый синтаксический код, который перетендует на понимание способа, которым ограничители математической моды TeX соответствуют друг другу. Когда вы вводите `$', который используется для выхода из математической моды, на секунду отображается позиция парного `$', который вводил в математическую моду. Это то же самое средство, которое показывает открывающую фигурную скобку, соответствующую вставленной закрывающей. Однако, нет способа узнать, является ли `$' входом или выходом из математической моды; поэтому когда вы вводите `$', который входит в математическую моду, показывается позиция предыдущего `$', как если бы она была они составляли пару, даже если фактически они не относятся друг к другу.

TeX использует фигурные скобки как ограничители, которые обязаны составлять пары. Некоторые пользователи предпочитают поддерживать фигурные скобки все время сбалансированными, а не вставлять их по отдельности. Используйте C-c { (tex-insert-braces), чтобы вставить пару фигурных скобок. Эта команда оставляет точку между двумя этими скобками, чтобы вы могли вставить текст внутрь. Потом используйте команду C-c } (up-list), чтобы перейти вперед через закрывающую фигурную скобку.

Существуют две команды для контроля соответствия фигурных скобок. C-j (tex-terminate-paragraph) проверяет абзац перед точкой и вставляет два ограничителя новой строки для начала нового абзаца. Если будет найдено какое-то несоответствие, она напечатает сообщение в эхо-области. M-x tex-validate-region проверяет область, абзац за абзацем. Ошибки перечисляются в буфере `*Occur*', и вы можете использовать в нем C-c C-c или Mouse-2, чтобы перейти к конкретному несоответствию.

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

Команды редактирования режима LaTeX

Режим LaTeX и его вариация, режим SliTeX, предоставляют несколько дополнительных возможностей, не относящихся к plain TeX.

C-c C-o
Вставляет `\begin' и `\end' для блока LaTeX и помещает точку на строке между ними (tex-latex-block).
C-c C-e
Закрывает самый внутренний еще не закрытый блок LaTeX (tex-close-latex-block).

В LaTeX для группировки блоков текста используются команды `\begin' и `\end'. Чтобы вставить `\begin' и парную `\end' (на новой строке после `\begin'), используйте C-c C-o (tex-latex-block). Между двумя этими строками вставляется пустая строка, и на ней оставляется точка. При вводе типа блока вы можете использовать завершение; чтобы задать имена дополнительных типов блоков, установите переменную latex-block-names. Например, добавить `theorem', `corollary' и `proof' можно таким образом:

(setq latex-block-names '("theorem" "corollary" "proof"))

Во входном тексте LaTeX команды `\begin' и `\end' должны соответствовать друг другу. Вы можете использовать C-c C-e (tex-close-latex-block), чтобы автоматически вставить `\end', соответствующую последней `\begin', оставшей без пары. Эта команда делает для `\end' отступ в соответствии с ее `\begin'. Если точка находится в начале строки, она вставляет после `\end' новую строку,

Команды печати для TeX

Вы можете вызвать TeX как подчиненный процесс Emacs либо для всего содержимого буфера, либо только на область, за один раз. Запуск TeX таким способом только в одной главе дает удобный метод увидеть, как выглядят ваши изменения, не тратя время на форматирование всего файла.

C-c C-r
Вызвать TeX для текущей области вместе с заголовоком буфера (tex-region).
C-c C-b
Вызывать TeX для всего текущего буфера (tex-buffer).
C-c TAB
Вызывать BibTeX для текущего файла (tex-bibtex-file).
C-c C-f
Вызывать TeX для текущего файла (tex-file).
C-c C-l
Переместить центр окна, показывающего вывод подчиненного TeX, чтобы можно было увидеть последнюю строку (tex-recenter-output-buffer).
C-c C-k
Уничтожить подпроцесс TeX (tex-kill-job).
C-c C-p
Печатать вывод из последней команды C-c C-r, C-c C-b или C-c C-f (tex-print).
C-c C-v
Запустить предварительный просмотр вывода последней команды C-c C-r, C-c C-b или C-c C-f (tex-view).
C-c C-q
Показать очередь принтера (tex-show-print-queue).

Вы можете пропустить текущий буфер через подчиненный TeX с помощью C-c C-b (tex-buffer). Отформатированный вывод появляется во временном файле; чтобы напечатать его, наберите C-c C-p (tex-print). Потом вы можете использовать C-c C-q (tex-show-printer-queue), чтобы увидеть, как скоро ваш вывод будет напечатан. Если ваш терминал может показывать выходные файлы TeX, вы можете просмотреть вывод на терминале с помощью команды C-c C-v (tex-view).

Вы можете указать каталог для запуска TeX, установив переменную tex-directory. Значением по умолчанию является ".". Если переменная среды `TEXINPUTS' содержит относительные имена каталогов, или ваши файлы содержат команды `\input' с относительными именами, то tex-directory должна быть равна ".", или вы получите неправильные результаты. В противном случае, можно без опасения задать какой-то другой каталог, например, "/tmp".

Если вы хотите указать, какие команды оболочки нужно использовать в подчиненном процессе TeX, вы можете сделать это установкой значений переменных tex-run-command, latex-run-command, slitex-run-command, tex-dvi-print-command, tex-dvi-view-command и tex-show-queue-command. Вы обязаны установить значение tex-dvi-view-command для вашего конкретного терминала; эта переменная не имеет значения по умолчанию. Другие переменные имеют значения по умолчанию, которые могут подойти (а могут и не подойти) для вашей системы.

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

(setq tex-dvi-print-command "dvips -f * | lpr")

Терминальный вывод TeX, включающий все сообщения об ошибках, появляется в буфере с именем `*tex-shell*'. Если TeX получил ошибку, вы можете переключиться в этот буфер и подать ему какой-то ввод (это работает как в режиме Shell, смотрите раздел Интерактивная подчиненная оболочка). Без переключения в этот буфер, вы можете прокрутить его с помощью C-c C-l так, что последняя строчка в нем станет видимой.

Наберите C-c C-k (tex-kill-job), чтобы уничтожить процесс TeX, если вы понимаете, что его вывод уже бесполезен. Использование C-c C-b или C-c C-r также уничтожает любой работающий процесс TeX.

Вы также можете пропустить произвольную область через подчиненный TeX, набрав C-c C-r (tex-region). Однако, это ненадежно, потому что большинство входных файлов TeX содержат в начале команды, устанавливающие какие-то параметры и определяющие макросы, без которых дальнейшая часть файла не отформатируется правильно. Для того, чтобы решить эту проблему, C-c C-r позволяет вам обозначить часть файла как содержащую важные команды; она вставляется перед заданной областью как часть ввода TeX. Обозначенная часть файла называется заголовком.

Чтобы обозначить границы заголовка в режиме Plain TeX, вы вставляете в файл две специальные строки. Вставьте `%**start of header' перед заголовком и `%*end of header' после него. Обе должны появиться полностью на одной строке, но перед ними или после них допускается другой текст. Строки, содержащие эти фразы, включаются в заголовок. Если `%**start of header' не появится в пределах первых 100 строк буфера, C-c C-r предполагает, что заголовка нет.

В режиме LaTeX заголовок начинается с команды `\documentstyle' и заканчивается командой `\begin{document}'. LaTeX требует, чтобы вы использовали эти команды в любом случае, так что для определения заголовка не требуется делать ничего особенного.

Команды (tex-buffer) и (tex-region) делают свою работу во временном каталоге, и им недоступны вспомогательные файлы, нужные TeX для перекрестных ссылок; эти команды в общем случае не подходят для обработки окончательной копии, в которой все перекрестные ссылки должны быть правильными.

Когда вам нужны вспомогательные файлы для перекрестных ссылок, используйте C-c C-f (tex-file), которая запускает TeX для файла текущего буфера в каталоге этого файла. Перед запуском TeX она предлагает сохранить все измененные буферы. В общем случае, вы должны использовать (tex-file) дважды, чтобы получить правильные перекрестные ссылки.

Значение переменной tex-start-options-string задает ключи для запуска TeX. Значение по умолчанию велит TeX работать в безостановочном режиме. Чтобы запустить TeX интерактивно, установите эту переменную равной "".

Большие документы TeX часто разбивают на несколько файлов -- один главный плюс подфайлы. Запуск TeX для подфайла как правило не сработает; вы должны запускать его для главного файла. Чтобы сделать tex-file полезной при редактировании подфайла, вы можете установить переменную tex-main-file равной имени главного файла. Тогда tex-file запустит TeX для этого файла.

Наиболее удобный способ использования tex-main-file -- указать ее в перечне локальных переменных в каждом из подфайлов. Смотрите раздел Локальные переменные в файлах.

С LaTeX-файлами вы можете использовать BibTeX, чтобы обработать вспомогательные файлы для файла текущего буфера. BibTeX находит библиографические цитаты в базе данных и подготавливает процитированные ссылки для раздела библиграфии. Команда C-c TAB (tex-bibtex-file) запускает команду оболочки (tex-bibtex-command), чтобы получить `.bbl'-файл для файла текущего буфера. Вообще говоря, вам нужно сначала сделать C-c C-f (tex-file), чтобы получить `.aux'-файл, затем сделать C-c TAB (tex-bibtex-file) и после этого повторить C-c C-f (tex-file) еще раз, чтобы сгенерировать правильные перекрестные ссылки.

При входе в любую разновидность режима TeX запускаюся ловушки text-mode-hook и tex-mode-hook. Затем запускаюся plain-tex-mode-hook или latex-mode-hook, что подходит. Для SliTeX-файлов запускается ловушка slitex-mode-hook. При старте оболочки TeX запускается tex-shell-hook. Смотрите раздел Ловушки.

Режим Nroff

Режим Nroff -- это режим, похожий на режим Text, но модифицированный для управления командами nroff, присутствующими в тексте. Вызовите M-x nroff-mode, чтобы войти в этот режим. Он отличается от режима Text только несколькими возможностями. Все строки команд nroff считаются разделителем абзацев, так что заполнение никогда не исказит команды nroff. Страницы разделяются командами `.bp'. Комментарии начинаются с обратной косой черты и двойных кавычек. Также предусмотрены три специальные команды, которых нет в режиме Text:

M-n
Перейти на начало следующей строки, которая не является командой nroff (forward-text-line). Аргумент служит счетчиком повторов.
M-p
Похожа на M-n, но сдвигает вверх (backward-text-line).
M-?
Напечатать в эхо-области число текстовых строк (строк, которые не являются командами nroff) в текущей области (count-text-lines).

Другое свойство режима Nroff -- это то, что вы можете включать режим Electric Nroff. Это второстепенный режим, который вы можете включать или выключать при помощи M-x electric-nroff-mode (смотрите раздел Второстепенные режимы). Если этот режим включен, то каждый раз, когда вы набираете RET для окончания строки, которая содержит команду nroff, открывающую некоторый вид группы, в следующую строку автоматически вставляется соответствующая закрывающая группу команда nroff. Например, если вы находитесь в начале строки и наберете . ( b RET, то в новую строку, следующую за точкой, будет вставлена соответствующая команда `.)b'.

Если с режимом Nroff вы используете второстепенный режим Outline (смотрите раздел Режим Outline), строками заголовков будут строки вида `.H' с последующим числом (уровнем заголовка).

Вход в режим Nroff запускает ловушку text-mode-hook, а затем ловушку nroff-mode-hook (смотрите раздел Ловушки).

Редактирование форматированного текста

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

Режим Enriched -- это второстепенный режим (смотрите раздел Второстепенные режимы). Как правило он используется вместе с режимом Text (смотрите раздел Режим Text). Однако, вы можете также использовать его и с другими основными режимами, такими как режим Outline и режим Paragraph-Indent Text.

Потенциально Emacs может сохранять файлы с форматированным текстом во многих форматах. На текущий момент реализован только один формат: text/enriched, который определяется протоколом MIME. Смотрите раздел `Format Conversion' в the Emacs Lisp Reference Manual, для получения подробностей о том, как Emacs распознает и пребразует форматы файлов.

Дистрибутив Emacs содержит файл с форматированным текстом, который может служить примером. Он называется `etc/enriched.doc'. Этот файл содержит образцы, иллюстрирующие все возможности, описанные в этом разделе. В нем также есть перечень идей для будущих улучшений.

Запрос на редактирование форматированного текста

Когда вы обращаетесь к файлу, который был сохранен в формате text/enriched, Emacs автоматически преобразует информацию о форматировании из этого файла во внутренний формат Emacs (свойства текста) и включает режим Enriched.

Чтобы создать новый файл с форматированным текстом, обратитесь сначала к несуществующему файлу, а перед тем как начать редактирование наберите M-x enriched-mode. Эта команда включает режим Enriched. Делайте это до того, как вы начнете вставлять текст, чтобы вставляемый текст наверняка обрабатывался правильно.

В более общем виде, команда enriched-mode включает режим Enriched, если он был выключен, и выключает его, если он был включен. Запущенная с числовым аргументом, эта команда включает режим Enriched, если аргумент положителен, и выключает в противном случае.

Когда вы сохраняете буфер при задействованном режиме Enriched, Emacs автоматически преобразует текст к формату text/enriched во время записи в файл. Когда вы снова обратитесь к этому файлу, Emacs автоматически распознает формат, преобразует текст обратно и снова включит режим Enriched.

Обычно после обращения к файлу в формате text/enriched, Emacs перезаполняет каждый абзац так, чтобы он умещался по заданному правому полю. Вы можете выключить это перезаполнение, чтобы сэкономить время, установив переменную enriched-fill-after-visiting в значение nil или ask.

Однако, при обращении к файлу, записанному в формате Enriched, нет нужды в перезаполнении, поскольку Emacs сохраняет установки правого поля вместе с текстом.

Делая добавления к enriched-translations, вы можете вносить пометки для сохранения дополнительных свойств текста, которые Emacs обычно не сохраняет. Заметьте, что стандарт text/enriched требует, чтобы имена всех нестандартных пометок начинались с `x-', например `x-read-only'. Это позволяет быть уверенным в том, что они не будут конфликтовать со стандартными пометками, добавленными позже.

Жесткие и гибкие переводы строк

Emacs различает в форматированном тексте два разных вида переводов строк: жесткие и гибкие.

Жесткие переводы строк используются для разделения абзацев, или пунктов перечня, или везде, где строка должна всегда разрываться вне зависимости от полей. Команды RET (newline) и C-o (open-line) вставляют жесткие переводы строк.

Гибкие переводы строк применяются для того, чтобы уместить текст в пределы полей. Все команды заполнения, включая Auto Fill, вставляют гибкие переводы строк, и они удаляют всегда только гибкие переводы строк.

Хотя жесткие и гибкие переводы строк выглядят одинаково, важно помнить об их различии. Не используйте RET, чтобы разорвать строку в середине заполненного абзаца, или иначе вы получите жесткие переводы строк, которые послужат барьером последующему заполнению. Вместо этого позвольте разбивать строки режиму Auto Fill, чтобы при изменении текста или полей Emacs мог правильно перезаполнить строки. Смотрите раздел Режим Auto Fill.

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

Редактирование информации о формате

Есть два способа изменить информацию о формате для файла с форматированным текстом: командами клавиатуры или с помощью мыши.

Простейший способ добавить свойства к вашему документу --- воспользоваться меню Text Properties. Вы можете попасть в это меню двумя путями: из меню Edit в полоске меню или с помощью C-mouse-2 (прижмите клавишу CTRL и нажмите среднюю кнопку мыши).

Большинство пунктов из меню Text Properties ведут к другим подменю. Подменю описаны в последующих разделах. Некоторые пункты запускают команды непосредственно:

Remove Properties
Удаляет из области все свойства текста, с которыми работает меню Text Properties (facemenu-remove-props).
Remove All
Удаляет все свойства текста из области (facemenu-remove-all).
List Properties
Перечисляет все свойства текста для знака после точки (list-text-properties-at).
Display Faces
Показывает перечень всех определенных начертаний.
Display Colors
Показывает перечень всех определенных цветов.

Начертания в форматированном тексте

В подменю Faces перечислены разные начертания Emacs, включая bold, italic и underline. Выбор одного из них добавляет это начертание к области. Смотрите раздел Использование разных начертаний. Вы также можете задать начертания с помощью таких команд клавиатуры:

M-g d
Говорит, что область или следующий вставленный знак должны появиться в начертании default (facemenu-set-default).
M-g b
Говорит, что область или следующий вставленный знак должны появиться в начертании bold (facemenu-set-bold).
M-g i
Говорит, что область или следующий вставленный знак должны появиться в начертании italic (facemenu-set-italic).
M-g l
Говорит, что область или следующий вставленный знак должны появиться в начертании bold-italic (facemenu-set-bold-italic).
M-g u
Говорит, что область или следующий вставленный знак должны появиться в начертании underline (facemenu-set-underline).
M-g o начертание RET
Говорит, что область или следующий вставленный знак должны появиться в заданном начертании (facemenu-set-face).

Если вы используете эти команды с префиксным аргументом -- или, в режиме Transient Mark, если область не активна -- то они задают начертание для следующего самовставляющегося ввода. Смотрите раздел Режим Transient Mark. Это относится как к командам клавиатуры, так и к командам меню.

Режим Enriched определяет два дополнительных начертания: fixed и excerpt. Они соответствуют кодам, используемым в формате файлов text/enriched.

Начертание excerpt предназначено для цитат. Оно совпадает с начертанием italic, если вы его не перенастроили (смотрите раздел Настройка начертаний).

Начертание fixed означает "Использовать для этой части текста равноширинный шрифт". В настоящее время Emacs поддерживает только равноширинные шрифты; следовательно, пометка fixed пока не так необходима. Однако, в будущих версиях Emacs мы планируем реализовать поддержку шрифтов переменной ширины, и другие системы, способные отображать формат text/enriched, могут не использовать по умолчанию равноширинный шрифт. Поэтому если вы хотите, чтобы какая-то часть текста появлялась именно с равноширинным шрифтом, вам следут задать для этой части начертание fixed.

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

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

Цвета в форматированном тексте

Вы можете указать цвета букв и фона для фрагментов текста. Есть меню для задания цвета текста и меню для задания цвета фона. Оба меню цветов перечисляют все цвета, которые вы использовали в режиме Enriched в текущем сеансе Emacs.

Если вы задаете цвет с префиксным аргументом -- или, в режиме Transient Mark, если область не активна -- то этот цвет применяется для самовставляемого ввода. Смотрите раздел Режим Transient Mark. В противном случае эта команда относится к области.

Оба меню цветов содержат дополнительный пункт: `Other'. Вы можете использовать этот пункт для задания цвета, который не перечислен в меню; имя цвета считывается в минибуфере. Чтобы просмотреть перечень доступных цветов и их имена, используйте пункт `Display Colors' в меню Text Properties (смотрите раздел Редактирование информации о формате).

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

Для задания цветов нет привязок ключей, но вы можете указывать их при помощи расширенных команд M-x facemenu-set-foreground и M-x facemenu-set-background. Обе эти команды считывают имя цвета в минибуфере.

Отступы в форматированном тексте

При редактировании форматированного текста вы можете задать различные величины отступа для правого или левого края целого абзаца или его части. Указанные вам поля автоматически учитываются команды Emacs для заполнения (смотрите раздел Заполнение текста) и разрыва строк.

Подменю Indentation предоставляет удобный интерфейс для указания этих свойств. Оно содержит четыре пункта:

Indent More
Увеличивает отступ области на 4 столбца (increase-left-margin). В режиме Enriched эта команда также доступна на C-x TAB; если вы предоставите числовой аргумент, то он говорит, сколько столбцов нужно добавить к полю (отрицательный аргумент уменьшает число столбцов).
Indent Less
Удаляет 4 столбца отступа из области.
Indent Right More
Сужает область, делая с правого края отступ в 4 столбца.
Indent Right Less
Удаляет 4 столбца отступа с правого края.

Вы можете использовать эти команды несколько раз для увеличения или уменьшения величины отступа.

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

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

Отступ в первой строке абзаца делается проще. Установите поле для всего абзаца там, где вы хотели бы видеть его для тела абзаца, а затем увеличьте отступ первой строки, добавив пробелы или знаки табуляции.

Иногда в результате редактирования заполнение абзаца сбивается --- части абзаца могут выйти за левые или правые поля. Когда такое происходит, воспользуйтесь M-q (fill-paragraph), чтобы перезаполнить этот абзац.

Число столбцов, которые добавляют или удаляют из отступа эти команды, задается переменной standard-indent. Ее значение равно по умолчанию четырем. Общее правое поле, принимаемое по умолчанию для режима Enriched, контролируется переменной fill-column, как обычно.

Префикс заполнения, если он задан, действует совместно с указанным отступом абзаца: C-x . не включает пропуск из указанного отступа в новое значение префикса заполнения, а команды заполнения ищут префикс заполнения в каждой строке после отступа. Смотрите раздел Префикс заполнения.

Выравнивание в форматированном тексте

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

Подменю Justification предоставляет удобный интерфейс для указания стиля выравнивания. Оно содержит пять пунктов:

Flush Left
Это наиболее распространенный стиль выравнивания (по крайней мере для английского языка). Строки выравниваются по левому полю, но оставляются неровными с правого края.
Flush Right
Это выравнивает каждую строку по правому полю. Если необходимо, слева добавляются пробелы и знаки табуляции, чтобы правые концы строк выстраивались в линию.
Full
Это выравнивает текст по обоим концам строк. Выровненный таким образом текст смотрится красиво в печатной книге, где все пробелы можно настроить одинаково, но смотрится не так хорошо с равноширинным шрифтом на экране. Возможно, будущие версии Emacs позволят настраивать ширину пробелов в строке, чтобы достичь элегантного выравнивания.
Center
Это центрирует каждую строку между текущими полями.
None
Это выключает заполнение полностью. Каждая строка будет оставаться такой, как вы ее написали; функции заполнения и автоматического заполнения не будут иметь эффекта в тексте с такой установкой. Вы все же можете делать отступ слева. В незаполненных областях все переводы строк считаются жесткими (смотрите раздел Жесткие и гибкие переводы строк) .

В режиме Enriched вы также можете задавать стиль выравнивания с клавиатуры, используя префиксный знак M-j:

M-j c
M-S
Центрирует область (set-justification-center).
M-j u
Делает область невыровненной (set-justification-none).
M-j l
Выравнивает область слева (set-justification-left).
M-j r
Выравнивает область справа (set-justification-right).
M-j f
Выравнивает область полностью (set-justification-full).

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

Стиль выравнивания по умолчанию задается переменной default-justification. Ее значением должен быть один из символов left, right, full, center или none.

Установка других свойств текста

Меню Other Properties позволяет вам добавлять или удалять три других полезных свойства текста: read-only, invisible и intangible. Свойство intangible запрещает движение точки внутри этого текста, свойство текста invisible делает текст невидимым, а свойство read-only запрещает изменение текста.

Для добавления каждого из этих особых свойств к области есть пункт меню. Последний пункт меню, `Remove Special', удаляет все эти особые свойства из текста области.

На данный момент свойства invisible и intangible не сохраняются в формате text/enriched. Свойство read-only сохраняется, но оно не входит в стандарт формата text/enriched, поэтому другие редакторы могут его игнорировать.

Принудительное включение режима Enriched

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

  • Когда вы обращаетесь к файлу, который был создан каким-то другим редактором, Emacs может не распознать этот файл как отфоратированный в text/enriched. В таком случае, когда вы обращаетесь к файлу, вы увидите команды форматирования, а не форматированный текст. Наберите M-x format-decode-buffer, чтобы перевести их.
  • Когда вы вставляете файл в буфер, а не обращаетесь к нему. Emacs делает необходимые преобразования вставляемого текста, но не включает режим Enriched. Если вы хотите сделать это, введите M-x enriched-mode.

Команда format-decode-buffer переводит текст из различных форматов во внутренний формат Emacs. Она просит вас указать формат, из которого делать преобразование; однако, как правило вы можете просто нажать RET, что велит Emacs предположить формат самому.

Если вы хотите просмотреть на текст в text/enriched-файле буквально, как последовательность знаков, а не как форматированный текст, воспользуйтесь командой M-x find-file-literally. Она обращается к файлу, как и find-file, но не производит преобразование формата. Она также подавляет преобразование кодов знаков (смотрите раздел Системы кодирования) и автоматическую распаковку (смотрите раздел Доступ к сжатым файлам). Чтобы выключить преобразование формата, но позволить перевод кодов знаков и/или автоматическую распаковку, если она нужна, используйте format-find-file с подходящими аргументами.

Редактирование программ

В Emacs есть много команд, предназначенных для понимания синтаксиса языков программирования, таких как Лисп и Си. Эти команды могут:

  • Передвигать или уничтожать сбалансированные выражения или s-выражения (смотрите раздел Списки и s-выражения).
  • Передвигать через или помечать выражения верхнего уровня --- определения функций в Лиспе, функции в Си (смотрите раздел Определения функций).
  • Показывать, как сбалансированы круглые скобки (смотрите раздел Автоматическое отображение парных скобок).
  • Вставлять, уничтожать или выравнивать комментарии (смотрите раздел Управление комментариями).
  • Следовать обычным соглашениям об отступах, принятых в языке (смотрите раздел Отступы в программах).

Команды для слов, предложений и абзацев очень удобны при редактировании программ, даже хотя их традиционным применением является редактирование текстов на естественном языке. Большинство символов содержат слова (смотрите раздел Слова); предложения могут быть найдены в строках или комментариях (смотрите раздел Предложения). Абзацы так таковые не присутствуют в коде, но команды работы с абзацами тем не менее полезны, так как основные режимы для языков программирования определяют абзацы как куски текста, начинающиеся и заканчивающиеся пустыми строками (смотрите раздел Абзацы). Разумное использование пустых строк для улучшения читаемости программы будет также предоставлять командам, оперрирующим с абзацами, интересные куски текста для работы.

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

Основные режимы для языков программирования

Emacs также имеет основные режимы для языков программирования Лисп, Scheme (вариант Лиспа), Awk, Си, Си++, Фортран, Icon, Java, Objective-C, Паскаль, Perl, Pike, CORBA IDL, и Tcl. Есть также основной режим для Make-файлов, называемый режимом Makefile. Второй альтернативный режим для Perl называется режимом CPerl.

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

Есть несколько разновидностей режима Lisp, которые отличаются способом взаимодействия с исполнением Лиспа. Смотрите раздел Вычисление выражений Emacs-Lisp.

Каждый из основных режимов для языка программирования определяет ключ TAB для запуска функции, делающей отступ, которой известны соглашения об отступах для этого языка и которая соответственно изменяет отступ текущей строки. Например, в режиме С, TAB привязан к c-indent-line. C-j обычно определяется так, чтобы делать RET, за которым следует TAB; таким образом, эта команда тоже делает отступ в режимозависимом виде.

В большинстве языков программирования отступ часто изменяется от строки к строке. Следовательно, основные режимы для таких языков перепривязывают DEL так, чтобы он трактовал знак табуляции как эквивалентное количество пробелов (используя команду backward-delete-char-untabify). Это позволяет стирать отступ по одному столбцу, не заботясь о том, сделан ли он с помощью пробелов или знаков табуляции. Чтобы удалить в этих режимах знак табуляции перед точкой, используйте C-b C-d.

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

Включение основного режима запускает обычную ловушку, называемую ловушкой режима, которая является значением лисповской переменной. Для каждого основного режима есть своя ловушка, и имя этой ловушки всегда составляется из имени команды, запускающей этот режим, и слова `-hook'. Например, включение режима С запускает ловушку c-mode-hook, тогда как включение режима Lisp запускает ловушку lisp-mode-hook. Смотрите раздел Ловушки.

Списки и s-выражения

По соглашению, ключи Emacs для работы со сбалансированными выражениями обычно являются Control-Meta-знаками. По действию они стремятся походить на свои Control- и Meta-аналоги. Обычно считается, что эти команды имеют отношение к выражениям в языках программирования, но они могут оказаться полезными в любом языке, в котором существует какая-либо разновидность круглых скобок (включая естественные языки).

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

Другие команды имеют дело с выражениями или s-выражениями. Слово `s-выражение' происходит от s-expression, старого термина для выражения в Лиспе. Но в Emacs понятие `s-выражение' не ограничивается Лиспом. Оно обозначает выражение в любом языке, на котором написана ваша программа. Каждый язык программирования имеет свой собственный основной режим, который настраивает синтаксические таблицы так, что выражения на этом языке рассматриваются как s-выражения.

Обычно s-выражение включает в себя символы, числа и строковые константы, а также все, что содержится в круглых, квадратных или фигурных скобках.

В языках, которые используют префиксные и инфиксные операторы, таких как Си, не все выражения могут быть s-выражениями. Например, режим С не распознает `foo + bar' как s-выражение, несмотря на то, что это является выражением Си; он распознает `foo' как одно s-выражение и `bar' как другое, со знаком `+' в качестве пунктуации между ними. Это фундаментальная неоднозначность: как `foo + bar', так и `foo' являются законными кандидатами на s-выражение, через которое нужно передвинуться, если точка находится на `f'. Заметьте, что `(foo + bar)' -- это единое s-выражение в режиме С.

Некоторые языки имеют туманную форму синтаксиса выражений, и никто не позаботился о том, чтобы Emacs его правильно понимал.

Команды работы со списками и s-выражениями

C-M-f
Передвинуться вперед через s-выражение (forward-sexp).
C-M-b
Передвинуться назад через s-выражение (backward-sexp).
C-M-k
Уничтожить s-выражение вперед (kill-sexp).
C-M-DEL
Уничтожить s-выражение назад (backward-kill-sexp).
C-M-u
Перейти вверх и назад по структуре списка (backward-up-list).
C-M-d
Перейти вниз и вперед по структуре списка (down-list).
C-M-n
Передвинуться вперед через список (forward-list).
C-M-p
Передвинуться назад через список (backward-list).
C-M-t
Переставить выражения (transpose-sexps).
C-M-@
Поставить метку после следующего выражения (mark-sexp).

Чтобы передвинуться вперед через s-выражение, используйте C-M-f (forward-sexp). Если первая значащая литера после точки -- это открывающий ограничитель (`(' в Лиспе; `(', `[' или `{' в Си), то C-M-f передвигает за парный закрывающий ограничитель. Если этот знак начинает символ, строку или число, то C-M-f передвигает через них.

Команда C-M-b (backward-sexp) двигает назад через s-выражение. Подробные правила похожи на описанные выше для C-M-f, но с противоположным направлением. Если перед s-выражением стоят какие-либо префиксные символы (в Лиспе это одиночная кавычка, обратная кавычка и запятая), то C-M-b переходит и через них. Команды для s-выражений передвигаются через комментарии, как это делается для пропусков в большинстве режимов.

C-M-f или C-M-b с аргументом повторяют операцию заданное число раз; с отрицательным аргументом, они перемещают в противоположном направлении.

Уничтожение целого s-выражения может быть сделано при помощи C-M-k (kill-sexp) или C-M-DEL (backward-kill-sexp). C-M-k уничтожает знаки, через которые передвинула бы C-M-f, а C-M-DEL уничтожает знаки, через которые передвинула бы C-M-b.

Команды для списков передвигают через списки, как и команды s-выражений, но легко перескакивают через любое количество других видов s-выражений (символы, строки и так далее). Это C-M-n (forward-list) и C-M-p (backward-list). Они полезны в основном тем, что обычно игнорируют комментарии (так как комментарии как правило не содержат никаких списков).

C-M-n и C-M-p остаются на одном уровне скобок, когда это возможно. Чтобы передвинуться вверх на один (или n) уровень, используйте C-M-u (backward-up-list). C-M-u двигает назад и вверх мимо одного непарного открывающего ограничителя. Положительный аргумент служит счетчиком повторов; отрицательный аргумент меняет направление движения и также запрашивает повторение, таким образом, в этом случае движение происходит вперед и вверх на один или больше уровней.

Чтобы передвинуться вниз по структуре списков, используйте C-M-d (down-list). В режиме Lisp, где `(' -- это единственный открывающий ограничитель, это почти то же самое, что и поиск `('. Количество уровней скобок, на какое следует спуститься, определяет аргумент.

Команда C-M-t (transpose-sexp), которая переносит предыдущее s-выражение через следующее, отчасти кажется случайно сюда попавшей, но тем не менее она очень удобна. Аргумент служит для подсчета числа повторов, а отрицательный аргумент перетаскивает выражение в обратном направлении (таким образом отменяя действие C-M-t с положительным аргументом). Аргумент, равный нулю, вместо того чтобы ничего не делать, переставляет местами s-выражения, кончающиеся после точки и метки.

Чтобы установить область вокруг следующего s-выражения в буфере, используйте C-M-@ (mark-sexp), которая ставит пометку в то же самое место, куда должна бы была передвинуться C-M-f. C-M-@ воспринимает аргумент так же, как C-M-f. В частности, отрицательный аргумент удобен для установки метки в начале предыдущего s-выражения.

Понимание синтаксиса командами для списков и s-выражений полностью управляется синтаксической таблицей. Любой знак может быть объявлен, например, открывающим ограничителем и действовать как открывающая круглая скобка. Смотрите раздел Синтаксическая таблица.

Определения функций

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

C-M-a
Передвинуться к началу текущего или предшествующего определения функции (beginning-of-defun).
C-M-e
Передвинуться в конец текущего или следующего определения функции (end-of-defun).
C-M-h
Пометить область вокруг всего текущего или следующего определения функции (mark-defun).

Команды движения к началу или концу текущего определения функции --- это C-M-a (beginning-of-defun) и C-M-e (end-of-defun).

Если вы пожелаете произвести какие-то действия над текущим определением функции, используйте C-M-h (mark-defun), которая ставит точку в начале и метку в конце текущего или следующего определения функции. Например, это простейший способ получить готовое для перемещения в другое место определение функции. В режиме С, C-M-h запускает функцию c-mark-function, которая почти эквивалентна mark-defun; различие состоит в том, что она переходит через объявления аргументов, имя функции и тип возвращаемых данных, так что функция Си оказывается внутри области полностью. Смотрите раздел Команды для пометки текстуальных объектов.

Emacs предполагает, что любые открывающие скобки, найденные в самом левом столбце, -- это начало определения функции. Поэтому никогда не ставьте открывающие скобки с левого края в Лисп-файле, если они не являются началом списка верхнего уровня. Никогда не ставьте открывающую фигурную скобку или другой открывающий ограничитель в начале строки в программе на Си, если только они не начинают тело функции. Большинство возможных проблем возникает, когда вы хотите поставить открывающий ограничитель в начале строки внутри строковой константы. Чтобы избежать неприятностей, поставьте экранирующий знак (`\' в Си и Emacs Lisp, `/' в некоторых других диалектах Лиспа) перед открывающим ограничителем. Это не повлияет на содержимое строки.

В очень далеком прошлом оригинальный Emacs находил определения функций, двигаясь вверх по уровням скобок до тех пор, пока не доходил до уровня, от которого некуда было идти дальше. Это всегда требовало просмотра полного пути обратно до начала буфера, даже для маленькой функции. Чтобы ускорить эту операцию, Emacs был изменен, и теперь он предполагает, что любой знак `(' (или любой другой, приписанный к синтаксическому классу открывающего ограничителя) на левой границе строки -- это начало определения функций. Эта эвристика почти всегда правильна и позволяет избежать ресурсоемкого просмотра; однако, она требует выполнения описанных выше соглашений.

Отступы в программах

Наилучший способ сохранить правильность отступов в программе -- это использовать Emacs для создания новых отступов по мере внесения изменений. В Emacs есть команды для создания правильного отступа одиночной строки, заданного числа строк или всех строк внутри одной группы, заключенной в скобки.

Emacs также предоставляет программу структурной печати для Лиспа, реализованную в библиотеке pp. Эта программа переформатирует лисповский объект, выбирая отступы таким образом, чтобы результат хорошо выглядел и удобно читался.

Основные команды для отступов в программах

TAB
Установить отступ текущей строки.
C-j
Эквивалент RET, за которым следует TAB (newline-and-indent).

Основная команда отступа -- это TAB, которая дает текущей строке правильный отступ, основываясь на отступе предыдущих строк. Функция, которую запускает TAB, зависит от основного режима; в режиме Lisp это lisp-indent-line, в режиме С это c-indent-line и так далее. Эти функции понимают различные синтаксисы разных языков, но все они делают примерно одно и то же. TAB в основном режиме любого языка программирования вставляет или удаляет пробельные знаки в начале текущей строки, независимо от того, где в строке располагается точка. Если точка находится среди пробельных знаков в начале строки, TAB оставляет ее после них; в противном случае TAB оставляет точку фиксированной по отношению к окружающим ее знакам.

Чтобы вставить в точке знак табуляции, используйте C-q TAB.

При вводе нового кода используйте C-j (newline-and-indent), которая эквивалентна RET, за которой следует TAB. C-j создает пустую строку, а затем дает ей соответствующий отступ.

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

Помните, что открывающие круглые и фигурные скобки или другие открывающие ограничители на левом крае рассматриваются Emacs (и правилами отступа) как начало функции. Поэтому вы никогда не должны ставить открывающий ограничитель, не являющийся началом функции, в нулевом столбце, даже внутри строковой константы. Это ограничение жизненно важно для скорости работы команд отступа; вы должны просто принять его. Для более подробной информации об этом смотрите раздел Определения функций.

Отступ в нескольких строках

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

C-M-q
Сделать новый отступ во всех строках в пределах одного списка (indent-sexp).
C-u TAB
Сдвинуть весь список жестко в сторону так, чтобы его первая строка получила надлежащий отступ.
C-M-\
Сделать новый отступ во всех строках в области (indent-region).

Вы можете вновь сделать отступ содержимого одиночного списка, переместив точку в его начало и набрав C-M-q (это команда indent-sexp в режиме Lisp, c-indent-exp в режиме С; она также привязана к другим подходящим функциям в других режимах). Отступ строки, на которой начинается это s-выражение, не изменяется; поэтому изменяется только относительный отступ в пределах списка, а не его позиция. Чтобы исправить также и его позицию, наберите TAB перед C-M-q.

Если относительный отступ внутри списка правильный, но отступ его первой строки -- нет, перейдите к этой строке и наберите C-u TAB. TAB с числовым аргументом делает в текущей строке обычный отступ, а затем изменяет отступ во всех строках в группе, начиная с текущей, на ту же самую величину. Другими словами, она обновляет отступ целой группы как неделимой единицы. Это разумно, хотя и не изменяет строки, которые начинаются внутри строковых констант, или строки препроцессора Си, когда это происходит в режиме С.

Можно указать диапазон строк, в которых следует вновь сделать отступ, другим способом -- с помощью области. Команда C-M-\ (indent-region) применяет TAB к каждой строке, чей первый знак находится между точкой и меткой.

Настройка отступов для Лиспа

Образец отступа для лисповского выражения может зависеть от функции, вызываемой этим выражением. Для каждой лисповской функции вы можете выбирать среди нескольких предопределенных образцов отступа или определить произвольный отступ с помощью программы на Лиспе.

Стандартный шаблон отступа таков: вторая строка выражения сдвигается под первый аргумент, если он находится на той же самой строке, что и начало выражения; в противном случае вторая строка сдвигается под имя функции. Каждая следующая строка имеет тот же отступ, что и предыдущая строка с той же глубиной вложенности.

Если переменная lisp-indent-offset не равна nil, то она перекрывает обычный шаблон отступа для второй строки выражения, так что такие строки всегда сдвигаются вправо на lisp-indent-offset столбцов дальше, чем содержащий их список.

Стандартный шаблон перекрывается в некоторых определенных функциях. Для функций, чьи имена начинаются с def, отступ второй строки всегда делается на lisp-body-indention дополнительных столбцов дальше открывающей скобки, начинающей выражение.

Стандартный шаблон может перекрываться различными способами для отдельных функций согласно свойству имени этой функции lisp-indent-function. Есть четыре варианта для этого свойства:

nil
Это то же самое, что и отсутствие свойства; используется стандартный шаблон отступа.
defun
Шаблон, используемый для имен функций, которые начинаются с def, также используется и для этой функции.
число, n
Первые n аргументов этой функции считаются отличительными аргументами, остальные рассматриваются как тело выражения. Строка в этом выражении отступается в соответствии с тем, является ли в ней первый аргумент отличительным или нет. Если аргумент является частью тела, то строка отступается на lisp-body-indent столбцов больше, чем открывающая скобка, начинающая содержащее ее выражение. Если аргумент является отличительным, и это первый или второй аргумент, то отступ делается на вдвое большее число дополнительных столбцов. Если аргумент отличителен и не является первым или вторым, то для этой строки применяется стандартный шаблон.
символ, символ
символ должен быть именем функции; эта функция вызывается для вычисления отступа строки в пределах этого выражения. Функция получает два аргумента:
состояние
Значение, возвращаемое из parse-partial-sexp (это примитив Лиспа для подсчета величины отступов и вложенностей), когда она делает разбор вплоть до начала этой строки.
позиция
Позиция, с которой начинается строка, в которой делается отступ.
Она должна возвращать либо число, которое равно количеству столбцов отступа для этой строки, либо список, чей головной элемент является таким числом. Отличие между возвращением числа и возвращением списка заключается в том, что число говорит, что все следующие строки того же уровня вложенности должны получать такой же отступ, как эта строка; список говорит, что следующие строки могут требовать отличные отступы. Это важно, если отступы подсчитываются с помощью C-M-q; если значение -- это число, то C-M-q не нуждается в пересчете отступа для следующих строк до конца списка.

Команды для отступов в Си

Вот команды для создания отступов в режиме C и родственных с ним:

C-c C-q
Обновляет отступ в текущем определении функции верхнего уровня или собирает в одно целое объявление типа (c-indent-defun).
C-M-q
Обновляет отступ в каждой строке сбалансированного выражения, которое следует после точки (c-indent-exp). Префиксный аргумент подавляет проверку ошибок и вывод предупреждений о недопустимом синтаксисе.
TAB
Обновляет отступ в текущей строке и/или в некоторых случаях вставляет знак табуляции (c-indent-command). Если c-tab-always-indent равна t, эта команда всегда обновляет отступ текущей строки и не делает ничего больше. Это принимается по умолчанию. Если эта переменная равна nil, данная команда обновляет отступ текущей строки, только если точка находится с левого края или на отступе; в противном случае она вставляет табуляцию (или эквивалентное число пробелов, если indent-tabs-mode равна nil). Любое другое значение (не nil или t) означает, что нужно всегда обновлять отступ строки, а также вставлять знак табуляции, если точка находится внутри комментария, строки или директивы препроцессора.
C-u TAB
Обновляет отступ текущей строки в соответствии с ее синтаксисом; кроме того, жестко смещает все остальные строки выражения, начинающегося на текущей строке. Смотрите раздел Отступ в нескольких строках.

Чтобы обновить отступ всего текущего буфера, наберите C-x h C-M-\. Это сначала выделяет весь буфер как область, а затем обновляет отступ в этой области.

Чтобы обновить отступ в текущем блоке, используйте C-M-u C-M-q. Эта команда перемещает к началу блока и делает в нем отступ.

Настройка отступа в Си

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

Шаг 1 -- синтаксический анализ

На первом шаге механизм отступов в Си смотрит на строку перед той, в которой вы в данный момент делаете отступ, и определяет синтаксические компоненты конструкции на этой строке. Он строит список этих синтаксических компонентов, где каждый компонент содержит синтаксический символ и, иногда, позицию в буфере. Некоторые синтаксические символы описывают грамматические элементы, например statement и substatement; другие описывают положения в составе грамматических элементов, например class-open и knr-argdecl.

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

Вот пример. Предположим, что у нас есть следующий код в буфере с режимом C++ (номера строк в действительности не появляются в буфере):

1: void swap (int& a, int& b)
2: {
3:   int tmp = a;
4:   a = b;
5:   b = tmp;
6: }

Если вы наберете C-c C-s (что запускает команду c-show-syntactic-information) на строке 4, будет показан результат работы механизма отступов для этой строки:

((statement . 32))

Это указывает на то, что данная строка является оператором, и она имеет отступ относительно позиции 32 в буфере, то есть относительно `i' в int на строке 3. Если вы переместите курсор к строке 3 и наберете C-c C-s, это покажет следующее:

((defun-block-intro . 28))

Это указывает на то, что строка int -- это первый оператор в блоке, и она имеет отступ относительно позиции 28, то есть фигурной скобки сразу после заголовка функции.

Вот еще один пример:

1: int add (int val, int incr, int doit)
2: {
3:   if (doit)
4:     {
5:       return (val + incr);
6:     }
7:   return (val);
8: }

Если в строке 4 набрать C-c C-s, вы увидите вот что:

((substatement-open . 43))

Это говорит, что данная фигурная скобка открывает блок подоператора. Кстати, подоператор -- это строка после операторов if, else, while, do, switch, for, try, catch, finally или synchronized.

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

Шаг 2 -- подсчет отступа

Механизма отступов в Си вычисляет величину отступа для текущей строки, используя список синтаксических компонентов, c-syntactic-context, полученный из синтаксического анализа. Каждый компонент -- это пара, которая содержит синтаксический символ и может содержать позицию в буфере.

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

Следующие примеры демонстрируют работу механизма отступов в языке Си:

1: void swap (int& a, int& b)
2: {
3:   int tmp = a;
4:   a = b;
5:   b = tmp;
6: }

Предположим, что точка находится на строке 3, и вы нажимаете TAB, чтобы обновить в этой строке отступ. Как объяснялось выше (смотрите раздел Шаг 1 -- синтаксический анализ), синтаксическим компонетом этой строки будет:

((defun-block-intro . 28))

В данном случае при подсчете отступа сначала просматривается defun-block-intro в ассоциативном списке c-offsets-alist. Предположим, что там найдено число 2; оно добавляется к общему (инициализированному нулем), выдавая общей обновленный отступ в 2 пробела.

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

1: int add (int val, int incr, int doit)
2: {
3:   if (doit)
4:     {
5:       return(val + incr);
6:     }
7:   return(val);
8: }

Если вы нажмете TAB в строке 4, повторяется такой же процесс, но с иными данными. Список синтаксических компонентов для этой строки таков:

((substatement-open . 43))

Здесь первое, что делается для посчета отступа, -- ищется символ substatement-open в c-offsets-alist. Будем считать, что сдвиг для этого символа равен 2. В этом месте промежуточное общее значение равно 2 (0 + 2 = 2). Затем к нему добавляется номер строки позиции 43 в буфере, где стоит `i' из if на строке 3. Этот знак расположен во втором столбце на строке. Итого в сумме получается 4 пробела.

Если при анализе строки появляется синтаксический символ, который отсутствует в c-offsets-alist, он игнорируется; и это является ошибкой, если кроме того переменная c-strict-syntax-p отлична от nil.

Изменение стиля отступов

Есть два способа настроить стиль отступов для режимов, подобных режиму C. Во-первых, вы можете выбрать один из предопределенных стилей, каждый из которых задает сдвиги для всех синтаксических символов. Для большей гибкости вы можете настоить обработку отдельных синтаксических символов. Смотрите раздел Синтаксические символы, перечень всех определенных синтаксических символов.

M-x c-set-style RET стиль RET
Выбирает предопределенный стиль стиль. Чтобы получить перечень поддерживаемых стилей, наберите при вводе стиля знак ?; чтобы узнать, как выглядит тот или иной стиль, выберите его и примените для фрагмента кода на Си.
C-c C-o символ RET сдвиг RET
Устанавливает сдвиг для синтаксического символа символ (c-set-offset). Второй аргумент, сдвиг, указывает новую величину сдвига.

Размер отступа для каждого синтаксического символа управляется переменной c-offsets-alist. Ее значение -- это ассоциативный список, и каждый элемент этого списка имеет форму (синтаксический-символ . сдвиг). Изменяя сдвиги для разных синтаксических символов, вы можете настраивать отступы в мельчайших подробностях. Чтобы изменить этот ассоциативный список, используйте c-set-offset (смотрите ниже).

Значение каждого сдвига в c-offsets-alist может быть целым числом, именем функции или переменной, списком или одним их символов +, -, ++, --, * или /, обозначающих положительные или отрицательные кратные переменной c-basic-offset. Таким образом, если вы хотите поменять уровни отступов с трех пробелов на два пробела, установите c-basic-offset в значение 3.

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

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

Команда C-c C-o (c-set-offset) -- это простейший способ установить сдвиги, как интерактивно, так и в вашем файле `~/.emacs'. Сначала укажите синтаксический символ, а потом желаемый сдвиг. Смотрите раздел Синтаксические символы, перечень допустимых синтаксических символов и их значений.

Синтаксические символы

Это таблица допустимых синтаксических символов для отступов режима C и родственных с ним режимов и их синтаксические значения. Обычно всем этим символам приписывается сдвиг в c-offsets-alist.

string
Внутри строки, занимащей несколько строк в буфере.
c
Внутри многострочного блочного комментария в стиле Си.
defun-open
На фигурной скобке, которая открывает определение функции.
defun-close
На фигурной скобке, которая закрывает определение функции.
defun-block-intro
На первой строке определения функции верхнего уровня.
class-open
На фигурной скобке, которая открывает определение класса.
class-close
На фигурной скобке, которая закрывает определение класса.
inline-open
На фигурной скобке, которая открывает определяемый внутри класса inline-метод.
inline-close
На фигурной скобке, которая закрывает определяемый внутри класса inline-метод.
extern-lang-open
На фигурной скобке, которая открывает блок на внешнем языке.
extern-lang-close
На фигурной скобке, которая закрывает блок на внешнем языке.
func-decl-cont
На области между списком аргументов в определении функции и открывающей это определение фигурной скобкой (исключая определения функций в стиле K&R). В Си вы не можете писать здесь ничего, кроме пробельных знаков и комментариев; в Си++ и Java в этом контекте могут появляться объявления throws и другие вещи.
knr-argdecl-intro
На первой строке объявления аргументов в стиле K&R Си.
knr-argdecl
На одной из последующих строк объявления аргументов в стиле K&R Си.
topmost-intro
На первой строке определения конструкции самого верхнего уровня.
topmost-intro-cont
На остальных строках определения самого верхнего уровня.
member-init-intro
На первой строке списка инициализаций членов.
member-init-cont
На последующих строках списка инициализаций членов.
inher-intro
На первой строке списка множественного наследования.
inher-cont
На одной их последующих строк множественного наследования.
block-open
На открывающей фигурной скобке операторного блока.
block-close
На закрывающей фигурной скобке операторного блока.
brace-list-open
На открывающей фигурной скобке списка массива enum или static.
brace-list-close
На закрывающей фигурной скобке списка массива enum или static.
brace-list-intro
На первой строке списка массива enum или static.
brace-list-entry
На одной их последующих строк списка массива enum или static.
brace-entry-open
На одной из последующих строк списка массива enum или static, когда строка начинается с открывающей фигурной скобки.
statement
На обычном операторе.
statement-cont
На строке продолжения оператора.
statement-block-intro
На первой строке нового операторного блока.
statement-case-intro
На первой строке "блока" case.
statement-case-open
На первой строке блока case, начинающейся с фигурной скобки.
inexpr-statement
На операторном блоке внутри выражения. Это используется для расширения GNU в языке Си и для для специальных функций Pike, которые принимают в качестве аргумента операторный блок.
inexpr-class
На определении класса внутри выражения. Это используется для аноноимных классов и аноноимных инициализаторов массивов в Java.
substatement
На первой строке после if, while, for, do или else.
substatement-open
На фигурной скобке, открывающей блок подоператора.
case-label
На метке case или default.
access-label
На метках доступа Си++ private, protected или public.
label
На обычной метке.
do-while-closure
На while, который завершает конструкцию do-while.
else-clause
На else конструкции if-else.
catch-clause
На строках catch и finally в конструкциях try...catch в Си++ и Java.
comment-intro
На строке, содержащей только начало комментария.
arglist-intro
На первой строке списка аргументов.
arglist-cont
На одной из последующих строк списка аргументов, когда на строке с открывающей список аргументов круглой скобкой нет ни одного аргумента.
arglist-cont-nonempty
На одной из последующих строк списка аргументов, когда на строке с открывающей список аргументов круглой скобкой есть хотя бы один аргумент.
arglist-close
На закрывающей круглой скобке списка аргументов.
stream-op
На одной строк продолжения конструкции потокового оператора.
inclass
На конструкции, вложенной в определение класса. Отступ относителен открывающей фигурной скобке определения класса.
inextern-lang
На конструкции, вложенной в блок на внешнем языке.
inexpr-statement
На первой строке операторного блока внутри выражения. Это нужно для расширения GCC в языке Си, которое использует синтаксис ({ ... }). Это также нужно для специальных функций в Pike, принимающих в качестве аргумента операторный блок.
inexpr-class
На первой строке определения класса внутри выражения. Это используется для аноноимных классов и аноноимных инициализаторов массивов в Java.
cpp-macro
На начале макроса препроцессора.
friend
На объявлении Си++ friend.
objc-method-intro
На первой строке определения метода Objective-C.
objc-method-args-cont
На одной из строк продолжения определения метода Objective-C.
objc-method-call-cont
На одной из строк продолжения вызова метода Objective-C.
inlambda
Как inclass, но применяется внутри лямбда-функций (т.е. анонимных). Используется только в Pike.
lambda-intro-cont
На строке, продолжающей заголовок лямбда-функции, между ключевым словом lambda и телом функции. Используется только в Pike.

Переменные, управляющие отступами в Си

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

c-offsets-alist
Ассоциативный список синтаксических символов и их сдвигов. Вы не должны менять его прямо, делайте это через c-set-offset. Смотрите раздел Изменение стиля отступов, для подробностей.
c-style-alist
Переменная для определения стилей отступов; смотрите ниже.
c-basic-offset
Базовый сдвиг, используемый символами + и - в c-offsets-alist.
c-special-indent-hook
Ловушка для специальных подстроек отступов, определяемых пользователем. Эта ловушка вызывается после того, как в строке уже сделан отступ режимом C или родственным с ним режимом.

Переменная c-style-alist задает предопределенные стили отступов. Каждый элемент имеет форму (имя установка-переменной...), где имя -- это имя стиля. Каждая установка-переменной имеет форму (переменная . значение); переменная -- это одна из настроечных переменных, используемых режимом C, а значение -- это значение для этой переменной, когда используется выбранный стиль.

Когда переменная равна c-offsets-alist, это особый случай: значение добавляется в начало значения c-offsets-alist, а не замещает его. Следовательно, значение не обязано указывать каждый синтаксический символ --- можно написать только те, для которых стиль отличен от принимаемого по умолчанию.

Отступы строк, содержащих только комментарии, также подвержены влиянию переменной c-comment-only-line-offset (смотрите раздел Комментарии в режимах C).

Стили отступов в Си

Стиль Си -- это набор настроек стиля отступов. Emacs поставляется с несколькими предопределенными стилями отступов для C и родственных режимов, включая gnu, k&r, bsd, stroustrup, linux, python, java, whitesmith, ellemtel и cc-mode. По умолчанию применяется стиль gnu.

Чтобы выбрать нужный вам стиль, используйте команду M-x c-set-style. Задавайте имя стиля в качестве аргумента (регистр не имеет значения). Выбранный стиль применяется только к новым буферам, но не к тем, что вы уже редактируете. Вы также можете установить переменную c-default-style, чтобы указать стиль для различных основных режимов. Ее значением должен быть ассоциативный список, где каждый элемент задает один основной режим и стиль отступов, который для него нужно использовать. Например,

(setq c-default-style
      '((java-mode . "java") (other . "gnu")))

определяет явный выбор для режима Java и велит принимать стиль `gnu' по умолчанию для остальных C-подобных режимов.

Чтобы определить новый стиль отступов в Си, вызовите функцию c-add-style:

(c-add-style имя значения применить-сразу)

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

Если применить-сразу не равна nil, c-add-style переключает в новый стиль сразу после его определения.

Автоматическое отображение парных скобок

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

В Лиспе автоматическое соответствие применяется только к круглым скобкам. В Си оно применяется также к фигурным и квадратным скобкам. Emacs узнает, какие знаки рассматривать как парные ограничители, основываясь на синтаксической таблице, которая устанавливается основным режимом. Смотрите раздел Синтаксическая таблица.

Если отрывающий и закрывающий ограничители не соответствуют друг другу, как например в `[x)', в эхо-области появляется предупреждающее сообщение. Правильные пары описываются в синтаксической таблице.

Отображением парных скобок управляют три переменные. blink-matching-paren включает или выключает эту возможность; nil выключает, а значение по умолчанию, равное t, включает ее. blink-matching-delay говорит, сколько секунд нужно ожидать; по умолчанию это 1, но на некоторых системах полезно задать часть секунды. blink-matching-paren-distance указывает, сколько знаков в обратном направлении надо исследовать, чтобы найти парный открывающий ограничитель. Если пара не будет найдена на таком расстоянии, то сканирование останавливается и ничего не отображается. Это делается для того, чтобы избежать больших затрат времени на поиск парного ограничителя в том случае, если пары не существует. По умолчанию она равна 12000.

При использовании X Windows вы можете запросить более мощную альтернативную разновидность автоматического показа парных скобок, включив режим Show Paren. Этот режим выключает обычный способ отображения парных скобок и использует вместо него подсветку совпадений. Когда точка находится после закрывающей скобки, подвечиваются эта закрывающая скобка и парная ей открывающая; иначе, если точка находится перед открывающей скобкой, подсвечивается парная скобка. (Подсвечивать открывающую скобку после точки не нужно, потому что поверх этого знака находится курсор.) Для включения и выключения этого режима используйте команду M-x show-paren-mode.

Управление комментариями

Поскольку комментарии являются весьма важной частью программирования, Emacs предоставляет особые команды для редактирования и вставки комментарев.

Команды для комментариев

Команды комментариев вставляют, уничтожают и выравнивают комментарии:

M-;
Вставить или выровнять комментарий в текущей строке (indent-for-comment).
C-x ;
Установить столбец комментария (set-comment-column).
C-u - C-x ;
Уничтожить комментарий в текущей строке (kill-comment).
C-M-j
Подобна RET, за которой следует вставка или выравнивание комментария (indent-new-comment-line).
M-x comment-region
Добавить или удалить ограничители комментариев на всех строках области.

Команда, которая создает комментарии, называется M-; (indent-for-comment). Если на строке еще нет комментария, то создается новый комментарий, выровненный по особому столбцу, называемому столбцом комментария. Комментарий создается вставкой строки, с которой, как думает Emacs, должны начинаться комментарии (значение comment-start, смотрите ниже). Точка оставляется за этой строкой. Если текст в строке текста простирается дальше столбца комментария, то делается отступ до подходящей границы (обычно вставляется по крайней мере один пробел). Если основной режим определил строку, завершающую комментарий, то она вставляется после точки, чтобы сохранить правильный синтаксис.

M-; может быть использована также и для выравнивания существующего комментария. Если строка уже содержит начало комментария, то M-; просто передвигает за него точку и делает отступ до принятой позиции. Исключение: комментарии, начинающиеся в столбце 0, не сдвигаются.

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

;; Эта просто пример функции
;;; Здесь годятся и 2, и 3 точки с запятой.
(defun foo (x)
;;; А теперь первая часть функции
  ;; Следующая строка добавляет единицу.
  (1+ x))           ; Эта строка добавляет единицу.

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

Даже когда существующий комментарий имеет правильный отступ, M-; по-прежнему полезна для перехода сразу к началу комментария.

Команда C-u - C-x ; (kill-comment) уничтожает комментарий в текущей строке, если он там есть. Отступ перед началом комментария также уничтожается. Если на этой строке нет комментария, то ничего не делается. Чтобы перенести комментарий в другую строку, передвиньтесь в конец этой строки, сделайте C-y и затем M-;, чтобы заново его выровнять. Заметьте, что C-u - C-x ; -- это не отдельный ключ; это C-x ; (set-comment-column) с отрицательным аргументом. Эта команда запрограммирована таким образом, что когда она получает отрицательный аргумент, она вызывает kill-comment. Однако, kill-comment -- это допустимая команда, которую вы можете непосредственно привязать к ключу, если вы этого хотите.

Многострочные комментарии

Если вы набираете комментарий и обнаруживаете, что хотели бы продолжить его на другой строке, то вы можете использовать команду C-M-j (indent-new-comment-line). Она завершает набранный вами комментарий, затем создает новую пустую строку и начинает новый комментарий, с отступом под старым комментарием. Когда действует режим Auto Fill, то переход за столбец заполнения во время набора комментария приводит к тому, что комментарий будет продолжаться именно таким образом. Если во время набора C-M-j точка находится не в конце строки, то текст в оставшейся части строки становится частью новой строки комментария.

Чтобы превратить существующие строки в строки комментариев, используйте команду M-x comment-region. Она добавляет ограничители к строкам, которые начинаются в области, делая их таким образом комментариями. С отрицательным аргуменом, она делает обратное --- удаляет ограничители комментариев из строк области.

С положительнм аргументом, comment-region повторяет последний знак из добавляемой последовательности, начинающей комментарий. Таким образом, в режиме Lisp, C-u 2 M-x comment-region добавит `;;' на каждую строку. Повторение ограничителей комментария -- это способ привлечения к нему внимания. В Лиспе для получения правильных отступов вы должны использовать аргумент, равный двум, между определениями функций, и трем -- внутри определений функций.

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

Параметры управления комментариями

Столбец комментария хранится в переменной comment-column. Вы можете явно установить ее на нужное число. Или вы можете использовать команду C-x ; (set-comment-column), которая устанавливает столбец комментария равным тому столбцу, где находится точка. C-u C-x ; устанавливает столбец комментария так, чтобы он соответствовал последнему комментарию перед точкой в этом буфере, и затем делает M-;, чтобы выравнять строку текущего комментария под предыдущую. Отметим, что C-u - C-x ; запускает функцию kill-comment, как описано выше.

Переменная comment-column -- это собственная переменная каждого буфера: установка ее влияет только на текущий буфер, но существует и значение по умолчанию, которое вы также можете изменить с помощью setq-default. Смотрите раздел Локальные переменные. Многие основные режимы инициализируют эту переменную для текущего буфера.

Команды работы с комментариями распознают комментарии, основываясь на регулярном выражении, которое является значением переменной comment-start-skip. Убедитесь, что это регулярное выражение не соответствует пустой строке. Оно может соответствовать чему-то большему, чем просто ограничителю, начинающему комментарий, в самом строгом значении этого слова; например, в режиме С значение этой переменной равно "/\\*+ *", что соответствует дополнительным звездочкам и пробелам после самого `/*'. (Обратите внимание, `\\' требуется в синтаксисе Лиспа для того, чтобы включить в строку `\', которая нужна, чтобы отменить для первой звездочки ее специальное значение в синтаксисе регулярных выражений. Смотрите раздел Синтаксис регулярных выражений.)

Когда команда для комментариев создает новый комментарий, она вставляет в его начало значение comment-start. Значение comment-end вставляется после точки, так что оно будет следовать за текстом, который вы вставите в этот комментарий. В режиме С comment-start имеет значение "/* ", а comment-end имеет значение " */".

Переменная comment-multi-line управляет тем, как ведет себя C-M-j (indent-new-comment-line) при использовании внутри комментария. Если comment-multi-line равна nil, как это обычно и бывает, то комментарий на текущей строке завершается, а на новой строке начинается новый комментарий. Если comment-multi-line отлична от nil, то новая следующая строка подготавливается как часть того же самого комментария, который находился на первой строке. Это выполняется следующим образом: в старой строке не вставляется ограничитель комментария, и в новую строку не вставляеся начало комментария. В тех языках, где работают многострочные комментарии, выбор значений для этой переменной -- дело вашего вкуса.

Переменная comment-indent-function должна содержать функцию, которая будет вызываться для подсчета отступа во вновь вставляемом комментарии или для выравнивания существующего комментария. Эта функция вызывается без аргумента, но с точкой в начале комментария или в конце строки, если вставляется новый комментарий. Она должна возвратить номер столбца, в котором должен начинаться комментарий. Например, в режиме Lisp эта функция-ловушка для создания отступа основывает свое решение на том, сколько точек с запятой начинают существующий комментарий, и на коде в предыдущих строках.

Редактирование без разбалансированных скобок

M-(
Поставить скобки вокруг следующего s-выражения (или s-выражений) (insert-parentheses).
M-)
Передвинуться через следующую закрывающую скобку и сделать новый отступ (move-past-close-and-reindent).

Команды M-( (insert-parentheses) и M-) (move-past-close-and-reindent) созданы для облегчения такого вида редактирования, при котором скобки всегда остаются сбалансированными. M-( вставляет пару скобок, либо вместе, как в `()', либо, если задан аргумент, вокруг следующих нескольких s-выражений, и оставляет точку после открытой скобки. Точка остается после открывающей скобки. Команда M-) перемещается через закрывающую скобку, удаляя любой предшествующий ей отступ и делая после нее отступ при помощи C-j.

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

M-( может вставлять перед открывающей скобкой пробел в зависимости от синтаксического класса предыдущего знака. Установите parens-require-spaces в значение nil, если вы хотите подавить это.

Завершение для имен символов

Обычно завершение происходит в минибуфере. Но один из видов завершения доступен во всех буферах: завершение для имен символов.

M-TAB (lisp-complete-symbol) запускает команду, завершающую частично набранный символ перед точкой, используя множество имен символов, имеющих смысл в этом контексте. Все дополняющие знаки, определяемые по частичному имени, вставляются в точке.

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

В большинстве основных режимов для языков программирования, M-TAB запускает команду complete-symbol, которая предоставляет два типа завершения. Обычно она делает завершения, основываясь на таблице тегов (смотрите раздел Таблицы тегов); с числовым аргументом (независимо от его зачения), она делает завершение, основываясь на именах, перечисленных в указателе понятий в Info-файле для этого языка. Поэтому чтобы завершить имя символа, определенного в вашей собственной программе, используйте M-TAB без аргумента; чтобы завершить имя стандартной библиотечной функции, используйте C-u M-TAB. Конечно, основанное на Info завершение работает, только если есть Info-файл для стандартной библиотеки функций вашего языка, и только если он установлен в вашей системе.

В режиме Emacs-Lisp пространство имен для завершения обычно состоит из нетривиальных символов, присутствующих в данный момент в Emacs -- тех, что имеют определение функции, значение или свойства. Однако, если непосредственно перед началом частичного символа есть открывающая скобка, в качестве завершений рассматриваются только символы с определением функции. Команда, реализующая это, называется lisp-complete-symbol.

В режиме Text и родственных с ним, M-TAB завершает слова, основываясь на словаре программы проверки правописания. Смотрите раздел Поиск и исправление орфографических ошибок.

Режим Which Function

Режим Which Function -- это второстепенный режим, который показывает в строке режима имя текущей функции по мере того, как вы передвигаетесь по буферу.

Чтобы включить (или выключить) режим Which Function, используйте команду M-x which-function-mode. Это глобальная команда; она применяется ко всем буферам, как к существующим, так и к тем, что еще будут созданы. Однако, это затрагивает только определенные основные режимы, перечисленные в значении which-func-modes. (Если это значение t, то режим Which Function применяется ко всем основным режимам, которые знают, как это поддерживается -- к основным режимам, поддерживающим Imenu.)

Команды документации

Когда вы редактируете код на Лиспе, предназначенный для запуска в Emacs, вы можете использованы команды C-h f (describe-function) и C-h v (describe-variable) для печати документации о функциях и переменных, которые вы хотите вызвать. Эти команды используют минибуфер для считывания имени функции или переменной и показывают документацию в окне.

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

Для кода на Emacs Lisp вы также можете использовать режим Eldoc. Этот второстепенный режим постоянно показывает в эхо-области список аргументов для функции, которая вызывается в точке. (Другими словами, он находит вызов функции, который содержит точку, и показывает список аргументов этой функции.) Режим Eldoc применим только к режимам Emacs Lisp и Lisp Interaction. Для включения и выключения этого режима используйте команду M-x eldoc-mode.

Для Си, Лиспа и других языков вы можете использовать C-h C-i (info-lookup-symbol), чтобы просмотреть документацию Info по какому-то символу. Вы задаете символ в минибуфере; по умолчанию берется символ, находящийся в буфере в точке. Где искать документацию по символам -- в каких Info-файлах и каких именных указателях --- определяет основной режим. Вы можете также использовать M-x info-lookup-file для нахождения документации для имени файла.

Вы можете прочитать "страницу man" для команды операционной системы, библиотечной функции или системного вызова с помощью команды M-x manual-entry. Для форматирования страницы она запускает программу man и, если позволяет ваша операционная система, делает это асинхронно, чтобы вы могли продолжать редактирование, пока страница форматируется. (MS-DOS и MS-Windows 3 не допускают асинхронных подпроцессов, так что на этих системах вы не можете редактировать, когда Emacs ожидает, пока man закончит работу.) Результат направляется в буфер с именем `*Man тема*'. Эти буферы используют особый основной режим, режим Man, который облегчает прокрутку и просмотр других страниц man. Для получения подробностей наберите C-h m в буфере страницы man.

Для длинных страниц правильная установка начертаний может занять значительное время. По умолчанию Emacs использует в страницах man начертания, если может показывать разные шрифты или цвета. Вы можете выключить использование разных начертаний в страницах man, установив переменную Man-fontify-manpage-flag равной nil.

Если вы вставите текст страницы man в буфер Emacs каким-то другим способом, вы можете использовать команду M-x Man-fontify-manpage, чтобы произвести те же преобразования, что делает M-x manual-entry.

Проект GNU надеется когда-нибудь заменить большинство страниц man на лучше организованные руководства, которые вы можете просматривать с помощью Info. Смотрите раздел Другие команды для получения справки. Поскольку этот процесс завершен лишь частично, читать страницы man все еще полезно.

Журналы изменений

Команда Emacs C-x 4 a добавляет в журнал изменений новую запись для файла, который вы редактируете (add-change-log-entry-other-window).

Файл журнала изменений содержит хронологическое описание того, почему и когда вы изменяли программу, состоящее из последовательности записей, описывающих отдельные изменения. Как правило оно хранится в файле с именем `ChangeLog' в том же самом каталоге, в котором находится файл, который вы редактируете, или в одном из его родительских каталогов. Единственный файл `ChangeLog' может записывать изменения для всех файлов в его каталоге и во всех его подкаталогах.

Запись в журнале изменений начинается со строки заголовка, которая содержит ваше имя, ваш адрес электронной почты (получаемый из переменной user-mail-address) и текущую дату и время. Кроме этих строк заголовка, каждая строка в журнале изменений начинается с пробела или табуляции. Основная часть записи состоит из пунктов, каждый из которых начинается со строки, начинающейся с пропуска и звездочки. Вот пример двух записей, обе датированы маем 1993 года и обе содержат два пункта:

1993-05-25  Richard Stallman  

        * man.el: Rename symbols `man-*' to `Man-*'.
        (manual-entry): Make prompt string clearer.

        * simple.el (blink-matching-paren-distance):
        Change default to 12,000.

1993-05-24  Richard Stallman  

        * vc.el (minor-mode-map-alist): Don't use it if it's void.
        (vc-cancel-version): Doc fix.

(Предыдущие версии Emacs использовали другой формат даты.)

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

C-x 4 a обращается к файлу журнала изменений и создает новую запись, если только последний по времени пункт не датирован сегодняшним днем и не несет ваше имя. Также она создает новый пункт для текущего файла. Для многих языков она может даже предположить имя измененной функции или объекта.

К файлу журнала изменений обращаются в режиме Change Log. В этом основном режиме каждая связка сгруппированных пунктов считается одним абзацем, а каждая запись считается страницей. Это облегчает редактирование записей. C-j и автоматическое заполнение делают в каждой новой строке такой же отступ, как в предыдущей; это удобно для ввода содержимого записей.

Системы управления версиями дают другой способ отслеживания изменений в вашей программе и ведения журнала изменений. Смотрите раздел Буфер журнальной записи.

Таблицы тегов

Таблица тегов -- это описание того, как многофайловая программа разбивается на файлы. Она перечисляет имена файлов-компонентов и имена и позиции функций (или других именованных подъединиц) в каждом файле. Объединение связанных файлов делает возможным поиск или замену во всех файлах с помощью одной команды. Запись имен функций и позиций делает возможной команду M-., которая находит определение, отыскивая сведения о том, в каком файле оно находится.

Таблицы тегов хранятся в файлах, именуемых файлами таблиц тегов. Общепринятое имя для файла таблицы тегов -- `TAGS'.

Каждый элемент в таблице тегов записывает имя одного тега, имя файла, в котором этот тег определен (явно), и местоположение определения тега в этом файле.

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

Синтаксис тегов исходного файла

В наиболее популярных языках синтаксис тегов определяется следующим образом:

  • В программе на Си, любая функция Си или typedef -- это тег, тегом являются и определения struct, union и enum. Определения макросов (#define) и констант (enum) также являются тегами, если только вы не задали при создании таблицы тегов ключ --no-defines. Аналогично, тегами являются глобальные переменные, если только вы не задали ключ --no-globals. Использование --no-globals и --no-defines может сделать файлы таблиц тегов гораздо меньше.
  • В коде на Си++, помимо всех тегов кода Си распознаются также функции-члены и, возможно, переменные-члены, если вы используете ключ --members. Теги для переменных и функций в классах именуются как `класс::переменная' и `класс::функция'.
  • В коде на Java, теги включают все конструкции, распознаваемые в Си++ плюс конструкции extends и implements. Теги для переменных и функций в классах именуются как `класс.переменная' и `класс.функция'.
  • В тексте для LaTeX, тегами служат аргументы каждой из команд \chapter, \section, \subsection, \subsubsection, \eqno, \label, \ref, \cite, \bibitem, \part, \appendix, \entry или \index. Другие команды тоже могут создавать теги, если вы укажете их в переменной среды `TEXTAGS' перед вызовом etags. Значением этой переменной среды должен быть разделенный двоеточиями список имен команд.
    TEXTAGS="def:newcommand:newenvironment"
    export TEXTAGS
    
    задает (с использованием синтаксиса Bourne shell), что команды `\def', `\newcommand' и `\newenvironment' также определяют теги.
  • В коде на Лиспе любая функция, определенная через defun, любая переменная, определенная через defvar или defconst, и вообще первый аргумент любого выражения, которое начинается с `(def' в нулевом столбце, являются тегом.
  • В коде на Scheme теги включают все определяемое с помощью def или конструкции, чье имя начинается с `def'. Они также включают переменные, установленные с помощью set! на верхнем уровне файла.

Поддерживаются также несколько других языков:

  • В коде ассемблера, теги -- это метки, появляющиеся в начале строки, за которыми идет двоеточие.
  • Во входных файлах Bison или Yacc каждое правило определяет конструируемый им нетерминал как тег. Части файла, содержащие код на Си, анализируются как код Си.
  • В коде на Cobol тегами служат имена параграфов; то есть любые слова, которые начинаются в столбце 8, и после которых стоит точка.
  • В коде на Erlang тегами служат определенные в файле функции, записи и макросы.
  • В Фортран-коде тегами являются функции, подпрограммы и блоки данных.
  • В коде на Паскале тегами будут определенные в файле функции и процедуры.
  • В коде на Perl тегами являются процедуры, определяемые ключевым словом sub.
  • В коде на Postscript тегами являются функции.
  • В коде на Прологе теги появляются на левой границе.

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

Создание таблицы тегов

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

etags входные-файлы...

Программа etags считывает указанные файлы и записывает таблицу тегов под именем `TAGS' в текущем рабочем каталоге. etags распознает язык, используемый во входном файле, основываясь на имени этого файла и его содержании. Вы можете указать язык с помощью ключа `--language=имя', описанного ниже.

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

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

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

Одна таблица тегов может как бы включать другую. Имя включаемого файла тегов указывается с помощью ключа `--include=файл' при создании включающего файла. Последний файл затем ведет себя так, как если бы он содержал все файлы, заданные во включенном файле, так же как и те файлы, которые он содержит непосредственно.

Если при запуске etags вы зададите исходные файлы по относительным именам, файл тегов будет содержать имена файлов, относительные к каталогу, в котором этот файл тегов был изначально записан. Тогда вы сможете переместить все дерево каталогов, содержащее и файл тегов, и исходные файлы, и файл тегов все равно будет правильно ссылаться на исходные файлы.

Если в качестве аргументов etags вы зададите абсолютные имена файлов, то файл тегов будет содержать абсолютные имена. Тогда файл тегов будет так же ссылаться на те же исходные файлы, даже если вы переместите его, до тех пор, пока исходные файлы остаются на старом месте. Абсолютные имена файлов начинаются с `/', или с `устройство:/' в MS-DOS и MS-Windows.

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

find . -name "*.[chCH]" -print | etags -

Используйте ключ --language=имя для явного указания языка. Вы можете перемешивать эти ключи с именами файлов; каждый относится к имена файла, которое следует за ним. Задайте --language=auto, чтобы велеть etags продолжать самой предполагать язык по имени и содержимому файла. Задайте --language=none, чтобы полностью выключить специфичную для языка обработку; тогда etags распознает теги только по сопоставлению с регулярным выражением. `etags --help' печатает перечень языков, которые знает etags, и правила предположения языка по имени файла.

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

--regex=/regexp-тег[/regexp-имя]/

где regexp-тег используется для нахождения строк тегов. Оно всегда зацепленное, то есть ведет себя так, как если бы в начале стояло `^'. Если вы хотите учесть отступы, просто назовите совпадением произвольное количество пропусков, начав ваше регулярное выражение с `[ \t]*'. Знак `\' в регулярных выражениях экранирует следующий знак, а `\t' обозначает символ табуляции. Обратите внимание, etags не обрабатывает другие управляющие последовательности Си для специальных знаков.

etags придерживается того же синтаксиса регулярных выражений, что и Emacs, но с введением оператора интервала, который работает как в grep и ed. Синтаксис оператора интервала такой: `\{m,n\}', это означает, что нужно найти совпадение с предыдущим выражением по меньшей мере m раз и вплоть до n раз.

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

Ключ -R удаляет все регулярные выражения, определенные ключами --regex. Он применяется к следующим за ним именам файлов, как вы можете видеть из следующего примера:

etags --regex=/reg1/ voo.doo --regex=/reg2/ \
    bar.ber -R --lang=lisp los.er

Здесь etags выбирает язык для анализа `voo.doo' и `bar.ber' в соответствии с их содержимым. etags также использует reg1 для распознавания дополнительных тегов в `voo.doo' и оба выражения reg1 и reg2 для распознавания дополнительных тегов в `bar.ber'. Для распознавания тегов в `los.er' etags использует правила тегов для Лиспа и не использует регулярные выражения.

Вот еще несколько примеров. Регулярные выражения взяты в кавычки, чтобы оболочка не интерпретировала их по-своему.

  • Сделать теги для макроса DEFVAR в исходных файлах Emacs:
    --regex='/[ \t]*DEFVAR_[A-Z_ \t(]+"\([^"]+\)"/'
    
  • Сделать теги для VHDL-файлов (этот пример -- одна строка, разбитая здесь для правильного форматирования):
    --language=none
    --regex='/[ \t]*\(ARCHITECTURE\|CONFIGURATION\) +[^ ]* +OF/'
    --regex='/[ \t]*\(ATTRIBUTE\|ENTITY\|FUNCTION\|PACKAGE\
    \( BODY\)?\|PROCEDURE\|PROCESS\|TYPE\)[ \t]+\([^ \t(]+\)/\3/'
    
  • Сделать теги для файлов на Tcl (этот последний пример показывает использование аргумента regexp-имя):
    --lang=none --regex='/proc[ \t]+\([^ \t]+\)/\1/'
    

Чтобы получить перечень других доступных ключей etags, выполните etags --help.

Выбор таблицы тегов

Emacs хранит в каждый момент одну выбранную таблицу тегов, и все команды для работы с таблицами тегов используют эту выбранную таблицу. Чтобы выбрать таблицу тегов, наберите M-x visit-tags-table, которая считает имя файла таблицы тегов как аргумент. Имя `TAGS' в каталоге по умолчанию используется как имя файла по умолчанию.

Все, что делает эта команда, -- сохраняет имя файла в переменной tags-file-name. Emacs фактически не считывает содержимое таблицы тегов до тех пор, пока вы не попытаетесь использовать его. Самостоятельная установка этой переменной так же хороша, как и использование visit-tags-table. Начальное значение переменной равно nil; это значение сообщает всем командам для работы с таблицами тегов, что они должны запрашивать, какое имя файла таблицы тегов надо использовать.

Использование visit-tags-table, когда таблица тегов уже загружена, дает вам выбор: вы можете добавить новую таблицу тегов к текущему списку таких таблиц или начать новый список. Команды работы с тегами используют все таблицы тегов в текущем списке. Если вы начинаете новый список, новая таблица тегов используется вместо остальных. Если вы добавляете новую таблицу тегов к текущему списку, она используется вместе с остальными. Когда команды работы с тегами сканируют список таблиц тегов, они не всегда начинают с начала списка; они начинают с первой таблицы, которая описывает текущий файл (если такая есть), проходят далее до конца списка и затем просматривают список с начала до тех пор, пока в нем не будут проверены все таблицы.

Вы можете явно задать список таблиц тегов, установив переменную tags-table-list в значение списка строк, как показано:

(setq tags-table-list
      '("~/emacs" "/usr/local/lib/emacs/src"))

Это заставляет команды, работающие с тегами, просматривать файлы `TAGS' в каталогах `~/emacs' и `/usr/local/lib/emacs/src'. Порядок зависит от того, в каком файле вы сейчас находитесь и какая таблица тегов упоминает этот файл, как обяснено выше.

Не установливайте переменные tags-file-name и tags-table-list одновременно.

Поиск определения тега

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

M-. тег RET
Найти первое определение тега (find-tag).
C-u M-.
Найти следующее по очереди определение последнего заданного тега.
C-u - M-.
Вернуться к предыдущему найденному тегу.
C-M-. образец RET
Найти тег, чье имя совпадает с образцом (find-tag-regexp).
C-u C-M-.
Найте следующий тег, чье имя совпадает с последним использованным образцом.
C-x 4 . тег RET
Найте первое определение тега, но показать его в другом окне (find-tag-other-window).
C-x 5 . тег RET
Найте первое определение тега и создать новый фрейм для выбора буфера (find-tag-other-frame).
M-*
Вернуться к тому месту, где вы ранее вызвали M-. и товарищей.

M-. (find-tag) -- это команда для поиска определения заданного тега. Она ищет его по таблице тегов как строку и затем использует эту информацию из таблицы тегов для того, чтобы определить файл, в котором находится определение, и приблизительную положение определения в файле. Затем find-tag обращается к этому файлу, передвигает точку в приблизительную позицию и начинает поиск определения на постоянно возрастающем расстоянии.

Если задается пустой аргумент (просто RET), то в качестве имени тега, который надо найти, используется s-выражение, находящееся в буфере перед или вокруг точки. Для получения информации о s-выражениях смотрите раздел Списки и s-выражения,

Аргумент для M-. не обязан быть полным именем тега; достаточно части. Это возможно, потому что M-. находит в таблице теги, которые содержат тег как построку. Однако, она предпочитает точное совпадение совпадению лишь построки. Чтобы найти другие теги, которые соответствуют той же подстроке, следует дать find-tag числовой аргумент, как в C-u M-.; эта команда не считываает имя тега, но продолжает поиск по тексту таблицы тегов другого тега, содержащего самую последнюю использованную подстроку. Если у вас есть настоящая клавиша META, то M-0 M-. может служить более простой альтернативой C-u M-..

Подобно большинству команд, которые могут переключать буферы, find-tag имеет вариант, который показывает новый буфер в другом окне, и еще один, который создает новый фрейм. Первая команда -- это C-x 4 ., которая вызывает функцию find-tag-other-window. Вторая, C-x 5 ., вызывает find-tag-other-frame.

Чтобы вернуться к местам, где вы недавно находили теги, используйте C-u - M-.; в более общем виде, M-. с отрицательным числовым аргументом. Эта команда может перенести вас в другой буфер. C-x 4 . с отрицательным аргументом находит предыдущее положение тега в другом окне.

Так же, как вы можете вернуться к местам, где вы недавно находили теги, вы можете вернуться к местам, откуда вы их нашли. Используйте для этого M-*, что вызывает команду pop-tag-mark. Типичное применение этих команд -- найти и изучить определение чего-то с помощью M-. и затем вернуться к тому месту, где вы были, с помощью M-*.

И C-u - M-., и M-* позволяют вам пошагово проходить назад до глубины, определяемой переменной find-tag-marker-ring-length.

Команда C-M-. (find-tag-regexp) обращается к тегам, соответствующим заданному регулярному выражению. Она похожа на M-., но производит сопоставление с регулярным выражением, а не со строкой.

Поиск и замена при помощи таблиц тегов

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

M-x tags-search RET regexp RET
Поиск regexp во всех файлах в выбранной таблице тегов.
M-x tags-query-replace RET regexp RET замена RET
Осуществить query-replace-regexp в каждом файле в выбранной таблице тегов.
M-,
Перезапустить одну из вышеупомянутых команд из текущего положения точки (tags-loop-continue).

M-x tags-search считывает регулярное выражение, используя минибуфер, затем ищет это регулярное выражение по очереди в каждом файле из выбранной таблицы тегов. Она показывает имя файла, который в данный момент просматривается, таким образом, вы можете следить за ходом поиска. Как только определяется местонахождение, tags-search возвращается.

Найдя одно соответствие, вы, вероятно, захотите найти все остальные. Чтобы найти еще одно соответствие, наберите M-, (tags-loop-continue), это возобновит tags-search. Эта команда просматривает остаток текущего буфера и затем оставшиеся файлы таблицы тегов.

M-x tags-query-replace осуществляет во всех файлах в таблице тегов единую замену регулярного выражения с подтверждением. Она считывает регулярное выражение, которое следует искать, и строку для замены, точно так же, как обычная M-x query-replace-regexp. Она ищет очень похоже на M-x tags-search, но с повторами, обрабатывая совпадения согласно вашему вводу. Смотрите раздел Команды замены, более подробную информацию о замене с подтверждением.

Можно пройти по всем файлам в таблице тегов с помощью едиственного вызова M-x tags-query-replace. Но иногда бывает полезно временно выйти, что вы можете сделать с помощью любого события ввода, не имеющего особого смысла при замене с подтверждением. Вы можете впоследствии возобновить замену с подтверждением, набрав M-,; эта команда возобновляет последнюю сделанную вами команду поиска или замены тегов.

Команды этого раздела приводят к гораздо более широкому поиску, чем семейство find-tag. Команды find-tag ищут только определения тегов, совпадающих с вашей подстрокой или регулярным выражением. Команды tags-search и tags-query-replace находят каждое вхождение регулярного выражения, как делают в текущем буфере обычные команды поиска и замены.

Эти команды создают буферы только временно, для файлов, в которых они должны делать поиск (для тех, к которым уже не обращается какой-нибудь буфер Emacs). Буферы, в которых нет совпадений, быстро уничтожаются; остальные продолжают существовать.

Вас, возможно, поразило, что tags-search очень похожа на grep. Вы можете также запустить саму grep как подчиненную Emacs, и Emacs покажет вам совпадающие строки одну за другой. Это работает во многом похоже на запуск компиляции; обращение к тем позициям в исходных файлах, где grep нашла совпадения, работает как обращение к ошибкам компиляции. Смотрите раздел Запуск компиляторов в Emacs.

Запросы к таблице тегов

M-x list-tags RET файл RET
Показать список тегов, определенных в заданном файле с текстом программы.
M-x tags-apropos RET regexp RET
Показать список всех тегов, соответствующих регулярному выражению regexp.

M-x list-tags считывает имя одного из файлов, описанных в выбранной таблице тегов, и показывает список всех тегов, определенных в этом файле. Аргумент "имя файла" фактически является просто строкой для сравнения с именами, записанными в таблице тегов; он считывается как строка, а не как имя файла. Поэтому завершение и значение по умолчанию невозможны, и вы должны вводить имя файла в том же самом виде, в котором оно появляется в таблице тегов. Не включайте каталог как часть имени файла, если имя файла, записанного в таблице тегов, не включает каталог.

M-x tags-apropos похожа на apropos для тегов (смотрите раздел Поиск по контексту). Она считывает регулярное выражение, затем находит все теги в выбранной таблице тегов, чьи вхождения соответствуют этому регулярному выражению, и показывает найденные имена тегов.

Вы также можете производить в буфере завершение в пространстве имен, составленном из имен тегов текущих таблиц. Смотрите раздел Завершение для имен символов.

Объединение файлов с помощью Emerge

Нередко программисты перебегают друг другу дорогу и изменяют одну и ту же программу в двух разных направлениях. Чтобы справиться с этой путаницей, вам необходимо объединить две эти версии. Emerge упрощает это. Смотрите также раздел Сравнение файлов, о командах для сравнения файлов более ручным методом, и раздел `Emerge' в The Ediff Manual.

Обзор Emerge

Чтобы запустить Emerge, выполните одну из этих четырех команд:

M-x emerge-files
Объединяет два заданных файла.
M-x emerge-files-with-ancestor
Объединяет два заданных файла, со ссылкой на общего предка.
M-x emerge-buffers
Объединяет два буфера.
M-x emerge-buffers-with-ancestor
Объединяет два буфера со ссылкой на общего предка в третьем буфере.

Команды Emerge сравнивают два файла или буфера и отображают результат сравнения в трех буферах: по одному на каждый входной файл (буфер A и буфер B) и один (буфер объединения), где объединение и происходит. Буфер объединения показывает весь объединяемый текст, а не только различия. Везде, где буферы различаются, вы можете выбрать тот, из которого вы хотите внести фрагмент.

Команды Emerge, которые принимают ввод из существующих буферов, используют только их доступные части, если эти буферы сужены (смотрите раздел Сужение).

Если доступна общая начальная версия, от которой происходят оба сливаемых текста, Emerge может использовать ее, чтобы вывести предположение о том, какая из альтернатив правильна. Когда одна из текущих версий находится в согласии с предком, Emerge предполагает, что другая текущая версия -- это обдуманное изменение, которое должно сохраниться в объединенной версии. Если вы хотите указать общий начальный текст, используйте команды `with-ancestor'. Эти команды считывают три файла или имени буфера -- вариант A, вариант B и их общего предка.

После того как сравнение завершено, и буферы подготовлены, начинается интерактивное объединение. Вы можете управлять им, набирая особые команды объединения в буфере объединения. Этот буфер показывает вам полный объединенный текст, а не только различия. Для каждого промежутка различий между входными текстами вы можете сохранить любой или отредактировать их вместе.

В буфере объединения используется особый основной режим, режим Emerge, с командами для принятия таких решений. Но вы также можете редактировать этот буфер с помощью обычных команд Emacs.

В любой момент времени внимание Emerge сосредоточено на одном конкретном изменении, называемом выделенным. Это изменение помечается в трех буферах таким образом:

vvvvvvvvvvvvvvvvvvvv
различающийся текст
^^^^^^^^^^^^^^^^^^^^

Emerge последовательно нумерует все различия, и строка режима всегда показывает номер выделенного различия.

Обычно буфер объединения изначально содержит версию A текста. Но когда версия A изменения согласуется с общим предком, для этого изменения предпочтение отдается версии B.

Когда вы выходите, Emerge оставляет объединенный текст в буфере объединения. Тогда вы можете сохранить его с помощью C-x C-w. Если вы задали emerge-files или emerge-files-with-ancestor числовой аргумент, эти команды считает имя выходного файла в минибуфере. (Это последнее имя, которое они считывают.) Тогда при выходе из Emerge объединенный текст сохраняется в выходном файле.

Обычно команды Emerge сохраняет выходной буфер, когда вы выходите. Если вы прервете Emerge с помощью C-], команда Emerge не сохранит выходной буфер, но вы можете записать его сами, если хотите.

Подрежимы Emerge

Вы можете выбирать из двух режимов для отдания команд объединения: режим Fast и режим Edit. В режиме Fast основные команды объединения --- это одиночные знаки, но обычные команды Emacs выключены. Это удобно, если вы используете только команды объединения. В режиме Edit все команды объединения начинаются с префикса C-c C-c, и доступны также обычные команды Emacs. Это позволяет редактировать буфер объединения, но замедляет операции Emerge.

Используйте e, чтобы переключится в режим Edit, и C-c C-c f, чтобы переключится в режим Fast. Строка режима изображает режимы Edit и Fast при помощи `E' и `F'.

Emerge имеет два дополнительных подрежима, которые затрагивают способ работы определенных команд объединения: режим Auto Advance и режим Skip Prefers.

Если действует режим Auto Advance, команды a и b продвигают к следующему различию. Это позволяет вам быстрее сделать объединение, поскольку вы просто выбираете одну из входных альтернатив. Строка режима изображает режим Auto Advance как `A'.

Если действует режим Skip Prefers, команды n и p пропускают различия в состояниях prefer-A и prefer-B (смотрите раздел Состояние различия). Таким образом, вы видите только те различия, для которых ни одна из версий не предполагается "правильной". Строка режима изображает режим Skip Prefers с помощью `S'.

Используйте команду s a (emerge-auto-advance-mode), чтобы установить или сбросить режим Auto Advance. Используйте s s (emerge-skip-prefers-mode), чтобы установить или сбросить режим Skip Prefers. Эти команды включают режим, если им задан положительный аргумент, выключают при отрицательном аргументе и переключают режим, если аргумент не задан.

Состояние различия

Различия в буфере объединения помечаются строками знаков `v' и `^'. Каждое различие имеет одно из семи следующих состояний:

A
Различие показывает версию A. Команда a всегда производит это состояние; строка режима отображает его как `A'.
B
Различие показывает версию B. Команда b всегда производит это состояние; строка режима отображает его как `B'.
default-A
default-B
Различие показывает версию A или B по умолчанию, потому что вы не сделали выбор. Все различия изначально имеют состояние default-A (и таким образом, буфер объединения -- это копия буфера A), кроме тех, для которых "предпочтительна" другая альтернатива (смотрите ниже). Когда вы выбираете различие, его состояние заменяется из default-A или default-B на простое A или B. Таким образом, выбранное различие никогда не находится в состоянии default-A или default-B, и эти состояния никогда не отображаются в строке режима. Команда d a выбирает в качестве состояния по умолчанию default-A, а d b выбирает default-B. Это состояние по умолчанию применяется ко всем различиям, которые вы никогда не выбирали и для которых нет предпочтительной альтернативы. Если вы продвигаетесь последовательно, то различия, которые вы не выбирали, -- это те, что находятся после выбранного. Таким образом, продвигаясь последовательно, вы можете в результате сделать A версией по умолчанию для некоторых фрагментов буфера объединения, а B -- версией по умолчанию для остальных фрагментов, используя между различиями d a и d b.
prefer-A
prefer-B
Различие показывает состояние A или B, потому что оно предпочтительно. Это означает, что вы не сделали явного выбора, но похоже на то, что верна одна из альтернатив, так как вторая согласуется с общим предком. Значит, когда буфер A находится в согласии с общим предком, предпочтительна версия B, потому что скорее всего это и есть действительное изменение. Эти состояния показываются в строке режима как `A*' и `B*'.
combined
Различие показывает комбинацию состояний A и B, как результат команд x c или x C. Когда различие имеет это состояние, команды a и b не делают для него ничего, если только вы не зададите им числовой аргумент. Строка режима показывает это состояние как `comb'.

Команды объединения

Это команды объединения для режима Fast; в режиме Edit предваряйте их набором C-c C-c:

p
Выбирает предыдущее различие.
n
Выбирает следующее различие.
a
Выбирает версию A этого различия.
b
Выбирает версию B этого различия.
C-u n j
Выбирает различие номер n.
.
Выбирает различие, содержащее точку. Вы можете использовать эту команды в буфере объединения или в буферах A и B.
q
Выход -- завершает объединение.
C-]
Прерывание -- выходит и не сохраняет вывод.
f
Переход в режим Fast. (В режиме Edit это на самом деле C-c C-c f.)
e
Переход в режим Edit.
l
Центирирует (как C-l) все три окна.
-
Задает часть префиксного числового аргумента.
цифра
Также задает часть префиксного числового аргумента.
d a
Выбирает A как версию по умолчанию для буфера объединения начиная с этого места.
d b
Выбирает B как версию по умолчанию для буфера объединения начиная с этого места.
c a
Копирует версию A этого различия в список уничтожений.
c b
Копирует версию B этого различия в список уничтожений.
i a
Вставляет версию A этого различия в точке.
i b
Вставляет версию B этого различия в точке.
m
Помещает точку и метку вокруг этого различия.
^
Прокручивает все три окна вниз (как M-v).
v
Прокручивает все три окна вверх (как C-v).
<
Прокручивает все три окна влево (как C-x <).
>
Прокручивает все три окна вправо (как C-x >).
|
Переустанавливает горизонтальную прокрутку во всех трех окнах.
x 1
Сужает окно объединения до одной строки. (Используйте C-u l, чтобы восстановить его полный размер.)
x c
Комбинирует две версии этого различия (смотрите раздел Комбинирование двух версий).
x f
Показывает имена файлов/буферов, с которыми работает Emerge, в окне справки. (Используйте C-u l, чтобы восстановить окна.)
x j
Сцепляет это различие со следующим. (C-u x j сцепляет это различие с предыдущим.)
x s
Разбивает это различие на два. До того, как применить эту команду, расположите точку в каждом их буферов в том месте, где вы хотите разбить различие.
x t
Выбрасывает одинаковые строки сверху и снизу различия. Такие строки появляются, когда версии A и B идентичны, но отличаются от первоначальной версии.

Выход из Emerge

Команда q (emerge-quit) завершает объединение, записывая результаты в выходной файл, если вы его задали. Она восстанавливает правильное содержимое буферов A и B или уничтожает их, если они были созданы Emerge, и вы не изменяли их. Она также выключает в буфере объединения команды Emerge, поскольку выполнение их теперь может повредить содержимое различных буферов.

C-] прерывает объединение. Это означает выход без записи выходного файла. Если вы не указали выходной файл, то между прерыванием и завершением объединения на самом деле нет разницы.

Если команды Emerge были вызваны из другой программы на Лиспе, то в случае успешного завершения возвращается значение t, а если вы прервали объединение, возвращается nil.

Комбинирование двух версий

Иногда вы хотите сохранить оба варианта некоторого изменения. Чтобы сделать так, используйте x c, которая редактирует буфер объединения следующим образом:

#ifdef NEW
версия из буфера A
#else /* not NEW */
версия из буфера B
#endif /* not NEW */

Хотя этот пример показывает условные конструкции препроцессора Си, разделяющие два альтернативные версии, вы можете задать используемые строки, устанавливая переменную emerge-combine-versions-template по вашему выбору. В этой строке `%a' говорит, где нужно помещать версию A, а `%b' говорит, говорит помещать версию B. Установка по умолчанию, которая выдает результат, показанный выше, выглядит следующим так:

"#ifdef NEW\n%a#else /* not NEW */\n%b#endif /* not NEW */\n"

Тонкие вопросы, связанные с Emerge

В процессе объединения вы не должны пытаться редактировать буферы A и B сами. Emerge временно изменяет их, но в конце возвращает в исходное состояние.

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

Запуск Emerge может занять продолжительное время, поскольку ей требуется полностью сравнить файлы. Emacs не можете ничего делать, пока diff не завершится. Возможно, в будущем кто-то изменит Emerge так, что она будет делать сравнение в фоновом режиме, когда входные файлы велики -- тогда вы могли бы продолжать в Emacs другие дела, пока Emerge действительно не будет готова принимать команды.

После подготовки объединения Emerge запускает ловушку emerge-startup-hook (смотрите раздел Ловушки).

Режим C и родственные с ним

Этот раздел описывает особые средства, доступные в режимах C, C++, Objective-C, Java, CORBA IDL и Pike. Когда мы говорим "режим C и родственные с ним", мы имеем в виду эти режимы.

Команды перемещения в режиме C

Этот раздел описывает команды для перемещения точки в режиме C и родственных с ним режимах.

C-c C-u
Перемещает точку назад к содержащей ее условной констукции препроцессора, оставляя метку в текущей позиции. Префиксный аргумент работает в качестве счетчика повторов. С отрицательным аргументом, перемещает точку вперед к концу этой условной констукции препроцессора. При проходе назад, #elif рассматривается как #else, за которой стоит #if. При проходе вперед #elif игнорируется.
C-c C-p
Перемещает точку назад через условную констукцию препроцессора, оставляя метку в текущей позиции. Префиксный аргумент служит в качестве счетчика повторов. С отрицательным аргументом, перемещает вперед.
C-c C-n
Перемещает точку вперед через условную констукцию препроцессора, оставляя метку в текущей позиции. Префиксный аргумент служит в качестве счетчика повторов. С отрицательным аргументом, перемещает назад.
M-a
Перемещает точку к началу самого внутреннего оперетора Си (c-beginning-of-statement). Если точка уже находится в начале оператора, перемещает к началу предыдущего. С префиксным аргументом n, перемещает назад на n - 1 операторов. Если точка находится внутри строки или комментария или после комментария (между ними только пропуск), эта команда перемещает по предложениям, а не по операторам. Если эта функция вызвана из программы, она принимает три необязательных аргумента: префиксный числовой аргумент, предел позиции в буфере (не перемещаться назад далее этой позиции) и флаг, который говорит, нужно ли двигаться по предложениям внутри комментария.
M-e
Перемещает точку к концу самого внутреннего оперетора Си; как M-a, но перемещает в противоположном направлении (c-end-of-statement).
M-x c-backward-into-nomenclature
Перемещает точку назад к началу секции или слова в нотации Си++. С префиксным аргументом n, перемещает n раз. Если n отрицательно, перемещает вперед. Нотация Си++ обозначает запись имен символов в стиле ИменованиеСимволовВСмешанномРегистреИБезПодчерков; каждая заглавная буква начинает секцию или слово. В проекте GNU мы рекомендуем использовать для разделения слов в идентификаторах Си или Си++ подчерки, а не изменение регистра.
M-x c-forward-into-nomenclature
Перемещает точку назад к концу секции или слова в нотации Си++. С префиксным аргументом n, перемещает n раз.

Электрик-знаки в Си

В режиме Си и родственных с ним некоторые печатные знаки являются "электрическими" -- помимо вставки самих себя, они также обновляют отступ в текущей строке и могут вставлять переводы строк. Это средство управляется переменной c-auto-newline. "Электрик"-знаки --- это {, }, :, #, ;, ,, <, >, /, *, ( и ).

Электрик-знаки вставляют переводы строк, только если включено средство auto-newline (это отображается в строке режима как `/a' после имени режима). Это средство управляется переменной c-auto-newline. Вы можете включить или выключить его командой C-c C-a:

C-c C-a
Перекючает автоматическую вставку переводов строк (c-toggle-auto-state). С префиксным аргументом, эта команда включает такую возможность, если аргумент положителен, и выключает, если аргумент отрицателен.

Двоеточие -- это электрик-знак, поскольку это подходит для одного двоеточия. Но это неудобно, когда вы хотите вставить двойное двоеточие в Си++. Вы можете вставить двойное двоеточие в Си++ без вставки отступа или перевода строки, набирая C-c :.

C-c :
Вставляет в точке оператор области видимости, двойное двоеточие, не изменяя отступ строки и не добавляя новых строк (c-scope-operator).

Электрик-ключ # обновляет отступ строки, если он оказался в начале директивы препроцессора. Это происходит, когда значение c-electric-pound-behavior равно (alignleft). Вы можете выключить эту возможность, устанавливая c-electric-pound-behavior в nil.

Переменная c-hanging-braces-alist управляет вставкой переводов строк до и после вставленных фигурных скобок. Это ассоциативный список с элементами в такой форме: (синтаксический-символ . список-пс). Большинство синтаксических символов, перечисленных в c-offsets-alist, имеют смысл и здесь.

Список список-пс может содержать один из символов before и after, либо оба, или это может быть nil. Когда вставляется фигурная скобка, в c-hanging-braces-alist ищется определяемый ей синтаксический контекст; если он найден, используется список-пс для выяснения того, где нужно вставить перевод строки: перед фигурной скобкой, после нее или и до, и после. Если ничего не найдено, по умолчанию вставляет перевод строки до и после фигурных скобок.

Переменная c-hanging-colons-alist управляет вставкой переводов строк до и после вставленных двоеточий. Это ассоциативный список, чьи элементы имеют форму (синтаксический-символ . список-пс). Список список-пс может содержать любые из символов before или after, либо оба, или это может быть nil.

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

Электрик-знаки могут также автоматически удалять переводы строк, когда включено средство для их автоматической вставки. Это делает автоматическую вставку переводов строк более приемлимой, путем удаления переводов строк в большинстве случаев, когда это было бы желательно; устанавливая переменную c-cleanup-list, вы можете указать в каких случаях это происходить. Значение этой переменной -- это список символов, каждый из которых описывает один случай возможного удаления перевода строки. Вот перечень воспринимаемых символов и их значений:

brace-catch-brace
Сжимает конструкцию `} catch (условие) {', помещаяя ее целиком на одну строку. Сжатие происходит, когда вы набираете `{', если между фигурными скобками нет ничего, кроме catch и условия.
brace-else-brace
Сжимает конструкцию `} else {', помещаяя ее целиком на одну строку. Сжатие происходит, когда вы набираете `{' после else, но только если между фигурными скобками и else нет ничего, кроме пропусков.
brace-elseif-brace
Сжимает конструкцию `} else if (...) {', помещаяя ее целиком на одну строку. Сжатие происходит, когда вы набираете `{', если между `}' и `{' нет ничего, кроме пропусков, не считая эти ключевые слова и условие для if.
empty-defun-braces
Сжимает фигурные скобки пустого определения функции, помещая их на одну строку. Сжатие происходит, когда вы набираете закрывающую фигурную скобку.
defun-close-semi
Сжимает двоеточие и struct или подобный тип объявления, помещая двоеточие на ту же строку, где стоит закрывающая фигурная скобка. Сжатие происходит, когда вы вводите двоеточие.
list-close-comma
Сжимает запятые, следующие после фигурных скобок в массивах и сложных инициализациях. Сжатие происходит, когда вы набираете запятые.
scope-operator
Сжимает двойное двоеточие, которое может обозначать оператор области видимости в Си++, помещая эти двоеточия вместе. Сжатие происходит, когда вы набираете второе двоеточие, но только если они разделены только пропуском.

Средство голодного удаления в Си

Когда включено средство голодного удаления (это показывается в строке режима как `/h' или `/ah' после имени режима), одна команда DEL удаляет весь предшествующий пропуск, а не только одни пробел. Чтобы включать и выключать эту возможность, используйте C-c C-d:

C-c C-d
Включает или выключает средство голодного удаления (c-toggle-hungry-state). С префиксным аргументом, эта команда включает такую возможность, если аргумент положителен, и выключает, если аргумент отрицателен.
C-c C-t
Переключает средства автоматической вставки перевода строки и голодного удаления одновременно (c-toggle-auto-hungry-state).

Переменная c-hungry-delete-key говорит, включено ли средство голодного удаления.

Другие команды режима C

C-M-h
Помещает метку в конце определения функции, а точку в начале (c-mark-function).
M-q
Заполняет абзац, обрабатывая комментарии Си и Си++ (c-fill-paragraph). Если какая-либо часть текущей строки является комментарием или находится внутри комментария, эта команда заполняет этот комментарий или его абзац, сохраняя отступы и ограничители комментария.
C-c C-e
Запускает препроцессор Си для текста в области и показывает результат, который включает раскрытия всех вызовов макросов (c-macro-expand). Текст буфера, написанный перед областью, также передается препроцессору, так как там могут быть определения макросов, но вывод для этой части не показывается. Когда вы отлаживаете использующий макросы код на Си, бывает трудно точно понять, как раскрываются макросы. С этой командой вам не нужно это понимать, вы можете видеть раскрытия.
C-c C-\
Вставляет или выравнивает знаки `\' в концах строк области (c-backslash-region). Это полезно после написания или редактирования определения макроса Си. Если строка уже завершается знаком `\', эта команда подстраивает размер пропуска перед ним. В противном случае она вставляет новый `\'. Однако, последняя строка области рассматривается особо; в нее не вставляется `\', а если если этот знак там стоит, то он удаляется.
M-x cpp-highlight-buffer
Подсвечивает части текста в соответствии с условными конструкциями препроцессора. Эта команда показывает еще один буфер с именем `*CPP Edit*', который служит в качестве графического меню для выбора способа отображения конкретных видов условных конструкций и их содержимого. После изменения различных установок щелкните на `[A]pply these settings' (или перейдите в этот буфер и нажмите a), чтобы соответственно обновить подветку в буфере с режимом C.
C-c C-s
Показывает информацию о синтаксисе текущей исходной строки (c-show-syntactic-information). Это та информация, которая управляет отступом строки.

Комментарии в режимах C

Режим C и родственные режимы используют несколько переменных для управления форматом комментариев.

c-comment-only-line-offset
Дополнительный сдвиг для строки, которая содержит только начало комментария. Это может быть либо число, либо пара в форме (не-привязанный-сдвиг . привязанный-сдвиг), где не-привязанный-сдвиг -- это размер сдвига, придаваемый полнострочным комментариям, начинающимся не в нулевом столбце, а привязанный-сдвиг -- это размер сдвига, даваемый полнострочным комментариям, начинающимся в нулевом столбце. Простое число в качестве значения эквивалентно (значение . 0).
c-comment-start-regexp
Эта локальная для буфера переменная указывает, как распознавать начало комментария.
c-hanging-comment-ender-p
Если эта переменная равна nil, c-fill-paragraph оставляет завершающую строку для блока комментария на отдельной строке. Значение по умолчанию равно t, что помещает закрывающий ограничитель комментария `*/' в конце последней строки текста комментария.
c-hanging-comment-starter-p
Если эта переменная равна nil, c-fill-paragraph оставляет начинающий ограничитель блока комментария на отдельной строке. Значение по умолчанию равно t, что помещает открывающий ограничитель комментария `/*' в начале первой строки текста комментария.

Режим Fortran

Режим Fortran предоставляет специальные команды движения для операторов и подпрограмм на Фортране и команды отступов, которые понимают фортрановские соглашения о вложенности, номера строк и операторы продолжения. Режим Fortran имеет свой собственный режим Auto Fill, который обрывает длинные строки на правильные с точки зрения Фортрана строки продолжения.

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

Используйте M-x fortran-mode, чтобы переключиться в этот режим. Эта команда запускает ловушку fortran-mode-hook (смотрите раздел Ловушки).

Команды движения

Режим Fortran обеспечивает специальные команды для движения через подпрограммы (функции и процедуры) и через операторы. Есть также команда для установки области вокруг подпрограмм, удобная для их уничтожения и перемещения.

C-M-a
Переместить точку на начало подпрограммы (beginning-of-fortran-subprogram).
C-M-e
Переместить точку на конец подпрограммы (end-of-fortran-subprogram).
C-M-h
Поставить точку в начале подпрограммы, а метку в ее конце (mark-fortran-subprogram).
C-c C-n
Перейти на начало текущего или следующего оператора (fortran-next-statement).
C-c C-p
Перейти на конец текущего или предыдущего оператора (fortran-previous-statement).

Отступы в Фортране

Для создания отступов в программах на Фортране необходимы специальные команды и средства, чтобы быть уверенным в том, что различные синтаксические единицы (номера строк, указатели комментариев и флаги продолжения строк) появляются в тех столбцах, которые требует стандарт Фортрана.

Команды отступа в Фортране

TAB
Сделать отступ текущей строки (fortran-indent-line).
C-j
Сделать отступ текущей строки и начать новую строку с отступом (fortran-indent-new-line).
C-M-j
Прервать текущую строку и подготовить строку продолжения.
M-^
Соединить эту строку со следующей.
C-M-q
Сделать отступ во всех строках подпрограммы, в которой находится точка (fortran-indent-subprogram).

Режим Fortran переопределяет TAB так, чтобы он делал новый отступ в текущей строке для Фортрана (fortran-indent-line). Номера строк и маркеры продолжения имеют отступ до требуемых столбцов, а тело оператора получает независимый отступ, основанный на его вложенности в программе.

Ключ C-j запускает команду fortran-indent-new-line, которая заново делает отступ в текущей строке, а затем создает новую строку и деалет отступ в ней. Эта команда полезна для создания нового отступа в закрывающем операторе циклов `do' и других блоков перед началом новой строки.

Ключ C-M-q запускает fortran-indent-subprogram, команду для создания отступа во всех строках фортрановской подпрограммы (функции и процедуры), cодержащей точку.

Ключ C-M-j запускает fortran-split-line, которая разрывает строку соответствующим Фортрану способом. В строке, которая не является комментарием, вторая половина становится строкой продолжения и имеет соответственный отступ. В строке комментария обе половины становятся отдельными строками комментария.

M-^ запускает команду fortran-join-line, которая более или менее является обращением fortran-split-line. Она объединяет текущую и предшествующую строки подходящим для Фортрана способом.

Строки продолжения

Большиство современных компиляторов Фортрана разрешают два способа написания строк продолжения. Если первый непробельный знак на строке находится в столбце 5, то эта строка считается продолжением предыдущей. Мы называем это фиксированным форматом; (В GNU Emacs мы всегда остчитываем столбцы от нуля.) Переменная fortran-continuation-string указывает, какой знак надо помещать в столбец 5. Строка, начинающаяся со знака табуляции, за которым стоит любая цифра, кроме `0', также является строкой продолжения. Этот стиль продолжения мы называем табулированным форматом.

Режим Fortran может делать строки продолжения в обоих стилях, но вы должны указать, какой вы предпочитаете. Этим выбором управляет значение прееменной indent-tabs-mode: nil означает фиксированный формат, а отличное от nil -- табулированный. Вы можете судить о действующим в данный момент формате по наличию или отсутствию в строке режима слова `Tab'.

Если текст на строке начинается с принятого в Фортране маркера продолжения `$' или с непробельного знака в столбце 5, режим Fortran считает эту строку строкой продолжения. Когда вы делаете в строке продолжения отступ с помощью TAB, эта строка приводится к текущему стилю продолжения. Когда вы разбиваете фортрановский оператор с помощью C-M-j, на новой строке создается маркер продолжения в соотвествии с этим стилем.

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

Когда вы включаете режим Fortran для существующего файла, он старается вычислить подходящий стиль продолжения автоматически, исходя из содержимого этого файла. Выбор определяет первая строка, которая начинается с табуляции или шести пробелов. Переменная fortran-analyze-depth определяет, сколько строк нужно рассмотреть (от начала файла); если ни одна их этих строк не укажет стиль, то он определяется по переменной fortran-tab-mode-default. Если она равна nil, то используется фиксированный формат, отличное от nil значение велит использовать табулированный формат.

Номера строк

Если первым непробельным текстом на строке является число, режим Fortran предполагает, что это номер строки, и перемещает его к столбцам от 0 до 4. (В GNU Emacs столбцы всегда отсчитываются от нуля.)

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

Простая вставка номера строки достаточна для того, чтобы отступ у него соответствовал этим правилам. Как только вставляется каждая цифра, отступ пересчитывается. Чтобы выключить это свойство, установите переменную fortran-electric-line-number в nil. Тогда вставка номеров строк будет похожа на вставку всего остального.

Синтаксические соглашения

Режим Fortran предполагает, что вы следуете определенным соглашениям, которые упрощают задачу понимания программ на Фортране в достаточной степени, чтобы делать в них правильный отступ:

  • Два вложенных цикла `do' никогда не имеют общего оператора `continue'.
  • Ключевые слова Фортрана, такие как `if', `else', `then', `do' и другие, написаны без внутренних пробелов и разрывов строк. Компиляторы Фортрана обычно игнорируют все пробельные знаки вне строковых констант, но режим Fortran не распознает эти ключевые слова, если они разорваны. Конструкции вроде `else if' или `end do' допустимы, но второе слово должно быть на той же строке, что и первое, а не на строке продолжения.

Если вы не следуете этим соглашениям, команды отступа могут сделать отступ в некоторых строках неэстетично. Однако, правильная программа на Фортране будет сохранять свое значение при новых отступах, даже если эти соглашения не соблюдались.

Переменные для управления отступами

Несколько дополнительных переменных управляют тем, как работает отступ в Фортране:

fortran-do-indent
Дополнительный отступ в пределах каждого уровня оператора `do' (по умолчанию 3).
fortran-if-indent
Дополнительный отступ в пределах каждого уровня оператора `if' (по умолчанию 3). Это же значение используется для дополнительного отступа каждого уровня оператора Фортрана90 `where'.
fortran-structure-indent
Дополнительный отступ в пределах каждого уровня операторов `structure', `union' или `map' (по умолчанию 3).
fortran-continuation-indent
Дополнительный отступ для тел строк продолжения (по умолчанию 5).
fortran-check-all-num-for-matching-do
Если это nil, команды отступа считают, что каждый оператор `do' кончается на операторе `continue'. Поэтому при вычислении отступа для оператора, отличного от `continue', они могут сократить время, не выполняя в этом месте проверку окончания оператора `do'. Если это не nil, то команды отступа для любого пронумерованного оператора должны проверять, не заканчивается ли там `do'. По умолчанию значение равно `nil'.
fortran-blink-matching-if
Если это t, создание отступа для оператора `endif' на мгновение перемещает курсор к парному оператору `if', чтобы вы видели, где он находится. По умолчанию nil.
fortran-minimum-statement-indent-fixed
Минимальный отступ для операторов Фортрана при использовании фиксированного формата для строк продолжения. Тела операторов никогда не получают отступ менее этого. По умолчанию это 6.
fortran-minimum-statement-indent-tab
Минимальный отступ для операторов Фортрана при использовании табулированного формата строк продолжения. Тела операторов никогда не получают отступ менее этого. По умолчанию это 8.

Комментарии в Фортране

Обычные команды Emacs для комментариев предполагают, что комментарии могут следовать за строкой кода. В Фортране стандартный синтаксис комментариев требует отведения строки целиком только под комментарий. Поэтому режим Fortran заменяет стандартные команды комментариев в Emacs и определяет некоторые новые переменные.

Режим Fortran также может обрабатывать нестандартный синтаксис комментариев, когда комментарии начинаются с `!' и могут следовать за другим текстом. Так как только некоторые компиляторы Фортрана признают такой синтаксис, режим Fortran не вставляет такие комментарии, если вы не потребовали этого заранее. Чтобы сделать это, установите переменной comment-start значение `"!"' (смотрите раздел Переменные).

M-;
Выровнять комментарий или вставить новый комментарий (fortran-comment-indent).
C-x ;
Применяется только к нестандартным комментариям `!'.
C-c ;
Превратить все строки области в комментарии или (с аргументом) превратить их обратно в реальный код (fortran-comment-region).

M-; в режиме Fortran переопределяется на fortran-comment-indent. Как и обычная команда M-;, она распознает любой вид существующих комментариев и соответственно выравнивает его текст; если существующего комментария нет, то комментарий вставляется и выравнивается. Но вставка и выравнивание комментариев в режиме Fortran не такие, как в других режимах.

Когда должен быть вставлен новый комментарий, то, если текущая строка пустая, вставляется полная строка комментария. В непустой строке вставляется нестандартный комментарий с `!', если вы сказали, что хотите их использовать. В противном случае в новую строку перед текущей вставляется полная строка комментария.

Нестандартные комментарии с `!' выравниваются, как комментарии в других языках, но полнострочные комментарии выравниваются иначе. В стандартном полнострочном комментарие сам ограничитель комментария должен всегда появляться в нулевом столбце. Что может выравниваться, так это текст в пределах комментария. Вы можете выбирать из трех возможных видов выравнивания, устанавливая переменную fortran-comment-indent-style в одно из этих значений:

fixed
Текст выравнивается по фиксированному столбцу, который является суммой fortran-commenrt-line-column и минимального отступа оператора. Это значение принимается по умолчанию. Минимальный отступ операторов -- это fortran-minimum-statement-indent-fixed для стиля продолжения с фиксированным форматом и fortran-minimum-statement-indent-tab для стиля с табулированным форматом.
relative
Текст выравнивается так, как если бы он был строкой кода, но с дополнительными fortran-comment-line-column столбцами отступа.
nil
Текст в полнострочных комментариях не перемещается автоматически.

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

В режиме Fortran вводятся две переменные, comment-line-start и comment-line-start-skip, которые играют для полнострочных комментариев ту же роль, что и comment-start и comment-start-skip для обычных, следующих за текстом комментариев. Обычно они устанавливаются правильно режимом Fortran, так что их не нужно менять.

Обычная команда Emacs для создания комментария C-x ; переопределена. Если вы используете комментарии с `!', эта команда может быть использована с ними. Иначе она бесполезна в режиме Fortran.

Команда C-c ; (fortran-comment-region) превращает все строки области в комментарии, вставляя `C$$$' в начале каждой из строк. С числовым аргументом, она превращает область обратно в реальный код, удаляя `C$$$' из начала каждой строки в этой области. Строка, используемая для этих комментариев, может управляться установкой переменной fortran-comment-region. Заметим, что здесь мы имеем пример команды и переменной с одним и тем же именем. Эти два варианта использования имени никогда не конфликтуют, так как в Лиспе и в Emacs всегда понятно по контексту, какое из них имеется в виду.

Режим Fortran Auto Fill

Режим Fortran Auto Fill -- это второстепенный режим, который автоматически разбивает фортрановские операторы, когда они становятся слишом широкими по мере того, как вы их вставляете. Разбиение оператора влечет создание строки продолжения с использованием fortran-continuation-string (смотрите раздел Строки продолжения). Разбиение происходит, когда вы набираете SPC, RET или TAB, а также в командах для отступов в Фортране.

M-x fortran-auto-fill-mode включает режим Fortran Auto Fill, если он был выключен, или выключает, если он был включен. Эта команда работает так же, как работает M-x auto-fill-mode для обычного режима Auto Fill (смотрите раздел Заполнение текста). Положительный аргумент включает режим Fortran Auto Fill, а отрицательный выключает. Вы можете узнать, действует ли режим Fortran Auto Fill, по наличию слова `Fill' в строке режима в круглых скобках. Режим Fortran Auto Fill -- это второстепенный режим, включаемый и выключаемый в каждом буфере отдельно. Смотрите раздел Второстепенные режимы.

Режим Fortran Auto Fill разрывает строки на пробелах или разделителях, когда строки становятся длиннее желаемой ширины (значения fill-column). Разделителями, на которых режим Fortran Auto Fill может разорвать строку, являются `,', `'', `+', `-', `/', `*', `=' и `)'. Разрыв происходит после разделителя, если переменная fortran-break-before-delimiters равна nil. Иначе (и по умолчанию) разрыв делается перед разделителем.

По умолчанию режим Fortran Auto Fill не задействован. Если вы хотите, чтобы это средство было включено постоянно, добавьте к fortran-mode-hook функцию-ловушку, которая выполнит (fortran-auto-fill-mode 1). Смотрите раздел Ловушки.

Проверка столбцов в Фортране

C-c C-r
Кратковременно показать "линейку столбцов" над текущей строкой (fortran-column-ruler).
C-c C-w
Временно разделить текущее окно по горизонтали таким образом, чтобы оно стало шириной в 72 столбца. Это может помочь вам избежать выхода за лимит в 72 столбца, который накладывают некоторые компиляторы Фортрана (fortran-window-create-momentarily).

Команда C-c C-r (fortran-column-ruler) кратковременно показывает над текущей строкой линейку столбцов. Линейка столбцов --- это две строки текста, которые показывают вам позиции столбцов, имеющих специальные значения в Фортран-программах. Квадратные скобки показывают границы столбцов для номеров строк, а фигурные скобки показывают границы столбцов для тела оператора. Над ними показаны номера столбцов.

Заметьте, что номера столбцов считаются от нуля, как всегда в GNU Emacs. В связи с этим номера могут на единицу меньше, чем те, к которым вы привыкли; но указываемые ими позиции в строке стандартны для Фортрана.

Текст, используемый для показа линейки столбцов, зависит от значения переменной indent-tabs-mode. Если indent-tabs-mode равна nil, то в качестве линейки столбцов используется значение переменной fortran-column-ruler-fixed. Иначе показывается переменная fortran-column-ruler-tab. Изменяя эти переменные, вы можете изменить вид линейки столбцов.

Для еще большей помощи используйте команду C-c C-w (fortran-window-create), которая разделяет теущее окно по горизонтали, делая его ширину равной 72 столбцам. При редактировании в этом окне вы можете непосредственно видеть, когда вы сделали строку слишком длинной, чтобы она была правильной с точки зрения Фортрана.

Сокращения ключевых слов Фортрана

Режим Fortran обеспечивает множество встроенных сокращений для часто встречающихся ключевых слов и объявлений. Это те же виды сокращений, которые вы можете определить сами. Чтобы использовать их, вы должны включить режим Abbrev. Смотрите раздел Сокращения.

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

Например, одно встроенное фортрановское сокращение -- это `;с' для `continue'. Если вы вставите `;с' и затем поставите знаки пунктуации, например пробел или перевод строки, то `;с' автоматически изменится на `continue', при условии, что включен режим Abbrev.

Наберите `;?' или `;C-h', чтобы просмотреть все встроенные сокращения для Фортрана и то, чему они соответствуют.

Другие команды режима Fortran

C-x n d
Сужает до текущей подпрограммы Фортрана.

Режим Fortran переопределяет ключ C-x n d для запуска команды fortran-narrow-to-subprogram, которая служит фортрановским аналогом обычного определения этого ключа. Она сужает буфер до подпрограммы, содержащей точку.

Режим Asm

Режим Asm -- это основной режим для редактирования файлов на ассемблерном коде. Он определяет следующие команды:

TAB
tab-to-tab-stop.
C-j
Вставляет перевод строки и делает отступ, используя tab-to-tab-stop.
:
Вставляет двоеточие и затем удаляет отступ перед меткой, предшествующей двоеточию. Затем делает tab-to-tab-stop.
;
Вставляет или выравнивает комментарий.

Переменная asm-comment-char определяет, какой знак начинает комментарий в синтаксисе ассемблера.


Обсудить данную тему на нашем форуме "Все о Linux"