;;; viper-in-more-modes.el --- vi-like keybindings for various Emacs modes ;; Copyright (C) 2007 Alessandro Piras, Brad Beveridge, Jason Spiro ;; ;; Version: 0.1.2 ;; Authors: Alessandro Piras , ;; Brad Beveridge ;; Maintainer: Jason Spiro ;; URL: http://emacswiki.org/elisp/viper-in-more-modes.el ;; ;; This file is not part of GNU Emacs. ;;; Commentary: ;; ;; This file is an unofficial add-on to viper-mode. It currently ;; provides vi-like keymaps for emacs-lisp-mode, lisp-interaction-mode, ;; slime-repl-mode, and lisp-mode. If you have any questions or ;; comments, please email the authors and maintainer. We provide no ;; guarantee of help with such early code. If you extended this file to ;; cover additional modes, we would be very grateful; please contact us. ;; ;; There are no installation instructions or usage instructions, but ;; we might be able to help you out if you contact us. If you wrote ;; such instructions and added them to this wiki page, we would be very ;; appreciative. ;; ;; This is alpha-quality code. If it works for you, we would ;; appreciate it if you let us know. ;;; Change Log: ;; ;; Version 0.1.2: Removed some duplicate keybinding code. Also, ;; slime-list-callees is now on the ">" key instead of on the "<" key ;; which was already taken. Thank you Stephen Bach . ;; Version 0.1.1: Made viper-leader-char a var, not a const. Thank you ;; John J Foerch . ;; Version 0.1: Initial upload to wiki. ;;; License: ;; ;; This program is free software; you can redistribute it and/or modify it under ;; the terms of the GNU General Public License as published by the Free Software ;; Foundation; either version 2 of the License, or any later version. ;; ;; This program is distributed in the hope that it will be useful, but WITHOUT ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ;; details. ;; ;; You should have received a copy of the GNU General Public License along with ;; this program; if not, write to the Free Software Foundation, Inc., 59 Temple ;; Place - Suite 330, Boston, MA 02111-1307, USA. ;; Begin utility code {{{ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Macro workaround to make some commands ;;; ;;; work on the character the cursor is on ;;; ;;; too (eg. in visual mode pressing "d" ;;; ;;; deletes also the char under the cursor ;;; ;;; (like in vim) ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmacro do-one-char-forward (&rest body) "Wraps the body between `forward-char' and `backward-char' to make commands work on closed parens like one can expect in vi." `(progn (forward-char) ,@body (backward-char))) (defmacro def-simple-vimper-wrapper-ocf (name &rest body) "; Define a wrapper for a command to execute it as if the cursor was one ; char forward the current position. Uses `do-one-char-forward'. Use it ; like a defun without lambdalist. ; ; For example, this: ; ; (def-simple-vimper-wrapper-ocf my-eval-last-sexp (eval-last-sexp)) ; ; expands to this: ; ; (defun my-eval-last-sexp () ; (interactive) ; (do-one-char-forward ; (eval-last-sexp)))" `(defun ,name () (interactive) (do-one-char-forward ,@body))) ;; }}} End utility code ;; Begin major mode keybinding code {{{ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Major mode keybindings and functions used by vimper ;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar viper-leader-char " ") (defmacro vimper-defkey-l (map key func) `(define-key ,map (concat viper-leader-char ,key) ,func)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Emacs Lisp Mode - Viper Mappings ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Commands definitions (Almost all are work-arounds due to the fact that ;;; Emacs wants the cursor to be _after_ the ")" to execute functions ;;; on sexps. We use the `do-one-char-forward' utility macro here, ;;; look at vimper/utilities.el for details on that macro). (defun vimper-eval-last-sexp (&optional eval-last-sexp-arg-internal) (interactive) (do-one-char-forward (eval-last-sexp eval-last-sexp-arg-internal))) (defun vimper-eval-region (&optional arg) (interactive "P") (if (not viper-visual-mode) (message "Select the region in Visual Mode!") (eval-region (min (mark) (point)) (max (mark) (point))) (viper-visual-mode 'toggle))) (defun vimper-pp-eval-region () (interactive) (message (pp-to-string (vimper-eval-region)))) (defun vimper-pp-eval-last-sexp (&optional eval-last-sexp-arg-internal) (interactive) (do-one-char-forward (pp-eval-last-sexp eval-last-sexp-arg-internal))) ;; macroexpand command (macroexpands last sexp) (def-simple-vimper-wrapper-ocf vimper-macroexpand (message (pp-to-string (macroexpand (sexp-at-point))))) ;; macroexpand-all command (macroexpands-all last sexp) (def-simple-vimper-wrapper-ocf vimper-macroexpand-all (message (pp-to-string (macroexpand-all (sexp-at-point))))) ;;; bindings (setq my-elisp-modified-vi-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "p" (make-sparse-keymap)) (vimper-defkey-l map "pe" 'vimper-pp-eval-last-sexp) (vimper-defkey-l map "pE" 'pp-eval-expression) (vimper-defkey-l map "pr" 'vimper-pp-eval-region) (vimper-defkey-l map "e" 'vimper-eval-last-sexp) (vimper-defkey-l map "r" 'vimper-eval-region) (vimper-defkey-l map "da" 'apropos) (vimper-defkey-l map "df" 'describe-function) (vimper-defkey-l map "dv" 'describe-variable) (vimper-defkey-l map "E" 'eval-expression) (vimper-defkey-l map "m" 'vimper-macroexpand) (vimper-defkey-l map "M" 'vimper-macroexpand-all) (vimper-defkey-l map "B" 'byte-compile-file) map)) (viper-modify-major-mode 'emacs-lisp-mode 'vi-state my-elisp-modified-vi-map) (viper-modify-major-mode 'lisp-interaction-mode 'vi-state my-elisp-modified-vi-map) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Common Lisp Mode - Viper Mappings ;;; ;;; Slime ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Commands (def-simple-vimper-wrapper-ocf vimper-slime-compile-defun (slime-compile-defun)) (def-simple-vimper-wrapper-ocf vimper-slime-eval-defun (slime-eval-defun)) (def-simple-vimper-wrapper-ocf vimper-slime-eval-last-expression (slime-eval-last-expression)) (def-simple-vimper-wrapper-ocf vimper-slime-pprint-eval-last-expression (slime-pprint-eval-last-expression)) (defun vimper-slime-eval-region () (interactive) (if (not viper-visual-mode) (message "Select the region in Visual Mode!") (slime-eval-region (min (mark) (point)) (max (mark) (point))) (viper-visual-mode 'toggle))) (defun vimper-slime-macroexpand-1 (&optional REPEATEDLY) (interactive "P") (do-one-char-forward (slime-macroexpand-1 REPEATEDLY))) (def-simple-vimper-wrapper-ocf vimper-slime-macroexpand-all (slime-macroexpand-all)) ;; Bindings ;; In general the Viper Slime mappings are much the same as regular Slime bindings, ;; The C-c and C-x prefixes are dropped. ;; When commands are similar, we use a lower case letter for the C- case and an upper ;; case letter for the M-, such as: ;; C-c C-k : slime-compile-and-load-file : (vip-slime-leader k) ;; C-c M-k : slime-compile-file : (vip-slime-leader K) ;; All commands begin with vip-slime-leader, which defaults to ;; the M-x commands are not mapped, as they are presumably rare ;; Some keys are a triple key sequence. The second key is a marker for a category ;; the third key is the activation key. (setq my-lisp-modified-vi-map (let ((map (make-sparse-keymap))) ;; Compilation Commands (vimper-defkey-l map "k" 'slime-compile-and-load-file) (vimper-defkey-l map "K" 'slime-compile-file) (vimper-defkey-l map "c" 'vimper-slime-compile-defun) (vimper-defkey-l map "C" 'slime-remove-notes) ;; Do I want to change those??? Meta key -_-'' ;; TODO: of course I want to change theese!! we're using ;; leader char here, so it definately sucks!! ;; Finding definitions (they are same as Slime default) (vimper-defkey-l map "\M-." 'slime-edit-definition) (vimper-defkey-l map "\M-," 'slime-pop-find-definition-stack) ;; Note handling has the same binding as Slime defaults (vimper-defkey-l map "\M-n" 'slime-next-note) (vimper-defkey-l map "\M-p" 'slime-previous-note) ;; Lisp Evaluation (vimper-defkey-l map "x" 'vimper-slime-eval-defun) (vimper-defkey-l map "e" 'vimper-slime-eval-last-expression) (vimper-defkey-l map "p" 'vimper-slime-pprint-eval-last-expression) (vimper-defkey-l map "r" 'vimper-slime-eval-region) ; watch for visual mode!! ;; Lisp Documentation ;; 3 key sequences (vimper-defkey-l map "dd" 'slime-describe-symbol) (vimper-defkey-l map "da" 'slime-apropos) (vimper-defkey-l map "dz" 'slime-apropos-all) (vimper-defkey-l map "dp" 'slime-apropos-package) (vimper-defkey-l map "dh" 'slime-hyperspec-lookup) (vimper-defkey-l map "d~" 'common-lisp-hyperspec-format) ;; Macro expansion (vimper-defkey-l map "m" 'vimper-slime-macroexpand-1) (vimper-defkey-l map "M" 'vimper-slime-macroexpand-all) (vimper-defkey-l map "t" 'slime-toggle-trace-fdefinition) ;; Disassembly (vimper-defkey-l map "D" 'slime-disassemble-symbol) ;; Abort/Recovery (vimper-defkey-l map "b" 'slime-interrupt) (vimper-defkey-l map "~" 'slime-sync-package-and-default-directory) (vimper-defkey-l map "P" 'slime-repl-set-package) ;; Cross-reference ;; All cross-reference functions are ;; triple key sequences ;; (vip-slime-leader ?w key) (vimper-defkey-l map "wc" 'slime-who-calls) (vimper-defkey-l map "wr" 'slime-who-references) (vimper-defkey-l map "wb" 'slime-who-binds) (vimper-defkey-l map "ws" 'slime-who-sets) (vimper-defkey-l map "wm" 'slime-who-macroexpands) (vimper-defkey-l map "<" 'slime-list-callers) (vimper-defkey-l map ">" 'slime-list-callees) ;; Inspector (vimper-defkey-l map "i" 'slime-inspect) ;;Repl! (vimper-defkey-l map "R" 'slime-switch-to-output-buffer) (vimper-defkey-l map "z" 'slime-switch-to-output-buffer) ;; Profiler ;; "p" is already taken as a key, we ;; use "f" to access the profiler functions (vimper-defkey-l map "f" (make-sparse-keymap)) (vimper-defkey-l map "ft" 'slime-toggle-profile-fdefinition) (vimper-defkey-l map "fp" 'slime-profile-package) (vimper-defkey-l map "fu" 'slime-unprofile-all) (vimper-defkey-l map "fr" 'slime-profile-report) (vimper-defkey-l map "fR" 'slime-profile-reset) map)) (viper-modify-major-mode 'lisp-mode 'vi-state my-lisp-modified-vi-map) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Slime Inspector Mode - Viper Mappings ;;; ;;; Slime ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Slime REPL Mode - Viper Mappings ;;; ;;; Slime ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq my-repl-modified-vi-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "m" 'vimper-slime-macroexpand-1) (vimper-defkey-l map "i" 'slime-inspect) (vimper-defkey-l map "" 'slime-repl-closing-return) (vimper-defkey-l map "G" 'end-of-buffer))) (viper-modify-major-mode 'slime-repl-mode 'vi-state my-repl-modified-vi-map) (setq my-repl-modified-insert-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "" 'slime-repl-closing-return))) (viper-modify-major-mode 'slime-repl-mode 'insert-state my-repl-modified-insert-map) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; LaTeX Mode - Viper Mappings ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq my-LaTeX-modified-vi-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "pp" 'preview-at-point) (vimper-defkey-l map "pw" 'preview-copy-region-as-mml) (vimper-defkey-l map "pe" 'preview-environment) (vimper-defkey-l map "ps" 'preview-section) (vimper-defkey-l map "pr" 'preview-region) (vimper-defkey-l map "pb" 'preview-buffer) (vimper-defkey-l map "pd" 'preview-document) (vimper-defkey-l map "Pp" 'preview-clearout-at-point) (vimper-defkey-l map "Ps" 'preview-clearout-section) (vimper-defkey-l map "Pr" 'preview-clearout-region) (vimper-defkey-l map "Pb" 'preview-clearout-buffer) (vimper-defkey-l map "Pd" 'preview-clearout-document) (vimper-defkey-l map "pf" 'preview-cache-preamble) (vimper-defkey-l map "Pf" 'preview-cache-preamble-off) (vimper-defkey-l map "pi" 'preview-goto-info-page) (vimper-defkey-l map "p?" 'preview-goto-info-page) (vimper-defkey-l map "%" 'TeX-comment-or-uncomment-paragraph) (vimper-defkey-l map ";" 'TeX-comment-or-uncomment-region) (vimper-defkey-l map "?" 'TeX-doc) (vimper-defkey-l map "e" 'LaTeX-environment) (vimper-defkey-l map "]" 'LaTeX-close-environment) (vimper-defkey-l map "k" 'TeX-kill-job) (vimper-defkey-l map "l" 'TeX-recenter-output-buffer) (vimper-defkey-l map "^" 'TeX-home-buffer) (vimper-defkey-l map "_" 'TeX-master-file-ask) (vimper-defkey-l map "d" 'TeX-save-document) (vimper-defkey-l map "`" 'TeX-next-error) (vimper-defkey-l map "tb" 'TeX-toggle-debug-bad-boxes) (vimper-defkey-l map "tw" 'TeX-toggle-debug-warnings) (vimper-defkey-l map "c" 'TeX-command-master) (vimper-defkey-l map "r" 'TeX-command-region) (vimper-defkey-l map "tr" 'TeX-pin-region) (vimper-defkey-l map "b" 'TeX-command-buffer) (vimper-defkey-l map "tp" 'TeX-PDF-mode) (vimper-defkey-l map "ti" 'TeX-interactive-mode) (vimper-defkey-l map "ts" 'TeX-source-specials-mode) (vimper-defkey-l map "to" 'TeX-Omega-mode) (vimper-defkey-l map "f" 'TeX-font) ; TODO: Try to find a way to define "fb" and similar (vimper-defkey-l map "N" 'TeX-normal-mode) (vimper-defkey-l map "ob" 'TeX-fold-buffer) (vimper-defkey-l map "Ob" 'TeX-fold-clearout-buffer) (vimper-defkey-l map "or" 'TeX-fold-region) (vimper-defkey-l map "Or" 'TeX-fold-clearout-region) (vimper-defkey-l map "op" 'TeX-fold-paragraph) (vimper-defkey-l map "Op" 'TeX-fold-clearout-paragraph) (vimper-defkey-l map "om" 'TeX-fold-macro) (vimper-defkey-l map "oe" 'TeX-fold-env) (vimper-defkey-l map "oc" 'TeX-fold-comment) (vimper-defkey-l map "Oi" 'TeX-fold-clearout-item) (vimper-defkey-l map "oo" 'TeX-fold-dwim) (vimper-defkey-l map "qe" 'TeX-fill-environment) (vimper-defkey-l map "qp" 'TeX-fill-paragraph) (vimper-defkey-l map "qr" 'TeX-fill-region) (vimper-defkey-l map "qs" 'TeX-fill-section) (vimper-defkey-l map "Q" 'TeX-fill-paragraph) (vimper-defkey-l map "s" 'LaTeX-section) (vimper-defkey-l map "v" 'TeX-view) (vimper-defkey-l map "i" 'LaTeX-insert-item) (vimper-defkey-l map "qr" 'TeX-fill-region) (vimper-defkey-l map "qs" 'TeX-fill-section) (vimper-defkey-l map "Q" 'TeX-fill-paragraph) (vimper-defkey-l map "s" 'LaTeX-section) (vimper-defkey-l map "~" 'LaTeX-math-mode) (vimper-defkey-l map "&" 'reftex-view-crossref) (vimper-defkey-l map "(" 'reftex-label) (vimper-defkey-l map ")" 'reftex-reference) (vimper-defkey-l map "-" 'reftex-toc-recenter) (vimper-defkey-l map "/" 'reftex-index-selection-or-word) (vimper-defkey-l map "<" 'reftex-index) (vimper-defkey-l map "=" 'reftex-toc) (vimper-defkey-l map ">" 'reftex-display-index) (vimper-defkey-l map "[" 'reftex-citation) (vimper-defkey-l map "\\" 'reftex-index-phrase) (vimper-defkey-l map "|" 'reftex-index-visit-phrases-buffer) map)) (viper-modify-major-mode 'LaTeX-mode 'vi-state my-LaTeX-modified-vi-map) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Haskell Mode - Viper Mappings ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq my-haskell-modified-vi-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "t" 'inferior-haskell-type) ;;(vimper-defkey-l map "T" 'inferior-haskell-insert-type) (vimper-defkey-l map "i" 'inferior-haskell-info) (vimper-defkey-l map "h" 'haskell-hoogle) (vimper-defkey-l map "l" 'inferior-haskell-load-file) (vimper-defkey-l map "d" 'inferior-haskell-find-haddock) (vimper-defkey-l map "?" 'inferior-haskell-find-haddock) (vimper-defkey-l map "=" 'haskell-indent-insert-equal) (vimper-defkey-l map "|" 'haskell-indent-insert-guard) (vimper-defkey-l map "o" 'haskell-indent-insert-otherwise) (vimper-defkey-l map "w" 'haskell-indent-insert-where) (vimper-defkey-l map "." 'haskell-indent-align-guards-and-rhs) (vimper-defkey-l map "z" 'switch-to-haskell) (vimper-defkey-l map ">" 'haskell-indent-put-region-in-literate) (vimper-defkey-l map "\M-." 'inferior-haskell-find-definition) map)) (viper-modify-major-mode 'haskell-mode 'vi-state my-haskell-modified-vi-map) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Prolog Mode - Viper Mappings ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq my-prolog-modified-vi-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "l" 'inferior-prolog-load-file) (vimper-defkey-l map "c" 'inferior-prolog-load-file) (vimper-defkey-l map "z" 'switch-to-prolog) map)) (viper-modify-major-mode 'prolog-mode 'vi-state my-prolog-modified-vi-map) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Ruby Mode - Viper Mappings ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (setq my-ruby-modified-vi-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "l" 'ruby-load-file) (vimper-defkey-l map "r" 'ruby-send-region) (vimper-defkey-l map "R" 'ruby-send-region-and-go) (vimper-defkey-l map "b" 'ruby-send-block) (vimper-defkey-l map "B" 'ruby-send-block-and-go) (vimper-defkey-l map "x" 'ruby-send-definition) (vimper-defkey-l map "X" 'ruby-send-definition-and-go) (vimper-defkey-l map "z" 'switch-to-ruby) (vimper-defkey-l map "l" 'ruby-load-file) (vimper-defkey-l map "s" 'run-ruby) map)) (viper-modify-major-mode 'ruby-mode 'vi-state my-ruby-modified-vi-map) (setq my-inferior-ruby-modified-vi-map (let ((map (make-sparse-keymap))) (vimper-defkey-l map "l" 'ruby-load-file) map)) (viper-modify-major-mode 'inferior-ruby-mode 'vi-state my-inferior-ruby-modified-vi-map) ;; }}} End major mode keybinding code (provide 'viper-in-more-modes)