71 / dance

Make your cursors dance with Kakoune-like modal editing in VS Code.
https://marketplace.visualstudio.com/items?itemName=gregoire.dance
ISC License
440 stars 56 forks source link

Option keys not usable as mappings on macOS #18

Open timjs opened 4 years ago

timjs commented 4 years ago

On macOS the alt/option key is used as a second shift like key: one can enter special characters as ∂, ƒ, ¬, ø (option+d, option+f, option+l, option+o). Problematic are the keys option+\``,option+e,option+u,option+i, option+n which are dead keys to compose diacritics like è, é, ë, ê and ñ. These can't be used to map Kakoune/Dance chords.

This solution only adds support to use option as meta in the terminal emulator of VSCode. Using something like this in the editor is currently not supported and should probably be fixed in core VSCode.

71 commented 4 years ago

This probably requires separate key bindings, but fortunately https://github.com/microsoft/vscode/pull/54894 makes this very easy. However we have a bigger problem for international layouts and Chrome OS.

71 commented 4 years ago

Out of curiosity, how does it work in Kakoune?

timjs commented 4 years ago

I'm affraid separate key bindings for macOS won't work. The problem is more fundamental, namely that you're simply not able to bind anything to option+e/u/i/n because it produces a dead character. I.e. to type é in any text field on macOS, you first hit option+e which gives you the ´, and then e. The OS merges the two into é.

It works in Kakoune, because the macOS Terminal app (and other third party terminal apps) provide a setting to interpret the option key as the meta key.

timjs commented 4 years ago

The solution is as follows. The editorTextFocus condition in the keybindings kind of triggers this issue. By removing it, everything works.

So when the keybinding is defined as follows:

  {
    "key": "alt+e",
    "command": "dance.select.word.alt.end",
    "when": "dance.mode == 'normal'"
  },

everything is all right. This holds for commands bound to alt+e/u/i/n and alt+backtick on macOS.

71 commented 4 years ago

I'm okay with removing editorTextFocus, but won't it have side effects?

timjs commented 4 years ago

Yeah, it will have side effects. I think you'll be allowed to fire the shortcut regardless of the focus. So when your editing your commit message in a Git side-bar, and hit alt+e, the editor will react.

Conclusion: it will introduce new "bugs". Question: are they worth it? If we remove the editorTextFocus we should only do this for alt+e/u/i/n and alt+backtick and only on macOS I think.

71 commented 4 years ago

We can always make this optional by providing alternate keybindings in layouts/. It would be nice if this was generated automatically (e.g by adding flags in commands/commands.yaml) rather than by hand, though.

timjs commented 4 years ago

Conclusion: it will introduce new "bugs". Question: are they worth it? If we remove the editorTextFocus we should only do this for alt+e/u/i/n and alt+backtick and only on macOS I think.

Experimented a bit more with this. Sadly doesn't work in every case. I recommend users to switch to the keyboard layout "Unicode Hex-input", which doesn't have dead keys under the option key. Closing this for now. If anybody has a more sustainable solution, please let us know!

bfulop commented 2 years ago

I wanted to share my workaround:

I'm using Karabiner to remap option to control-option and updated all the shortcuts in VScode.

In the end I went even further. I remapped spacebar to control-option when pressed together with another key and to space when pressed alone.

Here's what the setup looks like in Karabiner Elements.

{
                        "description": "Change spacebar to control+alt in VScode for Dance actions",
                        "manipulators": [
                            {
                                "conditions": [
                                    {
                                        "bundle_identifiers": [
                                            "com\\.microsoft\\.VSCode",
                                            "com\\.microsoft\\.VSCodeInsiders"
                                        ],
                                        "type": "frontmost_application_if"
                                    }
                                ],
                                "from": {
                                    "key_code": "spacebar",
                                    "modifiers": {}
                                },
                                "parameters": {
                                    "basic.to_if_alone_timeout_milliseconds": 240,
                                    "basic.to_if_held_down_threshold_milliseconds": 5
                                },
                                "to_if_alone": [
                                    {
                                        "key_code": "spacebar"
                                    }
                                ],
                                "to_if_held_down": [
                                    {
                                        "key_code": "left_control",
                                        "modifiers": ["left_option"]
                                    }
                                ],

                                "type": "basic"
                            }
                        ]
                    }

In my experience this is what the timeouts mean:

basic.to_if_alone_timeout_milliseconds → the maximum time you have to finish pressing and then releasing the spacebar to be registered.

basic.to_if_held_down_threshold_milliseconds → the minimum time the spacebar has to be pressed down to be considered as a modifier key. If you press the second key sooner than this timeout, it will not work.

71 commented 2 years ago

Reviving this -- I'm working on updated keybindings for Dance on Mac (and for alternative keyboard layouts). Given that the user will have a set-up step where they'll choose their layout and OS, what do you think should be changed to make Dance friendlier to macOS? Ideally we wouldn't need system-wide changes or Karabiner.

Spirarel commented 1 year ago

@71 apologies if this has been discussed elsewhere; I didn't see it.

Has there been any progress on implementing a set-up step? I'm happy to test if it's in dev and not released yet.

what do you think should be changed to make Dance friendlier to macOS?

Probably a setting to remap alt to space or something similar, app-wide. Like how in vim you can set leader.

max-sixty commented 1 year ago

I'm just trying out Dance, and hitting this.

This might be a basic question — but how does vscodevim succeed at this?

71 commented 1 year ago

I'm not even sure whether there are commands in Vim that use Alt+I or similar bindings (that don't work on Mac). I just switched to a Mac and I'm much more familiar with the Compose Key, so I disable Option+I (and others) and just use the compose key for accented characters. I switched to the "Unicode Hex Input" layout for that, but I've seen other ways to disable Option+....

max-sixty commented 1 year ago

I switched to the "Unicode Hex Input"

The problem with this is that it seems to be QWERTY only...

71 commented 1 year ago

@max-sixty Yes, but there are other ways of doing this. One promising way is to use Ukulele (or something similar) to create a copy of whatever keyboard layout you want but without the keys bound to Option+; you might even find existing layouts built this way online. I haven't tried these solutions though (since I'm on Qwerty using "Unicode Hex Input" is good enough), so I won't recommend anything in particular.

max-sixty commented 1 year ago

Hope it's OK to come back to this

I'm not even sure whether there are commands in Vim that use Alt+I or similar bindings (that don't work on Mac).

Here's a quick example — in vscode I have a custom shortcut:

  {
    "key": "alt+d",
    "command": "editor.action.addSelectionToNextFindMatch",
    "when": "editorFocus"
  },

When I have this set,alt+d selects the next match. When I don't have it selected, it enters the character. So somehow things are able to grab alt+X shortcuts.

...indeed, I get 23 matches for "alt\+\w" in the default shortcuts page.

(I wish I could be more helpful than "here's something that does it", I realize it's not nearly as helpful as understanding how...)

merlindru commented 1 year ago

I've been using Dance on VSCode for a while now and it's working out really well.

There are two things you can do:

This SO question lists multiple options for creating your own keyboard layout.

TL;DR: Use Ukulele. If you're on QWERTY, someone left their fixed layout in the comments. (But in that case, why not use the "Unicode Hex Input" keyboard layout already provided by MacOS?)

71 commented 1 year ago

@max-sixty Oh that's a great point, but I don't know how that works exactly and how the OS chooses which keybindings you can override and which ones you cannot.

niklasravnsborg commented 7 months ago

I've also stumbled upon this and tried a few solutions. Nothing seems ideal. I have my own keyboard layout made with Ukelele and I need the alt key for some text input of special characters...

Reviving this -- I'm working on updated keybindings for Dance on Mac (and for alternative keyboard layouts). Given that the user will have a set-up step where they'll choose their layout and OS, what do you think should be changed to make Dance friendlier to macOS? Ideally we wouldn't need system-wide changes or Karabiner.

Thank you, @71! Could you make any progress on this since last summer?

niklasravnsborg commented 7 months ago

Update: activating the VSCode setting terminal.integrated.macOptionIsMeta fixes the problem for me. I can continue using a key layout with special characters mapped on Alt/Option, and it works in the editor as well.

max-sixty commented 4 months ago

Update: activating the VSCode setting terminal.integrated.macOptionIsMeta fixes the problem for me. I can continue using a key layout with special characters mapped on Alt/Option, and it works in the editor as well.

This works well!

FWIW it doesn't work for all keys — e.g. o-u — though I think that's a VS Code / Chromium issue.