Default to `jj` to return to normal mode and add support for customized

sequence

See readme to configure Spacemacs to use the initial `fd` sequence.
This commit is contained in:
syl20bnr 2014-10-04 00:28:42 -04:00
parent 77f4065491
commit e6a8d11f4b
4 changed files with 47 additions and 36 deletions

View File

@ -284,17 +284,19 @@ design flaw in Vim key bindings because the `ESC` key is very far from the
home row.
The popular way to avoid this is to replace `ESC` by `jj` pressed rapidly.
`Spacemacs` proposes to press `fd` instead and reserves the zone around `j`
for text reformatting.
`Spacemacs` **initialy** proposed to press `fd` instead of `jj`. But since
`jj` is one of the most used combination `Spacemacs` now **defaults to `jj`**
`fd` also works to quit the minibuffer.
This sequence can be customized in your `~/.spacemacs`, for instance to
revert back to the initial configuration using `fd` add this to your file:
**Note:** For those who know about [keychords.el][keychords] mode. This mode is
not used to return to the normal mode, the reason for this is latency and the
fact that keychords wants you to press several keys at almost the same time
which is something very difficult to master correctly on a keyboard.
`Spacemacs` has a special function called `fd-trigger` to handle the `fd` key
sequence and fix the above keychords issues.
```elisp
(defun dotspacemacs/init ()
"User initialization for Spacemacs. This function is called at the very startup."
(defvar spacemacs-normal-state-sequence '(?f . ?d))
(defvar spacemacs-normal-state-sequence-delay 0.1)
)
```
### Executing Vim and Emacs commands

View File

@ -19,6 +19,12 @@
;; Edit
;; ---------------------------------------------------------------------------
;; set the 2 keys sequence to return to normal state
;; default is "fd"
(defvar spacemacs-normal-state-sequence '(?j . ?j)
"Two keys sequence to return to normal state.")
(defvar spacemacs-normal-state-sequence-delay 0.2
"Maximum delay between the two keys to trigger the normal state.")
;; start scratch in text mode (usefull to get a faster Emacs load time
;; because it avoids autoloads of elisp modes)
(setq initial-major-mode 'text-mode)
@ -31,7 +37,7 @@
;; use only spaces and no tabs
(setq-default indent-tabs-mode nil)
(setq default-tab-width 2)
;; Text -----------------------------------------------------------------------
;; Text
(setq longlines-show-hard-newlines t)
;; ---------------------------------------------------------------------------

View File

@ -3,24 +3,24 @@
;; auto-indent on RET
(define-key global-map (kbd "RET") 'newline-and-indent)
;; simple and more consistent keyboard quit key bindings
;; thanks to Bin Chen for the idea (http://blog.binchen.org/?p=735)
(global-set-key (kbd "f")
(lambda () (interactive) (fd-trigger 'keyboard-quit)))
(define-key minibuffer-local-map (kbd "f")
(lambda () (interactive) (fd-trigger 'abort-recursive-edit)))
;; evil
;; ---------------------------------------------------------------------------
;; evil key bindings tweaks
;; ---------------------------------------------------------------------------
;; easier toggle for emacs-state
(evil-set-toggle-key "s-`")
;; returns to normal mode
(define-key evil-insert-state-map "f"
(lambda () (interactive) (fd-trigger 'evil-normal-state)))
(define-key evil-visual-state-map "f"
(lambda () (interactive) (fd-trigger 'evil-exit-visual-state)))
(define-key evil-emacs-state-map "f"
(lambda () (interactive) (fd-trigger 'evil-normal-state)))
(define-key evil-motion-state-map "f"
(lambda () (interactive) (fd-trigger 'evil-normal-state)))
(let ((seq spacemacs-normal-state-sequence)
(key (char-to-string (car spacemacs-normal-state-sequence))))
;; simple and more consistent keyboard quit key bindings
;; thanks to Bin Chen for the idea (http://blog.binchen.org/?p=735)
(global-set-key key `(lambda () (interactive) (spacemacs/switch-to-normal-mode ',seq 'keyboard-quit)))
(define-key minibuffer-local-map key `(lambda () (interactive) (spacemacs/switch-to-normal-mode ',seq 'abort-recursive-edit)))
(define-key evil-insert-state-map key `(lambda () (interactive) (spacemacs/switch-to-normal-mode ',seq 'evil-normal-state)))
(define-key evil-visual-state-map key `(lambda () (interactive) (spacemacs/switch-to-normal-mode ',seq 'evil-exit-visual-state)))
(define-key evil-emacs-state-map key `(lambda () (interactive) (spacemacs/switch-to-normal-mode ',seq 'evil-normal-state)))
(define-key evil-motion-state-map key `(lambda () (interactive) (spacemacs/switch-to-normal-mode ',seq 'evil-normal-state))))
;; set back go to char key bindings in normal modes
(define-key evil-normal-state-map "f" 'evil-find-char)
(define-key evil-operator-state-map "f" 'evil-find-char)

View File

@ -150,27 +150,30 @@ which require an initialization must be listed explicitly in the list.")
(progn
;; inspired from:
;; https://github.com/roman/emacs.d/blob/master/zoo/zoo-evil.el
(evil-define-command fd-trigger (callback)
"Allows to execute the passed function using 'fd'."
(evil-define-command spacemacs/switch-to-normal-mode (triggers callback)
"Allows to execute the passed CALLBACK using TRIGGERS. TRIGGERS is a
cons cell of 2 characters."
:repeat change
(unless buffer-read-only
(let ((modified (buffer-modified-p)))
(insert "f")
(let ((evt (read-event
(format "Insert %c to exit insert state" ?d)
nil 0.1)))
(let ((modified (buffer-modified-p))
(first (car triggers))
(second (cdr triggers)))
(insert first)
(let* ((evt (read-event
(format "Insert %c to exit insert state" second)
nil spacemacs-normal-state-sequence-delay)))
(cond
((null evt)
(message ""))
((and (integerp evt)
(char-equal evt ?d))
(char-equal evt second))
;; remove the f character
(delete-char -1)
(set-buffer-modified-p modified)
(funcall callback))
(t ; otherwise
(setq unread-command-events (append unread-command-events
(list evt)))))))))
(t ; otherwise
(setq unread-command-events
(append unread-command-events (list evt)))))))))
;; load evil-leader
(use-package evil-leader
:init