Add emacs directory
git-svn-id: http://photonzero.com/dotfiles/trunk@54 23f722f6-122a-0410-8cef-c75bd312dd78
This commit is contained in:
parent
e50f8f4bc8
commit
5b6729933d
100 changed files with 37586 additions and 0 deletions
BIN
.emacs.d/vim-mode/.hg/00changelog.i
Normal file
BIN
.emacs.d/vim-mode/.hg/00changelog.i
Normal file
Binary file not shown.
1
.emacs.d/vim-mode/.hg/branch
Normal file
1
.emacs.d/vim-mode/.hg/branch
Normal file
|
|
@ -0,0 +1 @@
|
|||
default
|
||||
2
.emacs.d/vim-mode/.hg/branchheads.cache
Normal file
2
.emacs.d/vim-mode/.hg/branchheads.cache
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
9c9e1bf0c4a2ed90304bab5e7b00bbbe23ea1fe7 286
|
||||
9c9e1bf0c4a2ed90304bab5e7b00bbbe23ea1fe7 default
|
||||
BIN
.emacs.d/vim-mode/.hg/dirstate
Normal file
BIN
.emacs.d/vim-mode/.hg/dirstate
Normal file
Binary file not shown.
2
.emacs.d/vim-mode/.hg/hgrc
Normal file
2
.emacs.d/vim-mode/.hg/hgrc
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
[paths]
|
||||
default = http://bitbucket.org/lyro/vim-mode
|
||||
3
.emacs.d/vim-mode/.hg/requires
Normal file
3
.emacs.d/vim-mode/.hg/requires
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
revlogv1
|
||||
store
|
||||
fncache
|
||||
BIN
.emacs.d/vim-mode/.hg/store/00changelog.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/00changelog.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/00manifest.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/00manifest.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/.hgignore.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/.hgignore.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/.hgtags.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/.hgtags.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-combat.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-combat.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-commands.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-commands.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-compat.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-compat.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-ex-commands.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-ex-commands.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-ex.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-ex.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-insert-mode.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-insert-mode.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-keymap.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-keymap.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-keys.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-keys.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-maps.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-maps.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-modes.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-modes.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-motions.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-motions.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-node.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-node.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-normal-mode.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-normal-mode.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-scroll.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-scroll.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-search.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-search.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-undo.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-undo.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-vim.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-vim.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-visual-mode.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-visual-mode.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim-window.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim-window.el.i
Normal file
Binary file not shown.
BIN
.emacs.d/vim-mode/.hg/store/data/vim.el.i
Normal file
BIN
.emacs.d/vim-mode/.hg/store/data/vim.el.i
Normal file
Binary file not shown.
22
.emacs.d/vim-mode/.hg/store/fncache
Normal file
22
.emacs.d/vim-mode/.hg/store/fncache
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
data/.hgignore.i
|
||||
data/.hgtags.i
|
||||
data/vim-combat.el.i
|
||||
data/vim-commands.el.i
|
||||
data/vim-compat.el.i
|
||||
data/vim-ex-commands.el.i
|
||||
data/vim-ex.el.i
|
||||
data/vim-insert-mode.el.i
|
||||
data/vim-keymap.el.i
|
||||
data/vim-keys.el.i
|
||||
data/vim-maps.el.i
|
||||
data/vim-modes.el.i
|
||||
data/vim-motions.el.i
|
||||
data/vim-node.el.i
|
||||
data/vim-normal-mode.el.i
|
||||
data/vim-scroll.el.i
|
||||
data/vim-search.el.i
|
||||
data/vim-undo.el.i
|
||||
data/vim-vim.el.i
|
||||
data/vim-visual-mode.el.i
|
||||
data/vim-window.el.i
|
||||
data/vim.el.i
|
||||
BIN
.emacs.d/vim-mode/.hg/store/undo
Normal file
BIN
.emacs.d/vim-mode/.hg/store/undo
Normal file
Binary file not shown.
5
.emacs.d/vim-mode/.hg/tags.cache
Normal file
5
.emacs.d/vim-mode/.hg/tags.cache
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
286 9c9e1bf0c4a2ed90304bab5e7b00bbbe23ea1fe7 e20b66a15626ce3c3dedc3de035c0d65915f1159
|
||||
|
||||
1f59539819aa706d915e97ecdf7a513d1e5e664e v0.1
|
||||
9c22feb593237c76560cfc1b817c2ece500e6ac9 v0.2
|
||||
15dff001f097be2ffc0b717edb7fd019a36e407a v0.3
|
||||
1
.emacs.d/vim-mode/.hg/undo.branch
Normal file
1
.emacs.d/vim-mode/.hg/undo.branch
Normal file
|
|
@ -0,0 +1 @@
|
|||
default
|
||||
0
.emacs.d/vim-mode/.hg/undo.dirstate
Normal file
0
.emacs.d/vim-mode/.hg/undo.dirstate
Normal file
2
.emacs.d/vim-mode/.hgignore
Normal file
2
.emacs.d/vim-mode/.hgignore
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
~$
|
||||
\.elc$
|
||||
3
.emacs.d/vim-mode/.hgtags
Normal file
3
.emacs.d/vim-mode/.hgtags
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
1f59539819aa706d915e97ecdf7a513d1e5e664e v0.1
|
||||
9c22feb593237c76560cfc1b817c2ece500e6ac9 v0.2
|
||||
15dff001f097be2ffc0b717edb7fd019a36e407a v0.3
|
||||
698
.emacs.d/vim-mode/vim-commands.el
Normal file
698
.emacs.d/vim-mode/vim-commands.el
Normal file
File diff suppressed because it is too large
Load diff
537
.emacs.d/vim-mode/vim-compat.el
Normal file
537
.emacs.d/vim-mode/vim-compat.el
Normal file
File diff suppressed because it is too large
Load diff
132
.emacs.d/vim-mode/vim-ex-commands.el
Normal file
132
.emacs.d/vim-mode/vim-ex-commands.el
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
;;; vim-ex-commands.el - Implementation of some ex-mode commands.
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defun* vim:save-buffer (file-name &key begin end mustbenew append)
|
||||
"Saves the lines from `begin' to `end' to file `file-name'."
|
||||
(with-current-buffer vim:ex-current-buffer
|
||||
(when (null file-name)
|
||||
(setq file-name (buffer-file-name))
|
||||
(unless file-name
|
||||
(error "Please specify a file-name for this buffer!")))
|
||||
|
||||
(let (beg-pos end-pos)
|
||||
(when begin
|
||||
(setq beg-pos (save-excursion
|
||||
(goto-line begin)
|
||||
(line-beginning-position)))
|
||||
(setq end-pos (if end
|
||||
(save-excursion
|
||||
(goto-line end)
|
||||
(line-end-position))
|
||||
beg-pos)))
|
||||
|
||||
(cond
|
||||
((and (null beg-pos)
|
||||
(string= file-name (buffer-file-name)))
|
||||
(save-buffer))
|
||||
((and (null beg-pos)
|
||||
(null (buffer-file-name)))
|
||||
(write-file file-name))
|
||||
(t
|
||||
(write-region beg-pos end-pos file-name append nil nil mustbenew))))))
|
||||
|
||||
|
||||
(vim:defcmd vim:cmd-write (motion (argument:file file) nonrepeatable)
|
||||
"Saves file `file'."
|
||||
(vim:save-buffer file
|
||||
:begin (and motion (vim:motion-first-line motion))
|
||||
:end (and motion (vim:motion-last-line motion))
|
||||
:mustbenew t))
|
||||
|
||||
(vim:defcmd vim:cmd-write-q (motion (argument:file file) nonrepeatable)
|
||||
"Overwrites file `file'."
|
||||
(vim:save-buffer file
|
||||
:begin (and motion (vim:motion-first-line motion))
|
||||
:end (and motion (vim:motion-last-line motion))
|
||||
:mustbenew nil))
|
||||
|
||||
(vim:defcmd vim:cmd-write-all (nonrepeatable)
|
||||
"Saves all buffers."
|
||||
(save-some-buffers nil))
|
||||
|
||||
(vim:defcmd vim:cmd-write-all-q (nonrepeatable)
|
||||
"Overwrites all buffers."
|
||||
(save-some-buffers t))
|
||||
|
||||
(vim:defcmd vim:cmd-edit ((argument:file file) nonrepeatable)
|
||||
"Visits a certain file."
|
||||
(if file
|
||||
(find-file file)
|
||||
(when (buffer-file-name)
|
||||
(find-file (buffer-file-name)))))
|
||||
|
||||
(vim:defcmd vim:cmd-buffer ((argument:buffer buffer) nonrepeatable)
|
||||
"Switches to another buffer."
|
||||
(if buffer
|
||||
(when (or (get-buffer buffer)
|
||||
(y-or-n-p (format "No buffer with name \"%s\" exists. Create new buffer? " buffer)))
|
||||
(switch-to-buffer buffer))
|
||||
(switch-to-buffer (other-buffer))))
|
||||
|
||||
(vim:defcmd vim:cmd-delete-buffer ((argument:buffer buffer) nonrepeatable)
|
||||
"Deletes a buffer."
|
||||
(kill-buffer buffer))
|
||||
|
||||
(vim:defcmd vim:cmd-delete-buffer-q ((argument:buffer buffer) nonrepeatable)
|
||||
"Deletes a buffer without saving."
|
||||
(if buffer
|
||||
(with-current-buffer buffer
|
||||
(set-buffer-modified-p nil))
|
||||
(set-buffer-modified-p nil))
|
||||
(kill-buffer buffer))
|
||||
|
||||
(vim:defcmd vim:cmd-quit (nonrepeatable)
|
||||
"Closes the current window, exits Emacs if this is the last window."
|
||||
(condition-case nil
|
||||
(delete-window)
|
||||
(error
|
||||
(condition-case nil
|
||||
(delete-frame)
|
||||
(error (save-buffers-kill-emacs))))))
|
||||
|
||||
(vim:defcmd vim:cmd-quit-q (nonrepeatable)
|
||||
"Closes the current window, exits Emacs if this is the last window."
|
||||
(condition-case nil
|
||||
(delete-window)
|
||||
(error
|
||||
(condition-case nil
|
||||
(delete-frame)
|
||||
(error (kill-emacs))))))
|
||||
|
||||
(vim:defcmd vim:cmd-quit-all (nonrepeatable)
|
||||
"Exits Emacs, asking for saving."
|
||||
(save-buffers-kill-emacs))
|
||||
|
||||
(vim:defcmd vim:cmd-quit-all-q (nonrepeatable)
|
||||
"Exits Emacs, without saving."
|
||||
(kill-emacs))
|
||||
|
||||
(vim:defcmd vim:cmd-save-and-quit (nonrepeatable)
|
||||
"Exits Emacs, without saving."
|
||||
(save-buffers-kill-emacs 1))
|
||||
|
||||
(vim:defcmd vim:cmd-save-and-close ((argument:file file) nonrepeatable)
|
||||
"Saves the current buffer and closes the window."
|
||||
(vim:cmd-write :argument file)
|
||||
(vim:cmd-quit))
|
||||
|
||||
(vim:defcmd vim:cmd-save-and-close-q ((argument:file file) nonrepeatable)
|
||||
"Saves the current buffer and closes the window."
|
||||
(vim:cmd-write-q :argument file)
|
||||
(vim:cmd-quit))
|
||||
|
||||
(provide 'vim-ex-commands)
|
||||
|
||||
;;; vim-ex-commands.el ends here
|
||||
440
.emacs.d/vim-mode/vim-ex.el
Normal file
440
.emacs.d/vim-mode/vim-ex.el
Normal file
|
|
@ -0,0 +1,440 @@
|
|||
;;; vim-ex.el - Ex-mode.
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defvar vim:ex-commands nil
|
||||
"List of pairs (command . function).")
|
||||
|
||||
(defvar vim:ex-current-buffer)
|
||||
|
||||
(vim:deflocalvar vim:ex-local-commands nil
|
||||
"List of pairs (command . function).")
|
||||
|
||||
(defvar vim:ex-history nil
|
||||
"History of ex-commands.")
|
||||
|
||||
(defun vim:emap (keys command)
|
||||
"Maps an ex-command to some function."
|
||||
(unless (find-if #'(lambda (x) (string= (car x) keys)) vim:ex-commands)
|
||||
(add-to-list 'vim:ex-commands (cons keys command))))
|
||||
|
||||
(defun vim:local-emap (keys command)
|
||||
"Maps an ex-command to some function buffer-local."
|
||||
(unless (find-if #'(lambda (x) (string= (car x) keys)) vim:ex-local-commands)
|
||||
(add-to-list 'vim:ex-local-commands (cons keys command))))
|
||||
|
||||
(defun vim:ex-binding (cmd)
|
||||
"Returns the current binding of `cmd' or nil."
|
||||
(with-current-buffer vim:ex-current-buffer
|
||||
(or (cdr-safe (assoc cmd vim:ex-local-commands))
|
||||
(cdr-safe (assoc cmd vim:ex-commands)))))
|
||||
|
||||
(defvar vim:ex-keymap (make-sparse-keymap)
|
||||
"Keymap used in ex-mode.")
|
||||
|
||||
(define-key vim:ex-keymap "\t" 'minibuffer-complete)
|
||||
(define-key vim:ex-keymap [return] 'exit-minibuffer)
|
||||
(define-key vim:ex-keymap (kbd "RET") 'exit-minibuffer)
|
||||
(define-key vim:ex-keymap " " 'vim:ex-expect-argument)
|
||||
(define-key vim:ex-keymap (kbd "C-j") 'vim:ex-execute-command)
|
||||
(define-key vim:ex-keymap (kbd "C-g") 'abort-recursive-edit)
|
||||
(define-key vim:ex-keymap [up] 'previous-history-element)
|
||||
(define-key vim:ex-keymap [down] 'next-history-element)
|
||||
(define-key vim:ex-keymap "\d" 'vim:ex-delete-backward-char)
|
||||
|
||||
(defun vim:ex-delete-backward-char (n)
|
||||
"Delete the previous `n' characters. If ex-buffer is empty,
|
||||
cancel ex-mode."
|
||||
(interactive "p")
|
||||
(if (and (>= n 1)
|
||||
(zerop (length (minibuffer-contents))))
|
||||
(exit-minibuffer))
|
||||
(delete-backward-char n))
|
||||
|
||||
(defvar vim:ex-keep-reading nil)
|
||||
(defvar vim:ex-cmdline nil)
|
||||
(defvar vim:ex-cmd nil)
|
||||
(defvar vim:ex-beg nil)
|
||||
(defvar vim:ex-end nil)
|
||||
|
||||
(defun vim:ex-split-cmdline (cmdline)
|
||||
(multiple-value-bind (cmd-region beg end) (vim:ex-parse cmdline)
|
||||
(if (null cmd-region)
|
||||
(values cmdline "" cmdline "" beg end)
|
||||
(let ((range (substring cmdline 0 (car cmd-region)))
|
||||
(cmd (substring cmdline (car cmd-region) (cdr cmd-region)))
|
||||
(spaces "")
|
||||
(arg (substring cmdline (cdr cmd-region))))
|
||||
|
||||
;; skip whitespaces
|
||||
(when (string-match "\\`\\s-*" arg)
|
||||
(setq spaces (match-string 0 arg)
|
||||
arg (substring arg (match-end 0))))
|
||||
|
||||
(values range cmd spaces arg beg end)))))
|
||||
|
||||
(defun vim:ex-expect-argument (n)
|
||||
;; called if the space separating the command from the argument has
|
||||
;; been pressed
|
||||
(interactive "p")
|
||||
(let ((cmdline (vim:minibuffer-contents)))
|
||||
(self-insert-command n)
|
||||
(multiple-value-bind (range cmd spaces arg beg end) (vim:ex-split-cmdline cmdline)
|
||||
|
||||
(when (and (= (point) (point-max))
|
||||
(zerop (length spaces))
|
||||
(zerop (length arg)))
|
||||
(while (stringp cmd)
|
||||
(setq cmd (vim:ex-binding cmd)))
|
||||
|
||||
(if (null cmd) (ding)
|
||||
(let ((result (case (vim:cmd-arg cmd)
|
||||
(file
|
||||
(vim:ex-complete-file-argument nil nil nil))
|
||||
(buffer
|
||||
(vim:ex-complete-buffer-argument nil nil nil))
|
||||
((t)
|
||||
(vim:ex-complete-text-argument nil nil nil)))))
|
||||
(when result (insert result))))))))
|
||||
|
||||
(defun vim:ex-complete (cmdline predicate flag)
|
||||
(multiple-value-bind (range cmd spaces arg beg end) (vim:ex-split-cmdline cmdline)
|
||||
(setq vim:ex-cmd cmd)
|
||||
|
||||
(cond
|
||||
;; only complete at the end of the command
|
||||
((< (point) (point-max)) nil)
|
||||
|
||||
;; if at the end of a command, complete the command
|
||||
((and (zerop (length spaces)) (zerop (length arg)))
|
||||
(let ((result (vim:ex-complete-command cmd predicate flag)))
|
||||
(cond
|
||||
((null result) nil)
|
||||
((eq t result) t)
|
||||
((stringp result)
|
||||
(if flag result (concat range result)))
|
||||
((listp result) (if flag result (mapcar #'(lambda (x) (concat range x)) result)))
|
||||
(t (error "Completion returned unexpected value.")))))
|
||||
|
||||
;; otherwise complete the argument
|
||||
(t
|
||||
(let ((result (vim:ex-complete-argument arg predicate flag)))
|
||||
(cond
|
||||
((null result) nil)
|
||||
((eq t result) t)
|
||||
((stringp result) (if flag result (concat range cmd spaces result)))
|
||||
((listp result) (if flag result (mapcar #'(lambda (x) (concat range cmd spaces x)) result)))
|
||||
(t (error "Completion returned unexpected value."))))))))
|
||||
|
||||
|
||||
(defun vim:ex-complete-command (cmd predicate flag)
|
||||
;; completes the command
|
||||
(with-current-buffer vim:ex-current-buffer
|
||||
(cond
|
||||
((null flag) (or (try-completion cmd vim:ex-local-commands predicate)
|
||||
(try-completion cmd vim:ex-commands predicate)))
|
||||
|
||||
((eq t flag) (or (all-completions cmd vim:ex-local-commands predicate)
|
||||
(all-completions cmd vim:ex-commands predicate)))
|
||||
|
||||
((eq 'lambda flag) (or (vim:test-completion cmd vim:ex-local-commands predicate)
|
||||
(vim:test-completion cmd vim:ex-commands predicate))))))
|
||||
|
||||
(defun vim:ex-complete-argument (arg predicate flag)
|
||||
;; completes the argument
|
||||
(let ((cmd vim:ex-cmd))
|
||||
(while (stringp cmd)
|
||||
(setq cmd (vim:ex-binding cmd)))
|
||||
|
||||
(if (null cmd) (ding)
|
||||
(case (vim:cmd-arg cmd)
|
||||
(file
|
||||
(vim:ex-complete-file-argument arg predicate flag))
|
||||
(buffer
|
||||
(vim:ex-complete-buffer-argument arg predicate flag))
|
||||
((t)
|
||||
(vim:ex-complete-text-argument arg predicate flag))
|
||||
(t (ding))))))
|
||||
|
||||
(defun vim:ex-complete-file-argument (arg predicate flag)
|
||||
;; completes a file-name
|
||||
(if (null arg)
|
||||
default-directory
|
||||
(let ((dir (or (file-name-directory arg)
|
||||
(with-current-buffer vim:ex-current-buffer default-directory)))
|
||||
(fname (file-name-nondirectory arg)))
|
||||
(cond
|
||||
((null dir) (ding))
|
||||
((null flag)
|
||||
(let ((result (file-name-completion fname dir)))
|
||||
(case result
|
||||
((nil) nil)
|
||||
((t) t)
|
||||
(t (concat dir result)))))
|
||||
|
||||
((eq t flag)
|
||||
(file-name-all-completions fname dir))
|
||||
|
||||
((eq 'lambda flag)
|
||||
(eq (file-name-completion fname dir) t))))))
|
||||
|
||||
(defun vim:ex-complete-buffer-argument (arg predicate flag)
|
||||
;; completes a buffer name
|
||||
(when arg
|
||||
(let ((buffers (mapcar #'(lambda (buffer) (cons (buffer-name buffer) nil)) (buffer-list t))))
|
||||
(cond
|
||||
((null flag)
|
||||
(try-completion arg buffers predicate))
|
||||
((eq t flag)
|
||||
(all-completions arg buffers predicate))
|
||||
((eq 'lambda flag)
|
||||
(vim:test-completion arg buffers predicate))))))
|
||||
|
||||
(defun vim:ex-complete-text-argument (arg predicate flag)
|
||||
;; completes an arbitrary text-argument
|
||||
(when arg
|
||||
(case flag
|
||||
((nil) t)
|
||||
((t) (list arg))
|
||||
('lambda t))))
|
||||
|
||||
(defun vim:ex-execute-command (cmdline)
|
||||
(interactive)
|
||||
|
||||
(multiple-value-bind (range cmd spaces arg beg end) (vim:ex-split-cmdline cmdline)
|
||||
(setq vim:ex-cmd cmd)
|
||||
|
||||
(let ((cmd vim:ex-cmd)
|
||||
(motion (cond
|
||||
((and beg end)
|
||||
(vim:make-motion :begin (save-excursion
|
||||
(goto-line beg)
|
||||
(line-beginning-position))
|
||||
:end (save-excursion
|
||||
(goto-line end)
|
||||
(line-beginning-position))
|
||||
:has-begin t
|
||||
:type 'linewise))
|
||||
(beg
|
||||
(vim:make-motion :begin (save-excursion
|
||||
(goto-line beg)
|
||||
(line-beginning-position))
|
||||
:end (save-excursion
|
||||
(goto-line beg)
|
||||
(line-beginning-position))
|
||||
:has-begin t
|
||||
:type 'linewise))))
|
||||
(count (and (not end) beg)))
|
||||
|
||||
(while (stringp cmd)
|
||||
(setq cmd (vim:ex-binding cmd)))
|
||||
|
||||
(when (zerop (length arg))
|
||||
(setq arg nil))
|
||||
|
||||
(with-current-buffer vim:ex-current-buffer
|
||||
(cond
|
||||
(cmd (case (vim:cmd-type cmd)
|
||||
('complex
|
||||
(if (vim:cmd-arg-p cmd)
|
||||
(funcall cmd :motion motion :argument arg)
|
||||
(funcall cmd :motion motion)))
|
||||
('simple
|
||||
(when end
|
||||
(error "Command does not take a range: %s" vim:ex-cmd))
|
||||
(if (vim:cmd-arg-p cmd)
|
||||
(if (vim:cmd-count-p cmd)
|
||||
(funcall cmd :count beg :argument arg)
|
||||
(funcall cmd :argument arg))
|
||||
(if (vim:cmd-count-p cmd)
|
||||
(funcall cmd :count count)
|
||||
(funcall cmd))))
|
||||
(t (error "Unexpected command-type bound to %s" vim:ex-cmd))))
|
||||
(beg (vim:motion-go-to-first-non-blank-beg :count (or end beg)))
|
||||
(t (ding)))))))
|
||||
|
||||
|
||||
;; parser for ex-commands
|
||||
(defun vim:ex-parse (text)
|
||||
"Extracts the range-information from `text'.
|
||||
Returns a list of up to three elements: (cmd beg end)"
|
||||
(let (begin
|
||||
(begin-off 0)
|
||||
sep
|
||||
end
|
||||
(end-off 0)
|
||||
(pos 0)
|
||||
(cmd nil))
|
||||
|
||||
(multiple-value-bind (beg npos) (vim:ex-parse-address text pos)
|
||||
(when npos
|
||||
(setq begin beg
|
||||
pos npos)))
|
||||
|
||||
(multiple-value-bind (off npos) (vim:ex-parse-offset text pos)
|
||||
(when npos
|
||||
(unless begin (setq begin 'current-line))
|
||||
(setq begin-off off
|
||||
pos npos)))
|
||||
|
||||
(when (and (< pos (length text))
|
||||
(or (= (aref text pos) ?\,)
|
||||
(= (aref text pos) ?\;)))
|
||||
(setq sep (aref text pos))
|
||||
(incf pos)
|
||||
(multiple-value-bind (e npos) (vim:ex-parse-address text pos)
|
||||
(when npos
|
||||
(setq end e
|
||||
pos npos)))
|
||||
|
||||
(multiple-value-bind (off npos) (vim:ex-parse-offset text pos)
|
||||
(when npos
|
||||
(unless end (setq end 'current-line))
|
||||
(setq end-off off
|
||||
pos npos))))
|
||||
|
||||
;; handle the special '%' range
|
||||
(when (or (eq begin 'all) (eq end 'all))
|
||||
(setq begin 'first-line
|
||||
begin-off 0
|
||||
end 'last-line
|
||||
end-off 0
|
||||
sep ?,))
|
||||
|
||||
(when (= pos (or (string-match "[a-zA-Z0-9!]+" text pos) -1))
|
||||
(setq cmd (cons (match-beginning 0) (match-end 0))))
|
||||
|
||||
(multiple-value-bind (start end) (vim:ex-get-range (and begin (cons begin begin-off)) sep (and end (cons end end-off)))
|
||||
(values cmd start end))))
|
||||
|
||||
|
||||
(defun vim:ex-parse-address (text pos)
|
||||
(cond
|
||||
((>= pos (length text)) nil)
|
||||
|
||||
((= pos (or (string-match "[0-9]+" text pos) -1))
|
||||
(values (cons 'abs (string-to-number (match-string 0 text)))
|
||||
(match-end 0)))
|
||||
|
||||
((= (aref text pos) ?$)
|
||||
(values (cons 'abs (line-number-at-pos (point-max))) (1+ pos)))
|
||||
|
||||
((= (aref text pos) ?\%)
|
||||
(values 'all (1+ pos)))
|
||||
|
||||
((= (aref text pos) ?.)
|
||||
(values 'current-line (1+ pos)))
|
||||
|
||||
((= (aref text pos) ?')
|
||||
(if (>= (1+ pos) (length text))
|
||||
nil
|
||||
(values `(mark ,(aref text (1+ pos))) (+ 2 pos))))
|
||||
|
||||
((= (aref text pos) ?/)
|
||||
(when (string-match "\\([^/]+\\|\\\\.\\)\\(?:/\\|$\\)"
|
||||
text (1+ pos))
|
||||
(values (cons 're-fwd (match-string 1 text))
|
||||
(match-end 0))))
|
||||
|
||||
((= (aref text pos) ??)
|
||||
(when (string-match "\\([^?]+\\|\\\\.\\)\\(?:?\\|$\\)"
|
||||
text (1+ pos))
|
||||
(values (cons 're-bwd (match-string 1 text))
|
||||
(match-end 0))))
|
||||
|
||||
((and (= (aref text pos) ?\\)
|
||||
(< pos (1- (length text))))
|
||||
(case (aref text (1+ pos))
|
||||
(?/ (values 'next-of-prev-search (1+ pos)))
|
||||
(?? (values 'prev-of-prev-search (1+ pos)))
|
||||
(?& (values 'next-of-prev-subst (1+ pos)))))
|
||||
|
||||
(t nil)))
|
||||
|
||||
|
||||
(defun vim:ex-parse-offset (text pos)
|
||||
(let ((off nil))
|
||||
(while (= pos (or (string-match "\\([-+]\\)\\([0-9]+\\)?" text pos) -1))
|
||||
(if (string= (match-string 1 text) "+")
|
||||
(setq off (+ (or off 0) (if (match-beginning 2)
|
||||
(string-to-number (match-string 2 text))
|
||||
1)))
|
||||
|
||||
(setq off (- (or off 0) (if (match-beginning 2)
|
||||
(string-to-number (match-string 2 text))
|
||||
1))))
|
||||
(setq pos (match-end 0)))
|
||||
(and off (values off pos))))
|
||||
|
||||
|
||||
(defun vim:ex-get-range (start sep end)
|
||||
(with-current-buffer vim:ex-current-buffer
|
||||
(when start
|
||||
(setq start (vim:ex-get-line start)))
|
||||
|
||||
(when (and sep end)
|
||||
(save-excursion
|
||||
(when (= sep ?\;) (goto-line start))
|
||||
(setq end (vim:ex-get-line end))))
|
||||
|
||||
(values start end)))
|
||||
|
||||
|
||||
(defun vim:ex-get-line (address)
|
||||
(let ((base (car address))
|
||||
(offset (cdr address)))
|
||||
|
||||
(cond
|
||||
((null base) nil)
|
||||
((consp offset)
|
||||
(let ((line (vim:ex-get-line (car address))))
|
||||
(when line
|
||||
(save-excursion
|
||||
(goto-line line)
|
||||
(vim:ex-get-line (cdr address))))))
|
||||
|
||||
(t
|
||||
(+ offset
|
||||
(case (or (car-safe base) base)
|
||||
(abs (cdr base))
|
||||
|
||||
;; TODO: (1- ...) may be wrong if the match is the empty string
|
||||
(re-fwd (save-excursion
|
||||
(beginning-of-line 2)
|
||||
(and (re-search-forward (cdr base))
|
||||
(line-number-at-pos (1- (match-end 0))))))
|
||||
|
||||
(re-bwd (save-excursion
|
||||
(beginning-of-line 0)
|
||||
(and (re-search-backward (cdr base))
|
||||
(line-number-at-pos (match-beginning 0)))))
|
||||
|
||||
(current-line (line-number-at-pos (point)))
|
||||
(first-line (line-number-at-pos (point-min)))
|
||||
(last-line (line-number-at-pos (point-max)))
|
||||
(mark (line-number-at-pos (vim:get-local-mark (cadr base))))
|
||||
(next-of-prev-search (error "Next-of-prev-search not yet implemented."))
|
||||
(prev-of-prev-search (error "Prev-of-prev-search not yet implemented."))
|
||||
(next-of-prev-subst (error "Next-of-prev-subst not yet implemented."))
|
||||
(t (error "Invalid address: %s" address))))))))
|
||||
|
||||
|
||||
(defun vim:ex-read-command (&optional initial-input)
|
||||
"Starts ex-mode."
|
||||
(interactive)
|
||||
(let ((vim:ex-current-buffer (current-buffer)))
|
||||
(let ((minibuffer-local-completion-map vim:ex-keymap))
|
||||
(let ((result (completing-read ":" 'vim:ex-complete nil nil initial-input 'vim:ex-history)))
|
||||
(when (and result
|
||||
(not (zerop (length result))))
|
||||
(vim:ex-execute-command result))))))
|
||||
|
||||
(provide 'vim-ex)
|
||||
|
||||
;;; vim-ex.el ends here
|
||||
79
.emacs.d/vim-mode/vim-insert-mode.el
Normal file
79
.emacs.d/vim-mode/vim-insert-mode.el
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
;;; vim-insert-mode.el - VIM insert-mode.
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; TODO :
|
||||
;; - for some reason GNU Emacs does not show '-- REPLACE --'
|
||||
|
||||
;;; Code:
|
||||
|
||||
(vim:deflocalvar vim:last-insert-undo nil)
|
||||
|
||||
(defcustom vim:insert-mode-replace-cursor 'hbar
|
||||
"Cursor for replace-mode."
|
||||
:group 'vim-mode)
|
||||
|
||||
(vim:define-keymap insert-mode "insert-mode" :map-command imap)
|
||||
|
||||
(vim:define-mode insert "VIM insert-mode"
|
||||
:ident "I"
|
||||
:message "-- INSERT --"
|
||||
:keymaps '(vim:insert-mode-keymap)
|
||||
:command-function 'vim:insert-mode-command
|
||||
:cursor 'bar)
|
||||
(add-hook 'vim:insert-mode-on-hook 'vim:insert-mode-activated)
|
||||
(add-hook 'vim:insert-mode-off-hook 'vim:insert-mode-deactivated)
|
||||
|
||||
(vim:defcmd vim:insert-mode-toggle-replace ()
|
||||
"Toggles overwrite-mode in insert-mode."
|
||||
(unless (vim:insert-mode-p)
|
||||
(error "Toggling overwrite-mode only allowed in insert-mode."))
|
||||
(overwrite-mode nil)
|
||||
(if overwrite-mode
|
||||
(progn
|
||||
(let (message-log-max) (message "-- REPLACE --"))
|
||||
(setq cursor-type vim:insert-mode-replace-cursor)
|
||||
(vim:update-mode-line "R"))
|
||||
(progn
|
||||
(let (message-log-max) (message "-- INSERT --"))
|
||||
(setq cursor-type vim:insert-mode-cursor)
|
||||
(vim:update-mode-line "I"))))
|
||||
|
||||
(defun vim:insert-mode-command (command)
|
||||
"Executes a simple command in insert mode."
|
||||
(case (vim:cmd-type command)
|
||||
('simple (vim:normal-execute-simple-command command))
|
||||
('complex (error "No complex command allowed in insert-mode."))
|
||||
(t (vim:normal-execute-motion command))))
|
||||
|
||||
(defun vim:insert-mode-activated ()
|
||||
"Called when insert-mode is activated."
|
||||
(overwrite-mode -1)
|
||||
(setq vim:last-insert-undo vim:last-undo)
|
||||
(add-hook 'pre-command-hook 'vim:insert-save-key-sequence))
|
||||
|
||||
(defun vim:insert-mode-deactivated ()
|
||||
"Called when insert-mode is deactivated."
|
||||
(overwrite-mode -1)
|
||||
(vim:set-mark ?^)
|
||||
(remove-hook 'pre-command-hook 'vim:insert-save-key-sequence)
|
||||
;; the command that has just ended insert-mode should NOT be repeatable
|
||||
;; and will therefore NOT override repeat-sequence.
|
||||
(setq vim:repeat-events (vconcat vim:repeat-events
|
||||
vim:current-key-sequence))
|
||||
(setq vim:last-undo vim:last-insert-undo))
|
||||
|
||||
(defun vim:insert-save-key-sequence ()
|
||||
"Called in insert-mode to save key-events."
|
||||
(when (and (vim:toplevel-execution)
|
||||
(not (eq this-command 'vim:intercept-ESC)))
|
||||
(setq vim:current-key-sequence (vconcat vim:current-key-sequence
|
||||
(vim:this-command-keys)))))
|
||||
|
||||
(provide 'vim-insert-mode)
|
||||
|
||||
;;; vim-insert-mode.el ends here
|
||||
144
.emacs.d/vim-mode/vim-keymap.el
Normal file
144
.emacs.d/vim-mode/vim-keymap.el
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
;;; vim-keymap.el - Basic keymapping for vim-mode
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defmacro vim:kbdmacro-to-command (events)
|
||||
"Creates a command passing prefix-argument to given keyboard-macro `events'."
|
||||
(let ((arg (gensym)))
|
||||
`(lambda (,arg)
|
||||
(interactive "P")
|
||||
(execute-kbd-macro
|
||||
(if ,arg
|
||||
(vconcat (number-to-string (prefix-numeric-value ,arg))
|
||||
,events)
|
||||
,events)))))
|
||||
|
||||
|
||||
(defun* vim:map (keys command &key (keymap nil))
|
||||
"Maps the sequence of events `keys' to a `command' in a certain
|
||||
`keymap.'"
|
||||
(if (or (stringp command)
|
||||
(vectorp command))
|
||||
(lexical-let ((kbdevents command))
|
||||
(define-key keymap keys (vim:kbdmacro-to-command kbdevents)))
|
||||
(define-key keymap keys command)))
|
||||
|
||||
(defun vim:make-keymap (&optional parent)
|
||||
"Creates a new keymap with a certain `parent' keymap."
|
||||
(let ((kmap (make-sparse-keymap)))
|
||||
(when parent (set-keymap-parent kmap parent))
|
||||
kmap))
|
||||
|
||||
(defmacro vim:define-keymap (name
|
||||
doc
|
||||
&key
|
||||
map-command)
|
||||
"Defines global and local keymaps for a mode with name
|
||||
vim:`name'-[local-]keymap and a map command vim:`map-command'
|
||||
and vim:local-`map-command'."
|
||||
(let ((glbkeym (concat "vim:" (symbol-name name) "-keymap"))
|
||||
(lockeym (concat "vim:" (symbol-name name) "-local-keymap")))
|
||||
`(progn
|
||||
(defconst ,(intern glbkeym) (vim:make-keymap)
|
||||
,(concat "VIM global keymap: " doc))
|
||||
(defconst ,(intern lockeym) (vim:make-keymap)
|
||||
,(concat "VIM buffer local keymap: " doc))
|
||||
,@(when map-command
|
||||
`((defsubst ,(intern (concat "vim:" (symbol-name map-command)))
|
||||
(keys command)
|
||||
,(concat "Maps the sequence of events `keys' to a `command' in keymap "
|
||||
glbkeym)
|
||||
(vim:map keys command :keymap ,(intern glbkeym)))
|
||||
(defsubst ,(intern (concat "vim:local-" (symbol-name map-command)))
|
||||
(keys command)
|
||||
,(concat "Maps the sequence of events `keys' to a `command' in keymap "
|
||||
lockeym)
|
||||
(vim:map keys command :keymap ,(intern lockeym))))))))
|
||||
(font-lock-add-keywords 'emacs-lisp-mode '("vim:define-keymap"))
|
||||
|
||||
|
||||
|
||||
|
||||
;; Interception of ESC event. The ESC event is intercepted. If not
|
||||
;; followed by another key, i.e. not used as a prefix-key, the event
|
||||
;; [escape] is sent, otherwise the interception-keymap is disabled for
|
||||
;; the next command and the ESC event is resent.
|
||||
(defcustom vim:intercept-ESC-timeout 0.1
|
||||
"Time in seconds to wait for another key after an ESC event."
|
||||
:group 'vim-mode)
|
||||
|
||||
(defconst vim:intercept-ESC-keymap (make-sparse-keymap)
|
||||
"Keymap to map ESC to [escape].")
|
||||
|
||||
(define-minor-mode vim:intercept-ESC-mode
|
||||
"VIM minor mode to capture ESC."
|
||||
nil nil nil)
|
||||
|
||||
;; This function is defined in vim:compat.el
|
||||
;; (defun vim:intercept-ESC () ...)
|
||||
|
||||
(defun vim:enable-intercept-ESC ()
|
||||
"Enables interception of ESC after executing a (prefix-)command."
|
||||
(unless (eq this-command 'vim:intercept-ESC)
|
||||
(remove-hook 'pre-command-hook 'vim:enable-intercept-ESC)
|
||||
(vim:intercept-ESC-mode 1)))
|
||||
|
||||
;; Catch '\e' and convert it to [escape] if not used as prefix key.
|
||||
(vim:map (kbd "ESC") 'vim:intercept-ESC :keymap vim:intercept-ESC-keymap)
|
||||
|
||||
|
||||
;; The override keymap, useful especially in normal-mode.
|
||||
(defconst vim:override-keymap (make-keymap)
|
||||
"Global parent keymap to override some Emacs default bindings.")
|
||||
(suppress-keymap vim:override-keymap)
|
||||
(vim:map (kbd "ESC ESC ESC")
|
||||
(lambda ()
|
||||
"Exits any VIM mode and returns to normal-mode."
|
||||
(interactive)
|
||||
(vim:activate-normal-mode)
|
||||
(ding))
|
||||
:keymap vim:override-keymap)
|
||||
|
||||
|
||||
;; This function sets up the keymaps for the current mode.
|
||||
(defmacro vim:set-keymaps (mode-name keymaps)
|
||||
(when (eq (car-safe mode-name) 'quote)
|
||||
(setq mode-name (cadr mode-name)))
|
||||
(when (eq (car-safe keymaps) 'quote)
|
||||
(setq keymaps (cadr keymaps)))
|
||||
`(setq vim:emulation-mode-alist
|
||||
(list ,@(cons '(cons 'vim:intercept-ESC-mode vim:intercept-ESC-keymap)
|
||||
(mapcan #'(lambda (keym)
|
||||
(let ((localname (intern (replace-regexp-in-string "mode-keymap" "mode-local-keymap"
|
||||
(symbol-name keym)))))
|
||||
(if (eq localname keym)
|
||||
(list `(cons ',mode-name ,keym))
|
||||
(list `(cons ',mode-name ,localname)
|
||||
`(cons ',mode-name ,keym)))))
|
||||
keymaps)))))
|
||||
|
||||
;; TODO: This function is currently empty and serves only as hook for
|
||||
;; defadvice.
|
||||
(defun vim:reset-key-state ()
|
||||
"Resets the current internal key-state."
|
||||
nil)
|
||||
|
||||
(vim:deflocalvar vim:current-key-sequence nil
|
||||
"The key-sequence of the current command.")
|
||||
|
||||
(vim:deflocalvar vim:new-buffer nil
|
||||
"The buffer the be made current at the end of key-handline.")
|
||||
|
||||
(defun vim:clear-key-sequence ()
|
||||
"Clears the internal log of key-sequences."
|
||||
(setq vim:current-key-sequence nil))
|
||||
|
||||
(provide 'vim-keymap)
|
||||
|
||||
;;; vim-keymap.el ends here
|
||||
364
.emacs.d/vim-mode/vim-maps.el
Normal file
364
.emacs.d/vim-mode/vim-maps.el
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
;;; vim-maps.el
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file contains all standard keymaps. Key mappings are defined
|
||||
;; using one of the following vim-like macros:
|
||||
|
||||
;; - vim:map ... general mapping in an arbitrary mode
|
||||
;; - vim:nmap ... mapping in the normal-mode keymap
|
||||
;; - vim:omap ... mapping in the operator-pending keymap
|
||||
;; - vim:imap ... mapping in the insert-mode keymap
|
||||
;; - vim:vmap ... mapping in the visual-mode keymap
|
||||
;; - vim:emap ... mapping in the ex-mode keymap
|
||||
;;
|
||||
;; Furthermore, for each of these map-function there's a buffer-local
|
||||
;; variant
|
||||
;;
|
||||
;; - vim:local-nmap ... mapping in the normal-mode local keymap
|
||||
;; - vim:local-omap ... mapping in the operator-pending local keymap
|
||||
;; - vim:local-imap ... mapping in the insert-mode local keymap
|
||||
;; - vim:local-vmap ... mapping in the visual-mode local keymap
|
||||
;; - vim:local-emap ... mapping in the ex-mode local keymap
|
||||
;;
|
||||
;; The local versions should be used to define mode specific bindings
|
||||
;; as local-set-key would do.
|
||||
;;
|
||||
;; Commands should usually be placed in the normal-mode keymap.
|
||||
;; Motions should be placed in the operator-pending keymap. All
|
||||
;; commands in the operator-pending-keymap are available as
|
||||
;; operator-pending in normal-mode and visual-mode (but may be
|
||||
;; overwritten by the corresponding keymaps) and as motion-arguments
|
||||
;; for complex commands in normal-mode.
|
||||
;;
|
||||
;; A mapping has one of the following two forms:
|
||||
;;
|
||||
;; (vim:map KEYEVENTS 'my-command)
|
||||
;;
|
||||
;; (vim:map KEYEVENTS MAPEVENTS)
|
||||
;;
|
||||
;; The first form maps the events in KEYEVENTS to the command
|
||||
;; my-command. The second form defines a vim-like mapping of
|
||||
;; KEYEVENTS to MAPEVENTS, i.e. the activation of KEYEVENTS invokes
|
||||
;; the (key-)events in MAPEVENTS.
|
||||
;;
|
||||
;; KEYEVENTS is a usual Emacs-sequence of events as it would be used by
|
||||
;; define-key.
|
||||
|
||||
;;; TODO:
|
||||
;; - better mapping to support stuff like
|
||||
;; (vim:def-map "c" "d{motion}a")
|
||||
;;
|
||||
;; - because of this, mapping "cc" to "0C" does not work with a
|
||||
;; count since the count is eaten by the '0'
|
||||
;;
|
||||
;; - similarily 'o' and 'O' won't work
|
||||
;;
|
||||
;; - should we have a 'deep-mapping' function: for example, "x" is
|
||||
;; mapped to "dl" in the default keymap. If someone decides to
|
||||
;; redefine "l" to some other command, "x" will change its
|
||||
;; behaviour, too. A 'deep-mapping' should save the mapping on
|
||||
;; definition of "x", therefor let "x" behave as usual even after
|
||||
;; redefining "l"
|
||||
|
||||
;;; Code:
|
||||
|
||||
(vim:nmap "\\" 'vim:cmd-emacs)
|
||||
|
||||
(vim:nmap (kbd "C-z") 'vim:activate-emacs-mode)
|
||||
(vim:map (kbd "C-z") 'vim:activate-normal-mode :keymap vim:emacs-keymap)
|
||||
|
||||
(vim:omap [escape] 'vim:operator-pending-mode-exit)
|
||||
(vim:omap "0" 'vim:motion-beginning-of-line-or-digit-argument)
|
||||
(vim:omap "1" 'digit-argument)
|
||||
(vim:omap "2" 'digit-argument)
|
||||
(vim:omap "3" 'digit-argument)
|
||||
(vim:omap "4" 'digit-argument)
|
||||
(vim:omap "5" 'digit-argument)
|
||||
(vim:omap "6" 'digit-argument)
|
||||
(vim:omap "7" 'digit-argument)
|
||||
(vim:omap "8" 'digit-argument)
|
||||
(vim:omap "9" 'digit-argument)
|
||||
(vim:nmap "\"" 'vim:select-register)
|
||||
|
||||
(vim:nmap "ZZ" 'vim:cmd-write-and-close)
|
||||
|
||||
(vim:mmap "h" 'vim:motion-left)
|
||||
(vim:mmap "l" 'vim:motion-right)
|
||||
(vim:mmap "^" 'vim:motion-first-non-blank)
|
||||
(vim:mmap "$" 'vim:motion-end-of-line)
|
||||
(vim:mmap "g_" 'vim:motion-last-non-blank)
|
||||
|
||||
(vim:mmap "k" 'vim:motion-up)
|
||||
(vim:mmap "j" 'vim:motion-down)
|
||||
(vim:mmap "-" "k^")
|
||||
(vim:mmap "+" "j^")
|
||||
(vim:mmap "G" 'vim:motion-go-to-first-non-blank-end)
|
||||
(vim:mmap "gg" 'vim:motion-go-to-first-non-blank-beg)
|
||||
|
||||
(vim:mmap "w" 'vim:motion-fwd-word)
|
||||
(vim:mmap "W" 'vim:motion-fwd-WORD)
|
||||
(vim:mmap "e" 'vim:motion-fwd-word-end)
|
||||
(vim:mmap "E" 'vim:motion-fwd-WORD-end)
|
||||
(vim:mmap "b" 'vim:motion-bwd-word)
|
||||
(vim:mmap "B" 'vim:motion-bwd-WORD)
|
||||
(vim:mmap "ge" 'vim:motion-bwd-word-end)
|
||||
(vim:mmap "gE" 'vim:motion-bwd-WORD-end)
|
||||
|
||||
(vim:mmap "(" 'vim:motion-bwd-sentence)
|
||||
(vim:mmap ")" 'vim:motion-fwd-sentence)
|
||||
(vim:mmap "{" 'vim:motion-bwd-paragraph)
|
||||
(vim:mmap "}" 'vim:motion-fwd-paragraph)
|
||||
(vim:mmap "]]" 'vim:motion-fwd-section)
|
||||
(vim:mmap "][" 'vim:motion-fwd-section)
|
||||
(vim:mmap "[[" 'vim:motion-bwd-section)
|
||||
(vim:mmap "[]" 'vim:motion-bwd-section)
|
||||
|
||||
(vim:omap "f" 'vim:motion-find)
|
||||
(vim:omap "F" 'vim:motion-find-back)
|
||||
(vim:omap "t" 'vim:motion-find-to)
|
||||
(vim:omap "T" 'vim:motion-find-back-to)
|
||||
(vim:omap ";" 'vim:motion-repeat-last-find)
|
||||
(vim:omap "," 'vim:motion-repeat-last-find-opposite)
|
||||
|
||||
(vim:omap "%" 'vim:motion-jump-item)
|
||||
|
||||
(vim:omap "'" 'vim:motion-mark-line)
|
||||
(vim:omap "`" 'vim:motion-mark)
|
||||
|
||||
(vim:omap "iw" 'vim:motion-inner-word)
|
||||
|
||||
;(vim:nmap "x" "dl")
|
||||
(vim:nmap "m" 'vim:cmd-set-mark)
|
||||
(vim:nmap "x" 'vim:cmd-delete-char)
|
||||
(vim:nmap "D" "d$")
|
||||
(vim:nmap "d" 'vim:cmd-delete)
|
||||
|
||||
(vim:nmap "C" 'vim:cmd-change-rest-of-line)
|
||||
(vim:nmap "c" 'vim:cmd-change)
|
||||
(vim:nmap "s" 'vim:cmd-change-char)
|
||||
|
||||
(vim:nmap "r" 'vim:cmd-replace-char)
|
||||
(vim:nmap "R" 'vim:cmd-replace)
|
||||
|
||||
(vim:nmap "y" 'vim:cmd-yank)
|
||||
(vim:nmap "Y" "yy")
|
||||
(vim:nmap "p" 'vim:cmd-paste-behind)
|
||||
(vim:nmap "P" 'vim:cmd-paste-before)
|
||||
|
||||
(vim:nmap "J" 'vim:cmd-join-lines)
|
||||
|
||||
(vim:nmap "/" 'vim:search-start)
|
||||
(vim:nmap "?" 'vim:search-start-backward)
|
||||
(vim:nmap "*" 'vim:search-word)
|
||||
(vim:nmap "#" 'vim:search-word-backward)
|
||||
(vim:nmap "g*" 'vim:search-unbounded-word)
|
||||
(vim:nmap "g#" 'vim:search-unbounded-word-backward)
|
||||
(vim:nmap "n" 'vim:search-repeat)
|
||||
(vim:nmap "N" 'vim:search-repeat-opposite)
|
||||
;; The next two maps are very special for an active search.
|
||||
(vim:map "n" 'vim:search-repeat :keymap vim:search-keymap)
|
||||
(vim:map "N" 'vim:search-repeat-opposite :keymap vim:search-keymap)
|
||||
|
||||
(vim:nmap "i" 'vim:cmd-insert)
|
||||
(vim:nmap "a" 'vim:cmd-append)
|
||||
(vim:nmap "I" 'vim:cmd-Insert)
|
||||
(vim:nmap "A" 'vim:cmd-Append)
|
||||
(vim:nmap "o" 'vim:cmd-insert-line-below)
|
||||
(vim:nmap "O" 'vim:cmd-insert-line-above)
|
||||
|
||||
(vim:nmap "u" 'vim:cmd-undo)
|
||||
(vim:nmap (kbd "C-r") 'vim:cmd-redo)
|
||||
|
||||
(vim:nmap "." 'vim:cmd-repeat)
|
||||
|
||||
(vim:nmap "=" 'vim:cmd-indent)
|
||||
(vim:nmap "<" 'vim:cmd-shift-left)
|
||||
(vim:nmap ">" 'vim:cmd-shift-right)
|
||||
|
||||
(vim:nmap "~" "g~l")
|
||||
(vim:nmap "g~" 'vim:cmd-toggle-case)
|
||||
(vim:nmap "gU" 'vim:cmd-make-upcase)
|
||||
(vim:nmap "gu" 'vim:cmd-make-downcase)
|
||||
|
||||
(vim:omap (kbd "C-e") 'vim:scroll-line-down)
|
||||
(vim:omap (kbd "C-d") 'vim:scroll-down)
|
||||
(vim:omap (kbd "C-f") 'vim:scroll-page-down)
|
||||
(vim:omap "z+" 'vim:scroll-bottom-line-to-top)
|
||||
|
||||
(vim:omap (kbd "C-y") 'vim:scroll-line-up)
|
||||
(vim:omap (kbd "C-u") 'vim:scroll-up)
|
||||
(vim:omap (kbd "C-b") 'vim:scroll-page-up)
|
||||
(vim:omap "z^" 'vim:scroll-top-line-to-bottom)
|
||||
|
||||
(vim:omap "zt" 'vim:scroll-line-to-top)
|
||||
(vim:omap (vconcat "z" [return]) "zt^")
|
||||
(vim:omap (kbd "z RET") (vconcat "z" [return]))
|
||||
(vim:omap "zz" 'vim:scroll-line-to-center)
|
||||
(vim:omap "z." "z.^")
|
||||
(vim:omap "zb" 'vim:scroll-line-to-bottom)
|
||||
(vim:omap "z-" "zb^")
|
||||
|
||||
|
||||
(vim:wmap (kbd "C-w +") 'vim:window-increase-height)
|
||||
(vim:wmap (kbd "C-w -") 'vim:window-decrease-height)
|
||||
(vim:wmap (kbd "C-w =") 'vim:window-balance)
|
||||
(vim:wmap (kbd "C-w >") 'vim:window-increase-width)
|
||||
(vim:wmap (kbd "C-w <") 'vim:window-decrease-width)
|
||||
(vim:wmap (kbd "C-w H") 'vim:window-move-far-left)
|
||||
(vim:wmap (kbd "C-w J") 'vim:window-move-very-bottom)
|
||||
(vim:wmap (kbd "C-w K") 'vim:window-move-very-top)
|
||||
(vim:wmap (kbd "C-w L") 'vim:window-move-far-right)
|
||||
(vim:wmap (kbd "C-w R") 'vim:window-rotate-upwards)
|
||||
(vim:wmap (kbd "C-w C-R") (kbd "C-w R"))
|
||||
(vim:wmap (kbd "C-w r") 'vim:window-rotate-downwards)
|
||||
(vim:wmap (kbd "C-w C-r") (kbd "C-w r"))
|
||||
(vim:wmap (kbd "C-w _") 'vim:window-set-height)
|
||||
(vim:wmap (kbd "C-w C-_") (kbd "C-w _"))
|
||||
(vim:wmap (kbd "C-w |") 'vim:window-set-width)
|
||||
(vim:wmap (kbd "C-w b") 'vim:window-bottom-right)
|
||||
(vim:wmap (kbd "C-w C-b") (kbd "C-w b"))
|
||||
(vim:wmap (kbd "C-w t") 'vim:window-top-left)
|
||||
(vim:wmap (kbd "C-w C-t") (kbd "C-w t"))
|
||||
(vim:wmap (kbd "C-w c") 'vim:window-close)
|
||||
(vim:wmap (kbd "C-w h") 'vim:window-left)
|
||||
(vim:wmap (kbd "C-w C-h") (kbd "C-w h"))
|
||||
(vim:wmap (kbd "C-w j") 'vim:window-down)
|
||||
(vim:wmap (kbd "C-w C-j") (kbd "C-w j"))
|
||||
(vim:wmap (kbd "C-w k") 'vim:window-up)
|
||||
(vim:wmap (kbd "C-w C-k") (kbd "C-w k"))
|
||||
(vim:wmap (kbd "C-w l") 'vim:window-right)
|
||||
(vim:wmap (kbd "C-w C-l") (kbd "C-w l"))
|
||||
(vim:wmap (kbd "C-w p") 'vim:window-lru)
|
||||
(vim:wmap (kbd "C-w C-p") (kbd "C-w p"))
|
||||
(vim:wmap (kbd "C-w w") 'vim:window-next)
|
||||
(vim:wmap (kbd "C-w C-w") (kbd "C-w w"))
|
||||
(vim:wmap (kbd "C-w W") 'vim:window-prev)
|
||||
(vim:wmap (kbd "C-w n") 'vim:window-new)
|
||||
(vim:wmap (kbd "C-w C-n") (kbd "C-w n"))
|
||||
(vim:wmap (kbd "C-w o") 'vim:window-only)
|
||||
(vim:wmap (kbd "C-w C-o") (kbd "C-w o"))
|
||||
(vim:wmap (kbd "C-w s") 'vim:window-split)
|
||||
(vim:wmap (kbd "C-w C-s") (kbd "C-w s"))
|
||||
(vim:wmap (kbd "C-w S") (kbd "C-w s"))
|
||||
(vim:wmap (kbd "C-w v") 'vim:window-vsplit)
|
||||
(vim:wmap (kbd "C-w C-v") (kbd "C-w v"))
|
||||
|
||||
(vim:nmap "v" 'vim:visual-toggle-normal)
|
||||
(vim:nmap "V" 'vim:visual-toggle-linewise)
|
||||
(vim:nmap (kbd "C-v") 'vim:visual-toggle-block)
|
||||
(vim:nmap "gv" 'vim:visual-mode-reactivate)
|
||||
|
||||
(vim:nmap ":" 'vim:ex-read-command)
|
||||
(vim:nmap "q" 'vim:cmd-toggle-macro-recording)
|
||||
(vim:nmap "@" 'vim:cmd-execute-macro)
|
||||
|
||||
|
||||
(vim:imap (vector vim:ESC-event) 'vim:insert-mode-exit)
|
||||
(vim:imap [insert] 'vim:insert-mode-toggle-replace)
|
||||
(vim:imap [kp-insert] [insert])
|
||||
(vim:imap [insertchar] [insert])
|
||||
|
||||
(vim:vmap (vector vim:ESC-event) 'vim:visual-mode-exit)
|
||||
(vim:vmap "v" 'vim:visual-toggle-normal)
|
||||
(vim:vmap "V" 'vim:visual-toggle-linewise)
|
||||
(vim:vmap (kbd "C-v") 'vim:visual-toggle-block)
|
||||
(vim:vmap "\"" 'vim:select-register)
|
||||
|
||||
(vim:vmap "d" 'vim:cmd-delete)
|
||||
(vim:vmap "D" 'vim:cmd-delete)
|
||||
(vim:vmap "x" 'vim:cmd-delete)
|
||||
|
||||
(vim:vmap "c" 'vim:cmd-change)
|
||||
(vim:vmap "C" "Vc")
|
||||
(vim:vmap "r" 'vim:cmd-replace-region)
|
||||
(vim:vmap "R" 'vim:cmd-change)
|
||||
(vim:vmap "s" 'vim:cmd-change)
|
||||
(vim:vmap "S" 'vim:cmd-change)
|
||||
|
||||
(vim:vmap "y" 'vim:cmd-yank)
|
||||
(vim:vmap "Y" 'vim:cmd-yank)
|
||||
|
||||
(vim:vmap "J" 'vim:cmd-join)
|
||||
|
||||
(vim:vmap "=" 'vim:cmd-indent)
|
||||
(vim:vmap "<" 'vim:cmd-shift-left)
|
||||
(vim:vmap ">" 'vim:cmd-shift-right)
|
||||
|
||||
(vim:vmap "~" 'vim:cmd-toggle-case)
|
||||
(vim:vmap "U" 'vim:cmd-make-upcase)
|
||||
(vim:vmap "u" 'vim:cmd-make-downcase)
|
||||
|
||||
(vim:vmap "I" 'vim:visual-insert)
|
||||
(vim:vmap "A" 'vim:visual-append)
|
||||
|
||||
(vim:vmap "o" 'vim:visual-exchange-point-and-mark)
|
||||
(vim:vmap "O" 'vim:visual-jump-point)
|
||||
|
||||
(vim:vmap ":" 'vim:visual-ex-read-command)
|
||||
|
||||
|
||||
|
||||
(vim:emap "edit" 'vim:cmd-edit)
|
||||
(vim:emap "e" "edit")
|
||||
(vim:emap "write" 'vim:cmd-write)
|
||||
(vim:emap "w" "write")
|
||||
(vim:emap "write!" 'vim:cmd-write-q)
|
||||
(vim:emap "w!" "write!")
|
||||
(vim:emap "wall" 'vim:cmd-write-all)
|
||||
(vim:emap "wa" "wall")
|
||||
(vim:emap "wall!" 'vim:cmd-write-all-q)
|
||||
(vim:emap "wa!" "wall!")
|
||||
(vim:emap "buffer" 'vim:cmd-buffer)
|
||||
(vim:emap "b" "buffer")
|
||||
|
||||
(vim:emap "split" 'vim:window-split)
|
||||
(vim:emap "sp" "split")
|
||||
(vim:emap "vsplit" 'vim:window-vsplit)
|
||||
(vim:emap "vs" "vsplit")
|
||||
(vim:emap "new" 'vim:window-new)
|
||||
(vim:emap "vnew" 'vim:window-vnew)
|
||||
(vim:emap "vne" "vnew")
|
||||
(vim:emap "close" 'vim:window-close)
|
||||
(vim:emap "clo" "close")
|
||||
(vim:emap "only" 'vim:window-only)
|
||||
(vim:emap "on" "only")
|
||||
(vim:emap "quit" 'vim:cmd-quit)
|
||||
(vim:emap "q" "quit")
|
||||
(vim:emap "quit!" 'vim:cmd-quit-q)
|
||||
(vim:emap "q!" "quit")
|
||||
(vim:emap "wq" 'vim:cmd-save-and-close)
|
||||
(vim:emap "wq!" 'vim:cmd-save-and-close-q)
|
||||
(vim:emap "quitall" 'vim:cmd-quit-all)
|
||||
(vim:emap "quita" "quitall")
|
||||
(vim:emap "qall" "quitall")
|
||||
(vim:emap "qa" "qall")
|
||||
(vim:emap "quitall!" 'vim:cmd-quit-all-q)
|
||||
(vim:emap "quita!" "quitall!")
|
||||
(vim:emap "qall!" "quitall!")
|
||||
(vim:emap "qa!" "qall!")
|
||||
(vim:emap "wqall" 'vim:cmd-save-and-quit)
|
||||
(vim:emap "wqa" "wqall")
|
||||
(vim:emap "xall" "wqall")
|
||||
(vim:emap "xa" "xall")
|
||||
(vim:emap "bdelete" 'vim:cmd-delete-buffer)
|
||||
(vim:emap "bd" "bdelete")
|
||||
(vim:emap "bdelete!" 'vim:cmd-delete-buffer-q)
|
||||
(vim:emap "bd!" "bdelete!")
|
||||
(vim:emap "substitute" 'vim:cmd-substitute)
|
||||
(vim:emap "s" "substitute")
|
||||
(vim:emap "marks" 'vim:cmd-show-marks)
|
||||
|
||||
|
||||
(vim:nmap (vector vim:down-mouse-1) 'vim:visual-mouse-clicked)
|
||||
(vim:vmap (vector vim:down-mouse-1) 'vim:visual-mouse-clicked)
|
||||
|
||||
(provide 'vim-maps)
|
||||
|
||||
;;; vim-maps.el ends here
|
||||
87
.emacs.d/vim-mode/vim-modes.el
Normal file
87
.emacs.d/vim-mode/vim-modes.el
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
;;; vim-modes.el
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(vim:deflocalvar vim:mode-string)
|
||||
(defun vim:update-mode-line (ident)
|
||||
"Updates the mode-line to show the specified identifier `ident'."
|
||||
(setq vim:mode-string (concat "<" (or ident "?") ">"))
|
||||
(force-mode-line-update))
|
||||
|
||||
|
||||
(defun vim:mode-name (mode)
|
||||
"Converts a mode-name to vim-mode naming conventions, e.g.
|
||||
'normal is converted to 'vim:normal-mode."
|
||||
(intern (concat "vim:" (symbol-name mode) "-mode")))
|
||||
|
||||
(vim:deflocalvar vim:active-mode nil
|
||||
"The currently active vim-mode.")
|
||||
|
||||
(vim:deflocalvar vim:active-command-function nil
|
||||
"The command function of the currently active vim-mode.")
|
||||
|
||||
(defun vim:activate-mode (mode)
|
||||
"Activates a certain vim-mode, disabling the currently active one."
|
||||
(when vim:active-mode
|
||||
(funcall vim:active-mode -1))
|
||||
(when mode
|
||||
(funcall (vim:mode-name mode) 1)))
|
||||
|
||||
|
||||
(defmacro* vim:define-mode (name doc
|
||||
&rest body
|
||||
&key
|
||||
ident
|
||||
message
|
||||
command-function
|
||||
(cursor ''box)
|
||||
keymaps)
|
||||
"Defines a new VIM-mode with certain `name', mode-line-identifier `ident',
|
||||
activation `message', a `command-function' to be called when a
|
||||
vim-command should be executed, a `cursor' shape and a list of `keymaps'."
|
||||
(let* ((mode-name (vim:mode-name name))
|
||||
(pred-name (intern (concat (symbol-name mode-name) "-p")))
|
||||
(on-name (intern (concat "vim:activate-" (symbol-name name) "-mode")))
|
||||
(cursor-name (intern (concat (symbol-name mode-name)
|
||||
"-cursor"))))
|
||||
`(progn
|
||||
(defcustom ,cursor-name ,cursor
|
||||
,(concat "The cursor-type for vim-mode " (symbol-name name) ".")
|
||||
:group 'vim-mode)
|
||||
|
||||
(define-minor-mode ,mode-name ,doc nil nil nil
|
||||
(when ,mode-name
|
||||
,@(when ident `((vim:update-mode-line ,ident)))
|
||||
,@(when message `((let (message-log-max) (message ,message))))
|
||||
(setq vim:active-mode ',mode-name)
|
||||
(setq vim:active-command-function
|
||||
,(if command-function
|
||||
command-function
|
||||
'vim:default-command-function))
|
||||
(vim:set-cursor ,cursor-name)
|
||||
(vim:set-keymaps ',mode-name ,keymaps))
|
||||
,@(progn
|
||||
(while (keywordp (car body)) (pop body) (pop body))
|
||||
body))
|
||||
|
||||
(defun ,pred-name ()
|
||||
,(concat "Returns t iff vim-mode is in " (symbol-name name) " mode.")
|
||||
(and ,mode-name t))
|
||||
|
||||
(defun ,on-name ()
|
||||
,(concat "Activates " (symbol-name name) " mode.")
|
||||
(interactive)
|
||||
(vim:activate-mode ',name)))))
|
||||
|
||||
(font-lock-add-keywords 'emacs-lisp-mode '("vim:define-mode"))
|
||||
|
||||
(provide 'vim-modes)
|
||||
|
||||
;;; vim-modes.el ends here
|
||||
|
||||
666
.emacs.d/vim-mode/vim-motions.el
Normal file
666
.emacs.d/vim-mode/vim-motions.el
Normal file
File diff suppressed because it is too large
Load diff
192
.emacs.d/vim-mode/vim-normal-mode.el
Normal file
192
.emacs.d/vim-mode/vim-normal-mode.el
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
;;; vim-insert-mode.el - VIM normal mode.
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
|
||||
;;; TODO:
|
||||
;; - bindings in local-omap keymap will not be seen as motions in
|
||||
;; normal-mode since the parent-keymap of the normal-mode keymap
|
||||
;; is operator-pending-keymap and not its local counterpart. The
|
||||
;; reason is that the binding of the local counterpart will be
|
||||
;; changed to a buffer-local binding.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defconst vim:operator-repeat-keymap (vim:make-keymap)
|
||||
"Keymap to bind the repeat-operator-event.")
|
||||
|
||||
(vim:define-keymap operator-pending-mode
|
||||
"operator pending mode"
|
||||
:map-command omap)
|
||||
|
||||
(vim:define-mode operator-pending "VIM operator-pending mode"
|
||||
:ident "O"
|
||||
:keymaps '(vim:operator-pending-mode-keymap
|
||||
vim:motion-mode-keymap
|
||||
vim:operator-repeat-keymap
|
||||
vim:override-keymap)
|
||||
:command-function 'vim:operator-pending-mode-command)
|
||||
|
||||
(add-hook 'vim:operator-pending-mode-hook 'vim:operator-pending-activate)
|
||||
(add-hook 'vim:operator-pending-mode-off-hook 'vim:operator-pending-deactivate)
|
||||
|
||||
(defun vim:operator-pending-activate ()
|
||||
(cond
|
||||
(vim:operator-pending-mode
|
||||
(setq vim:operator-repeat-last-event (vector last-command-event))
|
||||
(vim:map vim:operator-repeat-last-event 'vim:motion-lines
|
||||
:keymap vim:operator-repeat-keymap)
|
||||
(add-hook 'post-command-hook 'vim:operator-pending-mode-exit))
|
||||
|
||||
(vim:operator-repeat-last-event
|
||||
(vim:map vim:operator-repeat-last-event nil :keymap vim:operator-repeat-keymap))))
|
||||
|
||||
|
||||
(defun vim:operator-pending-deactivate ()
|
||||
(remove-hook 'post-command-hook 'vim:operator-pending-mode-exit))
|
||||
|
||||
(defun vim:operator-pending-mode-exit ()
|
||||
"Exits operator-pending-mode and returns to normal-mode."
|
||||
(interactive)
|
||||
(unless (or (vim:cmd-function this-command)
|
||||
(eq this-command 'digit-argument)
|
||||
(eq this-command 'universal-argument-other-key))
|
||||
(vim:activate-normal-mode)))
|
||||
|
||||
|
||||
(defun vim:operator-pending-mode-command (command)
|
||||
"Executes a complex command in operator-pending mode."
|
||||
(case (vim:cmd-type command)
|
||||
('simple (error "No simple-commands allowed in operator-pending mode."))
|
||||
('complex (error "No complex-commands allowed in operator-pending mode."))
|
||||
(t (vim:normal-execute-complex-command command)))
|
||||
|
||||
(when (vim:operator-pending-mode-p)
|
||||
(vim:activate-normal-mode)))
|
||||
|
||||
|
||||
(vim:define-keymap normal-mode "normal mode" &map-command nmap)
|
||||
|
||||
(vim:define-mode normal "VIM normal mode"
|
||||
:ident "N"
|
||||
:message "-- NORMAL --"
|
||||
:keymaps '(vim:normal-mode-keymap
|
||||
vim:operator-pending-mode-keymap
|
||||
vim:motion-mode-keymap
|
||||
vim:window-mode-keymap
|
||||
vim:override-keymap)
|
||||
:command-function 'vim:normal-mode-command)
|
||||
|
||||
(defun vim:normal-mode-command (command)
|
||||
"Executes a motion or simple-command or prepares a complex command."
|
||||
(case (vim:cmd-type command)
|
||||
('simple (vim:normal-execute-simple-command command))
|
||||
('complex (vim:normal-prepare-complex-command command))
|
||||
('special (error "no special so far"))
|
||||
(t (vim:normal-execute-motion command))))
|
||||
|
||||
|
||||
(defun vim:normal-execute-motion (command)
|
||||
"Executes a motion."
|
||||
(setq vim:current-motion command)
|
||||
|
||||
(when current-prefix-arg
|
||||
(setq vim:current-motion-count (prefix-numeric-value current-prefix-arg)))
|
||||
|
||||
(when (vim:cmd-char-arg-p command)
|
||||
(setq vim:current-motion-arg (read-char-exclusive)))
|
||||
|
||||
(vim:execute-current-motion)
|
||||
|
||||
(vim:reset-key-state)
|
||||
(vim:clear-key-sequence)
|
||||
(vim:adjust-point))
|
||||
|
||||
|
||||
(defun vim:normal-execute-simple-command (command)
|
||||
"Executes a simple command."
|
||||
(when current-prefix-arg
|
||||
(setq vim:current-cmd-count (prefix-numeric-value current-prefix-arg)))
|
||||
|
||||
(when (vim:cmd-char-arg-p command)
|
||||
(setq vim:current-cmd-arg (read-char-exclusive)))
|
||||
|
||||
(let ((parameters nil)
|
||||
(vim:last-undo buffer-undo-list))
|
||||
(when (vim:cmd-count-p command)
|
||||
(push vim:current-cmd-count parameters)
|
||||
(push :count parameters))
|
||||
(when (vim:cmd-char-arg-p command)
|
||||
(push vim:current-cmd-arg parameters)
|
||||
(push :argument parameters))
|
||||
(when (and (vim:cmd-register-p command)
|
||||
vim:current-register)
|
||||
(push vim:current-register parameters)
|
||||
(push :register parameters))
|
||||
(vim:apply-save-buffer (vim:cmd-function command) parameters)
|
||||
(when (vim:cmd-repeatable-p command)
|
||||
(setq vim:repeat-events (vconcat vim:current-key-sequence
|
||||
(vim:this-command-keys))))
|
||||
(vim:connect-undos vim:last-undo))
|
||||
|
||||
(vim:reset-key-state)
|
||||
(vim:clear-key-sequence)
|
||||
(vim:adjust-point))
|
||||
|
||||
|
||||
(defun vim:normal-prepare-complex-command (command)
|
||||
"Prepares a complex command, switching to operator-pending mode."
|
||||
(when current-prefix-arg
|
||||
(setq vim:current-cmd-count (prefix-numeric-value current-prefix-arg)))
|
||||
|
||||
(setq vim:current-cmd command)
|
||||
(setq vim:current-key-sequence (vconcat vim:current-key-sequence (vim:this-command-keys)))
|
||||
(vim:activate-operator-pending-mode))
|
||||
|
||||
(defun vim:normal-execute-complex-command (motion-command)
|
||||
"Executes a complex command with a certain motion command."
|
||||
(setq vim:current-motion motion-command)
|
||||
|
||||
(when current-prefix-arg
|
||||
(setq vim:current-motion-count (prefix-numeric-value current-prefix-arg)))
|
||||
|
||||
(when (or vim:current-motion-count vim:current-cmd-count)
|
||||
(setq vim:current-motion-count (* (or vim:current-cmd-count 1)
|
||||
(or vim:current-motion-count 1)))
|
||||
(setq vim:current-cmd-count nil))
|
||||
|
||||
(when (vim:cmd-char-arg-p motion-command)
|
||||
(setq vim:current-motion-arg (read-char-exclusive)))
|
||||
|
||||
(let ((vim:last-undo buffer-undo-list))
|
||||
(if (and (vim:cmd-register-p vim:current-cmd) vim:current-register)
|
||||
(vim:funcall-save-buffer (vim:cmd-function vim:current-cmd)
|
||||
:motion (vim:get-current-cmd-motion)
|
||||
:register vim:current-register)
|
||||
(vim:funcall-save-buffer (vim:cmd-function vim:current-cmd)
|
||||
:motion (vim:get-current-cmd-motion)))
|
||||
(when (vim:cmd-repeatable-p vim:current-cmd)
|
||||
(setq vim:repeat-events (vconcat vim:current-key-sequence
|
||||
(vim:this-command-keys))))
|
||||
(vim:connect-undos vim:last-undo))
|
||||
|
||||
(vim:reset-key-state)
|
||||
(vim:clear-key-sequence)
|
||||
(vim:adjust-point))
|
||||
|
||||
|
||||
(vim:define-mode operator-pending "VIM operator-pending mode"
|
||||
:ident "O"
|
||||
:keymaps '(vim:operator-pending-mode-keymap
|
||||
vim:motion-mode-keymap
|
||||
vim:operator-repeat-keymap
|
||||
vim:override-keymap)
|
||||
:command-function 'vim:operator-pending-mode-command)
|
||||
|
||||
(provide 'vim-normal-mode)
|
||||
|
||||
;;; vim-normal-mode.el ends here
|
||||
136
.emacs.d/vim-mode/vim-scroll.el
Normal file
136
.emacs.d/vim-mode/vim-scroll.el
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
;;; vim-scroll.el - Implementation of scrolling commands
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file contains implementations for the scrolling. Scroll
|
||||
;; operations are usually just simple commands and should not be
|
||||
;; repeatable but should keep visual mode.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(vim:define-keymap motion-mode "motion mode" :map-command mmap)
|
||||
|
||||
(vim:define-mode motion "VIM motion mode"
|
||||
:ident "M"
|
||||
:keymaps '(vim:motion-mode-keymap vim:window-mode-keymap)
|
||||
:command-function 'vim:normal-mode-command)
|
||||
|
||||
(defun vim:num-visible-lines ()
|
||||
"Returns the number of currently visible lines."
|
||||
(- (window-height) 1))
|
||||
|
||||
(defun vim:max-scroll-up ()
|
||||
"Returns the maximal number of lines that can be scrolled up."
|
||||
(1- (line-number-at-pos (window-start))))
|
||||
|
||||
(defun vim:max-scroll-down ()
|
||||
"Returns the maximal number of lines that can be scrolled down."
|
||||
(if (pos-visible-in-window-p (window-end))
|
||||
0
|
||||
(1+ (- (line-number-at-pos (point-max))
|
||||
(line-number-at-pos (window-end))))))
|
||||
|
||||
(vim:defcmd vim:scroll-line-up (count nonrepeatable keep-visual)
|
||||
"Scrolls the window `count' lines upwards."
|
||||
(vim:use-last-column)
|
||||
(scroll-down (or count 1)))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-line-down (count nonrepeatable keep-visual)
|
||||
"Scrolls the window `count' lines downwards."
|
||||
(vim:use-last-column)
|
||||
(scroll-up (or count 1)))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-up (count nonrepeatable keep-visual)
|
||||
"Scrolls the window and the cursor `count' lines upwards, default half of the screen."
|
||||
(vim:use-last-column)
|
||||
(let ((p (point))
|
||||
(c (or count (/ (vim:num-visible-lines) 2))))
|
||||
(save-excursion
|
||||
(scroll-down (min (vim:max-scroll-up) c)))
|
||||
(forward-line (- c))
|
||||
(when (= (line-number-at-pos p)
|
||||
(line-number-at-pos (point)))
|
||||
(ding))))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-down (count nonrepeatable keep-visual)
|
||||
"Scrolls the window and the cursor `count' lines downwards, default half of the screen."
|
||||
(vim:use-last-column)
|
||||
(let ((p (point))
|
||||
(c (or count (/ (vim:num-visible-lines) 2))))
|
||||
(save-excursion
|
||||
(scroll-up (min (vim:max-scroll-down) c)))
|
||||
(forward-line c)
|
||||
(when (= (line-number-at-pos p)
|
||||
(line-number-at-pos (point)))
|
||||
(ding))))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-page-up (count nonrepeatable keep-visual)
|
||||
"Scrolls the window `count' pages upwards."
|
||||
(vim:use-last-column)
|
||||
(condition-case nil
|
||||
(dotimes (i (or count 1))
|
||||
(scroll-down nil))
|
||||
(error (goto-char (point-min)))))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-page-down (count nonrepeatable keep-visual)
|
||||
"Scrolls the window `count' pages upwards."
|
||||
(vim:use-last-column)
|
||||
(condition-case nil
|
||||
(dotimes (i (or count 1))
|
||||
(scroll-up nil))
|
||||
(error (goto-char (point-max)))))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-line-to-top (count nonrepeatable keep-visual)
|
||||
"Scrolls line number `count' (or the cursor line) to the top of the window."
|
||||
(vim:use-last-column)
|
||||
(goto-line (or count (line-number-at-pos (point))))
|
||||
(recenter 0))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-line-to-center (count nonrepeatable keep-visual)
|
||||
"Scrolls line number `count' (or the cursor line) to the center of the window."
|
||||
(vim:use-last-column)
|
||||
(goto-line (or count (line-number-at-pos (point))))
|
||||
(recenter nil))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-line-to-bottom (count nonrepeatable keep-visual)
|
||||
"Scrolls line number `count' (or the cursor line) to the bottom of the window."
|
||||
(vim:use-last-column)
|
||||
(goto-line (or count (line-number-at-pos (point))))
|
||||
(recenter -1))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-bottom-line-to-top (count nonrepeatable keep-visual)
|
||||
"Scrolls the line right below the window or line `count' to the top of the window."
|
||||
(if count
|
||||
(goto-line count)
|
||||
(goto-char (window-end))
|
||||
(unless (bobp) (backward-char)))
|
||||
(recenter 0)
|
||||
(vim:motion-first-non-blank))
|
||||
|
||||
|
||||
(vim:defcmd vim:scroll-top-line-to-bottom (count nonrepeatable keep-visual)
|
||||
"Scrolls the line right below the window or line `count' to the top of the window."
|
||||
(if count
|
||||
(goto-line count)
|
||||
(goto-char (window-start)))
|
||||
(recenter -1)
|
||||
(vim:motion-first-non-blank))
|
||||
|
||||
(provide 'vim-scroll)
|
||||
|
||||
;;; vim-scroll.el ends here
|
||||
243
.emacs.d/vim-mode/vim-search.el
Normal file
243
.emacs.d/vim-mode/vim-search.el
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
;;; vim-search.el - Search und substitute commands for ex-mode.
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;; TODO:
|
||||
;;
|
||||
;; - searching currently uses isearch. Although this is quite powerful,
|
||||
;; it's only usuably as interactive search and difficult to use with
|
||||
;; semi-interactive stuff like the "*" command. The current implementation
|
||||
;; using unread-command-events is quite ugly.
|
||||
;; - the substitute command should be more interactive and especially an operation
|
||||
;; without the 'g' option should highlight all future occurences
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defconst vim:search-keymap (make-sparse-keymap))
|
||||
(vim:set-keymap-default-binding vim:search-keymap 'vim:search-mode-exit)
|
||||
|
||||
(vim:deflocalvar vim:search-last-direction nil
|
||||
"The last search direction, either 'forward or 'backward.")
|
||||
|
||||
(defun vim:search-mode-activate ()
|
||||
(setq cursor-type vim:normal-mode-cursor))
|
||||
|
||||
(defun vim:search-mode-deactivate ()
|
||||
(isearch-exit))
|
||||
|
||||
(vim:defcmd vim:search-mode-exit ()
|
||||
(vim:activate-normal-mode)
|
||||
(push last-command-event unread-command-events))
|
||||
|
||||
;; Search mode is a very special mode being activated during a search
|
||||
;; command. Its purpose is to disable highlighting of search results
|
||||
;; if something else than a repeat-search event occurs.
|
||||
(vim:define-mode search "VIM search mode"
|
||||
:ident "S"
|
||||
:keymaps '(vim:search-keymap)
|
||||
:command-function 'vim:search-mode-command)
|
||||
(add-hook 'vim:search-mode-on-hook 'vim:search-mode-activate)
|
||||
(add-hook 'vim:search-mode-off-hook 'vim:search-mode-activate)
|
||||
|
||||
(defun vim:search-mode-command (command)
|
||||
"Executes a simple-command in search-mode."
|
||||
(case (vim:cmd-type command)
|
||||
('simple (vim:normal-execute-simple-command command))
|
||||
(t (error "Only simple commands allowed in search-mode."))))
|
||||
|
||||
(vim:defcmd vim:search-start (nonrepeatable)
|
||||
"Starts an incremental regexp search."
|
||||
(let ((search-nonincremental-instead nil))
|
||||
(ad-activate 'isearch-message-prefix)
|
||||
(isearch-forward-regexp)
|
||||
(ad-deactivate 'isearch-message-prefix)
|
||||
(setq vim:last-search-direction (if isearch-forward 'forward 'backward))))
|
||||
|
||||
(vim:defcmd vim:search-start-backward (nonrepeatable)
|
||||
"Starts an incremental regexp search."
|
||||
(let ((search-nonincremental-instead nil))
|
||||
(ad-activate 'isearch-message-prefix)
|
||||
(isearch-backward-regexp)
|
||||
(ad-deactivate 'isearch-message-prefix)
|
||||
(setq vim:last-search-direction (if isearch-forward 'forward 'backward))))
|
||||
|
||||
(vim:defcmd vim:search-repeat (nonrepeatable)
|
||||
"Repeats the last incremental search."
|
||||
(unless (vim:search-mode-p)
|
||||
(vim:activate-search-mode))
|
||||
(ad-activate 'isearch-message-prefix)
|
||||
(isearch-repeat vim:last-search-direction)
|
||||
(ad-deactivate 'isearch-message-prefix))
|
||||
|
||||
(vim:defcmd vim:search-repeat-opposite (nonrepeatable)
|
||||
"Starts an incremental regexp search."
|
||||
(unless (vim:search-mode-p)
|
||||
(vim:activate-search-mode))
|
||||
(ad-activate 'isearch-message-prefix)
|
||||
(isearch-repeat (if (eq vim:last-search-direction 'forward) 'backward 'forward))
|
||||
(ad-deactivate 'isearch-message-prefix))
|
||||
|
||||
(defadvice isearch-message-prefix (after vim:isearch-message-prefix (&optional c-q-hack ellipsis nonincremental))
|
||||
"This advice changes the minibuffer indicator to '/' or '?'"
|
||||
(setq ad-return-value (if isearch-forward "/" "?")))
|
||||
|
||||
(defun vim:start-word-search (unbounded direction)
|
||||
|
||||
(condition-case nil
|
||||
(goto-char (vim:motion-bwd-word-end :count 1))
|
||||
(error nil))
|
||||
|
||||
(save-excursion
|
||||
(re-search-forward (concat "\\<[" vim:word "]+\\>")))
|
||||
|
||||
(when (eq direction 'backward)
|
||||
(goto-char (1+ (match-end 0))))
|
||||
(let ((events (reverse (append (if (eq direction 'forward)
|
||||
"/"
|
||||
"?")
|
||||
(if unbounded
|
||||
(regexp-quote (match-string 0))
|
||||
(concat "\\<"
|
||||
(regexp-quote (match-string 0))
|
||||
"\\>"))
|
||||
[return]
|
||||
"n"
|
||||
nil))))
|
||||
(while events
|
||||
(push (car events) unread-command-events)
|
||||
(setq events (cdr events)))))
|
||||
|
||||
|
||||
(vim:defcmd vim:search-word (nonrepeatable)
|
||||
"Searches the next occurence of word under the cursor."
|
||||
(vim:start-word-search nil 'forward))
|
||||
|
||||
|
||||
(vim:defcmd vim:search-word-backward (nonrepeatable)
|
||||
"Searches the next occurence of word under the cursor."
|
||||
(vim:start-word-search nil 'backward))
|
||||
|
||||
|
||||
(vim:defcmd vim:search-unbounded-word (nonrepeatable)
|
||||
"Searches the next occurence of word under the cursor."
|
||||
(vim:start-word-search t 'forward))
|
||||
|
||||
|
||||
(vim:defcmd vim:search-unbounded-word-backward (nonrepeatable)
|
||||
"Searches the next occurence of word under the cursor."
|
||||
(vim:start-word-search t 'backward))
|
||||
|
||||
|
||||
(vim:defcmd vim:cmd-substitute (motion argument nonrepeatable)
|
||||
"The VIM substitutde command: [range]s/pattern/replacement/flags"
|
||||
(multiple-value-bind (pattern replacement flags) (vim:parse-substitute argument)
|
||||
(lexical-let* ((pattern pattern)
|
||||
(replacement replacement)
|
||||
(first-line (if motion (vim:motion-first-line motion) (line-number-at-pos (point))))
|
||||
(last-line (if motion (vim:motion-last-line motion) (line-number-at-pos (point))))
|
||||
(whole-line (and flags (find ?g flags)))
|
||||
(confirm (and flags (find ?c flags)))
|
||||
(ignore-case (and flags (find ?i flags)))
|
||||
(dont-ignore-case (and flags (find ?I flags)))
|
||||
(case-fold-search (or (and case-fold-search
|
||||
(not dont-ignore-case))
|
||||
(and (not case-fold-search)
|
||||
ignore-case)))
|
||||
(case-replace case-fold-search)
|
||||
(last-point (point))
|
||||
(overlay (make-overlay (point) (point)))
|
||||
(next-line (line-number-at-pos (point)))
|
||||
(nreplaced 0))
|
||||
|
||||
(unwind-protect
|
||||
(if whole-line
|
||||
;; this one is easy, just use the built in function
|
||||
(vim:perform-replace pattern replacement confirm t nil nil nil
|
||||
(save-excursion
|
||||
(goto-line first-line)
|
||||
(line-beginning-position))
|
||||
(save-excursion
|
||||
(goto-line last-line)
|
||||
(line-end-position)))
|
||||
(if confirm
|
||||
(progn
|
||||
;; this one is more difficult, we have to do the
|
||||
;; highlighting and questioning on our own
|
||||
(overlay-put overlay 'face
|
||||
(if (internal-find-face 'isearch nil)
|
||||
'isearch 'region))
|
||||
(map-y-or-n-p #'(lambda (x)
|
||||
(set-match-data x)
|
||||
(move-overlay overlay (match-beginning 0) (match-end 0))
|
||||
(concat "Query replacing "
|
||||
(match-string 0)
|
||||
" with "
|
||||
(match-substitute-replacement replacement case-fold-search)
|
||||
": "))
|
||||
#'(lambda (x)
|
||||
(set-match-data x)
|
||||
(replace-match replacement case-fold-search)
|
||||
(incf nreplaced)
|
||||
(setq last-point (point)))
|
||||
#'(lambda ()
|
||||
(let ((end (save-excursion
|
||||
(goto-line last-line)
|
||||
(line-end-position))))
|
||||
(goto-line next-line)
|
||||
(beginning-of-line)
|
||||
(when (and (> end (point))
|
||||
(re-search-forward pattern end t nil))
|
||||
(setq last-point (point))
|
||||
(setq next-line (1+ (line-number-at-pos (point))))
|
||||
(match-data))))))
|
||||
|
||||
;; just replace the first occurences per line
|
||||
;; without highlighting and asking
|
||||
(goto-line first-line)
|
||||
(beginning-of-line)
|
||||
(while (and (<= (line-number-at-pos (point)) last-line)
|
||||
(re-search-forward pattern (save-excursion
|
||||
(goto-line last-line)
|
||||
(line-end-position))
|
||||
t nil))
|
||||
(incf nreplaced)
|
||||
(replace-match replacement)
|
||||
(setq last-point (point))
|
||||
(forward-line)
|
||||
(beginning-of-line)))
|
||||
|
||||
(goto-char last-point)
|
||||
(if (= nreplaced 1)
|
||||
(message "Replaced 1 occurence")
|
||||
(message "Replaced %d occurences" nreplaced)))
|
||||
|
||||
;; clean-up the overlay
|
||||
(delete-overlay overlay)))))
|
||||
|
||||
|
||||
(defun vim:parse-substitute (text)
|
||||
(when (string-match "\\`\\s-*/\\(\\(?:[^/]\\|\\\\.\\)+\\)/\\(\\(?:[^/]\\|\\\\.\\)*\\)\\(?:/\\([giIc]*\\)\\)?\\s-*\\'"
|
||||
text)
|
||||
(let ((pattern (match-string 1 text))
|
||||
(replacement (match-string 2 text))
|
||||
(flags (match-string 3 text)))
|
||||
(values pattern
|
||||
;; handle some special escapes, especially \\ and \/
|
||||
(replace-regexp-in-string "\\\\."
|
||||
(lambda (x)
|
||||
(cond ((string= x "\\n") "\n")
|
||||
((string= x "\\t") "\t")
|
||||
((string= x "\\r") "\r")
|
||||
((string= x "\\/") "/")
|
||||
((string= x "\\\\") "\\\\\\\\")
|
||||
(t x)))
|
||||
replacement)
|
||||
flags))))
|
||||
|
||||
(provide 'vim-search)
|
||||
|
||||
;;; vim-search.el ends here
|
||||
71
.emacs.d/vim-mode/vim-undo.el
Normal file
71
.emacs.d/vim-mode/vim-undo.el
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
;;; 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
|
||||
404
.emacs.d/vim-mode/vim-vim.el
Normal file
404
.emacs.d/vim-mode/vim-vim.el
Normal file
|
|
@ -0,0 +1,404 @@
|
|||
;;; vim-vim.el - Basic functions and macros for vim-mode.
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defvar vim:repeat-events nil
|
||||
"The sequence of events for the repeat command.")
|
||||
|
||||
(vim:deflocalvar vim:current-register nil
|
||||
"The register of the current command.")
|
||||
|
||||
(vim:deflocalvar vim:current-cmd-count nil
|
||||
"The count of the current command.")
|
||||
|
||||
(vim:deflocalvar vim:current-cmd nil
|
||||
"The node of the current command.")
|
||||
|
||||
(vim:deflocalvar vim:current-cmd-arg nil
|
||||
"The argument of the current command.")
|
||||
|
||||
(vim:deflocalvar vim:current-motion-count nil
|
||||
"The count of the current motion.")
|
||||
|
||||
(vim:deflocalvar vim:current-motion nil
|
||||
"The node of the current motion.")
|
||||
|
||||
(vim:deflocalvar vim:current-motion-arg nil
|
||||
"The argument of the current motion.")
|
||||
|
||||
(vim:deflocalvar vim:current-motion-type nil
|
||||
"The type of the current motion (inclusive, exclusive, linewise).")
|
||||
|
||||
(defun vim:toplevel-execution ()
|
||||
"Returns t iff this is a toplevel execution, not a mapping or repeat."
|
||||
(not executing-kbd-macro))
|
||||
|
||||
|
||||
(defadvice vim:reset-key-state (before vim:vim-reset-key-state)
|
||||
"Resets the current state of the keymap."
|
||||
(setq vim:current-register nil
|
||||
vim:current-cmd-count nil
|
||||
vim:current-cmd nil
|
||||
vim:current-cmd-arg nil
|
||||
vim:current-motion-count nil
|
||||
vim:current-motion nil
|
||||
vim:current-motion-arg nil
|
||||
vim:current-motion-type nil))
|
||||
(ad-activate 'vim:reset-key-state)
|
||||
|
||||
|
||||
(defmacro* vim:defcmd (name (&rest args) &rest body)
|
||||
"Defines a new VIM-command."
|
||||
(declare (indent defun))
|
||||
(let ((count nil)
|
||||
(register nil)
|
||||
(motion nil)
|
||||
(argument nil)
|
||||
(keep-visual nil)
|
||||
(repeatable t)
|
||||
(params nil)
|
||||
(named-params nil)
|
||||
(doc nil))
|
||||
|
||||
;; extract documentation string
|
||||
(if (and (consp body)
|
||||
(cdr body)
|
||||
(stringp (car body)))
|
||||
(setq doc (car body)
|
||||
body (cdr body))
|
||||
(setq doc (format "VIM - command (%s %s)" name args)))
|
||||
|
||||
;; collect parameters
|
||||
(dolist (arg args)
|
||||
(case (if (consp arg) (car arg) arg)
|
||||
('count
|
||||
(setq count t)
|
||||
(push '(count nil) params)
|
||||
(when (and (consp arg)
|
||||
(not (eq (cadr arg) 'count)))
|
||||
(push `(,(cadr arg) count) named-params)))
|
||||
|
||||
('register
|
||||
(setq register t)
|
||||
(push '(register nil) params)
|
||||
(when (and (consp arg)
|
||||
(not (eq (cadr arg) 'register)))
|
||||
(push `(,(cadr arg) register) named-params)))
|
||||
|
||||
('motion
|
||||
(when motion
|
||||
(error "%s: only one motion argument may be specified: %s" 'vim:defcmd arg))
|
||||
(setq motion t)
|
||||
(push 'motion params)
|
||||
(when (and (consp arg)
|
||||
(not (eq (cadr arg) 'motion)))
|
||||
(push `(,(cadr arg) motion) named-params)))
|
||||
|
||||
('motion:optional
|
||||
(when motion
|
||||
(error "%s: only one motion argument may be specified: %s" 'vim:defcmd arg))
|
||||
(setq motion ''optional)
|
||||
(push 'motion params)
|
||||
(when (and (consp arg)
|
||||
(not (eq (cadr arg) 'motion)))
|
||||
(push `(,(cadr arg) motion) named-params)))
|
||||
|
||||
((argument argument:char argument:file argument:buffer)
|
||||
(when argument
|
||||
(error "%s: only one argument may be specified: %s" 'vim:defcmd arg))
|
||||
(let* ((arg-name (symbol-name (if (consp arg) (car arg) arg)))
|
||||
(pos (position ?: arg-name))
|
||||
(arg-type (if pos
|
||||
`',(intern (substring arg-name (1+ pos)))
|
||||
t)))
|
||||
(setq argument arg-type)
|
||||
(push 'argument params)
|
||||
(when (and (consp arg)
|
||||
(not (eq (cadr arg) 'argument)))
|
||||
(push `(,(cadr arg) argument) named-params))))
|
||||
|
||||
('keep-visual (setq keep-visual t))
|
||||
('do-not-keep-visual (setq keep-visual nil))
|
||||
('repeatable (setq repeatable t))
|
||||
('nonrepeatable (setq repeatable nil))
|
||||
|
||||
(t (error "%s: Unexpected argument: %s" 'vim:defcmd arg))))
|
||||
|
||||
`(progn
|
||||
(put ',name 'type ',(if motion 'complex 'simple))
|
||||
(put ',name 'count ,count)
|
||||
(put ',name 'motion ,motion)
|
||||
(put ',name 'argument ,argument)
|
||||
(put ',name 'register ,register)
|
||||
(put ',name 'keep-visual ,keep-visual)
|
||||
(put ',name 'repeatable ,repeatable)
|
||||
(put ',name 'function
|
||||
(function* (lambda (,@(when params `(&key ,@params))
|
||||
,@(when named-params `(&aux ,@named-params)))
|
||||
,@body)))
|
||||
(defun* ,name (&rest args)
|
||||
,doc
|
||||
(interactive)
|
||||
(if (vim:called-interactively-p)
|
||||
(funcall vim:active-command-function ',name)
|
||||
(apply (get ',name 'function) args))))))
|
||||
|
||||
(defmacro* vim:defmotion (name (&rest args) &rest body)
|
||||
(declare (indent defun))
|
||||
(let ((type nil)
|
||||
(count nil)
|
||||
(argument nil)
|
||||
(params nil)
|
||||
(named-params nil)
|
||||
(doc nil))
|
||||
|
||||
;; extract documentation string
|
||||
(if (and (consp body)
|
||||
(cdr body)
|
||||
(stringp (car body)))
|
||||
(setq doc (car body)
|
||||
body (cdr body))
|
||||
(setq doc (format "VIM - motion (%s %s)" name args)))
|
||||
|
||||
;; collect parameters
|
||||
(dolist (arg args)
|
||||
(case (if (consp arg) (car arg) arg)
|
||||
((inclusive exclusive linewise block)
|
||||
(setq type arg))
|
||||
|
||||
('count
|
||||
(setq count t)
|
||||
(push '(count nil) params)
|
||||
(when (and (consp arg)
|
||||
(not (eq (cadr arg) 'count)))
|
||||
(push `(,(cadr arg) count) named-params)))
|
||||
|
||||
((argument argument:char)
|
||||
(when argument
|
||||
(error "%s: only one argument may be specified: %s" 'vim:defcmd arg))
|
||||
(setq argument ''char)
|
||||
(push 'argument params)
|
||||
(when (and (consp arg)
|
||||
(not (eq (cadr arg) 'argument)))
|
||||
(push `(,(cadr arg) argument) named-params)))
|
||||
|
||||
(t (error "%s: Unexpected argument: %s" 'vim:defmotion arg))))
|
||||
|
||||
(unless type
|
||||
(error "%s: Motion type must be specified" 'vim:defmotion))
|
||||
|
||||
`(progn
|
||||
(put ',name 'type ',type)
|
||||
(put ',name 'count ,count)
|
||||
(put ',name 'argument ,argument)
|
||||
(put ',name 'function
|
||||
(function* (lambda (,@(when params `(&key ,@params))
|
||||
,@(when named-params `(&aux ,@named-params)))
|
||||
(vim:do-motion ',type (progn ,@body)))))
|
||||
(defun* ,name (&rest args)
|
||||
,doc
|
||||
(interactive)
|
||||
(if (vim:called-interactively-p)
|
||||
(vim:execute-command ',name)
|
||||
(apply (get ',name 'function) args))))))
|
||||
|
||||
(font-lock-add-keywords 'emacs-lisp-mode '("vim:defcmd" "vim:defmotion"))
|
||||
|
||||
(defun vim:cmd-count-p (cmd)
|
||||
"Returns non-nil iff command cmd takes a count."
|
||||
(get cmd 'count))
|
||||
|
||||
(defun vim:cmd-register-p (cmd)
|
||||
"Returns non-nil iff command may take a register."
|
||||
(get cmd 'register))
|
||||
|
||||
(defun vim:cmd-motion-p (cmd)
|
||||
"Returns non-nil iff command `cmd' takes a motion parameter."
|
||||
(get cmd 'motion))
|
||||
|
||||
(defun vim:cmd-arg (cmd)
|
||||
"Returns the type of command's argument."
|
||||
(get cmd 'argument))
|
||||
|
||||
(defun vim:cmd-arg-p (cmd)
|
||||
"Returns non-nil iff command cmd takes an argument of arbitrary type."
|
||||
(not (null (get cmd 'argument))))
|
||||
|
||||
(defun vim:cmd-text-arg-p (cmd)
|
||||
"Returns non-nil iff command cmd takes a text argument."
|
||||
(eq (vim:cmd-arg cmd) t))
|
||||
|
||||
(defun vim:cmd-char-arg-p (cmd)
|
||||
"Returns non-nil iff command cmd takes a char argument."
|
||||
(eq (vim:cmd-arg cmd) 'char))
|
||||
|
||||
(defun vim:cmd-file-arg-p (cmd)
|
||||
"Returns non-nil iff command cmd takes a file argument."
|
||||
(eq (vim:cmd-arg cmd) 'file))
|
||||
|
||||
(defun vim:cmd-buffer-arg-p (cmd)
|
||||
"Returns non-nil iff command cmd takes a buffer argument."
|
||||
(eq (vim:cmd-arg cmd) 'buffer))
|
||||
|
||||
(defun vim:cmd-repeatable-p (cmd)
|
||||
"Returns non-nil iff command cmd is repeatable."
|
||||
(get cmd 'repeatable))
|
||||
|
||||
(defun vim:cmd-keep-visual-p (cmd)
|
||||
"Returns non-nil iff command cmd should stay in visual mode."
|
||||
(get cmd 'keep-visual))
|
||||
|
||||
(defun vim:cmd-type (cmd)
|
||||
"Returns the type of command cmd."
|
||||
(get cmd 'type))
|
||||
|
||||
(defun vim:cmd-function (cmd)
|
||||
"Returns the function of command `cmd'."
|
||||
(get cmd 'function))
|
||||
|
||||
|
||||
(defmacro vim:apply-save-buffer (&rest args)
|
||||
"Like `apply' but stores the current buffer."
|
||||
(let ((ret (gensym)))
|
||||
`(progn
|
||||
(save-current-buffer
|
||||
(let ((,ret (apply ,@args)))
|
||||
(setq vim:new-buffer (current-buffer))
|
||||
,ret)))))
|
||||
|
||||
|
||||
(defmacro vim:funcall-save-buffer (&rest args)
|
||||
"Like `funcall' but stores the current buffer."
|
||||
(let ((ret (gensym)))
|
||||
`(progn
|
||||
(save-current-buffer
|
||||
(let ((,ret (funcall ,@args)))
|
||||
(setq vim:new-buffer (current-buffer))
|
||||
,ret)))))
|
||||
|
||||
(defun vim:select-register ()
|
||||
"Sets the register for the next command."
|
||||
(interactive)
|
||||
(setq vim:current-register (read-char-exclusive)))
|
||||
|
||||
(defun vim:get-register (register)
|
||||
"Returns the content of `register', signals error on fail."
|
||||
(let ((txt (get-register register)))
|
||||
(unless txt
|
||||
(error "Register '%c' empty." register))
|
||||
txt))
|
||||
|
||||
|
||||
(defun vim:execute-command (cmd)
|
||||
"Executes the vim-command `cmd'.
|
||||
If an error occures, this function switches back to normal-mode.
|
||||
Since all vim-mode commands go through this function, this is
|
||||
the perfect point to do some house-keeping."
|
||||
(condition-case err
|
||||
(funcall vim:active-command-function cmd)
|
||||
(error
|
||||
(vim:reset-key-state)
|
||||
(vim:clear-key-sequence)
|
||||
(vim:adjust-point)
|
||||
(vim:activate-normal-mode)
|
||||
(signal (car err) (cdr err)))))
|
||||
|
||||
|
||||
(defun vim:execute-current-motion ()
|
||||
"Executes the current motion and returns the representing
|
||||
vim:motion object."
|
||||
(if (null vim:current-motion)
|
||||
nil
|
||||
(let ((cmd vim:current-motion)
|
||||
(count (if (or vim:current-cmd-count
|
||||
vim:current-motion-count)
|
||||
(* (or vim:current-cmd-count 1)
|
||||
(or vim:current-motion-count 1))
|
||||
nil))
|
||||
(parameters nil))
|
||||
|
||||
;; build the parameter-list
|
||||
(when (vim:cmd-char-arg-p cmd)
|
||||
(push vim:current-motion-arg parameters)
|
||||
(push :argument parameters))
|
||||
(when (vim:cmd-count-p cmd)
|
||||
(push count parameters)
|
||||
(push :count parameters))
|
||||
|
||||
(vim:apply-save-buffer cmd parameters))))
|
||||
|
||||
|
||||
(defun vim:get-current-cmd-motion ()
|
||||
"Returns the motion range for the current command w.r.t.
|
||||
command-specific transformations."
|
||||
(let ((motion (save-excursion (vim:execute-current-motion))))
|
||||
(when (and (eq (vim:motion-type motion) 'exclusive)
|
||||
(save-excursion
|
||||
(goto-char (vim:motion-end-pos motion))
|
||||
(bolp)))
|
||||
|
||||
;; exclusive motions may be modified
|
||||
(let ((end (vim:adjust-end-of-line-position (1- (vim:motion-end-pos motion)))))
|
||||
(if (< (vim:motion-begin motion)
|
||||
(vim:motion-end motion))
|
||||
(setf (vim:motion-end motion) end)
|
||||
(setf (vim:motion-begin motion) end)))
|
||||
|
||||
(if (save-excursion
|
||||
(goto-char (vim:motion-begin-pos motion))
|
||||
(vim:looking-back "^\\s-*"))
|
||||
;; motion becomes linewise(-exclusive)
|
||||
(setf (vim:motion-type motion) 'linewise)
|
||||
|
||||
;; motion becomes inclusive
|
||||
(setf (vim:motion-type motion) 'inclusive)))
|
||||
motion))
|
||||
|
||||
|
||||
(defconst vim:emacs-keymap (vim:make-keymap)
|
||||
"Keymap for EMACS mode.")
|
||||
|
||||
(vim:define-mode emacs "VIM emacs-mode"
|
||||
:ident "E"
|
||||
:message "-- EMACS --"
|
||||
:keymaps '(vim:emacs-keymap)
|
||||
:command-function 'vim:normal-mode-command)
|
||||
|
||||
;; from viper
|
||||
(defsubst vim:ESC-event-p (event)
|
||||
(let ((ESC-keys '(?\e (control \[) escape))
|
||||
(key (event-basic-type event)))
|
||||
(member key ESC-keys)))
|
||||
|
||||
;; from viper
|
||||
(defun vim:escape-to-emacs (events)
|
||||
"Executes some `events' in emacs."
|
||||
|
||||
(let* ((vim-key-mode nil)
|
||||
(unread-command-events events)
|
||||
(keys (read-key-sequence nil))
|
||||
(event (elt (listify-key-sequence keys) 0)))
|
||||
|
||||
(when (vim:ESC-event-p event)
|
||||
(let ((unread-command-events keys))
|
||||
(setq keys (read-key-sequence nil))))
|
||||
|
||||
(let ((command (key-binding keys)))
|
||||
(setq this-command command)
|
||||
(setq last-command-event (elt keys (1- (length keys))))
|
||||
(setq last-command-char last-command-event)
|
||||
(command-execute command)
|
||||
(when (memq command '(digit-argument
|
||||
universal-argument))
|
||||
(vim:escape-to-emacs nil)))))
|
||||
|
||||
|
||||
(provide 'vim-vim)
|
||||
|
||||
;;; vim-vim.el ends here
|
||||
774
.emacs.d/vim-mode/vim-visual-mode.el
Normal file
774
.emacs.d/vim-mode/vim-visual-mode.el
Normal file
File diff suppressed because it is too large
Load diff
328
.emacs.d/vim-mode/vim-window.el
Normal file
328
.emacs.d/vim-mode/vim-window.el
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
;;; vim-window.el - Implementation of window commands.
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; This file contains implementations for the window operations.
|
||||
;; Window operations are usually just simple commands and should not
|
||||
;; be repeatable.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(condition-case nil
|
||||
(require 'windmove)
|
||||
(error
|
||||
(message "vim-mode: Could not load 'windmove', window-commands not available.")
|
||||
nil))
|
||||
|
||||
(vim:define-keymap window-mode "window mode" :map-command wmap)
|
||||
|
||||
(vim:define-mode window "VIM window mode"
|
||||
:ident "W"
|
||||
:keymaps '(vim:window-mode-keymap)
|
||||
:command-function 'vim:normal-mode-command)
|
||||
|
||||
(defun vim:resize-window (new-size &optional horizontal)
|
||||
"Sets the current window's with or height to `new-size'."
|
||||
(let ((wincfg (current-window-configuration))
|
||||
(nwins (length (window-list)))
|
||||
(count (if horizontal
|
||||
(- new-size (window-width))
|
||||
(- new-size (window-height)))))
|
||||
|
||||
(catch 'loop
|
||||
(save-window-excursion
|
||||
(while (not (zerop count))
|
||||
(if (> count 0)
|
||||
(progn (enlarge-window 1 horizontal) (decf count))
|
||||
(progn
|
||||
(shrink-window 1 horizontal)
|
||||
(incf count)))
|
||||
(if (= nwins (length (window-list)))
|
||||
(setq wincfg (current-window-configuration))
|
||||
(throw 'loop t)))))
|
||||
(set-window-configuration wincfg)))
|
||||
|
||||
|
||||
(defun vim:get-buffer-tree (wintree)
|
||||
"Extracts the buffer tree from a given window-tree."
|
||||
(if (consp wintree)
|
||||
(cons (car wintree) (mapcar #'vim:get-buffer-tree (cddr wintree)))
|
||||
(window-buffer wintree)))
|
||||
|
||||
|
||||
(defun vim:restore-window-tree (win tree)
|
||||
"Restores the given buffer-tree layout as subwindows of win."
|
||||
(cond
|
||||
((and (consp tree) (cddr tree))
|
||||
(let ((newwin (split-window win nil (not (car tree)))))
|
||||
(vim:restore-window-tree win (cadr tree))
|
||||
(vim:restore-window-tree newwin (cons (car tree) (cddr tree)))))
|
||||
((consp tree)
|
||||
(set-window-buffer win (cadr tree)))
|
||||
(t (set-window-buffer win tree))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-split (count (argument:file file) nonrepeatable)
|
||||
"Splits the current window horizontally, `count' lines height, editing a certain `file'."
|
||||
(let ((new-win (split-window (selected-window) count)))
|
||||
(when file
|
||||
(vim:cmd-edit :argument file))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-vsplit (count (argument:file file) nonrepeatable)
|
||||
"Splits the current window vertically, `count' columns width, editing a certain `file'."
|
||||
(let ((new-win (split-window (selected-window) count t)))
|
||||
(when file
|
||||
(vim:cmd-edit :argument file))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-close (nonrepeatable)
|
||||
"Closes the current window."
|
||||
(delete-window))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-only (nonrepeatable)
|
||||
"Closes all but the current window."
|
||||
(delete-other-windows))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-left (count nonrepeatable)
|
||||
"Move the cursor to new `count'-th window left of the current one."
|
||||
(dotimes (i (or count 1))
|
||||
(windmove-left)))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-right (count nonrepeatable)
|
||||
"Move the cursor to new `count'-th window right of the current one."
|
||||
(dotimes (i (or count 1))
|
||||
(windmove-right)))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-up (count nonrepeatable)
|
||||
"Move the cursor to new `count'-th window above the current one."
|
||||
(dotimes (i (or count 1))
|
||||
(windmove-up)))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-down (count nonrepeatable)
|
||||
"Move the cursor to new `count'-th window below the current one."
|
||||
(dotimes (i (or count 1))
|
||||
(windmove-down)))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-bottom-right (nonrepeatable)
|
||||
"Move the cursor to bottom-right window."
|
||||
(do ((success t))
|
||||
((not success))
|
||||
(setq success nil)
|
||||
(condition-case nil
|
||||
(progn
|
||||
(windmove-right)
|
||||
(setq success t))
|
||||
(error nil))
|
||||
(condition-case nil
|
||||
(progn
|
||||
(windmove-down)
|
||||
(setq success t))
|
||||
(error nil))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-top-left (nonrepeatable)
|
||||
"Move the cursor to top-left window."
|
||||
(do ((success t))
|
||||
((not success))
|
||||
(setq success nil)
|
||||
(condition-case nil
|
||||
(progn
|
||||
(windmove-left)
|
||||
(setq success t))
|
||||
(error nil))
|
||||
(condition-case nil
|
||||
(progn
|
||||
(windmove-up)
|
||||
(setq success t))
|
||||
(error nil))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-lru (nonrepeatable)
|
||||
"Move the cursor to the previous (last accessed) window."
|
||||
(select-window (get-lru-window)))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-next (count nonrepeatable)
|
||||
"Move the cursor to the next window in the cyclic order.
|
||||
With `count' go to the count-th window in the order starting from
|
||||
top-left."
|
||||
(if (not count)
|
||||
(select-window (next-window))
|
||||
(vim:window-top-left)
|
||||
(other-window (1- (or count 1)))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-prev (count nonrepeatable)
|
||||
"Move the cursor to the previous window in the cyclic order.
|
||||
With `count' go to the count-th window in the order starting from
|
||||
top-left."
|
||||
(if (not count)
|
||||
(select-window (previous-window))
|
||||
(vim:window-top-left)
|
||||
(other-window (1- (or count 1)))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-new (count (argument:file file) nonrepeatable)
|
||||
"Splits the current window horizontally and opens a new buffer or edits a certain `file'."
|
||||
(split-window (selected-window) count)
|
||||
(if file
|
||||
(vim:cmd-edit :argument file)
|
||||
(let ((buffer (generate-new-buffer "*new*")))
|
||||
(set-window-buffer (selected-window) buffer)
|
||||
(with-current-buffer buffer (normal-mode)))))
|
||||
|
||||
|
||||
|
||||
(vim:defcmd vim:window-vnew (count (argument:file file) nonrepeatable)
|
||||
"Splits the current window vertically and opens a new buffer name or edits a certain `file'."
|
||||
(split-window (selected-window) count t)
|
||||
(if file
|
||||
(vim:cmd-edit :argument file)
|
||||
(let ((buffer (generate-new-buffer "*new*")))
|
||||
(set-window-buffer (selected-window) buffer)
|
||||
(with-current-buffer buffer (normal-mode)))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-balance (nonrepeatable)
|
||||
"Balances all window sizes."
|
||||
(balance-windows))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-increase-height (count nonrepeatable)
|
||||
"Increase current window height by `count'."
|
||||
(vim:resize-window (+ (window-height) (or count 1))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-decrease-height (count nonrepeatable)
|
||||
"Decrease current window height by `count'."
|
||||
(vim:resize-window (- (window-height) (or count 1))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-increase-width (count nonrepeatable)
|
||||
"Increase current window width by `count'."
|
||||
(vim:resize-window (+ (window-width) (or count 1)) t))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-decrease-width (count nonrepeatable)
|
||||
"Decrease current window width by `count'."
|
||||
(vim:resize-window (- (window-width) (or count 1)) t))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-set-height (count nonrepeatable)
|
||||
"Sets the height of the current window to `count'."
|
||||
(vim:resize-window (or count (frame-height)) nil))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-set-width (count nonrepeatable)
|
||||
"Sets the width of the current window to `count'."
|
||||
(vim:resize-window (or count (frame-width)) t))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-rotate-upwards (nonrepeatable)
|
||||
"Rotates the windows according to the currenty cyclic ordering."
|
||||
(let ((wlist (window-list))
|
||||
(blist (mapcar #'(lambda (w) (window-buffer w))
|
||||
(window-list))))
|
||||
(setq blist (append (cdr blist) (list (car blist))))
|
||||
(while (and wlist blist)
|
||||
(set-window-buffer (car wlist) (car blist))
|
||||
(setq wlist (cdr wlist)
|
||||
blist (cdr blist)))
|
||||
(select-window (car (last (window-list))))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-rotate-downwards (nonrepeatable)
|
||||
"Rotates the windows according to the currenty cyclic ordering."
|
||||
(let ((wlist (window-list))
|
||||
(blist (mapcar #'(lambda (w) (window-buffer w))
|
||||
(window-list))))
|
||||
(setq blist (append (last blist) blist))
|
||||
(while (and wlist blist)
|
||||
(set-window-buffer (car wlist) (car blist))
|
||||
(setq wlist (cdr wlist)
|
||||
blist (cdr blist)))
|
||||
(select-window (cadr (window-list)))))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-move-very-top (nonrepeatable)
|
||||
"Closes the current window, splits the upper-left one horizontally
|
||||
and redisplays the current buffer there."
|
||||
(unless (one-window-p)
|
||||
(let ((b (current-buffer)))
|
||||
(delete-window)
|
||||
(let ((btree (vim:get-buffer-tree (car (window-tree)))))
|
||||
(vim:window-only)
|
||||
(let ((newwin (selected-window))
|
||||
(subwin (split-window)))
|
||||
(vim:restore-window-tree subwin btree)
|
||||
(set-window-buffer newwin b)
|
||||
(select-window newwin))))
|
||||
(balance-windows)))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-move-far-left (nonrepeatable)
|
||||
"Closes the current window, splits the upper-left one vertically
|
||||
and redisplays the current buffer there."
|
||||
(unless (one-window-p)
|
||||
(let ((b (current-buffer)))
|
||||
(delete-window)
|
||||
(let ((btree (vim:get-buffer-tree (car (window-tree)))))
|
||||
(vim:window-only)
|
||||
(let ((newwin (selected-window))
|
||||
(subwin (split-window-horizontally)))
|
||||
(vim:restore-window-tree subwin btree)
|
||||
(set-window-buffer newwin b)
|
||||
(select-window newwin))))
|
||||
(balance-windows)))
|
||||
|
||||
|
||||
(vim:defcmd vim:window-move-far-right (nonrepeatable)
|
||||
"Closes the current window, splits the lower-right one vertically
|
||||
and redisplays the current buffer there."
|
||||
(unless (one-window-p)
|
||||
(let ((b (current-buffer)))
|
||||
(delete-window)
|
||||
(let ((btree (vim:get-buffer-tree (car (window-tree)))))
|
||||
(vim:window-only)
|
||||
(let ((subwin (selected-window))
|
||||
(newwin (split-window-horizontally)))
|
||||
(vim:restore-window-tree subwin btree)
|
||||
(set-window-buffer newwin b)
|
||||
(select-window newwin))))
|
||||
(balance-windows)))
|
||||
|
||||
|
||||
|
||||
|
||||
(vim:defcmd vim:window-move-very-bottom (nonrepeatable)
|
||||
"Closes the current window, splits the lower-right one horizontally
|
||||
and redisplays the current buffer there."
|
||||
(unless (one-window-p)
|
||||
(let ((b (current-buffer)))
|
||||
(delete-window)
|
||||
(let ((btree (vim:get-buffer-tree (car (window-tree)))))
|
||||
(vim:window-only)
|
||||
(let ((subwin (selected-window))
|
||||
(newwin (split-window)))
|
||||
(vim:restore-window-tree subwin btree)
|
||||
(set-window-buffer newwin b)
|
||||
(select-window newwin))))
|
||||
(balance-windows)))
|
||||
|
||||
|
||||
(provide 'vim-window)
|
||||
|
||||
;;; vim-window.el ends here
|
||||
223
.emacs.d/vim-mode/vim.el
Normal file
223
.emacs.d/vim-mode/vim.el
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
;;; vim.el --- a VIM-emulation for Emacs
|
||||
|
||||
;; Copyright (C) 2009, 2010 Frank Fischer
|
||||
|
||||
;; Author: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;; Maintainer: Frank Fischer <frank.fischer@mathematik.tu-chemnitz.de>,
|
||||
;; 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue