Go to the first, previous, next, last section, table of contents.


The Version 18 Implementation

The version 18 implementation of zap-to-char is slightly different from the version 19 implementation: it zaps the text up to but not including the zapped-to-character; and zaps to the end of the buffer if the specified character is not found.

The difference is in the second argument to the kill-region command. Where the version 19 implementation looks like this:

(progn
  (search-forward (char-to-string char) nil nil arg)
  (point))

The version 18 implementation looks like this:

(if (search-forward (char-to-string char) nil t arg)
    (progn (goto-char
            (if (> arg 0) (1- (point)) (1+ (point))))
           (point))
  (if (> arg 0)
      (point-max)
    (point-min)))

This looks considerably more complicated, but the code can be readily understood if it is looked at part by part.

The first part is:

(if (search-forward (char-to-string char) nil t arg)

This fits into an if expression that does the following job, as we shall see:

(if able-to-locate-zapped-for-character-and-move-point-to-it
    then-move-point-to-the-exact-spot-and-return-this-location
   else-move-to-end-of-buffer-and-return-that-location)

Evaluation of the if expression specifies the second argument to kill-region. Since the first argument is point, this process makes it possible for kill-region to remove the text between point and the zapped-to location.

We have already described how search-forward moves point as a side effect. The value that search-forward returns is t if the search is successful and either nil or an error message depending on the value of the third argument to search-forward. In this case, t is the third argument and it causes the function to return nil when the search fails. As we will see, it is easy to write the code for handling the case when the search returns nil.

In the version 18 implementation of zap-to-char, the search takes place because the if causes the search expression to be evaluated as its true-or-false-test. If the search is successful, Emacs evaluates the then-part of the if expression. On the other hand, if the search fails, Emacs evaluates the else-part of the if expression.

In the if expression, when the search succeeds, a progn expression is executed--which is to say, it is run as a program.

As we said earlier, progn is a function that causes each of its arguments to be evaluated in sequence and then returns the value of the last one. The preceding expressions are evaluated only for the side effects they perform. The values produced by them are discarded.

In this version of zap-to-char, the progn expression is executed when the search-forward function finds the character for which it is searching. The progn expression has to do two things: put point in exactly the right position; and return the location of point so that kill-region will know how far to kill to.

The reason for all the code in the progn is that when search-forward finds the string it is looking for, it leaves point immediately after the last character in the target string. (In this case the target string is just one character long.) If the search is backwards, search-forward leaves point just before the first character in the target.

However, this version of the zap-to-char function is designed so that it does not remove the character being zapped to. For example, if zap-to-char is to remove all the text up to a `z', this version will not remove the `z' as well. So point has to be moved just enough that the zapped-to character is not removed.


Go to the first, previous, next, last section, table of contents.