Skip to content

Commit

Permalink
Allow god-literal-key to be toggled (#159)
Browse files Browse the repository at this point in the history
Allow god-literal-key to be toggled

---------

Co-authored-by: federkamm <federkamm@email.invalid>
Co-authored-by: Akhil Wali <akhil.wali.10@gmail.com>
  • Loading branch information
3 people authored Aug 12, 2024
1 parent 607aff1 commit 9ace725
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 26 deletions.
3 changes: 2 additions & 1 deletion .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,11 @@ This package defines the following key mappings:

* The literal key (<kbd>SPC</kbd>) is sticky. This means you don't have to enter
<kbd>SPC</kbd> repeatedly for key bindings such as <kbd>C-x</kbd> <kbd>r</kbd> <kbd>t</kbd>.
Entering the literal key again toggles its state.
The literal key can be changed through `god-literal-key`. Here are some examples:

* <kbd>x</kbd> <kbd>SPC</kbd> <kbd>r</kbd> <kbd>t</kbd> → <kbd>C-x</kbd> <kbd>r</kbd> <kbd>t</kbd>
* <kbd>x</kbd> <kbd>SPC</kbd> <kbd>r</kbd> <kbd>y</kbd> → <kbd>C-x</kbd> <kbd>r</kbd> <kbd>y</kbd>
* <kbd>x</kbd> <kbd>SPC</kbd> <kbd>r</kbd> <kbd>SPC</kbd> <kbd>g</kbd> <kbd>w</kbd> → <kbd>C-x</kbd> <kbd>r</kbd> <kbd>M-w</kbd>

* <kbd>g</kbd> is used to indicate the meta modifier (<kbd>M-</kbd>). This means
that there is no way to enter <kbd>C-g</kbd> in God mode, and you must
Expand Down
6 changes: 6 additions & 0 deletions features/c-commands.feature
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ Feature: C- commands
When I send the key sequence "c SPC b e g"
Then the cursor should be at point "1"

Scenario: toggle god-literal-key
Given I bind "C-c k M-l" to "beginning-of-buffer"
And I go to end of buffer
When I send the key sequence "c SPC k SPC g l"
Then the cursor should be at point "1"

Scenario: execute commands with C-arrow
Given I bind "C-x C-<left>" to "backward-word"
And I go to line "1"
Expand Down
46 changes: 21 additions & 25 deletions god-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ If it was not active when `god-local-mode-pause' was called, nothing happens."
"Enable `god-local-mode' on all buffers.")

(defvar god-literal-sequence nil
"Activated after `god-literal-key' is pressed in a command sequence.")
"Toggled when `god-literal-key' is pressed in a command sequence.")

;;;###autoload
(defun god-mode ()
Expand Down Expand Up @@ -308,38 +308,34 @@ from the command loop."
"Interpret god-mode special keys for KEY.
Consumes more keys if appropriate.
Appends to key sequence KEY-STRING-SO-FAR."
(let ((key-consumed t) (next-modifier "") next-key)
(let ((modifier "")
(next-key (lambda () (god-mode-sanitized-key-string (read-event key-string-so-far)))))
(message key-string-so-far)
(cond
;; Don't check for `god-literal-key' with the first key.
((and key-string-so-far (string= key god-literal-key))
(setq god-literal-sequence t))
(god-literal-sequence
(setq key-consumed nil))
((and (stringp key) (assoc key god-mode-alist))
(setq next-modifier (cdr (assoc key god-mode-alist))))
(t
(setq key-consumed nil
next-modifier (cdr (assoc nil god-mode-alist)))))
(setq next-key
(if key-consumed
(god-mode-sanitized-key-string (read-event key-string-so-far))
key))
(if (and key-string-so-far (string= next-key (format "%c" help-char)))
(god-mode-help-char-dispatch next-key key-string-so-far)
(when (and (= (length next-key) 1)
(string= (get-char-code-property (aref next-key 0) 'general-category) "Lu")
(when key-string-so-far ; Don't check for `god-literal-key' with the first key.
(while (string= key god-literal-key)
(setq god-literal-sequence (not god-literal-sequence)
key (funcall next-key))))
(unless god-literal-sequence
(let ((modifier-lookup (and (stringp key) (assoc key god-mode-alist))))
(if modifier-lookup
(setq modifier (cdr modifier-lookup)
key (funcall next-key))
(setq modifier (cdr (assoc nil god-mode-alist))))))
(if (and key-string-so-far (string= key (format "%c" help-char)))
(god-mode-help-char-dispatch key key-string-so-far)
(when (and (= (length key) 1)
(string= (get-char-code-property (aref key 0) 'general-category) "Lu")
;; If C- is part of the modifier, S- needs to be given
;; in order to distinguish the uppercase from the
;; lowercase bindings. If C- is not in the modifier,
;; then emacs natively treats uppercase differently
;; from lowercase, and the S- modifier should not be
;; supplied.
(string-prefix-p "C-" next-modifier))
(setq next-modifier (concat next-modifier "S-")))
(string-prefix-p "C-" modifier))
(setq modifier (concat modifier "S-")))
(if key-string-so-far
(concat key-string-so-far " " next-modifier next-key)
(concat next-modifier next-key)))))
(concat key-string-so-far " " modifier key)
(concat modifier key)))))

(defun god-mode-lookup-command (key-string)
"Execute extended keymaps in KEY-STRING, or call it if it is a command."
Expand Down

0 comments on commit 9ace725

Please sign in to comment.