aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--evil-core.el37
1 files changed, 29 insertions, 8 deletions
diff --git a/evil-core.el b/evil-core.el
index 125c166..271dfb0 100644
--- a/evil-core.el
+++ b/evil-core.el
@@ -283,20 +283,41 @@ See also `evil-initial-state'."
(when (setq mode (evil-initial-state mode))
(throw 'done mode)))))
(evil-initial-state major-mode)
+ ;; Check parent modes. Similar to `derived-mode-p'
+ (catch 'state
+ (let ((mode major-mode)
+ checked-modes)
+ (while (and mode (symbolp mode))
+ (when (memq mode checked-modes)
+ (message "Circular reference detected in ancestors of %s\n%s"
+ major-mode checked-modes)
+ (throw 'state nil))
+ (let ((state (evil-initial-state mode)))
+ (when state
+ (throw 'state state)))
+ (push mode checked-modes)
+ (setq mode (get mode 'derived-mode-parent)))
+ nil))
default)))
(defun evil-initial-state (mode &optional default)
- "Return the Evil state to use for MODE.
+ "Return the Evil state to use for MODE or its alias.
Returns DEFAULT if no initial state is associated with MODE.
The initial state for a mode can be set with
`evil-set-initial-state'."
- (let (state modes)
- (catch 'done
- (dolist (entry (evil-state-property t :modes) default)
- (setq state (car entry)
- modes (symbol-value (cdr entry)))
- (when (memq mode modes)
- (throw 'done state))))))
+ (when mode
+ (let ((mode-alias (let ((func (symbol-function mode)))
+ (when (symbolp func)
+ func)))
+ state modes)
+ (catch 'done
+ (dolist (entry (evil-state-property t :modes) default)
+ (setq state (car entry)
+ modes (symbol-value (cdr entry)))
+ (when (or (memq mode modes)
+ (and mode-alias
+ (memq mode-alias modes)))
+ (throw 'done state)))))))
(defun evil-set-initial-state (mode state)
"Set the initial state for MODE to STATE.