;;; vim.el --- a VIM-emulation for Emacs ;; Copyright (C) 2009, 2010 Frank Fischer ;; Author: Frank Fischer , ;; Maintainer: Frank Fischer , ;; URL: http://www.emacswiki.org/emacs/VimMode ;; License: GPLv2 or later, as described below under "License" ;; Compatibility: Emacs 22, 23, XEmacs 21.4 ;; Version: 0.3.0 ;; Keywords: emulation, vim ;; Human-Keywords: vim, emacs ;; ;; This file is not part of GNU Emacs. ;;; Acknowledgements: ;; This package contains code from several other packages: ;; ;; - rect-mark.el ;; - viper ;; - vimpulse.el ;; - windmove.el ;; ;; Special thanks go to the authors of those packages. ;;; Commentary: ;; A simple VIM-mode for Emacs ;; ;; This project is in a VERY early development state and many function ;; have not been implemented yet. ;; ;; If you want to try, open this file in your Emacs and evaluate the buffer. ;; The mode can be activated by 'M-x vim-mode'. ;; ;; Don't forget to disable Viper if you want to try vim-mode. ;; ;; The project is divided into many files. Each file implements some ;; almost-independent feature. If you want to learn how to implement ;; new commands or motions, look at the files vim-commands.el and ;; vim-motions.el. ;; ;; Here is a short description of the contents of each file: ;; ;; - vim.el: This file just sets up the mode and loads the other files. ;; ;; - vim-compat.el: Compatibility layer for different Emacsen. ;; ;; - vim-keymap.el: A few functions for defining keymaps for vim-mode. ;; ;; - vim-vim.el: This file contains the macros for defining motions ;; and commands as well as some utility functions for ;; calling them. ;; ;; - vim-modes.el: Each VIM-mode (normal-mode, insert-mode, ...) corresponds ;; to an Emacs-minor-mode. This file contains some macros and ;; functions to define new vim-modes in this context. ;; ;; - vim-insert-mode.el: The implementation of insert-mode. ;; ;; - vim-normal-mode.el: The implementation of normal-mode. ;; ;; - vim-visual-mode.el: The implementation of visual-mode. ;; ;; - vim-ex-mode.el: The implementation of ex-mode. ;; ;; - vim-commands.el: The implementations of commands like 'delete', ;; 'yank', 'paste' and so on. ;; ;; - vim-motions.el: The implementations of motion commands like 'h', ;; 'i', 'j', 'k', 'f', 'w', ... ;; ;; - vim-scroll.el: The implementation of scrolling commands like ;; 'zz', 'Ctrl-F'. ;; ;; - vim-window-el: The implementation of window commands like 'C-w s'. ;; ;; - vim-ex-commands.el: The implementations of commands like ':edit' ;; or ':buffer'. ;; ;; - vim-search.el: The implementation of '/' and ':substitute'. ;; ;; - vim-undo.el: Some variables and functions for undo/redo. ;; ;; - vim-maps.el: The definition of the basic keymaps. This file ;; connects the keymaps with the commands and motions ;; defined in vim-commands.el and vim-motions.el. ;; ;; TODO: ;; ;; HAVE: ;; - framework for keymaps, motions, commands and command-mappings ;; - insert-mode, normal-mode, visual-mode and ex-mode ;; - simple motions ;; - deletion, yank, paste, change, replace ;; - undo/redo ;; - repeat ;; ;; MISSING: ;; - better Emacs integration (modes, buffer local variables, ...) ;; - text objects ;; - several commands ;; - marks and register ;; - ... ;; - several calls 'looking-back' may be inefficient ;;; Code: (eval-when-compile (require 'cl)) (defgroup vim-mode nil "A VIM emulation mode." :group 'emulations) (defcustom vim:default-initial-mode 'normal "The default initial vim sub-mode." :type '(symbol :tag "vim-mode start mode") :group 'vim-mode) (defcustom vim:initial-modes '((debugger-mode . window) (compilation-mode . window) (grep-mode . window) (gud-mode . window) (sldb-mode . window) (slime-repl-mode . window) (reftex-select-bib-mode . window) (completion-list-mode . window) (help-mode . motion) (Info-mode . motion)) "Associated list of (major-mode . vim:mode) which specifies the vim sub-mode in which vim-mode should start when a buffer with the given major-mode is created." :type '(repeat (cons (symbol :tag "major mode") (symbol :tag "vim-mode start mode"))) :group 'vim-mode) (defmacro vim:deflocalvar (name &rest args) "Defines a buffer-local variable." (declare (indent defun)) `(progn (defvar ,name ,@args) (make-variable-buffer-local ',name))) (font-lock-add-keywords 'emacs-lisp-mode '("vim:deflocalvar")) (defvar vim:emulation-mode-alist nil "List of all keymaps used by some modes.") (let ((load-path (cons (expand-file-name ".") load-path))) (eval-when-compile (load "vim-compat") (load "vim-keymap") (load "vim-modes") (load "vim-vim") (load "vim-normal-mode") (load "vim-insert-mode") (load "vim-visual-mode") (load "vim-commands") (load "vim-motions") (load "vim-scroll") (load "vim-window") (load "vim-undo") (load "vim-ex") (load "vim-ex-commands") (load "vim-search") (load "vim-maps")) (require 'vim-compat) (require 'vim-keymap) (require 'vim-modes) (require 'vim-vim) (require 'vim-normal-mode) (require 'vim-insert-mode) (require 'vim-visual-mode) (require 'vim-commands) (require 'vim-motions) (require 'vim-scroll) (require 'vim-window) (require 'vim-undo) (require 'vim-ex) (require 'vim-ex-commands) (require 'vim-search) (require 'vim-maps)) (define-minor-mode vim-local-mode "VIM emulation mode." :lighter " VIM" :init-value nil :global nil (if vim-local-mode (progn (make-local-variable 'vim:emulation-mode-alist) (vim:initialize-keymaps t)) (progn (vim:initialize-keymaps nil) (setq global-mode-string (delq 'vim:mode-string global-mode-string )) (vim:activate-mode nil)))) (define-globalized-minor-mode vim-mode vim-local-mode vim:initialize) (defun vim:initialize () (unless (vim:minibuffer-p) (let ((mode (cdr (or (assoc major-mode vim:initial-modes) (cons t vim:default-initial-mode))))) (when mode (setq vim:active-mode nil) (vim-local-mode 1) (vim:intercept-ESC-mode 1) (vim:activate-mode mode) (unless (memq 'vim:mode-string global-mode-string) (setq global-mode-string (append '("" vim:mode-string) (cdr global-mode-string)))))))) (provide 'vim) ;;; vim.el ends here