| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
В этой главе, мы закрепим знания, полученные в предыдущих главах,
изучив несколько более сложных функций. Функция copy-to-buffer
иллюстрирует использование в одном определении двух выражений
save-excursion, а функция insert-buffer показывает
использование * в выражении interactive, использование
or и важную разницу между именем и объектом, к которому имя
относится.
5.1 Определение copy-to-bufferС set-buffer,get-buffer-create.5.2 Определение insert-bufferТолько-чтение, и функция or.5.3 Полное определение beginning-of-bufferИспользование goto-char,point-min, иpush-mark.
5.4 Обзор 5.5 Упражнения с &optionalаргументом
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
copy-to-buffer
После изучения принципа работы append-to-buffer, легко понять и
copy-to-buffer. Эта функция копирует текст в буфер, но вместо
того чтобы добавить его во второй буфер, она заменяет предыдущий текст
в том буфере. Код для функции copy-to-buffer почти такой же,
как и код для append-to-buffer, отличаясь только использованием
erase-buffer и второй формы save-excursion.
(See section The Definition of append-to-buffer,
для описания append-to-buffer.)
Тело copy-to-buffer выглядит следующим образом
...
(interactive "BCopy to buffer: \nr")
(let ((oldbuf (current-buffer)))
(save-excursion
(set-buffer (get-buffer-create buffer))
(erase-buffer)
(save-excursion
(insert-buffer-substring oldbuf start end)))))
|
Все это очень похоже на то, что мы видели в append-to-buffer,
только после того, как мы переключились в новый буфер куда и
собираемся копировать текст, исходные тексты этих двух функции
расходятся --- в функции copy-to-buffer уничтожается
первоначальное содержание буфера. (Обычно это называют замещением
--- чтобы заместить текст, Emacs стирает предыдущий текст и затем
вставляет новый). После того, как стерто прежнее содержание буфера,
второй раз используется save-excursion и вставляется новый
текст.
Почему же save-excursion используется дважды? Давайте
внимательно посмотрим что же делает эта функция.
Схематично, тело copy-to-buffer выглядит следующим образом:
(let (связать- |
Первое использование save-excursion вернет Emacs в буфер из
которого мы копируем текст. Это ясно, и точно такой же код
использовался в append-to-buffer. Зачем же использовать эту
функцию второй раз? Причина этого заключается в том, что
insert-buffer-substring всегда оставляет точку в конце
вставленного региона текста. Второе использование
save-excursion заставляет Emacs оставить точку в начале
вставленного текста. В большинстве случаев, пользователи предпочитают
обнаружить точку в начале вставленного текста. (Конечно, функция
copy-to-buffer вернет пользователя в первоначальный буфер когда
завершит свою работу --- но если пользователь потом
переключится в тот буфер, то точка будет в начале текста. То есть
второе использование save-excursion применяется для удобства).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
insert-buffer
insert-buffer --- еще одна функция связанная с буферами.
Эта команда копирует другой буфер в текущий буфер. Это обратное
действие, если сравнивать с append-to-buffer и
copy-to-buffer, поскольку они копируют регион текста из
текущего буфера в другой буфер.
Кроме того, код этой функции иллюстрирует использование
interactive с буфером который может быть
только-для-чтения и важную разницу между именем объекта и самим
объектом. Вот и исходный текст этой функции:
(defun insert-buffer (buffer)
"Вставить после точки содержимое BUFFER.
Поставить метку после вставленного текста.
BUFFER может быть буфером или именем буфера."
(interactive "*bInsert buffer: ")
(or (bufferp buffer)
(setq buffer (get-buffer buffer)))
(let (start end newmark)
(save-excursion
(save-excursion
(set-buffer buffer)
(setq start (point-min) end (point-max)))
(insert-buffer-substring buffer start end)
(setq newmark (point)))
(push-mark newmark)))
|
Как из другими определениями функции, вы можете использовать шаблон, для того, чтобы посмотреть на костяк этой функции:
(defun insert-buffer (buffer) "документация..." (interactive "*bInsert buffer: ") тело...) |
5.2.1 Интерактивное выражение в insert-bufferКогда буфер только-для-чтения. 5.2.2 Тело функции insert-buffer5.2.3 insert-bufferсifвместоorИспользуем ifвместоor.5.2.4 orв теле функции5.2.5 Выражение letвinsert-bufferДва выражения save-excursion.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
insert-buffer
В insert-buffer, аргумент к объявлению interactive
состоит из двух частей, звездочки `*', и строки `bInsert
buffer: '.
Буфер только-для-чтения `b' в интерактивном выражении
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Звездочка используется в тех ситуациях, когда буфер открыт в режиме
только-для-чтения --- то есть, это буфер, который нельзя
изменять. Если insert-buffer вызвали из буфера только для
чтения, то в эхо-области появится сообщение об ошибке и терминал
издаст звуковой сигнал или мигнет --- вам не разрешено изменять
текущий буфер. За звездочкой не должен следовать символ новой строки,
отделяющий ее от аргумента.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Следующий аргумент в интерактивном объявлении начинается с буквы
`b' в нижнем регистре. (Здесь есть отличие от текста функции
append-to-buffer, в котором используется `B' в верхнем
регистре. See section The Definition of append-to-buffer.) Строчная буква `b' сообщает
интерпретатору Лиспа, что аргументом для этой функции должен быть
существующий буфер или его имя. (Прописная буква `B' разрешает
отсутствие буфера). Emacs запросит у вас имя буфера, предложив вам
буфер по умолчанию, с возможностью дополнения. Если буфер не
существует, то вы получите сообщение, которое гласит "No match" (Нет
соответствия); и ваш терминал может издать звуковой сигнал.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
insert-buffer
Тело insert-buffer содержит две основные части ---
выражение or и выражение let. Задача выражения or
убедится в том, что аргумент buffer связан с существующим
буфером, а не является только именем буфера. Тело выражения let
содержит код, который копирует другой буфер в текущий буфер.
Схематично, что эти два выражения входят в состав функции
insert-buffer следующим образом:
(defun insert-buffer (buffer)
"документация..."
(interactive "*bInsert buffer: ")
(or ...
...
(let (список-переменных)
тело- |
Чтобы понять как выражение or проверяет что аргумент
buffer связан с буфером, а не просто является именем буфера,
нам вначале необходимо изучить функцию or.
До этого давайте, перепишем эту часть функции используя выражение
if таким образом, чтобы вы могли увидеть что происходит в
известном вам изложении.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
insert-buffer с if вместо or
Необходимо убедиться, что значение buffer --- это
существующий буфер а не просто имя буфера. Если это просто имя, то
тогда надо получить связанный с ним буфер.
Представьте что вы находитесь на конференции, где один из швейцаров ходит держа табличку с вашим именем и ищет вас; таким образом швейцар "связан" с вашим именем, а не с вами; но когда он найдет вас и возьмет за руку, то он станет связан уже с вами.
На Лиспе, вы можете описать эту ситуацию следующим образом:
(if (not (не-нашел-гостя))
(найти-и-взять-его-за-руку))
|
Иногда вы хотите проделать аналогичную штуку с буфером --- если у нас нет самого буфер, то мы хотим получить его.
Используя предикат bufferp, который проверяет является ли
буфером ли его аргумент или он является только его именем, мы можем
записать следующее:
(if (not (bufferp buffer)) ; if-часть
(setq buffer (get-buffer buffer))) ; then-часть
|
Здесь, проверка-истина-ложь в выражении if --- это
(not (bufferp buffer)); а then-часть --- выражение
(setq buffer (get-buffer buffer)).
В проверке, функция bufferp возвращает истину если его
аргумент --- буфер, и ложь, если его аргумент --- это имя
буфера. (Последний символ в имени функции bufferp --- это
символ `p'; как мы видели ранее, такое использование `p'
подчеркивает, что эта функция является предикатом, что означает, что
она проверяет, обладает ли ее аргумент каким-либо
свойством. See section Using the Wrong Type Object as an Argument.)
Перед выражением (bufferp buffer, расположена функция
not, так что проверка-истина-ложь выглядит следующим образом:
(not (bufferp buffer)) |
Функция not возвращает истину, если ее аргумент имеет значение
ложь, и ложь, если ее аргумент истина. Так, что если (bufferp
buffer) возвращает истину, то выражение not вернет ложь и
наоборот --- то, что "не истина" это ложь, а то, что "не ложь"
это истина.
С помощью этого теста выражение if, работает следующим
образом --- если значение переменной buffer на самом деле
буфер, а не только его имя, то тогда проверка-истина-ложь возвращает
ложь и then-часть выражения if не вычисляется. Это правильно,
поскольку нам и не надо ничего делать, если переменная buffer
на самом деле связана с буфером.
С другой стороны, когда значение buffer --- это не сам
буфер, а только его имя, то проверка-истина-ложь возвращает истину, и
тогда вычисляется then-часть всего выражения if. В этом случае
then-часть --- это (setq buffer (get-buffer buffer)). Это
выражения с помощью функции get-buffer возвращает фактический
буфер, который задан именем. Затем setq связывает переменную
buffer со значением самого буфера, замещая таким образом
предыдущее значение (которое было именем буфера).
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
or в теле функции
Цель выражения or в insert-buffer, убедиться, что аргумент
buffer связан с буфером, а не с именем оного. В предыдущем
разделе мы рассмотрели, как это задачу можно выполнить с помощью
выражения if. Однако в insert-buffer, на самом деле
используется or. Для этого нам необходимо познакомиться с этой
функцией.
У функции or может быть любое количество аргументов. Она
вычисляет каждый аргумент по очереди и возвращает значение первого из
них который вернул не nil. Также и это главная характеристика
функции or, после этого она не вычисляет другие аргументы, если
какой-то вернул значение не-nil.
Выражение or в функции insert-buffer выглядит следующим
образом:
(or (bufferp buffer)
(setq buffer (get-buffer buffer)))
|
Первый аргумент в or это выражение (bufferp buffer). Это
выражение возвращает истину (то есть не-nil) если переменная
buffer на самом деле связана с буфером, а не с именем буфера. В
общем выражении or в таком случае все выражение or
возвращает истину и не вычисляет свое следующее выражение---так и надо,
ведь нам уже не надо ничего делать если значение buffer сам буфер.
С другой стороны, если значения (bufferp buffer) это
nil, то есть если значением переменной buffer было имя
буфера, то интерпретатор Лиспа вычислит следующий элемент в выражении
or. Это выражение (setq buffer (get-buffer buffer)).
Это выражение вернет значение не-nil, а значение к которому
сейчас связана переменная buffer, то есть сам буфер, а не его
имя.
В результате всего этого символ buffer всегда будет связан с
буфером, даже если до этого он был связан с его именем. Все это
необходимо, поскольку функция set-buffer, которая используется
на следующей строке, работает только с буфером, а не с его именем.
Кстати, с помощью or, ситуацию со швейцаром можно записать
следующим образом:
(or (не-нашел-гостя) (найти-и-взять-его-за-руку)) |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
let в insert-buffer
После того, как мы убедились, что переменная buffer связана с
буфером, а не с его именем, в insert-buffer вычисляется
выражение let. В нем задаются три локальные переменные:
start, end и newmark и им присваивается
первоначальное значение nil. Эти переменные используются в теле
выражения let и временно маскируют переменные с такими же
именами, но определенные вне этой функции.
Тело let содержит два выражения save-excursion.
Вначале, мы рассмотрим в деталях внутренней выражение
save-excursion. Оно выглядит следующим образом:
(save-excursion (set-buffer buffer) (setq start (point-min) end (point-max))) |
Выражение (set-buffer buffer) переключает внимание Emacs от
текущего буфера к тому из которого будет копироваться текст. В этом
буфере, переменные start и end связываются с началом и
концом этого буфера с помощью команд point-min и
point-max. Отметим использование функции setq, которая
назначает значение сразу двум переменным. Первому аргументу
setq присваивается значение второго аргумента, а третьему
аргументу --- значение четвертого.
После вычисление тела внутреннего выражения save-excursion,
Emacs восстанавливает первоначальный буфер, но при этом значения
start и end остаются теми же, то есть они содержат точки
начала и конца буфера.
Внешнее выражение save-excursion выглядит следующим образом:
(save-excursion (внутреннее-expression- |
Функция insert-buffer-substring копирует текст в текущий
буфер из области ограниченной точками start и end
буфера buffer. Поскольку между точками start и
end находиться весь второй буфер, то он и будет скопирован в
ваш текущий буфер. Затем значение точки, которая будет в конце
вставленного текста записывается в переменную newmark.
После вычисления тела внутреннего save-excursion, точка и метка
восстанавливаются к их первоначальным значениям.
Однако это довольно удобно расположить метку в конце вставленного
недавно текста, а точку в начале. В переменной newmark записан
конец вставленного текста. В последней строке выражения let, с
помощью выражения (push-mark newmark) метка устанавливается на
это место. (Предыдущая метка все еще доступна --- она занесена в
кольцо меток и вы можете вернуться к ней с помощью сочетания клавиш
C-u C-SPC). В тоже время, точка расположена в начале
вставленного текста, располагаясь там же, где она была до вызова
функции insert-buffer.
Все выражение let выглядит следующим образом:
(let (start end newmark)
(save-excursion
(save-excursion
(set-buffer buffer)
(setq start (point-min) end (point-max)))
(insert-buffer-substring buffer start end)
(setq newmark (point)))
(push-mark newmark))
|
Как и в функции append-to-buffer, в функции
insert-buffer, используются let, save-excursion,
и set-buffer. Кроме этого, в этой функции проиллюстрирован еще
один способ использования функции or. Все эти функции являются
строительными блоками, которые мы будем использовать снова и снова.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
beginning-of-buffer
Мы уже рассмотрели основную идею функции beginning-of-buffer.
(See section A Simplified beginning-of-buffer Definition.) Сейчас давайте опишем ее
полностью.
Мы уже упоминали, что когда функция beginning-of-buffer
запускается с одним аргументом, то она перемещает курсор в начало
буфера, оставляя метку на предыдущем положении курсора. Однако, если
эту команду запустить с числовым аргументом от одного до десяти, то
тогда эта функция будет рассматривать это число, как долю к общей
длине буфера, измеренной в десятых долях, и переместит курсор в ту
часть буфера, которая соответствует заданному значению. То есть вы
можете или вызвать функцию с помощью M-<, что переместит курсор
к началу буфера, или с помощью C-u 7 M-<, что переместит курсор
к точке находящейся в 70% процентов от начала буфера. Если число
больше чем десять, тогда курсор будет перемещен в конец буфера.
Функцию beginning-of-buffer можно вызывать с аргументом или без
него. То есть аргумент является необязательным.
5.3.1 Необязательные аргументы 5.3.2 beginning-of-bufferс аргументомПример с необязательным аргументом. 5.3.3 Полный текст beginning-of-buffer
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Если не сказать заранее, то интерпретатор будет ожидать, что функцию в определении которой был задан аргумент, будут вызывать с аргументом. Если ее вызвать без аргументов, тогда вы получите сообщение об ошибке которое гласит `Wrong number of arguments'.
Однако в Лиспе существует возможность задать необязательные
аргументы --- для этого используется ключевое слово
&optional. (`&' перед `optional' --- это часть
ключевого слова). В определении функции, если за словом
&optional, следует аргумент, то тогда при вызове функции ей
необязательно передавать какие-либо аргументы.
Следовательно первая строка в определении функции
beginnig-of-buffer, выглядит следующим образом:
(defun beginning-of-buffer (&optional arg) |
Схематично, вся функция выглядит следующим образом:
(defun beginning-of-buffer (&optional arg)
"документация..."
(interactive "P")
(push-mark)
(goto-char
(если-есть-аргумент
рассчитать-куда-переместить-курсор
иначе-переместить-курсор-в
(point-min))))
|
Эта функция похожа на simplified-beginning-of-buffer, за
исключением того, что выражение interactive идет с аргументом
"P" и за выражением if-then-else, где вычисляется куда
переместить курсор, если задан аргумент, идет функция
goto-char.
"P" в выражении interactive заставляет Emacs передать в
функцию префикс-аргумент, если он был задан. Префикс-аргумент можно
задать или с помощью клавиши META, за которой будет следовать
число, или нажав C-u, и затем набрав какое-нибудь число (если вы
не задали число, то по умолчанию, C-u назначает ему 4).
Проверка-истина-ложь в выражение if очень проста --- это
просто аргумент arg. Если с arg связано значение
не-nil, то есть функцию beginning-of-buffer вызвали с
аргументом, то тогда проверка-истина-ложь возвращает истину и
вычисляется then-часть выражения if. С другой стороны, если
функцию beginning-of-buffer вызвали без аргумента, то тогда
значением arg будет nil, и будет вычислена else-часть
выражения if. Else-часть это просто point-min, в этом
случае полностью выражение для goto-char будет выглядеть
следующим образом (goto-char (point-min)), что мы и видели в
упрощенной версии beginning-of-buffer.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
beginning-of-buffer с аргументом
Если beginning-of-buffer вызван с аргументом, то тогда
вычисляется выражение, в котором рассчитывается значение, которое
будет передано функции goto-char. На первый взгляд это
выражение кажется довольно сложным. Там много арифметики и есть
вложенное if. Выглядит оно следующим образом:
(if (> (buffer-size) 10000)
;; Чтобы избежать переполнения в буферах больших размеров!
(* (prefix-numeric-value arg) (/ (buffer-size) 10))
(/
(+ 10
(*
(buffer-size) (prefix-numeric-value arg))) 10))
|
Как и другие сложные выражение, это выражение можно понять, если представить логику работы в виде шаблона; в нашем случае шаблона для выражения if-then-else. В схематичной форме, выражение выглядит следующим образом:
(if (буфер-большой
разделить-размер-буфера-на-10-и-умножить-на-arg
иначе-посчитать-по-другому
|
Проверка-истина-ложь в выражении if, проверяет размер буфера.
Это вызвано тем, что в 18 версии Emacs Лисп в вычислениях используются
числа не больше, чем восемь миллионов или около того (больше вроде и
не надо), и может получиться большее число, если буфер очень
большой. Для этого существует термин `переполнение', если число
больше, чем самое большое.
То есть перед нами два случая: если буфер большой и если не очень.
Что происходит в больших буферах Что происходит в маленьких буферах
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
В функции beginning-of-buffer, внутреннее выражение if,
проверяет больше ли размер буфера, чем 10,000 символов. Для этого
используются функции > и buffer-size. Эта строка
выглядит следующим образом:
(if (> (buffer-size) 10000) |
Если буфер больше, то тогда выполняется then-часть всего выражения
if. Она выглядит следующим образом (после надлежащего
форматирования):
(* (prefix-numeric-value arg) (/ (buffer-size) 10)) |
Это просто операция умножения с двумя аргументами.
Первый аргумент --- это (prefix-numeric-value arg). Когда
interactive задан аргумент "P", то в функцию передается
так называемый "сырой префикс-аргумент", а не число. (Это число в
списке). Для функции * требуется числовое значение и
prefih-numeric-value переводит "сырой префикс-аргумент" в
число.
Второй аргумент --- это (/ (buffer-size) 10). Это выражение
делит численное значение длины буфер на десять. В результате мы
получаем число, которое говорит нам сколько символов содержится в
одной десятой нашего буфера. (В Лиспе, / используют для
деления, а * для умножения).
Схематично все выражение для умножения можно представить следующим образом:
(* численное-значение-префикс-аргумента число-символов-в-одной-десятой-буфера) |
Например, если префикс-аргумент равен `7', то после умножения числа символов в одной десятой на 7 мы получим число которому соответствует точка на расстоянии в 70% от начала буфера.
Таким образом, если буфер большой, то все выражение для
goto-char будет выглядеть следующим образом:
(goto-char (* (prefix-numeric-value arg)
(/ (buffer-size) 10)))
|
Это переместит курсор куда мы хотим.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Если буфер содержит меньше чем 10,000 символов, то вычисление будет немножко другим. Вам может показаться, что это излишнее усложнение, поскольку и первый способ вполне себе хорош. Однако в небольших буферах первый способ не совсем точно перемещает курсор --- второй метод делает лучше.
Код выглядит следующим образом:
(/ (+ 10 (* (buffer-size) (prefix-numeric-value arg))) 10)) |
Это выражение легче понять, если мы будем видеть каким образом функции вложены друг в друга. Для этого лучше отформатировать это выражение следующим образом:
(/
(+ 10
(*
(buffer-size)
(prefix-numeric-value arg)))
10))
|
Сейчас хорошо видно, что самое внутреннее выражение это
(prefix-numeric-value arg), где необработанный префикс-аргумент
переводиться в численную форму. В следующем выражении полученое число
умножается на размер буфера:
(* (buffer-size) (prefix-numeric-value arg) |
В результате получится число, которое может быть меньше чем размер буфера --- в семь раз если аргумент был 7. Затем к результату будет добавлено десять и в конце это большое число поделят на десять --- так мы и получим значение которое на один символ больше чем процентная позиция в буфере.
Конечное число будет передано в функцию goto-char и в
результате курсор будет перемещен в нужное место.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
beginning-of-buffer
А вот и полный текст функции beginning-of-buffer:
(defun beginning-of-buffer (&optional arg)
"Переместить точку в начало буфера;
оставив метку в предыдущей позиции курсора.
С арг N, переместить точку в N/10 от начала
буфера.
Не используете эту функцию в своих программах!
\(goto-char (point-min)) быстрее и не устанавливает
метку."
(interactive "P")
(push-mark)
(goto-char
(if arg
(if (> (buffer-size) 10000)
;; Avoid overflow for large buffer sizes!
(* (prefix-numeric-value arg)
(/ (buffer-size) 10))
(/ (+ 10 (* (buffer-size)
(prefix-numeric-value arg)))
10))
(point-min)))
(if arg (forward-line 1)))
|
Кроме двух нюансов мы уже все обсудили. Во первых надо обсудить строку документации, и во вторых надо рассмотреть последнюю строку функции.
В строке документации, есть ссылка на выражение:
\(goto-char (point-min)) |
Перед открывающей скобкой этого выражения стоит `\'. Это сообщает интерпретатору Лиспа, что выражение так и должно присутствовать в документации, и вычислять его не надо.
В последней строке функции beginning-of-buffer производиться
перемещение курсора в начало строки, если команда была запущена с
аргументом:
(if arg (forward-line 1))) |
Этот код переместит курсор в начало строки, которая находиться на соответствующем расстоянии от начала буфера. Это неплохо, поскольку это значит, что курсор всегда будет расположен по крайней мере в указанной части пути через буфер, что является утонченностью, но не необходимостью, но которая вызовет возмущение, в случае отсутствия.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Кратко повторим темы, которые мы изучили в этой главе.
or
nil; если же все вернули nil,
то результат всего выражения также будет nil. Короче говоря,
эта функция возвращает первое истинное значение своих аргументов; она
возвращает истину если один, или любой другой аргумент истинен.
and
nil, то возвращает nil; если нет, то возвращает
значение своего последнего аргумента. Короче говоря, возвращает
истину, только если все аргументы истинны.
&optional
prefix-numeric-value
(interactive "P") в численное значение.
forward-line
forward-line не смогла продвинуться.
erase-buffer
bufferp
t если аргумент является буфером; в противном случае
возвращает nil.
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
&optional аргументом
Напишите интерактивную функцию с необязательным аргументом, которая
проверяет является ли ее аргумент числом, меньше оно или больше оно чем
значение переменно fill-column, и сообщает результат в виде
сообщения в мини-буфере. Однако, если аргумент не передан, то в
качестве значения по умолчанию должно использоваться число 56.
| [ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |