Next: kill-new function, Previous: last-command & this-command, Up: copy-region-as-kill body [Contents][Index]
kill-append
functionThe kill-append
function looks like this:
(defun kill-append (string before-p &optional yank-handler) "Append STRING to the end of the latest kill in the kill ring. If BEFORE-P is non-nil, prepend STRING to the kill. … " (let* ((cur (car kill-ring))) (kill-new (if before-p (concat string cur) (concat cur string)) (or (= (length cur) 0) (equal yank-handler (get-text-property 0 'yank-handler cur))) yank-handler)))
The kill-append
function is fairly straightforward. It uses the
kill-new
function, which we will discuss in more detail in a moment.
(Also, the function provides an optional argument called
yank-handler
; when invoked, this argument tells the function how to
deal with properties added to the text, such as bold or italics.)
It has a let*
function to set the value of the first element of the
kill ring to cur
. (I do not know why the function does not use
let
instead; only one value is set in the expression. Perhaps this
is a bug that produces no problems?)
Consider the conditional that is one of the two arguments to
kill-new
. It uses concat
to concatenate the new text to the
CAR of the kill ring. Whether it prepends or appends the text depends
on the results of an if
expression:
(if before-p ; if-part (concat string cur) ; then-part (concat cur string)) ; else-part
If the region being killed is before the region that was killed in the last
command, then it should be prepended before the material that was saved in
the previous kill; and conversely, if the killed text follows what was just
killed, it should be appended after the previous text. The if
expression depends on the predicate before-p
to decide whether the
newly saved text should be put before or after the previously saved text.
The symbol before-p
is the name of one of the arguments to
kill-append
. When the kill-append
function is evaluated, it
is bound to the value returned by evaluating the actual argument. In this
case, this is the expression (< end beg)
. This expression does not
directly determine whether the killed text in this command is located before
or after the kill text of the last command; what it does is determine
whether the value of the variable end
is less than the value of the
variable beg
. If it is, it means that the user is most likely
heading towards the beginning of the buffer. Also, the result of evaluating
the predicate expression, (< end beg)
, will be true and the text will
be prepended before the previous text. On the other hand, if the value of
the variable end
is greater than the value of the variable
beg
, the text will be appended after the previous text.
When the newly saved text will be prepended, then the string with the new text will be concatenated before the old text:
(concat string cur)
But if the text will be appended, it will be concatenated after the old text:
(concat cur string))
To understand how this works, we first need to review the concat
function. The concat
function links together or unites two strings
of text. The result is a string. For example:
(concat "abc" "def") ⇒ "abcdef"
(concat "new " (car '("first element" "second element"))) ⇒ "new first element" (concat (car '("first element" "second element")) " modified") ⇒ "first element modified"
We can now make sense of kill-append
: it modifies the contents of the
kill ring. The kill ring is a list, each element of which is saved text.
The kill-append
function uses the kill-new
function which in
turn uses the setcar
function.
Next: kill-new function, Previous: last-command & this-command, Up: copy-region-as-kill body [Contents][Index]