Разнообразные команды – ЧАСТЬ 14

Emacs различает эти два типа ввода, когда используется с X Window System. Он обрабатывает эти “особые” клавиши как функциональные с именами tab,  return, backspace, linefeed, escape и delete. Эти функциональные клавиши автоматически транслируются в соответствующие ASCII-знаки, если у них нет собственных привязок. В результате ни пользователи, ни программы на Лиспе не обязаны помнить об этом различии, если только им это не нужно.

Если вы не хотите различать (например) hTABi  и C-i,  просто сделайте одну привязку для ASCII-знака hTABi  (восьмиричный код 011). Если вы действительно хотите различать их,  то сделайте  одну привязку для этого ASCII-знака, а вторую для “функциональной клавиши” tab.

На обычных ASCII-терминалах нет способа различать hTABi  и C-i  (и аналогично для других таких пар), потому что терминал посылает один и тот же знак в обоих случаях.

31.4.9  Не-ASCII-знаки на клавиатуре

Если на вашей клавиатуре есть клавиши, которые посылают знаки, не  входящие в ASCII,  например акцентированные буквы,  перепривязка их  делается несколько хитро. Есть два решения.  Одно — указать систему кодирования для клавиатуры, используя set-keyboard-coding-system (см.  Раздел 18.9 [Задание кодирования],  с. 168). Затем вы можете привязывать эти клавиши обычным способом, но записывая

(global-set-key [?знак]  ’какая-то-функция)

и подставляя знак, который вы хотите привязать

Если вы не указываете систему кодирования для клавиатуры, этот способ не сработает. Вместо этого вам нужно выяснить код, который в действительности  посылает терминал. Простейший способ сделать это в Emacs — создать пустой буфер с помощью C-x b temp hRETi,  сделать его однобайтным,  набрав M-x toggle-enable-multibyte-characters hRETi, а затем нажать клавишу, которая вставит в этот буфер нужный знак.

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

(global-set-key [десятичныйкод]  ’какая-то-функция)

31.4.10  Перепривязка кнопок мыши

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

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

(global-set-key [mouse-2]  ’split-window-vertically)

Символы для события-проведения похожи на предыдущие, но имеют префикс ‘drag-’ перед словом ‘mouse’. Например, проведение с помощью первой кнопки генерирует событие drag-mouse-1.

Вы также  можете  определить привязки для событий, которые возникают в момент нажатия на кнопку  мыши.   Имена этих  событий начинаются со слова ‘down-’ вместо

‘drag-’. Такие события генерируются, только если они имеют привязку. Когда вы получите событие-нажатие, то за ним всегда будут следовать соответствующее  событие-щелчок или проведение.

Если хотите,  вы можете  различать одиночные,  двойные и тройные щелчки.  Двойной щелчок означает щелканье кнопкой мыши дважды почти в одном и том же месте. Первый щелчок генерирует  обычное событие-щелчок. Второй щелчок, если он приходит достаточно быстро, генерирует  событие-двойной щелчок.  Тип события для двойного щелчка начинается с ‘double-’: например, double-mouse-3.

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

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

“чуть больше”. Команда для события-двойного щелчка должна выполнять больше работы для двойного щелчка.

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

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

‘triple-’.    Emacs не  различает четвертное нажатие как  тип  события; щелчки свыше третьего   генерируют   дополнительные события-тройные  щелчки.       Однако  полное количество щелчков сохраняется в списке событий, так что вы можете  различать такие случаи, если вам это действительно нужно.   Мы не рекомендуем  особых значений для более  чем трех щелчков, но иногда полезно, чтобы последующие щелчки проходили по циклу того же набора трех значений, так что четыре щелчка эквивалентны одному, пять эквивалентны двум, а шесть — трем.

Emacs также записывает множественные нажатия в событиях проведения и нажатия. Например, когда вы дважды нажмете  кнопку,  а затем переместите мышь, держа кнопку нажатой, Emacs получит событие ‘double-drag-’.  А когда вы нажимаете  на кнопку второй раз, Emacs получит событие ‘double-down-’  (которое игнорируется, подобно всем событиям нажатия, если у них нет привязки).

Переменная  double-click-time задает промежуток  времени, который может пройти между  двумя щелчками, чтобы они считались парой.  Ее значение измеряется в миллисекундах.  Если значение равно nil,  то двойной щелчок не распознается  совсем. Если значение равно t, то нет никакого временного ограничения.

Символы для событий мыши также показывают статус клавиш-модификаторов, с обыч-

ными префиксами ‘C-’, ‘M-’, ‘H-’, ‘s-’,  ‘A-’  и ‘S-’.  Они всегда стоят перед ‘double-’ или

‘triple-’, которые всегда предшествуют ‘drag-’ или ‘down-’.

Фрейм включает области, которые не отображают текст буфера, такие как строка режима и линейка прокрутки.  Вы можете судить о том, что кнопка мыши нажата на специальной области экрана, посредством префиксных псевдо-ключей. Например, если вы щелкнете мышью в строке  режима, то вы получите  префиксный ключ mode-line  перед обычным символом, обозначающем  кнопку  мыши.   Вот  как  определить щелчок первой кнопкой на строке режима для запуска scroll-up:

(global-set-key  [mode-line mouse-1] ’scroll-up)

Вот полный список таких префиксных псевдо-ключей и их значений:

mode-line

Мышь находилась на строке режима окна.

vertical-line

Мышь находилась на вертикальной линии, разделяющей окна.  (Если вы используете полоски прокрутки,  они появляются вместо этих вертикальных линий).

vertical-scroll-bar

Мышь находилась на вертикальной полоске прокрутки.  (Пока это единствен-

ная разновидность полосок прокрутки, которые поддерживает Emacs).

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

31.4.11  Блокирование команд

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

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

Прямой механизм  блокирования команды — помещение  отличного от  nil свойства disabled в лисповский символ для данной команды.  Вот программа на Лиспе,  которая делает это:

(put ’delete-region ’disabled t)

Если значение свойства disabled является строкой, то эта строка включается в сооб-

щение, выводимое при использовании этой команды:

(put ’delete-region ’disabled

"It’s better to  use ‘kill-region’  instead.\n")

Вы  можете   блокировать команду  либо  непосредстенным редактированием файла

‘.emacs’,  либо с  помощью команды M-x disable-command,  которая  радактирует  файл

‘.emacs’ за вас.  Подобным образом команда M-x enable-command  изменяет ‘.emacs’ для постоянного разрешения команды. См. Раздел 31.7 [Файл инициализации], с. 366.

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

31.5  Перевод  клавиатуры

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

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

Вы можете  обойти эту проблему внутри Emacs, подготовив перевод клавиатуры для превращения C-h в hDELи hDELв C-h, как показано:

;; Переводит C-h в hDELi.

(keyboard-translate ?\C-h  ?\C-?)

;; Переводит hDELв C-h.

(keyboard-translate ?\C-?  ?\C-h)

Перевод клавиатуры — это не то же самое, что и привязка ключей в таблицах ключей (см.  Раздел 31.4.1 [Таблицы ключей], с. 356). Emacs содержит многочисленные таблицы ключей, которые применяются в разных ситуациях, но только один набор переводов клавиш, и он применяется к каждому знаку, который Emacs считывает с терминала. Перевод клавиатуры происходят на низшем уровне обработки ввода; ключи, поиск которых происходит в таблицах ключей, содержат знаки, появляющиеся  после перевода клавиатуры.

При работе в X, клавиша с именем hDELETEявляется функциональной клавишей, и она отличается от ASCII-знака с именем hDELi.  См. Раздел 31.4.8 [Именованные ASCII-знаки], с. 362. Перевод клавиатуры затрагивает только ввод ASCII-знаков, но не функциональных клавиш; таким образом, пример выше, примененный под X, не влияет на клавишу hDELETEi. Однако такой перевод не является  необходимым  под X, потому что Emacs может также различать клавишу hBACKSPACEи C-h; и обычно он рассматривает hBACKSPACEкак hDELi.

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

“Translating Input” в The Emacs Lisp Reference Manual.

31.6  Синтаксическая таблица

Все команды Emacs, которые разбирают слова или балансируют скобки, управляются синтаксической таблицей. Синтаксическая таблица говорит, какие знаки являются открывающими ограничителями, частями слов, кавычками строковых констант и так далее.  У каждого основного режима есть своя синтаксическая  таблица (хотя родственные основные режимы часто разделяют одну), которая устанавливается в любом буфере, использующем этот режим. Все команды применяют синтаксическую таблицу, установленную в текущем буфере; именно  ее мы имеем в виду, когда мы говорим просто “синтаксическая таблица”. Синтаксическая таблица — это лисповский объект, таблица знаков, чьими элементами являются числа.

Чтобы вывести на экран описание содержимого  текущей синтаксической таблицы, наберите C-h s (describe-syntax).  Описание каждого знака включает строку, которую вы передали бы modify-syntax-entry для установки текущего синтаксиса, и небольшое объяснение этой строки на английском, если необходимо.

Для получения полной информации о синтаксических таблицах смотрите раздел “Syntax

Tables” в The Emacs Lisp Reference Manual.

31.7  Файл  инициализации, ‘~/.emacs

Когда  Emacs запускается, он обычно загружет Лисп-программу из файла ‘.emacs’ в вашем начальном каталоге.  Мы называем этот файл вашим файлом инициализации,  поскольку он указывает, как  инициализировать Emacs для вас.  Вы можете  использовать ключи командной строки ‘-q’,  чтобы предотвратить загрузку файла инициализации,  и ‘-u’ (или ‘-user’), чтобы указать файл инициализации другого пользователя (см. Глава 3 [Вход в Emacs], с. 33).

Также  может  быть  файл инициализации по умолчанию, это библиотека с именем

‘default.el’, находимая по стандартному пути  поиска для библиотек.  В дистрибутиве Emacs нет такой библиотеки; она может быть создана на вашей системе для локальных настроек. Если эта библиотека существует, она загружается при запуске Emacs (только если вы не задали ‘-q’).   Но ваш файл инициализации, если он существует, загружается первым; если он устанавливает inhibit-default-init в отличное от nil значение, то

‘default’ не загружается.

На  вашей системе   также   может  быть  системный файл запуска;  он  называется

‘site-start.el’,   если  существует.      Emacs  загружает  эту   библиотеку  до  вашего файла инициализации.  Чтобы  подавить загрузку  этой библиотеки, используйте  ключ

‘-no-site-file’.

Если ваш файл ‘.emacs’ содержит большой объем кода, вам стоит переместить его в другой файл, как ‘~/чтонибудь.el’, скомпилировать его и сделать так, чтобы ваш файл

‘.emacs’ загружал его через (load "~/чтонибудь").   См.   раздел “Byte  Compilation” в the Emacs Lisp Reference Manual, для получения большей информации о компилировании программ на Emacs Lisp.

Если вы собираетесь писать настоящие программы на Emacs Lisp, которые идут дальше простой настройки, вам нужно прочитать книгу Emacs Lisp Reference Manual.

31.7.1  Синтаксис файла инициализации

Файл ‘.emacs’ содержит одно или несколько лисповских выражений вызовов функций.

Каждое из них состоит из имени функции, за которым следуют  аргументы, всё в окру-

жении круглых  скобок.  Например, (setq fill-column 60)  вызывает функцию setq  для установки переменной fill-column (см. Раздел 21.5 [Заполнение], с. 185) в значение 60.

Второй аргумент setq  — это выражение для нового значения переменной.  Это может быть константа, переменная или вызов функции. В файле ‘.emacs’ чаще всего используются константы. Это могут быть:

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

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

В строковых константах вы можете писать переводы строк и специальные знаки буквально. Но часто для ясности лучше использовать для них последовательности с обратной косой чертой: ‘\n’  для перевода строки, ‘\b’  для возврата на одну позицию, ‘\r’ для возврата каретки, ‘\t’ для табуляции, ‘\f’ для прогона страницы (control-L), ‘\e’  для escape, ‘\\’ для обратной косой черты, ‘\"’ для двойных кавычек или ‘\ooo’ для знака с восьмиричным кодом ooo. Обратная косая черта и двойные кавычки — это единственные знаки, для которых такие последовательности обязательны.

‘\C-’  можно использовать как префикс для управляющего знака, как ‘\C-s’ для ASCII control-S, а ‘\M-’ можно применять в качестве префикса для Meta-знака, как ‘\M-a’ для Meta-A или ‘\M-\C-a’ для Control-Meta-A.

Знаки:        Синтаксис лисповских знаковых констант состоит из ‘?’, за которым идет либо знак, либо последовательность,  начинающаяся  с ‘\’.   Примеры: ?x, ?\n,  ?\",

?\).  Заметьте,  что строки и знаки не взаимозаменимы  в Лиспе;  в некоторых контекстах требуется одно, в некоторых другое.

Истина:     t обозначает ‘истину’. Ложь:         nil обозначает ‘ложь’. Другие лисповские объекты:

Пишите одиночную кавычку (’) и за ней желаемый лисповский объект.

31.7.2  Примеры файла инициализации

Вот несколько примеров выполнения часто нужных вещей с помощью лисповских вы-

ражений:

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

дится в середине строки.

(setq c-tab-always-indent nil)

Здесь мы имеем переменную, чье значение обычно равно t, то есть ‘истина’, а альтер-

натива ему — nil, ‘ложь’.

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

(setq-default case-fold-search nil)

Это устанавливает  значение по умолчанию, оно распространяется на все буферы, в которых нет локальных значений для этой переменной.  Установка case-fold-search с помощью setq затрагивает только локальное значение текущего буфера, а это не то, что вы, скорее всего, хотите сделать в файле инициализации.

Указать ваш адрес электронной  почты, если Emacs не может правильно выяснить его сам.

(setq user-mail-address "coon@yoyodyne.com")

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

user-mail-address.

Сделать режим Text режимом для новых буферов по умолчанию.

(setq  default-major-mode ’text-mode)

Заметьте,  что используется text-mode,  поскольку это команда для входа в режим Text. Одиночная кавычка перед ним делает этот символ константой; иначе text-mode рассматривался бы как имя переменной.

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

вает большинство западноевропейских языков.

(set-language-environment "Latin-1")

Включать режим Auto Fill автоматически в режиме Text и родственных с ним.

(add-hook  ’text-mode-hook

’(lambda  () (auto-fill-mode  1)))

Это показывает, как  добавить функцию-ловушку к  переменной-ловушке  (см.   Раздел 31.2.3 [Ловушки],  с. 349).  Функция, которую мы предоставляем — это список, начинающийся с lambda, с одиночной кавычкой в начале, чтобы сделать этот список константой, а не выражением.

Объяснение функций Лиспа выходит за рамки данного руководства, но для этого примера достаточно знать, что действием будет вычисление (auto-fill-mode 1),  когда вы входите в режим Text. При желании вы можете заменить это на другое выражение или на несколько выражений подряд.

Emacs поставляется с функцией с именем turn-on-auto-fill, чье определение — это (lambda () (auto-fill-mode 1)). Таким образом, более простой способ написать приведенное выше выражение выглядит так:

(add-hook  ’text-mode-hook ’turn-on-auto-fill)

Загрузить установленную лисповскую библиотеку с именем ‘foo’  (на самом деле файл

‘foo.elc’ или ‘foo.el’ из стандартного каталога Emacs).

(load "foo")

Когда аргументом load является относительное имя файла, не начинающееся с ‘/’ или

‘~’, load просматривает каталоги из load-path (см. Раздел 23.7 [Библиотеки Лиспа],

с. 253).

Загрузить скомпилированный Лисп-файл ‘foo.elc’ из вашего начального каталога.

(load "~/foo.elc")

Здесь использовано абсолютное имя файла, поэтому поиск не производится.

Перепривязать ключ C-x l на запуск функции make-symbolic-link.

(global-set-key "\C-xl"  ’make-symbolic-link)

или

(define-key global-map  "\C-xl" ’make-symbolic-link)

Еще раз обратите внимание, одиночная кавычка используется для ссылки на символ

make-symbolic-link, а не на его значение как переменной.

Сделать то же самое, только для режима Lisp.

(define-key lisp-mode-map  "\C-xl" ’make-symbolic-link)

Переопределить  все ключи, которые сейчас запускают next-line в режиме Fundamental, чтобы они вместо этого запускали forward-line.

(substitute-key-definition  ’next-line  ’forward-line global-map)

Сделать C-x C-v неопределенным.

(global-unset-key "\C-x\C-v")

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

Присвоить ‘$’ синтаксическую категорию пунктуации в режиме Text.  Обратите вни-

мание на использование знаковой константы для ‘$’.

(modify-syntax-entry ?\$  "." text-mode-syntax-table)

Разрешить использование команды narrow-to-region без подтверждения.

(put ’narrow-to-region ’disabled nil)

31.7.3  Инициализация терминала

Для каждого  типа терминала может быть библиотека, загружаемая в Emacs, когда он запускается на этом типе  терминала.  Для типа терминала с именем типтерм эта библиотека называется ‘term/типтерм’,  и она находится, как  обычно, путем поиска в каталогах load-path, при этом пробуются окончания ‘.elc’ и ‘.el’. Обычно она появляется в подкаталоге ‘term’ из каталога, где хранится большинство библиотек Emacs.

Обычное назначение специфичной  для терминала библиотеки — отображение escapeпоследовательностей,  используемых функциональными клавишами терминала, в более осмысленные имена с помощью функции function-key-map. Пример того, как это делается, смотрите в файле ‘term/lk201.el’.  Многие функциональные клавиши отображаются автоматически в соответсвтии с базой данных Termcap; в специфичной для терминала библиотеке  нужно описать только те  функциональные  клавиши, которые на указаны в Termcap.

Когда  тип  терминала содержит дефис,  при выборе имени библиотеки имеет значе-

ние только часть перед первым дефисом.   Таким образом,  типы терминалов ‘aaa-48’  и

‘aaa-30-rv’ оба используют библиотеку ‘term/aaa’.    Код  библиотеки может применять

(getenv  "TERM") для выяснения полного имени типа терминала.

Имя библиотеки конструируется конкатенацией значения переменной term-file-prefix и типа терминала. Ваш файл ‘.emacs’ может предотвратить загрузку специфичной для терминала библиотеки, устанавливая term-file-prefix равной nil.

В конце  инициализации, когда считаны и ваш файл ‘.emacs’, и любая специфичная для терминала библиотека, Emacs запускает ловушку term-setup-hook. Добавьте к этой ловушке функции, если вы хотите перекрыть часть специфичной для терминала библиотеки или определить инициализацию для терминалов, к  которым нет библиотеки.  См. Раздел 31.2.3 [Ловушки], с. 349.

31.7.4  Как Emacs находит файл инициализации

Обычно для поиска файла ‘.emacs’ Emacs использует  переменную среды HOME; знак ‘~’ в  имени файла обозначает  именно это.  Но если вы сделали su, Emacs пытается найти ваш собственный ‘.emacs’, а не того пользователя, за кого вы себя сейчас выдаете.  Идея в том, чтобы вы получали свои собственные настройки редактора, даже если работаете как привелигированный пользователь.

Более точно, Emacs сначала определяет, файл инициализации какого пользователя нужно использовать. Он получает имя пользователя из переменных среды LOGNAME и USER; если ни одна из них не существует, берется эффективный  ID пользователя.  Если имя пользователя соответствует реальному пользовательскому ID, то Emacs использует HOME; иначе, он находит начальный каталог в системной  базе данных о пользователях.

Источник: Ричард Столмен, Руководство по GNU Emacs

Похожие посты:

Вы можете оставить комментарий, или ссылку на Ваш сайт.

Оставить комментарий