[comp.emacs] GNU Emacs Query

willner@cfa.harvard.EDU (Steve Willner) (01/15/87)

I would greatly appreciate some help with a mysterious problem.  The
following is in my .emacs initialization file:
(defun append-to-killring () "
       Append mark-point region to the last entry on the kill ring."
  (interactive)
  (append-next-kill)
  (kill-region (point) (mark))
  (message "%s" "Appended.")
  )

But when I execute this function, it's as if the (append-next-kill)
command had no effect.  That is, the commands
  [mark region]
  (append-to-killring)
create a new entry in the kill ring, rather than appending to the
previous entry.  (The region is killed, and the "Appended" message
appears, so it seems that the command is doing something.)  It makes
no difference whether the command is executed via a key-binding or
via M-x and typing the name literally.  On the other hand, the
command sequence
  [mark region]
  M-x append-next-kill
  kill-region  [activated by key binding]
works as I expect; i.e. the new kill is appended to the old.  But if
the kill-region command above is typed via M-x, again the kill fails
to append.

The program version is GNU Emacs 17.49.8 of Mon Jul 7 1986.

Please e-mail replies to one of the addresses below, if possible.
Thanks for any help.
-- 
Steve Willner              Phone 617-495-7123        Bitnet: willner@cfa1
60 Garden St.              FTS:      830-7123         UUCP:   willner@cfa
Cambridge, MA 02138 USA  Telex:  921428 satellite cam

jr@ALEXANDER.BBN.COM (John Robinson) (01/15/87)

Here's a definition that works:

(defun append-to-killring () "
       Append mark-point region to the last entry on the kill ring."
  (interactive)
  (setq last-command 'kill-region)
  (kill-region (point) (mark))
  (message "Appended.")
  )

The problem has to do with the semantics of (append-next-kill), and
the variables this-command and last-command.  (append-next-kill) sets
the variable "this-command" to 'kill-region.  When the command
interpreter returns to the top level (read more keyboard input, I
assume), it copies this-command to last-command.  (kill-region) then
notices whether last-command was 'kill-region, and does the append if
so.  This is why ^K^K appends the two kills.  Since your function
calls kill-region before it returns, setting this-command isn't good
enough; last-command needs to be set when kill-region is called; hence
the change I made.  (I also bummed the message line, though I guess
you'll pull that out).

Look in lisp/simple.el for more.  You could probably open-code the
whole function without having to call kill-region at all by seeing how
it works.

A similar thing happens with (yank) and (yank-pop).

Lesson 1: (append-next-kill) can never be called from inside an
interactive (or any other for that matter) function unless you want
the next *interactive* function to do the append iff it is or calls
(kill-region).

Lesson 2: look at the sources.  That's why you have them.

I won't comment on the correctness of this design, but there it is.

/jr
jr@bbn.com or jr@bbnccv.uucp

Without life, there wouldn't be chemical companies.