To switch between tasks on an unaltered MacOS Mojave (OS X 10.14.6), one uses command-tab, which is convenient when done with the thumb finger. Now, in order to turn on the meta key inside Terminal (to allow e.g. skipping words with the cursor inside bash backward and forward emacs-style), I can tick the 'use Option as Meta key' in Terminal.app preferences.

This setup leaves me with option as meta key inside emacs, which is not ergonomic, as the key is physically too much on the left and my thumb finger needs to bend to get there.

I would like to:

  • leave the command-tab system-wide key unaltered, in order to be able to exit the emacs context into another task
  • still have the command key to be the meta key in emacs (so that, e.g., meta-f and meta-b hop over words)
  • all of this while working inside terminal emacs, not emacs with GUI variant

Some things I tried:

  • swapping the command and option buttons in System Preferences/Keyboard/Modifier keys. This results in a need to press option-tab for the task manager
  • setting the mac-command-modifier variable, as explained here, however my emacs 26.3, installed via brew install emacs, doesn't seem to know about this variable (ctrl- h-v doesn't recognize it at all and changing the variable doesn't have any effect)

Can this be done? In other words, is there a way to have the command key be meta in emacs and yet have command-tab still switch between tasks system-wide?

  • Does your version of Emacs recognize the following variables?: ns-alternate-modifier; ns-right-alternate-modifier; ns-command-modifier; ns-right-command-modifier; ns-control-modifier; ns-right-control-modifier; ns-function-modifier. They are defined in the C source code library nsterm.m. – lawlist Jul 20 '20 at 21:15
  • Nope. I've done brew install emacs a couple hours ago. Ctrl-h-v ns- and then tab doesn't yield anything. However I think I got what I wanted using iTerm2 and it's ability to remap the command key, I'll post answer about that. – aleks224 Jul 20 '20 at 21:19
  • Maybe you have not done a Mac build of Emacs ... Try building Emacs for a Mac; e.g., --with-ns. I don't use brew though, so you may need to Google the Apple/Mac recipe. When building Emacs for Mac, the C source code library nsterm.m is used and so is the ns-win.el Lisp library during the build process. The latter Lisp library mentioned sets up the defvaralias that you mention in your question above. – lawlist Jul 20 '20 at 21:20
  • Revisiting this, I compiled emacs 27.1 from source on MacOS 10.14.6 (Mojave) using ./configure --with-ns. When I run emacs with the graphical UI, all ns-* variables are respected, however when I run emacs -nw (terminal interface), the ns-* commands are ignored, even though they are set (e.g. ns-option-modifier is set to `meta). For some reason, these variables are ignored in the terminal variant, there must be a line of code that disables them somewhere, for some reason (maybe due to interference with the environment commands?) – aleks224 Dec 2 '20 at 14:13
  • Perhaps you are using an outdated version of Emacs in the terminal. When the terminal version of Emacs is open, type M-x emacs-version to see. Also, in the the terminal, before launching Emacs, type which emacs. You may unwittingly be using the terminal version that comes with the OS; e.g., /usr/bin/emacs – lawlist Dec 2 '20 at 14:41

In non-windows mode, changes to ns-* variables (such as ns-alternate-modifier and ns-command-modifier) are ignored. In particular, if the -nw option is passed as argument to emacs, the logic that propagates changes to ns-* variables (implemented in src/nsterm.c) is not evaluated. See the call to init_display in the src/emacs.c in the Emacs 27.1 source code. Roughly, it'll evaluate stuff from nsterm.c only if the window system is not inhibited (controlled by the inhibit_window_system variable which is set if the -nw flag is passed) and otherwise rely on src/term.c. If the window system is inhibited, the ns-* variables will still be visible - this is because syms_of_nsterm is invoked regardless of the inhibit_window_system variable at emacs.c:1930. The variables are there but have no bearing on the actual key mappings.

As such when windows are inhibited, attempting to resolve this with ns-* is a dead end. Iterm2 and its remapping features can be of help here until there's a better way:

enter image description here

..which simply remaps the left command key to left option key.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.