Download

(provide 'goto-last-change) (or (fboundp 'last) (require 'cl)) (defvar goto-last-change-undo nil " The `buffer-undo-list' entry of the previous \\[goto-last-change] command. ") (make-variable-buffer-local 'goto-last-change-undo) (defun goto-last-change (&optional mark-point minimal-line-distance) " Set point to the position of the last change. Consecutive calls set point to the position of the previous change. With a prefix arg (optional arg MARK-POINT non-nil), set mark so \ \\[exchange-point-and-mark] will return point to the current position. " (interactive " P ") (when (eq buffer-undo-list t) (error " No undo information in this buffer ")) (when mark-point (push-mark)) (unless minimal-line-distance (setq minimal-line-distance 10)) (let ((position nil) (undo-list (if (and (eq this-command last-command) goto-last-change-undo) (cdr (memq goto-last-change-undo buffer-undo-list)) buffer-undo-list)) undo) (while (and undo-list (or (not position) (eql position (point)) (and minimal-line-distance (memq last-command '(goto-last-change goto-last-change-with-auto-marks)) (< (count-lines (min position (point-max)) (point)) minimal-line-distance)))) (setq undo (car undo-list)) (cond ((and (consp undo) (integerp (car undo)) (integerp (cdr undo))) (setq position (cdr undo))) ((and (consp undo) (stringp (car undo))) (setq position (abs (cdr undo)))) ((and (consp undo) (eq (car undo) t))) ((and (consp undo) (null (car undo))) (setq position (cdr (last undo)))) ((and (consp undo) (markerp (car undo)))) ((integerp undo)) ((null undo)) (t (error " Invalid undo entry: %s " undo))) (setq undo-list (cdr undo-list))) (cond (position (setq goto-last-change-undo undo) (goto-char (min position (point-max)))) ((and (eq this-command last-command) goto-last-change-undo) (setq goto-last-change-undo nil) (error " No further undo information ")) (t (setq goto-last-change-undo nil) (error " Buffer not modified "))))) (defun goto-last-change-with-auto-marks (&optional minimal-line-distance) " Calls goto-last-change and sets the mark at only the first invocations in a sequence of invocations. " (interactive " P ") (goto-last-change (not (or (eq last-command 'goto-last-change-with-auto-marks) (eq last-command t))) minimal-line-distance))