2017年9月10日 星期日

Writing GNU Emacs Extensinos Chapter 2 - Simple New Commands

interactive takes one argument: a trings of code letters, one code letter per argument being described. The code letter p means, "if there is a prefix argument, interpret it as a number, and if there is no prefix argument, interpret that as the number 1"

They keyword &optional appearing in a parameter list means that all subsequent pramtters are optional. The function may be called with or without a value for an optional parameter. If no value is given, the optional parameter gets the special value nil

Inside Lisp, symbol nil and the empty list () are the same object. However, if call symbolp on any other list, or listp on any other symbol, it gets nil - falsehood

Symbol t for designating truth Like nil, t is its own value and doesn't need to be quoted. All other Lisp values denote truth just like t does

Lisp or has an extra bit of usefulness: it evaluates each of it's arguments in order until it finds one that's non-nil, then it returns that value. If it doesn't find one, it returns nil. So the return value from or isn't merely false or true, it's false or the first true value in the list.

(if a a b) can be replaced by (or a b). The first will evaluate it twice whereas the second won't

A hook is an ordinary Lisp variable whose value is a list of functions that get executed under specific conditions

In Lisp, predicates traditionally have names ending in p or -p

A progn expression evaluates each of its subexpressions in order and returns the value of the last one. It groups two or more Lisp expressions where only one is expected.

It's possible to define a function without giving it a name. Such functions are appropriately known as anonymous functions. They're created with the Lisp keyword lambda, which works exactly like defun except that the name of the function is left out

Temporary variables (local variables) that exist only in a certain region of code, called the variable's scope. In Lisp, temporary variables are created with let, after executing body block, local variables will not exist

(let ((var1 value1)
(var2 value2)
(var3 value3)
...
(varn valuen))
body1 body2 ... bodyn)

A piece of advice attached to a Lisp function is code that gets executed before or after each time the funcion is invoked. Before advice can affect the arguments before they're passed to the advised function. After advice can affect the return value that comes out of the advised function.

Explanation

Following is an example of advice. When using C-u allows empty buffer name, otherwise, not allow empty buffer name.

defadvice creates a new piece of advice. It's first argument is the unquoted name of the existing function being advised --- in thie case, switch-to-buffer.

Next comes a specially formatted list, before or after shows this piece of advice code execution hook. existing-buffer is the name of piece of code. activate means that this advice should be active as soon as it's defined. compile means that the advice code should be 'byte-compiled' for speed.

Overriding the interactive declaration of switch-to-buffer using before advice --- passing a list as its argument, rather than a string of code letters. When the argument to interactive is some expression other than a string, that expression is evaluated to get a list of arguments that should be passed to the function.

read-buffer is called with a prompt string and two optional arguments: a default buffer to switch to, and a boolean stating whether input should be restricted to existing buffers only.

other-buffer computes a useful default buffer, usually it chooses the most recently used buffer that isn't presently visible in a window.

(null current-prefix-arg) tests whether current-prefix-arg is nil.

current-prefix-arg holds the raw prefix argument for the current command. Commands may examine it directly, but the usual method for accessing it is with (interactive "P").

(defadvice switch-to-buffer (before existing-buffer
activate compile)
"When interactive, switch to existing buffers only, unless given a prefix argument."
(interactive
(list (read-buffer "Switch to buffer:"
(other-buffer)
(null current-prefix-arg)))))

Prefix arguments table(

If the User Types Raw Value Numeric Value
C-u followed by a (possibly negative) number The number itself The number itself
C-u - (with no following number) The symbol - -1
C-u n times in a row (with no following number or minus sign) A list containing the number 4^n 4^n itself
No prefix argument nil 1

沒有留言:

張貼留言