Closed gcentauri closed 4 years ago
This isn't exactly a Spacemacs issue, but I'm trying to integrate the xah-fly-keys
package in a layer for an alternative modal map.
I've tested this out using Spacemacs with evil
, and the Spacemacs leader key as SPC
still works. However, I've been unable to determine how this is being accomplished. Perhaps it has something to do with how the evil
keymaps are implemented, and the Spacemacs leader key is defined there?
ofc now that i made an issue, i discovered bind-map
, which I think is how this is probably working :man_shrugging:
Confirmed.
After remembering how to setup xah-fly-keys
😄
In .spacemacs
:
xah-fly-keys
to dotspacemacs-additional-packages
.I remembered that the xah-fly-keys
layer instructions mentioning changing to the emacs
editing style, and to remove the leader key:
https://github.com/gcentauri/xah-fly-keys-layer#install
dotspacemacs-editing-style
to 'emacs
dotspacemacs-leader-key
from "SPC"
to an empty string ""
The instructions also mention:
set dotspacemacs-colorize-cursor-according-to-state nil so that the cursor will reflect the xah-fly-keys state instead.
I tried changing it to nil
but the cursor doesn't change shape/color, so maybe it's specific to the xah-fly-keys
layer, therefore it's not important while testing this.
dotspacemacs/user-config
section:
(require 'xah-fly-keys)
(xah-fly-keys-set-layout "qwerty")
(xah-fly-keys 1)
source: http://ergoemacs.org/misc/ergoemacs_vi_mode.html
Scroll down to the section: MELPA Install
I also found the screenshot of the xah-fly-keys
layout in the section:
What Does Command Mode Do?
That helped with remembering how to navigate 😄
After figuring out how to open a slime repl: M-x slime
The slime buffer prompt opened in xah-fly-keys command mode
.
(should it open in insert mode? then one can start typing directly, or is it more consistent to default to command mode?)
When SPC
is pressed, then it calls slime-autodoc-space
I noticed that the modeline shows the text: adoc
When moving the mouse over the text, then the minibuffer shows: slime-autodoc-mode
I tried disabling the mode: M-x slime-autodoc-mode
And now SPC
calls slime-space
.
C-SPC
works with slime-autodoc-mode
either enabled or disabled.
With slime-autodoc-mode
enabled.
C-h k SPC
shows:
SPC runs the command slime-autodoc-space (found in slime-autodoc-mode-map), which is an interactive compiled Lisp function in ‘slime-autodoc.el’.
It is bound to SPC.
(slime-autodoc-space N)
Like ‘slime-space’ but nicer.
At first I checked the definition for slime-space
:
(" " slime-space)
source: https://github.com/slime/slime/blob/26a79a673a1d0ed2ee3d6346b395aa8ba084ddde/slime.el#L585
I tried rebinding " "
in several slime key maps:
(define-key slime-repl-mode-map (kbd " ") 'xah-fly-leader-key-map)
(define-key slime-autodoc-mode-map (kbd " ") 'xah-fly-leader-key-map)
(define-key slime-doc-map (kbd " ") 'xah-fly-leader-key-map)
(define-key slime-prefix-map (kbd " ") 'xah-fly-leader-key-map)
(define-key slime-parent-map (kbd " ") 'xah-fly-leader-key-map)
(define-key slime-mode-map (kbd " ") 'xah-fly-leader-key-map)
(define-key slime-mode-indirect-map (kbd " ") 'xah-fly-leader-key-map)
but none of them worked.
Then I saw that slime-autodoc-space
was bound with "SPC"
in the slime-autodoc-mode
minor mode definition:
https://github.com/slime/slime/blob/26a79a673a1d0ed2ee3d6346b395aa8ba084ddde/contrib/slime-autodoc.el#L183
And when I tried:
(define-key slime-autodoc-mode-map (kbd "SPC") 'xah-fly-leader-key-map)
(define-key slime-repl-mode-map (kbd "SPC") 'xah-fly-leader-key-map)
Now SPC
opens the xah-fly-keys-leader-key-map
both when slime-autodoc-space
is enabled or disabled.
However it does that in both xah-fly-keys command and insert mode.
Maybe a hook can be used to only apply those key bindings when the xah-fly-keys
command mode is active. You probably know more about how to use hooks.
,
(comma)I also noticed that when the cursor is at the beginning of the slime prompt.
when ,
(comma) is pressed in both command and insert state, then slime-handle-repl-shortcut
gets called.
If another character is typed first, for example a
, then ,
inserts a comma as expected.
It seems to only be an issue at the prompts first position.
thanks for all the work @duianto ! - i really should have put more of that in my original issue.
The main issue really comes down to the fact that xah-fly-keys
is implemented as a minor-mode. There is no proper way to give precedence to minor mode key bindings. It seems that Evil gets around it by using emulation-mode
or something like that. I'm torn whether or not I should just do work-arounds with the xah-fly-keys layer or try to improve the package itself. I'll keep this issue open and report back with what I end up doing to make the modes cooperate better.
I discovered that Spacemacs is using bind-map
to declare the spacemacs leader key in an override map:
(defun spacemacs-bootstrap/init-bind-map ()
(require 'bind-map)
(bind-map spacemacs-default-map
:prefix-cmd spacemacs-cmds
:keys (dotspacemacs-emacs-leader-key)
:evil-keys (dotspacemacs-leader-key)
:override-minor-modes t
:override-mode-name spacemacs-leader-override-mode))
It seems like perhaps bind-map
is responsible for clearing the override of the SPC key in insert
mode and activating it in other modes. I think it is working because Evil defines separate minor modes and bind-map
will only do the override if one of the evil modes is specified here:
(defcustom bind-map-default-evil-states '(normal motion visual)
"Default states for evil bindings."
:group 'bind-map
:type '(repeat symbol))
Unfortunately, as is, I can't figure out a way to use bind map to at least give the xah-fly-keys leader precedence over the other minor mode keymaps.
I came up with a pretty hacky way to make it work without rebinding everything in this commit to the layer: https://github.com/gcentauri/xah-fly-keys-layer/commit/b288808663efb7cf04ce068cd9567c60de849525
I defined a new minor mode xah-fly-keys-command-mode
in the layer which just serves as an indicator that it is active so that bind-map
can give leader-key precedence to SPC
only when that minor mode is active. Without that, SPC acts as a leader key even when in xah-fly-keys
insert mode.
The package only defines one mode and one top level keymap and the bind-key
behavior as used in Spacemacs/Evil depends on the different minor modes being active.
I'd appreciate any insight on how to improve this and respect package ownership in layers. I'm using bind-key
directly because it is required in the spacemacs boostrap process. The funny thing is, if I don't run the bind-map
command until after slime
is loaded, it won't work. I can't quite figure out why. The way I have it now seems to do the trick, but feels "smelly". I can now fire up Spacemacs, open a lisp file, and SPC will act as a leader key in command mode, and turn off in insert mode. It is still slightly funny after opening a Slime REPL, as it will initially insert spaces, but after toggling into command mode again, it works fine. Seems like something about Slime is messing with the minor mode lists?
i found a better way. i think the issue is just that minor modes that are higher up in the order of the minor-mode-map-alist
get precedence over shared bindings. since xah-fly-keys loads early in my configuration, the slime modes get pushed onto the list later and take precedence. i added these lines to re-push the xah-fly-key-map onto it after slime loads. seems slightly hacky but cleaner than before. it also takes care of the ,
binding conflict and allows the slime keys to work as expected in insert mode
(with-eval-after-load 'slime
(push `(xah-fly-keys . ,xah-fly-key-map) minor-mode-map-alist))
(with-eval-after-load 'slime
(push `(xah-fly-keys . ,xah-fly-key-map) minor-mode-map-alist))
This doesn't work for me after upgrade to emacs 27 and the newest version of slime and xah-fly-keys (2020.2.27) For anyone encounters this problem, add this to your init file (after slime and xah-fly-keys):
(with-eval-after-load 'slime-repl
(push `(xah-fly-keys . ,xah-fly-key-map) minor-mode-map-alist))
Description :octocat:
Slime modes steal the xah-fly-keys
SPC
leader key.Reproduction guide :beetle:
Observed behaviour: :eyes: :broken_heart:
invokes one of the
slime-space
functions, and not the xah-fly-keys leaderExpected behaviour: :heart: :smile:
xah-fly-keys leader is used in command mode, slime-space functions in insert mode
System Info :computer:
Backtrace :paw_prints: