Revert hybrid mode to use an evil hybrid state
To follow with the refactor of the holy-mode which uses the emacs state of evil mode, the hybrid mode now uses the evil hybrid state. We have now a clean symmetry between all the editing styles where each of them has an associated state: - vim = insert state - emacs = emacs state - hybrid = hybrid state This gives consistent properties to all editing styles and most importantly allows to have true isolation of key binding maps. It has the huge benefit to be easier to explain since now everything can leverage the evil API regarding key bindings. Note: Regular Emacs key binding functions can still be used for emacs and hybrid states so there is no regression with the previous implementation, we just gain better isolation at the cost of a few duplicated lines of code which will be easy to update as needed if evil upstream code changes (this code has been commented with a link to the upstream code).
This commit is contained in:
parent
82fdd9a511
commit
cfdfcfab40
|
@ -360,13 +360,6 @@
|
|||
(evil-define-key 'insert comint-mode-map [up] 'comint-previous-input)
|
||||
(evil-define-key 'insert comint-mode-map [down] 'comint-next-input))
|
||||
|
||||
;; ivy/helm keys --------------------------------------------------------------
|
||||
|
||||
(defvar spacemacs-editing-style-hook nil
|
||||
"Hook run whenever an editing style is toggled.
|
||||
Each function in the hook is run with a single argument which is the current
|
||||
editing style.")
|
||||
|
||||
;; ---------------------------------------------------------------------------
|
||||
;; Transient-states
|
||||
;; ---------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
;;; config.el --- editing-style Layer configuration File for Spacemacs
|
||||
;;
|
||||
;; Copyright (c) 2012-2016 Sylvain Benner & Contributors
|
||||
;;
|
||||
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
|
||||
;; URL: https://github.com/syl20bnr/spacemacs
|
||||
;;
|
||||
;; This file is not part of GNU Emacs.
|
||||
;;
|
||||
;;; License: GPLv3
|
||||
|
||||
(defvar spacemacs-editing-style-hook nil
|
||||
"Hook run whenever an editing style is toggled.
|
||||
Each function in the hook is run with a single argument which is the current
|
||||
editing style.")
|
|
@ -40,65 +40,72 @@ to start in hybrid state (emacs bindings) by default."
|
|||
:group 'spacemacs
|
||||
:type 'symbol)
|
||||
|
||||
(defvar hybrid-mode-insert-cursor evil-hybrid-state-cursor)
|
||||
(defvar hybrid-mode-insert-cursor-backup evil-insert-state-cursor)
|
||||
(defvar hybrid-mode-insert-state-entry-hook)
|
||||
(defvar hybrid-mode-insert-state-exit-hook)
|
||||
|
||||
(defun hybrid-mode-insert-state-entry-hook ()
|
||||
"Run hooks in `hybrid-mode-insert-state-entry-hook'."
|
||||
(run-hooks 'hybrid-mode-insert-state-entry-hook))
|
||||
|
||||
(defun hybrid-mode-insert-state-exit-hook ()
|
||||
"Run hooks in `hybrid-mode-insert-state-exit-hook'."
|
||||
(run-hooks 'hybrid-mode-insert-state-exit-hook))
|
||||
(defadvice evil-insert-state (around hybrid-insert-to-hybrid-state disable)
|
||||
"Forces Hybrid state."
|
||||
(evil-hybrid-state))
|
||||
|
||||
;;;###autoload
|
||||
(define-minor-mode hybrid-mode
|
||||
"Global minor mode to allow emacs bindings in `evil-insert-state'."
|
||||
"Global minor mode to replace insert state by hybrid state."
|
||||
:global t
|
||||
:lighter " hybrid"
|
||||
:group 'spacemacs
|
||||
(if hybrid-mode
|
||||
(progn
|
||||
(setq hybrid-mode-default-state-backup evil-default-state
|
||||
evil-default-state hybrid-mode-default-state
|
||||
evil-insert-state-cursor hybrid-mode-insert-cursor)
|
||||
(put 'spacemacs-insert-face 'face-alias 'spacemacs-hybrid-face)
|
||||
;; using this function to set the variable triggers the defcustom :set
|
||||
;; property which actually does the work of removing the bindings.
|
||||
(customize-set-variable 'evil-disable-insert-state-bindings t)
|
||||
(add-hook 'evil-insert-state-entry-hook 'hybrid-mode-insert-state-entry-hook)
|
||||
(add-hook 'evil-insert-state-exit-hook 'hybrid-mode-insert-state-exit-hook))
|
||||
(setq evil-default-state hybrid-mode-default-state-backup
|
||||
evil-insert-state-cursor hybrid-mode-insert-cursor-backup)
|
||||
(put 'spacemacs-insert-face 'face-alias nil)
|
||||
(customize-set-variable 'evil-disable-insert-state-bindings nil)
|
||||
(remove-hook 'evil-insert-state-entry-hook 'hybrid-mode-insert-state-entry-hook)
|
||||
(remove-hook 'evil-insert-state-exit-hook 'hybrid-mode-insert-state-exit-hook)))
|
||||
(enable-hybrid-editing-style)
|
||||
(enable-hybrid-editing-style)))
|
||||
|
||||
;;; Temporary to support old method of defining bindings. Should be removed
|
||||
;;; eventually.
|
||||
(when (fboundp 'advice-add)
|
||||
(defun hybrid-mode-evil-define-key (old-func &rest args)
|
||||
(if (equal (car args) ''hybrid)
|
||||
(let ((map (nth 1 args))
|
||||
(key (nth 2 args))
|
||||
(def (nth 3 args))
|
||||
(bindings (nthcdr 4 args)))
|
||||
(message "warning: evil-define-key no longer supports \
|
||||
hybrid as a state please convert to (define-key map key def)")
|
||||
(while key
|
||||
(when (keymapp (symbol-value map))
|
||||
(define-key (symbol-value map) key def)
|
||||
(setq key (pop bindings)
|
||||
def (pop bindings)))))
|
||||
(apply old-func args)))
|
||||
(advice-add 'evil-define-key :around #'hybrid-mode-evil-define-key))
|
||||
(defun enable-hybrid-editing-style ()
|
||||
"Enable the hybrid editing style."
|
||||
(setq hybrid-mode-default-state-backup evil-default-state
|
||||
evil-default-state hybrid-mode-default-state)
|
||||
;; key bindings hooks for dynamic switching of editing styles
|
||||
(run-hook-with-args 'spacemacs-editing-style-hook 'hybrid)
|
||||
(ad-enable-advice 'evil-insert-state
|
||||
'around 'hybrid-insert-to-hybrid-state)
|
||||
(ad-activate 'evil-insert-state))
|
||||
|
||||
(defvar evil-hybrid-state-map
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(set-keymap-parent evil-insert-state-map map)
|
||||
map))
|
||||
(defun disable-hybrid-editing-style ()
|
||||
"Disable the hybrid editing style (reverting to 'vim style)."
|
||||
(setq evil-default-state hybrid-mode-default-state-backup)
|
||||
;; restore key bindings
|
||||
(run-hook-with-args 'spacemacs-editing-style-hook 'vim)
|
||||
(ad-disable-advice 'evil-insert-state
|
||||
'around 'hybrid-insert-to-hybrid-state)
|
||||
(ad-activate 'evil-insert-state))
|
||||
|
||||
;; This code is from evil insert state definition, any change upstream
|
||||
;; should be reflected here
|
||||
;; see https://bitbucket.org/lyro/evil/src/a25b848c90c7942fe89d9ec283c6bb44fb7b3cf4/evil-states.el?fileviewer=file-view-default#evil-states.el-74
|
||||
(evil-define-state hybrid
|
||||
"Hybrid state for hybrid mode."
|
||||
:tag " <H> "
|
||||
:cursor (bar . 2)
|
||||
:message "-- HYBRID --"
|
||||
:entry-hook (evil-start-track-last-insertion)
|
||||
:exit-hook (evil-cleanup-insert-state evil-stop-track-last-insertion)
|
||||
:input-method t
|
||||
(cond
|
||||
((evil-hybrid-state-p)
|
||||
(add-hook 'pre-command-hook #'evil-insert-repeat-hook)
|
||||
(unless (eq evil-want-fine-undo t)
|
||||
(evil-start-undo-step t)))
|
||||
(t
|
||||
(remove-hook 'pre-command-hook #'evil-insert-repeat-hook)
|
||||
(setq evil-insert-repeat-info evil-repeat-info)
|
||||
(evil-set-marker ?^ nil t)
|
||||
(unless (eq evil-want-fine-undo t)
|
||||
(evil-end-undo-step t (eq evil-want-fine-undo 'fine)))
|
||||
(when evil-move-cursor-back
|
||||
(when (or (evil-normal-state-p evil-next-state)
|
||||
(evil-motion-state-p evil-next-state))
|
||||
(evil-move-cursor-back))))))
|
||||
|
||||
(define-key evil-hybrid-state-map [escape] 'evil-normal-state)
|
||||
|
||||
;; Override stock evil function `evil-insert-state-p'
|
||||
(defun evil-insert-state-p (&optional state)
|
||||
"Whether the current state is insert."
|
||||
(and evil-local-mode
|
||||
(memq (or state evil-state) '(insert hybrid))))
|
||||
|
||||
(provide 'hybrid-mode)
|
||||
|
|
Loading…
Reference in New Issue