Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion evil-ghostel.el
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@
(require 'evil)
(require 'ghostel)

;; ---------------------------------------------------------------------------
;; Customization
;; ---------------------------------------------------------------------------

(defgroup evil-ghostel nil
"Evil-mode integration for ghostel."
:group 'ghostel
:prefix "evil-ghostel-")

(defcustom evil-ghostel-initial-state 'insert
"Initial evil state for new `ghostel-mode' buffers.
Setting this option via `customize-set-variable', `setopt', or the
Customize UI calls `evil-set-initial-state' so the change takes effect
immediately. Users who prefer the raw API can call
`evil-set-initial-state' directly from their config — the registry is
last-writer-wins."
:type '(choice (const :tag "Emacs" emacs)
(const :tag "Insert" insert)
(const :tag "Normal" normal)
(symbol :tag "Other state"))
:set (lambda (sym val)
(set-default-toplevel-value sym val)
(evil-set-initial-state 'ghostel-mode val)))

;; Apply the current value at load. Covers the case where the user set
;; the variable with plain `setq' before loading the package — in that
;; path `defcustom' preserves the value without invoking `:set'.
(evil-set-initial-state 'ghostel-mode evil-ghostel-initial-state)

;; ---------------------------------------------------------------------------
;; Guard predicate
;; ---------------------------------------------------------------------------
Expand Down Expand Up @@ -334,7 +363,6 @@ state transitions."
:keymap evil-ghostel-mode-map
(if evil-ghostel-mode
(progn
(evil-set-initial-state 'ghostel-mode 'insert)
(evil-ghostel--escape-stay)
(add-hook 'evil-normal-state-entry-hook
#'evil-ghostel--normal-state-entry nil t)
Expand Down
32 changes: 32 additions & 0 deletions test/evil-ghostel-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,38 @@ Uses mocks for native functions."
(should-not (memq 'evil-ghostel--insert-state-entry
evil-insert-state-entry-hook))))

;; -----------------------------------------------------------------------
;; Test: initial-state defcustom
;; -----------------------------------------------------------------------

(ert-deftest evil-ghostel-test-initial-state-load-applied ()
"Current value of `evil-ghostel-initial-state' is registered with evil at load."
(should (eq (evil-initial-state 'ghostel-mode)
evil-ghostel-initial-state)))

(ert-deftest evil-ghostel-test-initial-state-custom-set-updates-registry ()
"Setting the option via `customize-set-variable' updates evil's registry."
(let ((orig evil-ghostel-initial-state))
(unwind-protect
(progn
(customize-set-variable 'evil-ghostel-initial-state 'emacs)
(should (eq (evil-initial-state 'ghostel-mode) 'emacs))
(customize-set-variable 'evil-ghostel-initial-state 'normal)
(should (eq (evil-initial-state 'ghostel-mode) 'normal)))
(customize-set-variable 'evil-ghostel-initial-state orig))))

(ert-deftest evil-ghostel-test-mode-activation-preserves-initial-state ()
"Enabling `evil-ghostel-mode' must not clobber the initial-state setting.
Regression guard: the minor-mode body used to call
`evil-set-initial-state' on every activation, overriding user config."
(let ((orig evil-ghostel-initial-state))
(unwind-protect
(progn
(customize-set-variable 'evil-ghostel-initial-state 'emacs)
(evil-ghostel-test--with-evil-buffer
(should (eq (evil-initial-state 'ghostel-mode) 'emacs))))
(customize-set-variable 'evil-ghostel-initial-state orig))))

;; -----------------------------------------------------------------------
;; Test: escape-stay (evil-move-cursor-back disabled)
;; -----------------------------------------------------------------------
Expand Down
Loading