Skip to content

Commit

Permalink
Merge pull request #4 from countvajhula/evil-in-buffer-states
Browse files Browse the repository at this point in the history
Use evil backend instead of hydra for in-buffer modes
  • Loading branch information
countvajhula authored Mar 19, 2021
2 parents 0781bab + 49a57ed commit 36ebf02
Show file tree
Hide file tree
Showing 18 changed files with 683 additions and 429 deletions.
28 changes: 19 additions & 9 deletions chimera.el
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,39 @@
name
(enter nil :documentation "Primitive mode entry function.") ; this is required
(exit nil :documentation "Primitive mode exit function.") ; we don't need to rely on exit being defined
(pre-entry-hook nil)
(entry-hook nil)
(exit-hook nil)
(post-exit-hook nil)
(manage-hooks nil
:documentation "Whether hooks should be managed internally. \
:documentation "Whether within-mode hooks should be managed internally. \
If not, they are expected to be run by the underlying mode provider \
(e.g. evil or hydra)."))
(e.g. evil or hydra). Wrapping hooks (pre-entry and post-exit) are \
always managed by chimera."))

(defvar chimera-evil-states
(list "normal" "insert" "emacs" "visual" "replace"))
(list "normal" "insert" "emacs" "visual" "replace" "word" "line" "char" "symex"))

(defvar chimera-insertion-states
(list "insert" "emacs"))

(defun chimera-enter-mode (mode)
"Enter MODE."
(interactive)
(let ((name (chimera-mode-name mode)))
;; call a function (perform-entry-actions ...) that
;; handles any provider-specific jankiness, like checking
;; for hydras that didn't exit cleanly, and perform their
;; exit actions (which should be in a dedicated function
;; that can be called from here as well as the original
;; spot in the hydra exit lifecycle phase).
;; TODO: maybe call a function (perform-entry-actions ...) that
;; handles any provider-specific jankiness, like checking for
;; hydras that didn't exit cleanly, and perform their exit actions
;; (which should be in a dedicated function that can be called
;; from here as well as the original spot in the hydra exit
;; lifecycle phase).
;; we're using evil state variables to keep track of state (even
;; for non-evil backed modes), so ensure that the evil state is
;; entered here
(unless (member name chimera-evil-states)
(let ((evil-state-entry (intern (concat "evil-" name "-state"))))
(funcall evil-state-entry)))
(run-hooks (chimera-mode-pre-entry-hook mode))
(funcall (chimera-mode-enter mode))
(when (chimera-mode-manage-hooks mode)
;; for now, we rely on evil hooks for all modes (incl.
Expand Down
2 changes: 2 additions & 0 deletions rigpa-activity-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
(defvar chimera-activity-mode
(make-chimera-mode :name "activity"
:enter #'hydra-activity/body
:pre-entry-hook 'chimera-activity-mode-entry-hook
:post-exit-hook 'chimera-activity-mode-exit-hook
:entry-hook 'evil-activity-state-entry-hook
:exit-hook 'evil-activity-state-exit-hook))

Expand Down
2 changes: 2 additions & 0 deletions rigpa-application-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@
(defvar chimera-application-mode
(make-chimera-mode :name "application"
:enter #'hydra-application/body
:pre-entry-hook 'chimera-application-mode-entry-hook
:post-exit-hook 'chimera-application-mode-exit-hook
:entry-hook 'evil-application-state-entry-hook
:exit-hook 'evil-application-state-exit-hook))

Expand Down
2 changes: 2 additions & 0 deletions rigpa-buffer-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ current ('original') buffer."
(defvar chimera-buffer-mode
(make-chimera-mode :name "buffer"
:enter #'hydra-buffer/body
:pre-entry-hook 'chimera-buffer-mode-entry-hook
:post-exit-hook 'chimera-buffer-mode-exit-hook
:entry-hook 'evil-buffer-state-entry-hook
:exit-hook 'evil-buffer-state-exit-hook))

Expand Down
275 changes: 151 additions & 124 deletions rigpa-char-mode.el
Original file line number Diff line number Diff line change
@@ -1,82 +1,109 @@
(require 'chimera)
(require 'chimera-hydra)
(require 'rigpa-evil-support)

(defvar rigpa-char-mode-map (make-sparse-keymap))

(define-minor-mode rigpa-char-mode
"Minor mode to modulate keybindings in rigpa char mode."
:lighter "char"
:keymap rigpa-char-mode-map)

(evil-define-state char
"Char state."
:tag " <X> "
:message "-- CHAR --"
;;:cursor ;; inherit from normal
;;:exit-hook ;; none
;;:suppress-keymap) ;; should be t, but probably inherits from normal
:enable (normal))

(defun rigpa-char-info ()
"Info on character"
(interactive)
(what-cursor-position))

(defun rigpa-char-delete ()
"Delete character"
(evil-define-command rigpa-char-move-left (count)
"Move character left."
(interactive "p")
(forward-char)
(transpose-chars (- count))
(backward-char))

(defun rigpa-char-move-left-more ()
"Move character left more."
(interactive)
(rigpa-char-move-left 3))

(defun rigpa-char-move-left-most ()
"Move character left most."
(interactive)
(evil-delete-char (point) (1+ (point)))
(beginning-of-line)
(evil-paste-before nil nil)
(backward-char))

(evil-define-command rigpa-char-move-right (count)
"Move character right."
(interactive "p")
(forward-char)
(transpose-chars count)
(backward-char))

(defun rigpa-char-move-right-more ()
"Move character right more."
(interactive)
(evil-delete-char (point)
(+ (point) 1)
(quote exclusive) nil))
(rigpa-char-move-right 3))

;; TODO: seems to vary depending on the value of evil-move-cursor-back
(defun rigpa-char-move-left (&optional superlative)
"Move character left"
(defun rigpa-char-move-right-most ()
"Move character right most."
(interactive)
(when (not (bolp))
(rigpa-char-delete)
(let ((at-eol (eolp)))
(cond ((eq superlative nil) (evil-backward-char))
((eq superlative 'more) (evil-backward-char 3))
((eq superlative 'most) (evil-beginning-of-line)))
(if at-eol
;; for some reason delete-char doesn't update point
;; while in hydra at EOL, so the handling here
;; is different than it otherwise would be
(if (bolp)
(evil-paste-before nil nil)
(progn (evil-paste-after nil nil)
(backward-char)))
(evil-paste-before nil nil)))))

(defun rigpa-char-move-right (&optional superlative)
"Move character right"
(evil-delete-char (point) (1+ (point)))
(end-of-line)
(evil-paste-after nil nil))

(evil-define-command rigpa-char-move-down (count)
"Move character down."
(interactive "p")
(evil-delete-char (point) (1+ (point)))
(evil-next-line count)
(evil-paste-before nil nil)
(backward-char))

(defun rigpa-char-move-down-more ()
"Move character down more."
(interactive)
(rigpa-char-move-down 3))

(defun rigpa-char-move-down-most ()
"Move character down most."
(interactive)
(when (not (eolp))
(rigpa-char-delete)
(cond ((eq superlative 'more)
(condition-case nil
(evil-forward-char 2)
(error nil)))
((eq superlative 'most) (evil-end-of-line)))
(evil-paste-after nil nil)
;; Note: The above is sufficient when this command is run
;; interactively via M-x. But when run via the hydra, it
;; moves point forward an extra character. Not sure why this
;; happens but since hydra is the main entry point to this,
;; adding the line below for usage via hydra.
(let ((orig-column (current-column)))
(evil-delete-char (point) (1+ (point)))
(goto-char (nth 1 (evil-inner-paragraph)))
(evil-previous-line)
(evil-goto-column orig-column)
(evil-paste-before nil nil)
(backward-char)))

(defun rigpa-char-move-down (&optional superlative)
"Move character down"
(evil-define-command rigpa-char-move-up (count)
"Move character up."
(interactive "p")
(evil-delete-char (point) (1+ (point)))
(evil-previous-line count)
(evil-paste-before nil nil)
(backward-char))

(defun rigpa-char-move-up-more ()
"Move character up more."
(interactive)
(rigpa-char-delete)
(cond ((eq superlative nil) (evil-next-line))
((eq superlative 'more) (evil-next-line 3))
((eq superlative 'most) (evil-forward-paragraph)))
(evil-paste-before nil nil))

(defun rigpa-char-move-up (&optional superlative)
"Move character up"
(rigpa-char-move-up 3))

(defun rigpa-char-move-up-most ()
"Move character up most."
(interactive)
(rigpa-char-delete)
(cond ((eq superlative nil) (evil-previous-line))
((eq superlative 'more) (evil-previous-line 3))
((eq superlative 'most) (evil-backward-paragraph)))
(evil-paste-before nil nil))
(let ((orig-column (current-column)))
(evil-delete-char (point) (1+ (point)))
(goto-char (nth 0 (evil-inner-paragraph)))
(evil-goto-column orig-column)
(evil-paste-before nil nil)
(backward-char)))

(defun rigpa-char-change ()
"Change character"
Expand All @@ -86,82 +113,82 @@
(quote exclusive)
nil))

(defun rigpa-char-yank ()
(evil-define-operator rigpa-char-yank (beg end type register yank-handler)
"Yank (copy) character"
(interactive)
(evil-yank-characters (point) (+ (point) 1)))

(defun rigpa-char-toggle-case ()
"Toggle upper-/lower-case"
(interactive)
(evil-invert-char (point) (+ (point) 1) (quote exclusive)))

(defhydra hydra-char (:columns 4
:post (chimera-hydra-portend-exit chimera-char-mode t)
:after-exit (chimera-hydra-signal-exit chimera-char-mode
#'chimera-handle-hydra-exit))
"Character mode"
("h" evil-backward-char "left")
("j" evil-next-line "down")
("k" evil-previous-line "up")
("l" evil-forward-char "right")
("C-h" (lambda ()
(interactive)
(evil-backward-char 3)) "more left")
("C-j" (lambda ()
(interactive)
(evil-next-line 3)) "more down")
("C-k" (lambda ()
(interactive)
(evil-previous-line 3)) "more up")
("C-l" (lambda ()
(interactive)
(evil-forward-char 3)) "more right")
("M-h" (lambda ()
(interactive)
(evil-beginning-of-line)) "most left")
("M-j" (lambda ()
(interactive)
(evil-forward-paragraph)
(evil-previous-line)) "most down")
("M-k" (lambda ()
(interactive)
(evil-backward-paragraph)
(evil-next-line)) "most up")
("M-l" (lambda ()
(interactive)
(evil-end-of-line)) "most right")
("H" rigpa-char-move-left "move left")
("J" rigpa-char-move-down "move down")
("K" rigpa-char-move-up "move up")
("L" rigpa-char-move-right "move right")
("C-S-h" (lambda () (interactive) (rigpa-char-move-left 'more)) "move left more")
("C-S-j" (lambda () (interactive) (rigpa-char-move-down 'more)) "move down more")
("C-S-k" (lambda () (interactive) (rigpa-char-move-up 'more)) "move up more")
("C-S-l" (lambda () (interactive) (rigpa-char-move-right 'more)) "move right more")
("M-H" (lambda () (interactive) (rigpa-char-move-left 'most)) "move to far left")
("M-J" (lambda () (interactive) (rigpa-char-move-down 'most)) "move to bottom")
("M-K" (lambda () (interactive) (rigpa-char-move-up 'most)) "move to top")
("M-L" (lambda () (interactive) (rigpa-char-move-right 'most)) "move to far right")
("c" rigpa-char-change "change" :exit t)
("y" rigpa-char-yank "yank (copy)" :exit t)
("x" rigpa-char-delete "delete")
("~" rigpa-char-toggle-case "toggle case")
("i" rigpa-char-info "info" :exit t)
("?" rigpa-char-info "info" :exit t)
("H-m" rigpa-toggle-menu "show/hide this menu")
("<return>" rigpa-enter-lower-level "enter lower level" :exit t)
("<escape>" rigpa-enter-higher-level "escape to higher level" :exit t))
:motion evil-forward-char
(evil-yank beg end type register yank-handler))

(defvar rigpa--char-mode-keyspec
'(("h" . evil-backward-char)
("j" . evil-next-line)
("k" . evil-previous-line)
("l" . evil-forward-char)
("c" . evil-substitute)
("y" . rigpa-char-yank)
("C-h" . (lambda ()
(interactive)
(evil-backward-char 3)))
("C-j" . (lambda ()
(interactive)
(evil-next-line 3)))
("C-k" . (lambda ()
(interactive)
(evil-previous-line 3)))
("C-l" . (lambda ()
(interactive)
(evil-forward-char 3)))
("M-h" . (lambda ()
(interactive)
(evil-beginning-of-line)))
("M-j" . (lambda ()
(interactive)
(evil-forward-paragraph)
(evil-previous-line)))
("M-k" . (lambda ()
(interactive)
(evil-backward-paragraph)
(evil-next-line)))
("M-l" . (lambda ()
(interactive)
(evil-end-of-line)))
("H" . rigpa-char-move-left)
("J" . rigpa-char-move-down)
("K" . rigpa-char-move-up)
("L" . rigpa-char-move-right)
("?" . rigpa-char-info)
("C-S-h" . rigpa-char-move-left-more)
("C-S-j" . rigpa-char-move-down-more)
("C-S-k" . rigpa-char-move-up-more)
("C-S-l" . rigpa-char-move-right-more)
("M-H" . rigpa-char-move-left-most)
("M-J" . rigpa-char-move-down-most)
("M-K" . rigpa-char-move-up-most)
("M-L" . rigpa-char-move-right-most))
"Key specification for rigpa char mode.")

(rigpa--define-evil-keys-from-spec rigpa--char-mode-keyspec
rigpa-char-mode-map
'char)

(defvar chimera-char-mode-entry-hook nil
"Entry hook for rigpa char mode.")

(defvar chimera-char-mode-exit-hook nil
"Exit hook for rigpa char mode.")

(defun rigpa--enable-char-minor-mode ()
"Enable char minor mode."
(rigpa-char-mode 1))

(defun rigpa--disable-char-minor-mode ()
"Disable char minor mode."
(rigpa-char-mode -1))

(defvar chimera-char-mode
(make-chimera-mode :name "char"
:enter #'hydra-char/body
:enter #'evil-char-state
:pre-entry-hook 'chimera-char-mode-entry-hook
:post-exit-hook 'chimera-char-mode-exit-hook
:entry-hook 'evil-char-state-entry-hook
:exit-hook 'evil-char-state-exit-hook))

Expand Down
Loading

0 comments on commit 36ebf02

Please sign in to comment.