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

Set option as meta in MacOS #62

Open
saysjonathan opened this issue Jan 5, 2017 · 35 comments

Comments

Projects
None yet
@saysjonathan
Copy link

commented Jan 5, 2017

iTerm2 and Terminal.app both include the ability to use option as meta. This would be very useful as a boolean option in the config.

@saysjonathan saysjonathan changed the title Ability to set option as meta in MacOS Set option as meta in MacOS Jan 5, 2017

@jwilm

This comment has been minimized.

Copy link
Owner

commented Jan 5, 2017

Sounds reasonable

@jwilm jwilm added the enhancement label Jan 5, 2017

@rhaps0dy

This comment has been minimized.

Copy link

commented Jan 7, 2017

How do you get any key working as Meta in OS X? Using the default config, neither Cmd nor option send meta to tmux or emacs.

@rhaps0dy

This comment has been minimized.

Copy link

commented Jan 7, 2017

As a workaround, I'm adding lines to the config in the following style:

  - { key: T,        mods: Command|Shift, chars: "\x1bT",                }
  - { key: T,        mods: Command, chars: "\x1bt",                      }
  - { key: W,        mods: Command|Shift, chars: "\x1bW",                }
  - { key: W,        mods: Command, chars: "\x1bw",                      }
@casey

This comment has been minimized.

Copy link

commented Feb 20, 2017

For reasons I don't exactly understand, iTerm2 has three options for the behavior of the the option key. Leave it alone, make it set the meta bit, or send the escape key beforehand.

The faq recommends the third option, sending the escape character code beforehand, but doesn't say why.

Does anyone know what that is the recommended choice? I have always had it set the meta bit with no problems.

Asking here because it might mean that the config option should be allow either behavior.

@saysjonathan

This comment has been minimized.

Copy link
Author

commented Feb 20, 2017

I believe this explains why there are two options: http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/meta-bit.html

@tmiller

This comment has been minimized.

Copy link

commented Jul 18, 2017

I was trying to compile a local version to get this to work. I suspect the behavior could be changed here. If the only modifier key being pressed is Alt then use charactersIgnoreingModifiers from NSEvent documented here. However I couldn't get this version of glutin to compile on my machine to verify.

@tmiller

This comment has been minimized.

Copy link

commented Jul 18, 2017

I figured out had to compile glutin with alacrity. Below is the patch that I used in glutin to temporarily enable this feature. I'm not certain it is 100% behaving correctly. @jwilm any recommendations on how you would like this feature implemented?

diff --git a/src/api/cocoa/mod.rs b/src/api/cocoa/mod.rs
index 2282176..6eb0062 100644
--- a/src/api/cocoa/mod.rs
+++ b/src/api/cocoa/mod.rs
@@ -768,7 +768,7 @@ impl GlContext for Window {
 
     #[inline]
     fn swap_buffers(&self) -> Result<(), ContextError> {
-        unsafe { 
+        unsafe {
             let pool = NSAutoreleasePool::new(nil);
             self.context.flushBuffer();
             let _: () = msg_send![pool, release];
@@ -887,7 +887,12 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option<Event> {
         },
         appkit::NSKeyDown => {
             let mut events = VecDeque::new();
-            let received_c_str = nsevent.characters().UTF8String();
+            let ev_mods = event_mods(nsevent);
+
+            let received_c_str = match ev_mods {
+                mods::ALT => nsevent.charactersIgnoringModifiers().UTF8String(),
+                _ => nsevent.characters().UTF8String(),
+            };
             let received_str = CStr::from_ptr(received_c_str);
             let received_str = from_utf8(received_str.to_bytes()).unwrap();
             for received_char in received_str.chars() {
@@ -895,7 +900,6 @@ unsafe fn NSEventToEvent(window: &Window, nsevent: id) -> Option<Event> {
             }
 
             let vkey =  event::vkeycode_to_element(NSEvent::keyCode(nsevent));
-            let ev_mods = event_mods(nsevent);
             events.push_back(Event::KeyboardInput(ElementState::Pressed, NSEvent::keyCode(nsevent) as u8, vkey, ev_mods, Some(received_str.to_owned())));
             let event = events.pop_front();
             window.delegate.state.pending_events.lock().unwrap().extend(events.into_iter());
@aslpavel

This comment has been minimized.

Copy link

commented Jul 18, 2017

I have tried to dig into this problem too, and it looks like it is more or less what iTerm2 does. Maybe we can borrow more stuff from there. Another question is why are we using fork of glutin? It looks like code that you are referring is now resides in winit

@mishchea

This comment has been minimized.

Copy link

commented Oct 2, 2017

For the work-around, how do you figure out what chars to send for a given key/modifiers combination?

@jwilm

This comment has been minimized.

Copy link
Owner

commented Oct 2, 2017

@mishchea it should just be "\x1b" followed by the character. For instance:

  - { key: T,        mods: Command, chars: "\x1bt",                      }
@rlue

This comment has been minimized.

Copy link

commented Nov 28, 2017

If there's anyone who's manually assigned all the mappings themselves as a temporary workaround, would you care to share the relevant portion of your alacritty.yml file to spare the rest of us the tedium? Maybe we could dedicate a wiki page for this purpose, until the feature is available.

@kutsan

This comment has been minimized.

Copy link

commented Nov 28, 2017

@rlue Here is my bindings, feedback is welcome. I can edit it if there is something missing. Control + Alt combinations also work with these lines, no need to include.

I couldn't find a way for keys like Alt + ` (backtick). Alacritty won't open if you add backtick to key. (Thanks goes to @SteVwonder for pointing out the solution. I added these too.)

For other people, if you don't know, you need to put those lines to alacritty.yml, key_bindings: section.

  - { key: A,         mods: Alt,       chars: "\x1ba"                       }
  - { key: B,         mods: Alt,       chars: "\x1bb"                       }
  - { key: C,         mods: Alt,       chars: "\x1bc"                       }
  - { key: D,         mods: Alt,       chars: "\x1bd"                       }
  - { key: E,         mods: Alt,       chars: "\x1be"                       }
  - { key: F,         mods: Alt,       chars: "\x1bf"                       }
  - { key: G,         mods: Alt,       chars: "\x1bg"                       }
  - { key: H,         mods: Alt,       chars: "\x1bh"                       }
  - { key: I,         mods: Alt,       chars: "\x1bi"                       }
  - { key: J,         mods: Alt,       chars: "\x1bj"                       }
  - { key: K,         mods: Alt,       chars: "\x1bk"                       }
  - { key: L,         mods: Alt,       chars: "\x1bl"                       }
  - { key: M,         mods: Alt,       chars: "\x1bm"                       }
  - { key: N,         mods: Alt,       chars: "\x1bn"                       }
  - { key: O,         mods: Alt,       chars: "\x1bo"                       }
  - { key: P,         mods: Alt,       chars: "\x1bp"                       }
  - { key: Q,         mods: Alt,       chars: "\x1bq"                       }
  - { key: R,         mods: Alt,       chars: "\x1br"                       }
  - { key: S,         mods: Alt,       chars: "\x1bs"                       }
  - { key: T,         mods: Alt,       chars: "\x1bt"                       }
  - { key: U,         mods: Alt,       chars: "\x1bu"                       }
  - { key: V,         mods: Alt,       chars: "\x1bv"                       }
  - { key: W,         mods: Alt,       chars: "\x1bw"                       }
  - { key: X,         mods: Alt,       chars: "\x1bx"                       }
  - { key: Y,         mods: Alt,       chars: "\x1by"                       }
  - { key: Z,         mods: Alt,       chars: "\x1bz"                       }
  - { key: A,         mods: Alt|Shift, chars: "\x1bA"                       }
  - { key: B,         mods: Alt|Shift, chars: "\x1bB"                       }
  - { key: C,         mods: Alt|Shift, chars: "\x1bC"                       }
  - { key: D,         mods: Alt|Shift, chars: "\x1bD"                       }
  - { key: E,         mods: Alt|Shift, chars: "\x1bE"                       }
  - { key: F,         mods: Alt|Shift, chars: "\x1bF"                       }
  - { key: G,         mods: Alt|Shift, chars: "\x1bG"                       }
  - { key: H,         mods: Alt|Shift, chars: "\x1bH"                       }
  - { key: I,         mods: Alt|Shift, chars: "\x1bI"                       }
  - { key: J,         mods: Alt|Shift, chars: "\x1bJ"                       }
  - { key: K,         mods: Alt|Shift, chars: "\x1bK"                       }
  - { key: L,         mods: Alt|Shift, chars: "\x1bL"                       }
  - { key: M,         mods: Alt|Shift, chars: "\x1bM"                       }
  - { key: N,         mods: Alt|Shift, chars: "\x1bN"                       }
  - { key: O,         mods: Alt|Shift, chars: "\x1bO"                       }
  - { key: P,         mods: Alt|Shift, chars: "\x1bP"                       }
  - { key: Q,         mods: Alt|Shift, chars: "\x1bQ"                       }
  - { key: R,         mods: Alt|Shift, chars: "\x1bR"                       }
  - { key: S,         mods: Alt|Shift, chars: "\x1bS"                       }
  - { key: T,         mods: Alt|Shift, chars: "\x1bT"                       }
  - { key: U,         mods: Alt|Shift, chars: "\x1bU"                       }
  - { key: V,         mods: Alt|Shift, chars: "\x1bV"                       }
  - { key: W,         mods: Alt|Shift, chars: "\x1bW"                       }
  - { key: X,         mods: Alt|Shift, chars: "\x1bX"                       }
  - { key: Y,         mods: Alt|Shift, chars: "\x1bY"                       }
  - { key: Z,         mods: Alt|Shift, chars: "\x1bZ"                       }
  - { key: Key1,      mods: Alt,       chars: "\x1b1"                       }
  - { key: Key2,      mods: Alt,       chars: "\x1b2"                       }
  - { key: Key3,      mods: Alt,       chars: "\x1b3"                       }
  - { key: Key4,      mods: Alt,       chars: "\x1b4"                       }
  - { key: Key5,      mods: Alt,       chars: "\x1b5"                       }
  - { key: Key6,      mods: Alt,       chars: "\x1b6"                       }
  - { key: Key7,      mods: Alt,       chars: "\x1b7"                       }
  - { key: Key8,      mods: Alt,       chars: "\x1b8"                       }
  - { key: Key9,      mods: Alt,       chars: "\x1b9"                       }
  - { key: Key0,      mods: Alt,       chars: "\x1b0"                       }
  - { key: Space,     mods: Control,   chars: "\x00"                        } # Ctrl + Space
  - { key: Grave,     mods: Alt,       chars: "\x1b`"                       } # Alt + `
  - { key: Grave,     mods: Alt|Shift, chars: "\x1b~"                       } # Alt + ~
  - { key: Period,    mods: Alt,       chars: "\x1b."                       } # Alt + .
  - { key: Key8,      mods: Alt|Shift, chars: "\x1b*"                       } # Alt + *
  - { key: Key3,      mods: Alt|Shift, chars: "\x1b#"                       } # Alt + #
  - { key: Period,    mods: Alt|Shift, chars: "\x1b>"                       } # Alt + >
  - { key: Comma,     mods: Alt|Shift, chars: "\x1b<"                       } # Alt + <
  - { key: Minus,     mods: Alt|Shift, chars: "\x1b_"                       } # Alt + _
  - { key: Key5,      mods: Alt|Shift, chars: "\x1b%"                       } # Alt + %
  - { key: Key6,      mods: Alt|Shift, chars: "\x1b^"                       } # Alt + ^
  - { key: Backslash, mods: Alt,       chars: "\x1b\\"                      } # Alt + \
  - { key: Backslash, mods: Alt|Shift, chars: "\x1b|"                       } # Alt + |
@SteVwonder

This comment has been minimized.

Copy link

commented Nov 28, 2017

@kutsan: #821 and #639 might hold the answer to getting backtick to work. Trying using Grave

@kutsan

This comment has been minimized.

Copy link

commented Nov 28, 2017

@SteVwonder Awesome, thanks! I've added two of them too.

@Asheq

This comment has been minimized.

Copy link

commented Nov 29, 2017

Some additional mappings for useful bash commands like alt-. alt-* and alt-# :

- { key: Period,   mods: Alt,       chars: "\x1b."                       }
- { key: Key8,     mods: Alt|Shift, chars: "\x1b*"                       }
- { key: Key3,     mods: Alt|Shift, chars: "\x1b#"                       }
@valencik

This comment has been minimized.

Copy link

commented Dec 5, 2017

If you're a tmux user and like switching layouts these might be useful as well:

  - { key: Key1,     mods: Alt,     chars: "\x1b1"                       }
  - { key: Key2,     mods: Alt,     chars: "\x1b2"                       }
  - { key: Key3,     mods: Alt,     chars: "\x1b3"                       }
  - { key: Key4,     mods: Alt,     chars: "\x1b4"                       }
  - { key: Key5,     mods: Alt,     chars: "\x1b5"                       }
  - { key: Key6,     mods: Alt,     chars: "\x1b6"                       }
  - { key: Key7,     mods: Alt,     chars: "\x1b7"                       }
  - { key: Key8,     mods: Alt,     chars: "\x1b8"                       }
  - { key: Key9,     mods: Alt,     chars: "\x1b9"                       }
  - { key: Key0,     mods: Alt,     chars: "\x1b0"                       }
@kutsan

This comment has been minimized.

Copy link

commented Dec 5, 2017

@valencik I added those of them too for easy copy-pasting.

oschrenk added a commit to oschrenk/dotfiles that referenced this issue Jan 21, 2018

@spudlyo

This comment has been minimized.

Copy link

commented Feb 25, 2018

If you're an emacs user you might want these:

  - { key: Period,   mods: Alt|Shift, chars: "\x1b>"                       } # Alt + >
  - { key: Comma,    mods: Alt|Shift, chars: "\x1b<"                       } # Alt + <

If my yak stack wasn't already pretty deep I'd write a program to generate all of these.

ifyouseewendy added a commit to ifyouseewendy/dotfiles that referenced this issue Feb 25, 2018

@ptek

This comment has been minimized.

Copy link

commented Mar 6, 2018

Another useful shortcut for me as an emacs user is:

  - { key: Space,    mods: Control,   chars: "\x00"                        } # Ctrl + Space
@SteVwonder

This comment has been minimized.

Copy link

commented Mar 16, 2018

A few more I ran into while using emacs:

  - { key: Minus,     mods: Alt|Shift, chars: "\x1b_"                       } # Alt + _
  - { key: Key5,      mods: Alt|Shift, chars: "\x1b%"                       } # Alt + %
  - { key: Key6,      mods: Alt|Shift, chars: "\x1b^"                       } # Alt + ^
  - { key: Backslash, mods: Alt,       chars: "\x1b\\"                      } # Alt + \
  - { key: Backslash, mods: Alt|Shift, chars: "\x1b|"                       } # Alt + |
@kutsan

This comment has been minimized.

Copy link

commented Mar 16, 2018

@ptek @SteVwonder Done, thanks!

@ivanbrennan

This comment has been minimized.

Copy link

commented Mar 21, 2018

I wanted to define an AltReturn mapping in vim, so added to my alacritty.yml:

- { key: Return,  mods: Alt,  chars: "\x1b\x0d"   } # Alt + Return

then realized that's already what it sends so no need for the above line. But can anyone tell me what AltShiftReturn sends by default?

@ktsujister

This comment has been minimized.

Copy link

commented May 7, 2018

I added this for Alt + ; for emacs

  - { key: Semicolon, mods: Alt,       chars: "\x1b;"                       } # Alt + ;
@russelldavies

This comment has been minimized.

Copy link

commented Jun 20, 2018

How would one define Alt ??

I've tried - { key: Slash, mods: Alt|Shift, chars: "\x1b?" } but that gets interpreted as <ESC>DEL>. And prefixing the ? with a backslash doesn't work.

@clemensw

This comment has been minimized.

Copy link

commented Sep 19, 2018

Please note that for non-US Layouts one needs to differentiate between RightAlt for "special" characters like RightAlt-L -> '@' and LeftAlt to send Meta. iTerm2 does this. It doesn't look like glutin's winit dependency exposes this yet.

@mimoo

This comment has been minimized.

Copy link

commented Nov 23, 2018

Just want to say that this is a really cool project but as the meta key is not supported atm it's not really useful on mac.

@spamwax

This comment has been minimized.

Copy link

commented Jan 18, 2019

I am using the suggested key binds above to produce Meta-modifiers. While it works most of the time I have encountered an issue in kakoune editor. It uses Meta+I to drop to selection mode followed by a single keystroke to decide what to select.

For example Meta+I followed by B should select everything within parentheses. The first step (i.e. Meta+I ) correctly works and kakoune shows its prompt waiting for second key. But hitting B moves the curser Backward rather than selecting the Bracket.

This is my key binding:

  - { key: I,        mods: Alt,         chars: "\x1bi"                  } # M-i

And this is Alacritty's behavior vs iTerm's:

alacritty

iTerm:

iterm

any hints on how to fix this? or this can be an issue on kakoune side?

@mountainstorm

This comment has been minimized.

Copy link

commented Mar 17, 2019

For what it's worth I want the similar, but subtly different feature of "Command sends Meta"

@saysjonathan

This comment has been minimized.

Copy link
Author

commented Mar 22, 2019

@mountainstorm For now you can copy @kustan's suggestion and replace Alt with Command.

 - { key: N,         mods: Command,       chars: "\x1bn"                       }

Might be time for a config option:

keyboard:
  meta_key: Alt
@saysjonathan

This comment has been minimized.

Copy link
Author

commented Mar 22, 2019

@spamwax It looks like the behavior of subsequent characters is different in Alacritty vs other emulators. You can see the difference using ed (using your M-i b example)

In Terminal.app:

$ ed
^[ib

In Alacritty:

$ ed
^[iˆb
@spamwax

This comment has been minimized.

Copy link

commented Mar 22, 2019

As fully dissected in #2017, it seems it is the issue of the crate alacritty uses to handle key events.

Key binds such as

- { key: I,         mods: Alt,       chars: "\x1bi"                       }

don't fully address the issue since winit intercepts and changes keys before reaching alacritty.

@lsnch

This comment has been minimized.

Copy link

commented Mar 23, 2019

Is there a way to bind ctrl + / (undo) shortcut?

Edit: I've managed to make undo work with

- { key: Underline,               chars: "Underline"                       }

which can be triggered with ctrl + - or ctrl + _.
No success on ctrl + /, but still better than nothing.

@sandersantema

This comment has been minimized.

Copy link

commented Apr 9, 2019

What is the current status of using alt as meta on macOS?

@robertmeta

This comment has been minimized.

Copy link

commented Apr 10, 2019

@sandersantema this post #62 (comment) gets it mostly working for me.

@iugo-eric

This comment has been minimized.

Copy link

commented May 17, 2019

so kustan's workaround worked, and I have no idea why. I was expecting to see Option everywhere Alt appears in that workaround. Apparently option is already being remapped to alt?!?! In that case, why didn't alt_send_esc: true work? That's what it's for...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.