helix-editor / helix

A post-modern modal text editor.
https://helix-editor.com
Mozilla Public License 2.0
33.62k stars 2.5k forks source link

Alt(Opt)+_ keymaps do Not work on macOS #2280

Open ethanmsl opened 2 years ago

ethanmsl commented 2 years ago

Summary

None of the Alt+ (opt+) keys work on Mac.

Combining experiences (from Matrix chat and testing) neither on Intel nor M1 macs. And neither OSX_11 nor OSX_12. And in neither in default_OSX_terminal nor iTerm2.

iTerm2 allows remapping of Alt/Opt to send an escape code instead. Doing this seems to fix it here. (process outlined here:: https://www.clairecodes.com/blog/2018-10-15-making-the-alt-key-work-in-iterm2/). Though I'm not sure if it causes any other issues.

Note: Alt/Opt does not work by default in iTerm2, but it DOES work by default in the default_osXterminal -- however the Alt/Opt+ does not work in Helix in EITHER.

Reproduction Steps

I tried this: Any of the Alt+_ key sequences are sufficient for testing. Alt+` is a simple one, as it sends a selection to uppercase. Alt+. (repeat last motion) is another simple one.

I expected this to happen: The listed commands to work.

Instead, this happened: Standard behavior or nothing. (in cases where a combining mark would be produced (e.g. Alt+` or Alt+u, which create ` or ¨, respectively the highlighted combining mark is produced even though Helix is in Normal_Mode...)

Alt+` leads to accent in Normal Mode

Helix log

2022-04-25T06:08:09.677 helix_view::editor [ERROR] Failed to initialize the LSP for source.julia { cannot find binary path } 2022-04-25T07:45:54.383 helix_view::editor [ERROR] Failed to initialize the LSP for source.toml { LSP not defined } 2022-04-25T21:42:53.303 helix_view::theme [WARN] Theme: invalid style attribute: modifier 2022-04-25T21:43:18.683 helix_view::theme [WARN] Theme: malformed hexcode: fg 2022-04-25T21:43:18.683 helix_view::theme [WARN] Theme: malformed hexcode: form 2022-04-25T21:43:54.696 helix_view::theme [WARN] Theme: malformed hexcode: light-white 2022-04-25T21:44:44.544 helix_view::editor [ERROR] Failed to initialize the LSP for source.python { cannot find binary path } 2022-04-25T21:45:15.281 helix_view::theme [WARN] Theme: malformed hexcode: light-white 2022-04-25T21:46:12.776 helix_view::theme [WARN] Theme: malformed hexcode: foreground 2022-04-25T21:46:12.777 helix_view::theme [WARN] Theme: invalid style attribute: Modifiers 2022-04-25T21:46:12.777 helix_view::theme [WARN] Theme: malformed hexcode: grey3 2022-04-25T21:46:12.777 helix_view::theme [WARN] Theme: malformed hexcode: pink 2022-04-25T21:46:45.319 helix_view::theme [WARN] Theme: invalid style attribute: modifier 2022-04-25T21:47:35.998 helix_view::theme [WARN] Theme: malformed hexcode: light-white 2022-04-25T21:47:48.178 helix_view::theme [WARN] Theme: malformed hexcode: form 2022-04-25T21:47:48.178 helix_view::theme [WARN] Theme: malformed hexcode: fg 2022-04-25T21:48:26.578 helix_view::theme [WARN] Theme: malformed hexcode: light-white 2022-04-25T23:41:49.234 helix_view::editor [ERROR] Failed to initialize the LSP for source.toml { LSP not defined }

Platform

macOS

Terminal Emulator

default_Version 2.11 (440) && iTerm2_Build_3.4.15

Helix Version

helix 22.03 (d4e45fd4)

the-mikedavis commented 2 years ago

I'm not sure this can be handled within Helix since we're only getting what the terminal sends us for keycodes.

If you start up showkey -a without the fix, what happens when you input Alt-j? For example on linux:

$ showkey -a
Press any keys - Ctrl-D will terminate this program

^[j     27 0033 0x1b       # Alt-j
    106 0152 0x6a
^[k     27 0033 0x1b       # Alt-k
    107 0153 0x6b
^[h     27 0033 0x1b       # Alt-h
    104 0150 0x68
^[l     27 0033 0x1b       # Alt-l
    108 0154 0x6c
^J  10 0012 0x0a           # Ctrl-j
^K  11 0013 0x0b           # Ctrl-k
^H   8 0010 0x08           # Ctrl-h
^L  12 0014 0x0c           # Ctrl-l
^C   3 0003 0x03           # Ctrl-c
^D   4 0004 0x04           # Ctrl-d
tmke8 commented 2 years ago

I'm using linux but I had a similar problem because I configured my left alt key to be used as the level-3 key because I often use level-3 characters on my keyboard layout.

I solved the problem by just mapping the characters that my keyboard layout produces for alt+<something>:

"ó" = "repeat_last_motion"
"ij" = "expand_selection"
"ú" = "shrink_selection"
"ù" = "select_prev_sibling"
"ø" = "select_next_sibling"

(this is for the EurKEY layout)

ethanmsl commented 2 years ago
  1. showkey isn't available on mac (in zsh, bash, or fish).
  2. The C code from http://catb.org/esr/showkey/ can be downloaded, compiled, and run in terminal, but it doesn't output the raw codes.
  3. https://manytricks.com/keycodes/ is an app that gives keycodes on press, but only when you're in that app -- so if there's any nuance going on with the terminal it can't inform you about it

Using the 3rd option above:

(Alt := Option)

If there's a more useful way to acquire and relay these just lmk.

the-mikedavis commented 2 years ago

Actually the best tool to use would be crossterm's event-read example: https://github.com/crossterm-rs/crossterm/blob/09ffd70c30cd28ee06ef6952e40ec5b2b4eaa57f/examples/event-read.rs

That should output the KeyEvents crossterm reads which is what helix is reading.

BGR360 commented 2 years ago

The characters that @ethanmsl provided are the same ones that show up when I run showkey -a on Linux via SSH in iTerm2.

It's also what you get by default when typing in any text input on Mac OS. Mac OS just seems to translate the Alt+<key> presses into other unicode code points.

Here's the whole keyboard:

` 1 2 3 4 5 6 7 8 9 0 - = DELETE ``` ` 96 0140 0x60 # A-` (combining character; not emitted until followed by a second keypress that doesn't combine) ` 96 0140 0x60 # A-~ ¡ 194 0302 0xc2 # A-1 161 0241 0xa1 ⁄ 226 0342 0xe2 # A-! 129 0201 0x81 132 0204 0x84 ™ 226 0342 0xe2 # A-2 132 0204 0x84 162 0242 0xa2 € 226 0342 0xe2 # A-@ 130 0202 0x82 172 0254 0xac £ 194 0302 0xc2 # A-3 163 0243 0xa3 ‹ 226 0342 0xe2 # A-# 128 0200 0x80 185 0271 0xb9 ¢ 194 0302 0xc2 # A-4 162 0242 0xa2 › 226 0342 0xe2 # A-$ 128 0200 0x80 186 0272 0xba ∞ 226 0342 0xe2 # A-5 136 0210 0x88 158 0236 0x9e fi 239 0357 0xef # A-% 172 0254 0xac 129 0201 0x81 § 194 0302 0xc2 # A-6 167 0247 0xa7 fl 239 0357 0xef # A-^ 172 0254 0xac 130 0202 0x82 ¶ 194 0302 0xc2 # A-7 182 0266 0xb6 ‡ 226 0342 0xe2 # A-& 128 0200 0x80 161 0241 0xa1 • 226 0342 0xe2 # A-8 128 0200 0x80 162 0242 0xa2 ° 194 0302 0xc2 # A-* 176 0260 0xb0 ª 194 0302 0xc2 # A-9 170 0252 0xaa · 194 0302 0xc2 # A-( 183 0267 0xb7 º 194 0302 0xc2 # A-0 186 0272 0xba ‚ 226 0342 0xe2 # A-) 128 0200 0x80 154 0232 0x9a – 226 0342 0xe2 # A-<-> 128 0200 0x80 147 0223 0x93 — 226 0342 0xe2 # A-_ 128 0200 0x80 148 0224 0x94 ≠ 226 0342 0xe2 # A-= 137 0211 0x89 160 0240 0xa0 ± 194 0302 0xc2 # A-+ 177 0261 0xb1 ^? 127 0177 0x7f # A- (backspace) ```
TAB q w e r t y u i o p [ ] \ ``` 9 0011 0x09 # A- ^[[Z 27 0033 0x1b # A- 91 0133 0x5b 90 0132 0x5a œ 197 0305 0xc5 # A-q 147 0223 0x93 Œ 197 0305 0xc5 # A-Q 146 0222 0x92 ∑ 226 0342 0xe2 # A-w 136 0210 0x88 145 0221 0x91 „ 226 0342 0xe2 # A-W 128 0200 0x80 158 0236 0x9e ´ 194 0302 0xc2 # A-e (combining character; not emitted until followed by a second keypress that doesn't combine) 180 0264 0xb4 ´ 194 0302 0xc2 # A-E (normal; not a combining character like above) 180 0264 0xb4 ® 194 0302 0xc2 # A-r 174 0256 0xae ‰ 226 0342 0xe2 # A-R 128 0200 0x80 176 0260 0xb0 † 226 0342 0xe2 # A-t 128 0200 0x80 160 0240 0xa0 ˇ 203 0313 0xcb # A-T 135 0207 0x87 \ 92 0134 0x5c # A-y Á 195 0303 0xc3 # A-Y 129 0201 0x81 ¨ 194 0302 0xc2 # A-u (combining character; not emitted until followed by a second keypress that doesn't combine) 168 0250 0xa8 ¨ 194 0302 0xc2 # A-U (normal; not a combining character like above) 168 0250 0xa8 ˆ 203 0313 0xcb # A-i (combining character; not emitted until followed by a second keypress that doesn't combine) 134 0206 0x86 ˆ 203 0313 0xcb # A-I (normal; not a combining character like above) 134 0206 0x86 ø 195 0303 0xc3 # A-o 184 0270 0xb8 Ø 195 0303 0xc3 # A-O 152 0230 0x98 π 207 0317 0xcf # A-p 128 0200 0x80 ∏ 226 0342 0xe2 # A-P 136 0210 0x88 143 0217 0x8f “ 226 0342 0xe2 # A-[ 128 0200 0x80 156 0234 0x9c ” 226 0342 0xe2 # A-{ 128 0200 0x80 157 0235 0x9d ‘ 226 0342 0xe2 # A-] 128 0200 0x80 152 0230 0x98 ’ 226 0342 0xe2 # A-} 128 0200 0x80 153 0231 0x99 « 194 0302 0xc2 # A-\ 171 0253 0xab » 194 0302 0xc2 # A-| 187 0273 0xbb ```
a s d f g h j k l ; ' ENTER ``` å 195 0303 0xc3 # A-a 165 0245 0xa5 Å 195 0303 0xc3 # A-A 133 0205 0x85 ß 195 0303 0xc3 # A-s 159 0237 0x9f Í 195 0303 0xc3 # A-S 141 0215 0x8d ∂ 226 0342 0xe2 # A-d 136 0210 0x88 130 0202 0x82 Î 195 0303 0xc3 # A-D 142 0216 0x8e ƒ 198 0306 0xc6 # A-f 146 0222 0x92 Ï 195 0303 0xc3 # A-F 143 0217 0x8f © 194 0302 0xc2 # A-g 169 0251 0xa9 ˝ 203 0313 0xcb # A-G 157 0235 0x9d ˙ 203 0313 0xcb # A-h 153 0231 0x99 Ó 195 0303 0xc3 # A-H 147 0223 0x93 ∆ 226 0342 0xe2 # A-j 136 0210 0x88 134 0206 0x86 Ô 195 0303 0xc3 # A-J 148 0224 0x94 ˚ 203 0313 0xcb # A-k 154 0232 0x9a  239 0357 0xef # A-K 163 0243 0xa3 191 0277 0xbf ¬ 194 0302 0xc2 # A-l 172 0254 0xac Ò 195 0303 0xc3 # A-L 146 0222 0x92 … 226 0342 0xe2 # A-; 128 0200 0x80 166 0246 0xa6 Ú 195 0303 0xc3 # A-: 154 0232 0x9a æ 195 0303 0xc3 # A-' 166 0246 0xa6 Æ 195 0303 0xc3 # A-" 134 0206 0x86 ^M 13 0015 0x0d # A- and A- ```
z x c v b n m , . / ``` Ω 206 0316 0xce # A-z 169 0251 0xa9 ¸ 194 0302 0xc2 # A-Z 184 0270 0xb8 ≈ 226 0342 0xe2 # A-x 137 0211 0x89 136 0210 0x88 ˛ 203 0313 0xcb # A-X 155 0233 0x9b ç 195 0303 0xc3 # A-c 167 0247 0xa7 Ç 195 0303 0xc3 # A-C 135 0207 0x87 √ 226 0342 0xe2 # A-v 136 0210 0x88 154 0232 0x9a ◊ 226 0342 0xe2 # A-V 151 0227 0x97 138 0212 0x8a ∫ 226 0342 0xe2 # A-b 136 0210 0x88 171 0253 0xab ı 196 0304 0xc4 # A-B 177 0261 0xb1 ˜ 203 0313 0xcb # A-n (combining character; not emitted until followed by a second keypress that doesn't combine) 156 0234 0x9c ˜ 203 0313 0xcb # A-N (normal; not a combining character like above) 156 0234 0x9c µ 194 0302 0xc2 # A-m 181 0265 0xb5 Â 195 0303 0xc3 # A-M 130 0202 0x82 ≤ 226 0342 0xe2 # A-, 137 0211 0x89 164 0244 0xa4 ¯ 194 0302 0xc2 # A-< 175 0257 0xaf ≥ 226 0342 0xe2 # A-. 137 0211 0x89 165 0245 0xa5 ˘ 203 0313 0xcb # A-> 152 0230 0x98 ÷ 195 0303 0xc3 # A-/ 183 0267 0xb7 ¿ 194 0302 0xc2 # A-? 191 0277 0xbf ```
BGR360 commented 2 years ago

So for all the Alt-<key> mappings I can see in the docs, that would give:

[keys.normal]

# Mac Alt-.
"≥" = "repeat_last_motion"

# Mac Alt-` (no way to capture this; Alt-` is the same as `)
# "???" = "switch_to_uppercase"

# Mac Alt-u / Alt-U (no way to capture this; Alt-u is the same as Alt-U)
# "¨" = "earlier"
# "¨" = "later"

# Mac Alt-d
"∂" = "delete_selection_noyank"

# Mac Alt-c
"ç" = "change_selection_noyank"

# Mac Alt-|
"«" = "shell_pipe_to"

# Mac Alt-!
"⁄" = "shell_append_output"

# Mac Alt-s
"" = "split_selection_on_newline"

# Mac Alt-;
"…" = "flip_selections"

# Mac Alt-:
"Ú" = "ensure_selections_forward"

# Mac Alt-,
"≤" = "remove_primary_selection"

# Mac Alt-C
"Ç" = "copy_selection_on_prev_line"

# Mac Alt-(
"·" = "rotate_selection_contents_backward"

# Mac Alt-)
"‚" = "rotate_selection_contents_forward"

# Mac Alt-x
"≈" = "shrink_to_line_bounds"

# Mac Alt-K
"" = "remove_selections"

# Mac Alt-o
"ø" = "expand_selection"

# Mac Alt-i
"ˆ" = "shrink_selection"

# Mac Alt-p
"π" = "select_prev_sibling"

# Mac Alt-n
"˜" = "select_next_sibling"

[keys.insert]

# Mac Alt-d
"∂" = "delete_word_forward"

# Mac Alt-b
"∫" = "move_prev_word_end"

# Mac Alt-f
"ƒ" = "move_next_word_start"

# Mac Alt->
"˘" = "goto_file_end"

# Mac Alt-<
"¯" = "goto_file_start"

EDIT: Hmm... If I use that config (just the [keys.normal) part, I get:

Bad config: data did not match any variant of untagged enum KeyTrie for key `keys.normal` at line 1 column 1
ethanmsl commented 2 years ago

On further reading this what Helix is doing is the standard for most CLI programs. Mac Opt is different than Alt (with behavior like accenting characters). And terminal emulators that support macOS (almost?) invariably have a way to map the key code, typically to "Esc+".

I don't know what the practicality would be for Helix to work with both the default and mapped keycodes. But, minus giving explicit optioning support in program, naively the best path would be to retain current behavior, but (much like documentation reccomends a terminal emulator to get 24-bit colors) note that remapping the Opt_key is commonly done in mac terminal environments to access Alt-key short-cuts.

Given that Helix is especially appealing to terminal newcomers [raises hand] -- that bit of documentation will probably help some users.


For (hopefully) helpful reference here is how you remap Opt in 5 common terminal emulators on macOS.

Opt_key ~~~> ≃Alt_key

star-szr commented 2 years ago

For Alacritty, the main viable option I've seen is doing a bunch of manual mappings, see https://github.com/alacritty/alacritty/issues/62

nikaro commented 2 years ago

My 2 cents, when using Use Option as Meta key in Terminal it solves the problem... but you cannot use option as compose key anymore, and thus typing accents for example.

dcow commented 1 year ago

On further reading this what Helix is doing is the standard for most CLI programs. Mac Opt is different than Alt (with behavior like accenting characters). And terminal emulators that support macOS (almost?) invariably have a way to map the key code, typically to "Esc+".

I don't know what the practicality would be for Helix to work with both the default and mapped keycodes. But, minus giving explicit optioning support in program, naively the best path would be to retain current behavior, but (much like documentation reccomends a terminal emulator to get 24-bit colors) note that remapping the Opt_key is commonly done in mac terminal environments to access Alt-key short-cuts.

Given that Helix is especially appealing to terminal newcomers [raises hand] -- that bit of documentation will probably help some users.

For (hopefully) helpful reference here is how you remap Opt in 5 common terminal emulators on macOS.

Opt_key ~~~> ≃Alt_key

  • iTerm2 (3.4.15) [web reference] : remapping is done via Preferences > Profiles > Keys > General > [radio button interface]

iTerm2 Opt-Remapping
  • Kitty (0.25.1) [web reference] : remapping is done via Preferences > search for max_os_opt_as_alt > uncomment and set to left, right, or both

Kitty Opt-Remapping WezTerm Opt-Remapping (default)
  • Alacritty (0.10.1) [web ≈reference]

    • I was not able to quickly find clear documentation for this. By default, testing with Opt+` in Helix: running the command once did nothing and running it a second time performed the desired action. This seemed to occur regardless of time between key-combo presses, as long as there were no intervening presses. If anyone has info to add on configuring Alacrity keymapping behavior or documentation on the above behavior: please do share. :)
  • "Terminal" macOS_default (2.12.7) [web reference] : remapping is done via Preferences > Profiles > click button at bottom labelled "Use Option as Meta key"

default_terminal Opt-Remapping

It would be awesome to see this linked in the documentation somewhere so that newcomers can quickly move past this issue.

MattWilcox commented 1 year ago

+1 with this issue, and using Warp as the terminal app, but can be fixed by setting the preferences as follows:

Screenshot 2023-01-20 at 10 33 56
joshbainbridge commented 1 year ago

For Alacritty, I think this is relevant. A six year old issue in Alacritty has just been resolved with an upstream change to winit:

https://github.com/alacritty/alacritty/commit/d9ba129e9e722a551cc0cc4c1899c97593ca26b4

This allows the Option key to behave as Alt. An example alacritty.yml will look like:

window:
  # Make `Option` key behave as `Alt` (macOS only):
  #   - OnlyLeft
  #   - OnlyRight
  #   - Both
  #   - None (default)
  option_as_alt: OnlyLeft

Not released yet, but I'd imagine this will be out in the next version. These are the related issues leading to the change:

https://github.com/alacritty/alacritty/issues/62 https://github.com/rust-windowing/winit/pull/2576

rcorre commented 1 year ago

WezTerm (20220408-101518-b908e2dd) [unneeded web reference] : Already mapped by default. 👍

wezterm 20230320-124340-559cb7b0 does not appear to map this by default. I had to add this to my config:

config.send_composed_key_when_left_alt_is_pressed = false
config.send_composed_key_when_right_alt_is_pressed = false

See: https://wezfurlong.org/wezterm/config/keyboard-concepts.html#macos-left-and-right-option-key https://github.com/wez/wezterm/issues/216

ethanmsl commented 1 year ago

@rcorre according to change log 20200620-160318-e00b076c:

The default behavior on these systems is send_composed_key_when_left_alt_is_pressed=false and send_composed_key_when_right_alt_is_pressed=true

Yielding one that defaults to standard alt (left) and one that does mac option (right) by default. You might be someone that sues right alt and it appear broken or the behavior may have drifted from description (in which case I'd file a bug with Wezterm [behavior could be better documented either way!]

rcorre commented 1 year ago

You might be someone that sues right alt and it appear broken

I have control mapped to option, and I'm pressing left control. I guess maybe that sends right-alt somehow?

pascalkuthe commented 6 months ago

see also #2469 for some additional discussion

MatteoCalabro-TomTom commented 6 months ago

+1 with this issue, and using Warp as the terminal app, but can be fixed by setting the preferences as follows:

Screenshot 2023-01-20 at 10 33 56

For some reason, this does not work for me and even in WezTerm Opt-C does not go up one line (opposite of Shift-C)

jukremer commented 1 week ago

For Ghostty: add macos-option-as-alt = left to your config, alternatively you can set it to right or true for both.