Copyright (C) 2000-2012 |
GNU Info (emacs-lisp-intro.info)append save-excursion`save-excursion' in `append-to-buffer' -------------------------------------- The body of the `let' expression in `append-to-buffer' consists of a `save-excursion' expression. The `save-excursion' function saves the locations of point and mark, and restores them to those positions after the expressions in the body of the `save-excursion' complete execution. In addition, `save-excursion' keeps track of the original buffer, and restores it. This is how `save-excursion' is used in `append-to-buffer'. Incidentally, it is worth noting here that a Lisp function is normally formatted so that everything that is enclosed in a multi-line spread is indented more to the right than the first symbol. In this function definition, the `let' is indented more than the `defun', and the `save-excursion' is indented more than the `let', like this: (defun ... ... ... (let... (save-excursion ... This formatting convention makes it easy to see that the two lines in the body of the `save-excursion' are enclosed by the parentheses associated with `save-excursion', just as the `save-excursion' itself is enclosed by the parentheses associated with the `let': (let ((oldbuf (current-buffer))) (save-excursion (set-buffer (get-buffer-create buffer)) (insert-buffer-substring oldbuf start end)))) The use of the `save-excursion' function can be viewed as a process of filling in the slots of a template: (save-excursion FIRST-EXPRESSION-IN-BODY SECOND-EXPRESSION-IN-BODY ... LAST-EXPRESSION-IN-BODY) In this function, the body of the `save-excursion' contains only two expressions. The body looks like this: (set-buffer (get-buffer-create buffer)) (insert-buffer-substring oldbuf start end) When the `append-to-buffer' function is evaluated, the two expressions in the body of the `save-excursion' are evaluated in sequence. The value of the last expression is returned as the value of the `save-excursion' function; the other expression is evaluated only for its side effects. The first line in the body of the `save-excursion' uses the `set-buffer' function to change the current buffer to the one specified in the first argument to `append-to-buffer'. (Changing the buffer is the side effect; as we have said before, in Lisp, a side effect is often the primary thing we want.) The second line does the primary work of the function. The `set-buffer' function changes Emacs' attention to the buffer to which the text will be copied and from which `save-excursion' will return. The line looks like this: (set-buffer (get-buffer-create buffer)) The innermost expression of this list is `(get-buffer-create buffer)'. This expression uses the `get-buffer-create' function, which either gets the named buffer, or if it does not exist, creates one with the given name. This means you can use `append-to-buffer' to put text into a buffer that did not previously exist. `get-buffer-create' also keeps `set-buffer' from getting an unnecessary error: `set-buffer' needs a buffer to go to; if you were to specify a buffer that does not exist, Emacs would baulk. Since `get-buffer-create' will create a buffer if none exists, `set-buffer' is always provided with a buffer. The last line of `append-to-buffer' does the work of appending the text: (insert-buffer-substring oldbuf start end) The `insert-buffer-substring' function copies a string _from_ the buffer specified as its first argument and inserts the string into the present buffer. In this case, the argument to `insert-buffer-substring' is the value of the variable created and bound by the `let', namely the value of `oldbuf', which was the current buffer when you gave the `append-to-buffer' command. After `insert-buffer-substring' has done its work, `save-excursion' will restore the action to the original buffer and `append-to-buffer' will have done its job. Written in skeletal form, the workings of the body look like this: (let (BIND-`oldbuf'-TO-VALUE-OF-`current-buffer') (save-excursion ; Keep track of buffer. CHANGE-BUFFER INSERT-SUBSTRING-FROM-`oldbuf'-INTO-BUFFER) CHANGE-BACK-TO-ORIGINAL-BUFFER-WHEN-FINISHED LET-THE-LOCAL-MEANING-OF-`oldbuf'-DISAPPEAR-WHEN-FINISHED In summary, `append-to-buffer' works as follows: it saves the value of the current buffer in the variable called `oldbuf'. It gets the new buffer, creating one if need be, and switches Emacs to it. Using the value of `oldbuf', it inserts the region of text from the old buffer into the new buffer; and then using `save-excursion', it brings you back to your original buffer. In looking at `append-to-buffer', you have explored a fairly complex function. It shows how to use `let' and `save-excursion', and how to change to and come back from another buffer. Many function definitions use `let', `save-excursion', and `set-buffer' this way. automatically generated by info2www version 1.2.2.9 |