9.8.1 Indentation in Lisp Modes
The Lisp modes provide "flashing" of matching left parentheses; if the matching parenthesis is outside of the current window, the line it is on appears in the minibuffer. The Lisp modes also provide indentation via the Tabkey and C-jfor newline-and-indent(except in Lisp interaction mode, described later in this chapter). The indentation style supported by the Lisp modes "knows" a lot about Lisp keywords and list syntax; unfortunately, it is not easily customized. [67]
Here is an example, a Lisp equivalent of the "times" C function shown earlier in the chapter, that illustrates the indentation style:
(defun times (x y)
(let ((i 0)
(result 0))
(while (< i x)
(setq result (+ result y)
i (1+ i)))
result))
The basic indentation value is 2; this value is used whenever code on the next line goes down a level in nesting. For example, the body of the function, after the line containing defun, is indented by 2. The (while... and result))lines are indented by 2 with respect to the letbecause they are the body of the block letintroduces.
Things like defun, let, and whileare function calls, even though they act like keywords. The indentation convention for function calls is that if there are arguments on lines after the line where the function name and first argument appear, the additional arguments line up with the first one. In other words, this has the form:
(function-name arg1
arg2
arg3
...)
The multiple arguments to setqin the preceding function provide another example of this.
However, the indentation of the line (result 0)shows that something a bit different happens with lists that are not function calls. The list in question is actually ((i 0) (result 0)), which is a list with two elements (both of which are also lists). The indentation style supported by the Lisp modes lines up these two elements.
Even though keyword-like terms such as letand whileare actually function calls, the Lisp modes "understand" these functions to the extent that special indentation conventions are set up for them. For example, if we were to put the condition for the while-loop on a separate line and press Tabto indent it properly, the result would be:
(while
(< i x)
(setq result (+ result y)
i (1+ i)))
Similar things happen with ifand condcontrol structures; Chapter 11contains properly indented examples.
Another remark about indentation conventions: the Lisp modes are geared toward a style in which multiple right parentheses are put on the same line immediately following each other, instead of on separate lines. For example, the line i (1+ i)))contains right parentheses that close off the 1+function, the setq, and the whilerespectively. If you prefer, you can put your closing parentheses on separate lines, but if you press Tabto indent them, they won't line up properly with their matching open parentheses; you have to indent them manually.
In addition to the Taband C-jcommands for indentation, the Lisp modes support the command C-M-q(for indent-sexp), which indents every line in the S-expression just following the cursor. You can use this command, for example, to indent an entire function definition: just put the cursor right before the defunand type C-M-q.
9.8.2 Comments in Lisp Modes
Comments in the Lisp modes are handled by the universal comment command M-;, which indents out to comment-column(or, if there is text at that column, one space past the last character), inserts a semicolon, and puts the cursor just past it. If you want a comment to occupy an entire line (or to start anywhere other than at comment-column), you must move to where you want the comment to start and type the semicolon yourself. Note that if you press Tabon any line that contains only a comment, the comment moves out to comment-column. To get around this, use two or more semicolons; doing so causes Tabto leave the comments where they are. The Lisp modes also support the other comment commands discussed earlier in the chapter, including M-jto extend a comment to another line and M-x kill-comment Enterto get rid of a single-line comment. These features are common to all three Lisp modes; next, we discuss the features unique to each.
9.8.3 Emacs Lisp Mode Differences
Emacs Lisp mode was designed to be used with code meant to run within Emacs itself, so it facilitates running the code you type. Lisp is an interpreted (as opposed to purely compiled) language, so it is possible to blur the line between the write and run/debug phases of Lisp programming; Emacs Lisp mode takes some advantage of this opportunity, whereas Lisp interaction mode goes even further, as we'll see later. In Emacs Lisp mode, the command C-M-x( eval-defun) picks up the function definition around or after the cursor and evaluates it, meaning that it parses the function and stores it so that Emacs "knows" about the function when you invoke it.
Emacs Lisp mode also includes the command M-Tab(for lisp-complete-symbol), [68]which performs completion on the symbol (variable, function name, etc.) preceding the cursor, as described in Chapter 14 Chapter 14. The Help System Emacs has the most comprehensive help facility of any text editor—and one of the best such facilities of any program at all. In fact, the Emacs help facilities probably cut down the time it took for us to write this book by an order of magnitude, and they can help you immeasurably in your ongoing quest to learn more about Emacs. In this chapter, we describe Emacs help in the following areas: • The tutorial. • The help key ( C-h ) and Help menu, which allow you to get help on a wide variety of topics. • The help facilities of complex commands like query-replace and dired . • Navigating Emacs manuals and using the info documentation reader. • Completion , in which Emacs helps you finish typing names of functions, variables, filenames, and more. Completion not only saves you time and helps you complete names of functions you know about but can help you discover new commands and variables.
. Thus, you can type the shortest unambiguous prefix for the symbol, followed by M-Tab, and Emacs tries to complete the symbol's name for you as far as it can. If it completes the symbol name, you can go on with whatever you are doing. If it doesn't, you haven't provided an unambiguous prefix. You can type more characters (to disambiguate further), or you can type M-Tabagain, and a help window showing the choices pops up. Then you can type more characters and complete the symbol yourself, or you can try for completion again.
9.8.4 Lisp Mode Differences
Lisp mode (as opposed to Emacs Lisp mode) is meant for use with Lisp processors other than the Emacs Lisp interpreter. Therefore it includes a couple of commands for interfacing to an external Lisp interpreter. The Lisp mode command C-c C-z( run-lisp) starts up your system's Lisp interpreter as a subprocess and creates the *lisp*
buffer (with an associated window) for input and output. [69]If a Lisp subprocess already exists, C-c C-zuses it rather than creating a second one. You can send function definitions to the Lisp subprocess by putting the cursor anywhere within a function's definition and using C-M-x, which in this case stands for lisp-send-defun. This procedure causes the functions you define to become known to the Lisp interpreter so that you can invoke them later.
Читать дальше