| |
В Emacs есть много команд, предназначенных для понимания синтаксиса языков программирования, таких как Лисп и Си. Эти команды могут:
Команды для слов, предложений и абзацев очень удобны при редактировании программ, даже хотя их традиционным применением является редактирование текстов на естественном языке. Большинство символов содержат слова (смотрите раздел Слова); предложения могут быть найдены в строках или комментариях (смотрите раздел Предложения). Абзацы так таковые не присутствуют в коде, но команды работы с абзацами тем не менее полезны, так как основные режимы для языков программирования определяют абзацы как куски текста, начинающиеся и заканчивающиеся пустыми строками (смотрите раздел Абзацы). Разумное использование пустых строк для улучшения читаемости программы будет также предоставлять командам, оперрирующим с абзацами, интересные куски текста для работы.
Средство выборочного показа полезно для просмотра общей структуры функции (смотрите раздел Выборочный показ). Это средство делает так, что на экране появляются только те строки, отступ в которых меньше заданной величины.
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
. Смотрите раздел Ловушки.
По соглашению, ключи 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 его правильно понимал.
forward-sexp
).
backward-sexp
).
kill-sexp
).
backward-kill-sexp
).
backward-up-list
).
down-list
).
forward-list
).
backward-list
).
transpose-sexps
).
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 понимается как определение
функции, независимо от ее содержания и от используемого языка
программирования. Например, тело функции в Си -- это определение
функции.
beginning-of-defun
).
end-of-defun
).
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
. Эта программа переформатирует
лисповский объект, выбирая отступы таким образом, чтобы результат хорошо
выглядел и удобно читался.
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 (и правилами отступа) как начало функции. Поэтому вы никогда не должны ставить открывающий ограничитель, не являющийся началом функции, в нулевом столбце, даже внутри строковой константы. Это ограничение жизненно важно для скорости работы команд отступа; вы должны просто принять его. Для более подробной информации об этом смотрите раздел Определения функций.
Если вы хотите поменять отступ нескольких строк кода, которые были изменены или передвинуты на другой уровень в структуре списков, вы имеете в своем распоряжении несколько команд.
indent-sexp
).
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
,
также используется и для этой функции.
lisp-body-indent
столбцов больше,
чем открывающая скобка, начинающая содержащее ее выражение. Если
аргумент является отличительным, и это первый или второй аргумент, то
отступ делается на вдвое большее число дополнительных столбцов.
Если аргумент отличителен и не является первым или вторым, то для этой
строки применяется стандартный шаблон.
parse-partial-sexp
(это примитив Лиспа
для подсчета величины отступов и вложенностей), когда она делает разбор
вплоть до начала этой строки.
Вот команды для создания отступов в режиме 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 и родственные режимы используют простой, но гибкий механизм для настройки отступа. Этот механизм работает в два этапа: сначала строки классифицируются синтаксически в соответствии с их содержимым и контекстом; затем каждому виду синтаксических конструкций привязывается значение сдвига, который вы можете настроить.
На первом шаге механизм отступов в Си смотрит на строку перед той, в
которой вы в данный момент делаете отступ, и определяет синтаксические
компоненты конструкции на этой строке. Он строит список этих
синтаксических компонентов, где каждый компонент содержит
синтаксический символ и, иногда, позицию в буфере. Некоторые
синтаксические символы описывают грамматические элементы, например
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
. Каждый элемент этого списка ---
это синтаксический компонент: пара, содержащая синтаксический
символ и (возможно) соответствующую ему позицию в буфере. В списке
компонент может несколько элементов; как правило только один из них
имеет позицию в буфере.
Механизма отступов в Си вычисляет величину отступа для текущей строки,
используя список синтаксических компонентов, 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. Во-первых, вы можете выбрать один из предопределенных стилей, каждый из которых задает сдвиги для всех синтаксических символов. Для большей гибкости вы можете настоить обработку отдельных синтаксических символов. Смотрите раздел Синтаксические символы, перечень всех определенных синтаксических символов.
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-close
extern-lang-open
extern-lang-close
func-decl-cont
throws
и другие вещи.
knr-argdecl-intro
knr-argdecl
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
inexpr-class
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
({
... })
. Это также нужно для специальных функций в Pike,
принимающих в качестве аргумента операторный блок.
inexpr-class
cpp-macro
friend
friend
.
objc-method-intro
objc-method-args-cont
objc-method-call-cont
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-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 предоставляет особые команды для редактирования и вставки комментарев.
Команды комментариев вставляют, уничтожают и выравнивают комментарии:
indent-for-comment
).
set-comment-column
).
kill-comment
).
indent-new-comment-line
).
Команда, которая создает комментарии, называется 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 эта функция-ловушка для создания отступа основывает свое решение на
том, сколько точек с запятой начинают существующий комментарий, и на
коде в предыдущих строках.
insert-parentheses
).
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, используйте
команду 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 <[email protected]> * 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 <[email protected]> * 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'.
Каждый элемент в таблице тегов записывает имя одного тега, имя файла, в котором этот тег определен (явно), и местоположение определения тега в этом файле.
Какие именно имена из описанных файлов записываются в таблице тегов, зависит от языка программирования описанного файла. Обычно они включают все функции и подпрограммы, могут также включать глобальные переменные, типы данных и что-нибудь еще относящееся к делу. Каждое записанное имя называется тегом.
В наиболее популярных языках синтаксис тегов определяется следующим образом:
struct
, union
и enum
.
Определения макросов (#define
) и констант (enum
) также
являются тегами, если только вы не задали при создании таблицы тегов
ключ --no-defines
. Аналогично, тегами являются глобальные
переменные, если только вы не задали ключ --no-globals
.
Использование --no-globals
и --no-defines
может
сделать файлы таблиц тегов гораздо меньше.
--members
. Теги для переменных и функций в классах именуются
как `класс::переменная' и
`класс::функция'.
extends
и implements
. Теги для
переменных и функций в классах именуются как
`класс.переменная' и `класс.функция'.
\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' в нулевом столбце, являются тегом.
def
или
конструкции, чье имя начинается с `def'. Они также включают
переменные, установленные с помощью set!
на верхнем уровне файла.
Поддерживаются также несколько других языков:
sub
.
Вы также можете генерировать теги, основываясь на сопоставлении регулярных выражений (смотрите раздел Создание таблицы тегов), чтобы обработать другие форматы и языки.
Для создания файла таблицы тегов используется программа
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(]+"\([^"]+\)"/'
--language=none --regex='/[ \t]*\(ARCHITECTURE\|CONFIGURATION\) +[^ ]* +OF/' --regex='/[ \t]*\(ATTRIBUTE\|ENTITY\|FUNCTION\|PACKAGE\ \( BODY\)?\|PROCEDURE\|PROCESS\|TYPE\)[ \t]+\([^ \t(]+\)/\3/'
--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
одновременно.
Самая важная вещь, которую вам позволяют делать таблицы тегов, -- это поиск определения конкретного тега.
find-tag
).
find-tag-regexp
).
find-tag-other-window
).
find-tag-other-frame
).
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-., но производит сопоставление с регулярным выражением, а не со
строкой.
Команды этого раздела обращаются и просматривают все файлы, перечисленные в выбранной таблице тегов, один за другим. Таблица тегов служит для этих команд только для того, чтобы определить последовательность поиска в файлах.
query-replace-regexp
в каждом файле в выбранной
таблице тегов.
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 считывает имя одного из файлов, описанных в выбранной таблице тегов, и показывает список всех тегов, определенных в этом файле. Аргумент "имя файла" фактически является просто строкой для сравнения с именами, записанными в таблице тегов; он считывается как строка, а не как имя файла. Поэтому завершение и значение по умолчанию невозможны, и вы должны вводить имя файла в том же самом виде, в котором оно появляется в таблице тегов. Не включайте каталог как часть имени файла, если имя файла, записанного в таблице тегов, не включает каталог.
M-x tags-apropos похожа на apropos
для тегов
(смотрите раздел Поиск по контексту). Она считывает регулярное выражение,
затем находит все теги в выбранной таблице тегов, чьи вхождения
соответствуют этому регулярному выражению, и показывает найденные имена
тегов.
Вы также можете производить в буфере завершение в пространстве имен, составленном из имен тегов текущих таблиц. Смотрите раздел Завершение для имен символов.
Нередко программисты перебегают друг другу дорогу и изменяют одну и ту же программу в двух разных направлениях. Чтобы справиться с этой путаницей, вам необходимо объединить две эти версии. Emerge упрощает это. Смотрите также раздел Сравнение файлов, о командах для сравнения файлов более ручным методом, и раздел `Emerge' в The Ediff Manual.
Чтобы запустить Emerge, выполните одну из этих четырех команд:
Команды 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 не сохранит выходной буфер, но вы можете записать его сами, если хотите.
Вы можете выбирать из двух режимов для отдания команд объединения: режим 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' и `^'. Каждое различие имеет одно из семи следующих состояний:
Это команды объединения для режима Fast; в режиме Edit предваряйте их набором C-c C-c:
Команда 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"
В процессе объединения вы не должны пытаться редактировать буферы A и B сами. Emerge временно изменяет их, но в конце возвращает в исходное состояние.
Вы можете производить любое число объединений одновременно -- только не используйте один и тот же буфер в качестве входного более чем для одного объединения, так как временные изменения, сделанные в этих буферах, столкнулись бы друг с другом.
Запуск Emerge может занять продолжительное время, поскольку ей
требуется полностью сравнить файлы. Emacs не можете ничего делать, пока
diff
не завершится. Возможно, в будущем кто-то изменит Emerge
так, что она будет делать сравнение в фоновом режиме, когда входные
файлы велики -- тогда вы могли бы продолжать в Emacs другие дела, пока
Emerge действительно не будет готова принимать команды.
После подготовки объединения Emerge запускает ловушку
emerge-startup-hook
(смотрите раздел Ловушки).
Этот раздел описывает особые средства, доступные в режимах C, C++, Objective-C, Java, CORBA IDL и Pike. Когда мы говорим "режим 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
c-end-of-statement
).
M-x c-backward-into-nomenclature
M-x c-forward-into-nomenclature
В режиме Си и родственных с ним некоторые печатные знаки являются
"электрическими" -- помимо вставки самих себя, они также обновляют
отступ в текущей строке и могут вставлять переводы строк. Это средство
управляется переменной c-auto-newline
. "Электрик"-знаки ---
это {, }, :, #, ;, ,, <,
>, /, *, ( и ).
Электрик-знаки вставляют переводы строк, только если включено средство
auto-newline (это отображается в строке режима как `/a' после
имени режима). Это средство управляется переменной
c-auto-newline
. Вы можете включить или выключить его командой
C-c C-a:
c-toggle-auto-state
). С префиксным аргументом, эта команда
включает такую возможность, если аргумент положителен, и выключает, если
аргумент отрицателен.
Двоеточие -- это электрик-знак, поскольку это подходит для одного двоеточия. Но это неудобно, когда вы хотите вставить двойное двоеточие в Си++. Вы можете вставить двойное двоеточие в Си++ без вставки отступа или перевода строки, набирая 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
и
условия.
brace-else-brace
else
, но только если между фигурными скобками и else
нет
ничего, кроме пропусков.
brace-elseif-brace
if
.
empty-defun-braces
defun-close-semi
struct
или подобный тип объявления, помещая
двоеточие на ту же строку, где стоит закрывающая фигурная скобка.
Сжатие происходит, когда вы вводите двоеточие.
list-close-comma
scope-operator
Когда включено средство голодного удаления (это показывается в строке режима как `/h' или `/ah' после имени режима), одна команда DEL удаляет весь предшествующий пропуск, а не только одни пробел. Чтобы включать и выключать эту возможность, используйте C-c C-d:
c-toggle-hungry-state
). С префиксным аргументом, эта команда
включает такую возможность, если аргумент положителен, и выключает, если
аргумент отрицателен.
c-toggle-auto-hungry-state
).
Переменная c-hungry-delete-key
говорит, включено ли средство
голодного удаления.
c-mark-function
).
c-fill-paragraph
). Если какая-либо часть текущей строки является
комментарием или находится внутри комментария, эта команда заполняет
этот комментарий или его абзац, сохраняя отступы и ограничители
комментария.
c-macro-expand
). Текст буфера, написанный перед областью, также
передается препроцессору, так как там могут быть определения макросов,
но вывод для этой части не показывается.
Когда вы отлаживаете использующий макросы код на Си, бывает трудно точно
понять, как раскрываются макросы. С этой командой вам не нужно это
понимать, вы можете видеть раскрытия.
c-backslash-region
). Это полезно после написания или
редактирования определения макроса Си.
Если строка уже завершается знаком `\', эта команда подстраивает
размер пропуска перед ним. В противном случае она вставляет новый
`\'. Однако, последняя строка области рассматривается особо; в нее
не вставляется `\', а если если этот знак там стоит, то он
удаляется.
c-show-syntactic-information
). Это та информация, которая
управляет отступом строки.
Режим 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 имеет свой собственный режим Auto Fill, который обрывает длинные строки на правильные с точки зрения Фортрана строки продолжения.
Предусматриваются специальные команды для комментариев, так как комментарии в Фортране не похожи на комментарии в других языках. Возможны встроенные сокращения, которые убыстряют набор, когда вы вставляете ключевые слова Фортрана.
Используйте M-x fortran-mode, чтобы переключиться в этот режим.
Эта команда запускает ловушку fortran-mode-hook
(смотрите раздел Ловушки).
Режим Fortran обеспечивает специальные команды для движения через подпрограммы (функции и процедуры) и через операторы. Есть также команда для установки области вокруг подпрограмм, удобная для их уничтожения и перемещения.
beginning-of-fortran-subprogram
).
end-of-fortran-subprogram
).
mark-fortran-subprogram
).
fortran-next-statement
).
fortran-previous-statement
).
Для создания отступов в программах на Фортране необходимы специальные команды и средства, чтобы быть уверенным в том, что различные синтаксические единицы (номера строк, указатели комментариев и флаги продолжения строк) появляются в тех столбцах, которые требует стандарт Фортрана.
fortran-indent-line
).
fortran-indent-new-line
).
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 предполагает, что вы следуете определенным соглашениям, которые упрощают задачу понимания программ на Фортране в достаточной степени, чтобы делать в них правильный отступ:
Если вы не следуете этим соглашениям, команды отступа могут сделать отступ в некоторых строках неэстетично. Однако, правильная программа на Фортране будет сохранять свое значение при новых отступах, даже если эти соглашения не соблюдались.
Несколько дополнительных переменных управляют тем, как работает отступ в Фортране:
fortran-do-indent
fortran-if-indent
fortran-structure-indent
fortran-continuation-indent
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
fortran-minimum-statement-indent-tab
Обычные команды Emacs для комментариев предполагают, что комментарии могут следовать за строкой кода. В Фортране стандартный синтаксис комментариев требует отведения строки целиком только под комментарий. Поэтому режим Fortran заменяет стандартные команды комментариев в Emacs и определяет некоторые новые переменные.
Режим Fortran также может обрабатывать нестандартный синтаксис
комментариев, когда комментарии начинаются с `!' и могут следовать
за другим текстом. Так как только некоторые компиляторы Фортрана
признают такой синтаксис, режим Fortran не вставляет такие комментарии,
если вы не потребовали этого заранее. Чтобы сделать это, установите
переменной comment-start
значение `"!"'
(смотрите раздел Переменные).
fortran-comment-indent
).
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-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)
. Смотрите раздел Ловушки.
fortran-column-ruler
).
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-narrow-to-subprogram
, которая служит фортрановским
аналогом обычного определения этого ключа. Она сужает буфер до
подпрограммы, содержащей точку.
Режим Asm -- это основной режим для редактирования файлов на ассемблерном коде. Он определяет следующие команды:
tab-to-tab-stop
.
tab-to-tab-stop
.
tab-to-tab-stop
.
Переменная asm-comment-char
определяет, какой знак начинает
комментарий в синтаксисе ассемблера.
Закладки на сайте Проследить за страницей |
Created 1996-2024 by Maxim Chirkov Добавить, Поддержать, Вебмастеру |