dotfiles/.emacs.d/vim-mode/vim-undo.el
michener 5b6729933d Add emacs directory
git-svn-id: http://photonzero.com/dotfiles/trunk@54 23f722f6-122a-0410-8cef-c75bd312dd78
2010-08-12 01:19:45 +00:00

71 lines
2.1 KiB
EmacsLisp

;;; vim-undo.el - Undo/Redo for VIM.
;; Copyright (C) 2009, 2010 Frank Fischer
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
;;
;; This file is not part of GNU Emacs.
;;; Commentary:
;; Before the execution of an editing command, the calling function
;; should save the current head of buffer-undo-list. When the
;; editing-command has finished, the calling function should use
;; vim:connect-undos to connect the changes made during editing to one
;; single undo-block.
;;
;; Insert-mode has a special handling: when activated, it stores the
;; current head of buffer-undo-list in vim:last-insert-undo and used
;; this pointer to connect all editing actions during insert-mode to
;; one undo-block when insert-mode is deactivated. If a function
;; activates insert-mode it may modify vim:last-insert-undo to an
;; apropriate value (see vim:execute-mapping for an example).
;;; Code:
(condition-case nil
(require 'redo)
(error
(message "vim-mode: Could not load 'redo', redo-command not available.")))
(defvar vim:last-undo)
;; undo stuff
(defun vim:connect-undos (last-undo)
(labels
((find-mark (lst)
(while (not (or (null lst)
(eq lst last-undo)))
(setq lst (cdr lst)))
(not (null lst))))
;; ensure last-undo is still in the undo list
(when (and last-undo
(not (eq last-undo buffer-undo-list))
(find-mark buffer-undo-list))
;; add the end-of-command mark if not already there
(unless (null (car buffer-undo-list))
(push nil buffer-undo-list))
;; remove all nils until the mark
(let ((lst buffer-undo-list))
(while (and lst
(not (eq (cdr lst) last-undo)))
(if (null (cadr lst))
(setcdr lst (cddr lst))
(setq lst (cdr lst))))))))
(vim:defcmd vim:cmd-undo (count nonrepeatable)
(setq vim:last-undo nil)
(dotimes (i (or count 1))
(undo)))
(vim:defcmd vim:cmd-redo (count nonrepeatable)
(setq vim:last-undo nil)
(redo (or count 1)))
(provide 'vim-undo)
;;; vim-undo.el ends here