Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow god-literal-key to be toggled #159

Merged
merged 3 commits into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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)))))
darth10 marked this conversation as resolved.
Show resolved Hide resolved
(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))))))
darth10 marked this conversation as resolved.
Show resolved Hide resolved
(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