- (remove-list-of-text-properties start end
- yank-excluded-properties))))
-
-(defun insert-for-yank (&rest strings)
- "Insert STRINGS at point, stripping some text properties.
-Strip text properties from the inserted text
-according to `yank-excluded-properties'.
-Otherwise just like (insert STRINGS...)."
- (let ((opoint (point)))
- (apply 'insert strings)
- (remove-yank-excluded-properties opoint (point))))
+ (remove-list-of-text-properties start end yank-excluded-properties))))
+
+(defvar yank-undo-function)
+
+(defun insert-for-yank (string)
+ "Calls `insert-for-yank-1' repetitively for each `yank-handler' segment.
+
+See `insert-for-yank-1' for more details."
+ (let (to)
+ (while (setq to (next-single-property-change 0 'yank-handler string))
+ (insert-for-yank-1 (substring string 0 to))
+ (setq string (substring string to))))
+ (insert-for-yank-1 string))
+
+(defun insert-for-yank-1 (string)
+ "Insert STRING at point, stripping some text properties.
+
+Strip text properties from the inserted text according to
+`yank-excluded-properties'. Otherwise just like (insert STRING).
+
+If STRING has a non-nil `yank-handler' property on the first character,
+the normal insert behaviour is modified in various ways. The value of
+the yank-handler property must be a list with one to five elements
+with the following format: (FUNCTION PARAM NOEXCLUDE UNDO).
+When FUNCTION is present and non-nil, it is called instead of `insert'
+ to insert the string. FUNCTION takes one argument--the object to insert.
+If PARAM is present and non-nil, it replaces STRING as the object
+ passed to FUNCTION (or `insert'); for example, if FUNCTION is
+ `yank-rectangle', PARAM may be a list of strings to insert as a
+ rectangle.
+If NOEXCLUDE is present and non-nil, the normal removal of the
+ yank-excluded-properties is not performed; instead FUNCTION is
+ responsible for removing those properties. This may be necessary
+ if FUNCTION adjusts point before or after inserting the object.
+If UNDO is present and non-nil, it is a function that will be called
+ by `yank-pop' to undo the insertion of the current object. It is
+ called with two arguments, the start and end of the current region.
+ FUNCTION may set `yank-undo-function' to override the UNDO value."
+ (let* ((handler (and (stringp string)
+ (get-text-property 0 'yank-handler string)))
+ (param (or (nth 1 handler) string))
+ (opoint (point)))
+ (setq yank-undo-function t)
+ (if (nth 0 handler) ;; FUNCTION
+ (funcall (car handler) param)
+ (insert param))
+ (unless (nth 2 handler) ;; NOEXCLUDE
+ (remove-yank-excluded-properties opoint (point)))
+ (if (eq yank-undo-function t) ;; not set by FUNCTION
+ (setq yank-undo-function (nth 3 handler))) ;; UNDO
+ (if (nth 4 handler) ;; COMMAND
+ (setq this-command (nth 4 handler)))))