about summary refs log blame commit diff
path: root/configs/shared/emacs/.emacs.d/elpa/evil-leader-20140606.543/evil-leader.el
blob: 55bcf871ac621ec6eda8115f7a77f6ab300496ab (plain) (tree)




















































































































































































































                                                                                                         
;;; evil-leader.el --- let there be <leader>

;; Copyright (C) 2011-2013 by Michael Markert
;; Author: Michael Markert <markert.michael@googlemail.com>
;; URL: http://github.com/cofi/evil-leader
;; Package-Version: 20140606.543
;; Git-Repository: git://github.com/cofi/evil-leader.git
;; Created: 2011-09-13
;; Version: 0.4.3
;; Keywords: evil vim-emulation leader
;; Package-Requires: ((evil "0"))

;; This file is not part of GNU Emacs.

;; 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 3 of the License, or
;; (at your option) 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, see <http://www.gnu.org/licenses/>.

;;; Commentary:
;;
;; Known Bugs:
;; See http://github.com/cofi/evil-leader/issues

;; Install:
;; (require 'evil-leader)

;; Usage:
;;
;; (global-evil-leader-mode)
;;
;;    to enable `evil-leader' in every buffer where `evil' is enabled.
;;
;;    Note: You should enable `global-evil-leader-mode' before you enable
;;          `evil-mode', otherwise `evil-leader' won't be enabled in initial
;;          buffers (*scratch*, *Messages*, ...).
;;
;;    Use `evil-leader/set-key' to bind keys in the leader map.
;;    For example:
;;
;; (evil-leader/set-key "e" 'find-file)
;;
;;    You can also bind several keys at once:
;;
;; (evil-leader/set-key
;;   "e" 'find-file
;;   "b" 'switch-to-buffer
;;   "k" 'kill-buffer)
;;
;;    The key map can of course be filled in several places.
;;
;;    After you set up the key map you can access the bindings by pressing =<leader>=
;;    (default: \) and the key(s). E.g. \ e would call `find-file' to open a file.
;;
;;    If you wish to change so you can customize =evil-leader/leader= or call
;;    `evil-leader/set-leader', e.g. (evil-leader/set-leader ",") to change it to
;;    ",".
;;    The leader has to be readable by `read-kbd-macro', so using Space as a
;;    prefix key would be (evil-leader/set-leader "<SPC>").
;;
;;    Beginning with version 0.3 evil-leader has support for mode-local bindings:
;;
;; (evil-leader/set-key-for-mode 'emacs-lisp-mode "b" 'byte-compile-file)
;;
;;    Again, you can bind several keys at once.
;;
;;    A mode-local binding shadows a normal mode-independent binding.

;;; Code:

(require 'evil)

(defvar evil-leader--default-map (make-sparse-keymap)
  "Keymap used for mode-independent leader bindings.")

(defvar evil-leader--mode-maps nil
  "Alist of mode-local leader bindings, shadows mode-independent bindings.")

;;; customization
(defgroup evil-leader nil
  "<leader> support for evil."
  :group 'evil
  :prefix 'evil-leader/)

(defcustom evil-leader/leader "\\"
  "The <leader> key, used to access keys defined by `evil-leader/set-key' in normal and visual state.
Must be readable by `read-kbd-macro'. For example: \",\"."
  :type 'string
  :group 'evil-leader)

(defcustom evil-leader/non-normal-prefix "C-"
  "Prefix for leader-map in insert- and emacs-state.
`evil-leader/in-all-states' has to be non-nil for this to be set.
The combination has to be readable by `read-kbd-macro'."
  :type 'string
  :group 'evil-leader)

(defcustom evil-leader/no-prefix-mode-rx nil
  "List of regular expressions for mode names where `evil-leader/leader' is used regardless of the state.

If the current major mode is matched by one of the regular expressions
`evil-leader/leader' is installed in emacs/insert state without
the prefix additionally to the prefixed key.

`evil-leader/in-all-states' has to be non-nil for this setting to have any effect."
  :type 'list
  :group 'evil-leader)

(defcustom evil-leader/in-all-states nil
  "If is non-nil leader-map is accessible by <prefixed-leader> in emacs/insert state.

<prefixed-leader> is `evil-leader/non-normal-prefix' + `evil-leader/leader'"
  :type 'boolean
  :group 'evil-leader)

;;;###autoload
(define-minor-mode global-evil-leader-mode
  "Global minor mode for <leader> support."
  nil nil nil
  (if global-evil-leader-mode
      (add-hook 'evil-local-mode-hook #'evil-leader-mode t)
    (remove-hook 'evil-local-mode-hook #'evil-leader-mode t)))

;;;###autoload
(define-minor-mode evil-leader-mode
  "Minor mode to enable <leader> support."
  :init-value nil
  :keymap nil
  (let* ((prefixed (read-kbd-macro (concat evil-leader/non-normal-prefix evil-leader/leader)))
         (no-prefix (read-kbd-macro evil-leader/leader))
         (mode-map (cdr (assoc major-mode evil-leader--mode-maps)))
         (map (or mode-map evil-leader--default-map))
         (no-prefix-rx (if evil-leader/no-prefix-mode-rx
                           (mapconcat #'identity evil-leader/no-prefix-mode-rx "\\|")
                         nil)))
    (if evil-leader-mode
        (progn
          (evil-normalize-keymaps)
          (define-key evil-motion-state-local-map no-prefix map)
          (define-key evil-normal-state-local-map no-prefix map)
          (when evil-leader/in-all-states
            (define-key evil-emacs-state-local-map prefixed map)
            (define-key evil-insert-state-local-map prefixed map))
          (when (and no-prefix-rx (string-match-p no-prefix-rx (symbol-name major-mode)))
            (define-key evil-emacs-state-local-map no-prefix map)
            (define-key evil-insert-state-local-map no-prefix map)))
      (define-key evil-motion-state-local-map no-prefix nil)
      (define-key evil-normal-state-local-map no-prefix nil)
      (when evil-leader/in-all-states
        (define-key evil-emacs-state-local-map prefixed nil)
        (define-key evil-insert-state-local-map prefixed nil)
        (when (and no-prefix-rx (string-match-p no-prefix-rx (symbol-name major-mode)))
          (define-key evil-emacs-state-local-map no-prefix nil)
          (define-key evil-insert-state-local-map no-prefix nil))))))

(defun evil-leader/set-leader (key &optional prefix)
  "Set leader key to `key' and non-normal-prefix to `prefix' and remove old bindings.

Passing `nil' as `prefix' leaves prefix unchanged."
  (let ((global-on global-evil-leader-mode)
        (local-on evil-leader-mode))
    (when local-on
      (evil-leader-mode -1))
    (when global-on
      (global-evil-leader-mode -1))
    (setq evil-leader/leader key)
    (when prefix
      (setq evil-leader/non-normal-prefix prefix))
    (if global-on
        (global-evil-leader-mode 1)
      (when local-on
        (evil-leader-mode 1)))))

;;;###autoload
(defun evil-leader/set-key (key def &rest bindings)
  "Bind `key' to command `def' in `evil-leader/default-map'.

Key has to be readable by `read-kbd-macro' and `def' a command.
Accepts further `key' `def' pairs."
  (interactive "kKey: \naCommand: ")
  (evil-leader--def-keys evil-leader--default-map key def bindings))
(put 'evil-leader/set-key 'lisp-indent-function 'defun)

;;;###autoload
(defun evil-leader/set-key-for-mode (mode key def &rest bindings)
  "Create keybindings for major-mode `mode' with `key' bound to command `def'.

See `evil-leader/set-key'."
  (interactive "SMode: \nkKey: \naCommand: ")
  (let ((mode-map (cdr (assoc mode evil-leader--mode-maps))))
    (unless mode-map
      (setq mode-map (make-sparse-keymap))
      (set-keymap-parent mode-map evil-leader--default-map)
      (push (cons mode mode-map) evil-leader--mode-maps))
    (evil-leader--def-keys mode-map key def bindings)))
(put 'evil-leader/set-key-for-mode 'lisp-indent-function 'defun)

(defun evil-leader--def-keys (map key def bindings)
  (while key
    (define-key map (read-kbd-macro key) def)
    (setq key (pop bindings)
          def (pop bindings))))

(provide 'evil-leader)
;;; evil-leader.el ends here