wezterm icon indicating copy to clipboard operation
wezterm copied to clipboard

add ability to remap modifier and caps lock keys

Open marcuslannister opened this issue 2 years ago • 2 comments

Is your feature request related to a problem? Please describe. No

Describe the solution you'd like Because I use CAPS key as Command key on macOS, It can save many times when I use Command key. And in Terminal I also want to remap my command key to control key, because many hot key will use control key.

Describe alternatives you've considered No

Additional context No

marcuslannister avatar Mar 27 '22 14:03 marcuslannister

Remapping modifiers cross platform is potentially a bit gnarly, so I'm not eager to work on this.

I would suggest looking at https://karabiner-elements.pqrs.org/ to remap globally; that's what I use on macOS to remap caps lock to a dual role (tap = ESC, hold = control) key.

wez avatar Mar 27 '22 14:03 wez

Got it and thanks for your quick reply.

marcuslannister avatar Mar 27 '22 14:03 marcuslannister

Also want to check if remap Command to Alt and Option to Super is possible. I usually use Emacs inside terminal but want consistent Meta/Alt key across Mac and Linux.

qqldd avatar Sep 30 '22 23:09 qqldd

I find a way in Karabiner Elements to swap Option <-> Command only for WezTerm, for others: Here is the example and my configs:

 {
        "conditions": [
            {
                "bundle_identifiers": [
                    "^com\\.github\\.wez\\.wezterm$"
                ],
                "type": "frontmost_application_if"
            }
        ],
        "description": "WezTerm Left Option to Cmd",
        "from": {
            "key_code": "left_option",
            "modifiers": {
                "optional": [
                    "any"
                ]
            }
        },
        "to": [
            {
                "key_code": "left_command",
                "lazy": true
            }
        ],
        "type": "basic"
    },
    {
        "conditions": [
            {
                "bundle_identifiers": [
                    "^com\\.github\\.wez\\.wezterm$"
                ],
                "type": "frontmost_application_if"
            }
        ],
        "description": "WezTerm Left Cmd to Option",
        "from": {
            "key_code": "left_command",
            "modifiers": {
                "optional": [
                    "any"
                ]
            }
        },
        "to": [
            {
                "key_code": "left_option",
                "lazy": true
            }
        ],
        "type": "basic"
    }

qqldd avatar Oct 03 '22 22:10 qqldd

Thx @qqldd, this is exactly what I want~ I made some changes to the karabiner config~

{
  "title": "WezTerm switch option with cmd",
  "rules": [
    {
      "description": "WezTerm Left Option to Cmd",
      "manipulators": [
        {
          "conditions": [
            {
              "bundle_identifiers": ["^com\\.github\\.wez\\.wezterm$"],
              "type": "frontmost_application_if"
            }
          ],
          "from": {
            "key_code": "left_option",
            "modifiers": {
              "optional": ["any"]
            }
          },
          "to": [
            {
              "key_code": "left_command",
              "lazy": true
            }
          ],
          "type": "basic"
        }
      ]
    },
    {
      "description": "WezTerm Left Cmd to Option",
      "manipulators": [
        {
          "conditions": [
            {
              "bundle_identifiers": ["^com\\.github\\.wez\\.wezterm$"],
              "type": "frontmost_application_if"
            }
          ],
          "from": {
            "key_code": "left_command",
            "modifiers": {
              "optional": ["any"]
            }
          },
          "to": [
            {
              "key_code": "left_option",
              "lazy": true
            }
          ],
          "type": "basic"
        }
      ]
    }
  ]
}

LintaoAmons avatar Oct 18 '22 15:10 LintaoAmons

Remapping modifiers cross platform is potentially a bit gnarly, so I'm not eager to work on this.

I would suggest looking at https://karabiner-elements.pqrs.org/ to remap globally; that's what I use on macOS to remap caps lock to a dual role (tap = ESC, hold = control) key.

To switch Opt and CMD when using wezterm is a good solution, but I tried this for one day, found that it not that good because some system wide keybindings is not consistent since cmd is in opt position.

@wez So maybe there's a way to deem CMD as META when using mac?

LintaoAmons avatar Oct 19 '22 14:10 LintaoAmons

If you look at the flow chart at https://wezfurlong.org/wezterm/config/keyboard-concepts.html#keyboard-processing-flow, where do you envision the modifier remapping happening?

wez avatar Oct 19 '22 16:10 wez

Thx for your hint, I actually can just map the send key. And I finally come up with something that seems working well.

local wezterm = require("wezterm")
local act = wezterm.action

function macCMDtoMeta()
	local keys = "abdefghijklmnopqrstuwxyz" -- no c,v
	local keymappings = {}

	for i = 1, #keys do
		local c = keys:sub(i, i)
		table.insert(keymappings, {
			key = c,
			mods = "CMD",
			action = act.SendKey({
				key = c,
				mods = "META",
			}),
		})
		table.insert(keymappings, {
			key = c,
			mods = "CMD|CTRL",
			action = act.SendKey({
				key = c,
				mods = "META|CTRL",
			}),
		})
	end
	return keymappings
end

return {
	font = wezterm.font_with_fallback({
		"Hack Nerd Font Mono",
	}),
	color_scheme = "Gruvbox dark, medium (base16)",
	keys = macCMDtoMeta(),

	font_size = 18.0,
	hide_tab_bar_if_only_one_tab = true,
}

LintaoAmons avatar Oct 20 '22 02:10 LintaoAmons

Remapping modifiers cross platform is potentially a bit gnarly, so I'm not eager to work on this.

@wez I'd love to have an interceptor kind of function that listens to and potentially modify keyboard events right before the "Send key to terminal" step

image

The workaround from @LintaoAmons is fine for a subset of chars but it's not optimal if I want to literally remap every occurrence of a specific modifier for all chars, symbols, ..etc.

My use case: I use Linux, Mac, and Windows almost daily, so I have the CMD and Ctrl swapped in Mac which solves most of my problems except for the terminal.

While I can change Wezterm own keybinds to use the appropriate modifier based on the OS I need a way to still use ctrl for terminal-based apps like Vim (as in, I press ctrl -> OS swaps it with CMD -> Wezterm's SendKey sends Ctrl). So having the ability to override what gets sent to these apps would fix the final piece of the puzzle for me. Currently, I use Karabiner but it's messy, and with every shortcut, I add I have to make two: one for all apps and one for Terminals.

I don't know if that would make it any better in terms of implementation/maintenance but just throwing ideas here and am open to feedback.

z0al avatar Apr 13 '23 11:04 z0al

I imagine a something like public Lua interface of windowmods_to_termwiz_mods would suffice for my need.

z0al avatar Apr 13 '23 11:04 z0al

@LintaoAmons, sorry to revive - have you tried that script with CMD|SHIFT -> META|SHIFT, by any chance? This latter remap doesn't appear to work, for some reason.

Edit: in fact, even CMD|CTRL remap doesn't appear to be working for me - a key combination like Ctrl-Cmd-h still registers as Ctrl-Win-h inside the terminal. Not sure what I'm doing wrong..

dinvlad avatar Aug 30 '23 05:08 dinvlad

@dinvlad

wezterm/.wezterm.lua

Here's my up-to-date config, it working fine for me, and should be fine for you. If not maybe you should debug some other possible reason outside wezterm?

LintaoAmons avatar Aug 30 '23 10:08 LintaoAmons

@LintaoAmons thanks, and sorry for spam - does this work for you inside a terminal, or even more specifically inside Tmux? I'm probably missing something obvious - I'll create a discussion if it's more appropriate to discuss there. For now, I just created a different mapping that doesn't involve CMD, and the new binding seems to be working fine, as a workaround.

dinvlad avatar Aug 30 '23 23:08 dinvlad

@dinvlad Yes, it's working both in tmux and vim(within or without tmux)~

LintaoAmons avatar Aug 31 '23 03:08 LintaoAmons

@LintaoAmons thanks for your help - I got it working. Not sure what the ultimate culprit was, but I did all of the following:

  • set config.term = "wezterm" in .wezterm.lua, as well as programs.tmux.terminal = "wezterm"; and home.sessionVariables.TERMINFO_DIRS = "${config.home.profileDirectory}/share/terminfo:$TERMINFO_DIRS"; in Nix's home-manager (which is what I'm using for config management). Obviously, these settings should only affect things like undercurls, but I figured they might be relevant

  • double-checked I'm using your config without any other logic that may affect it. I think at one point I had a condition whether we're on macOS or not - and it turned out there was a syntactic mistake in that condition when I tried it again. For posterity, here's an expanded config that I'm using now to do an even more comprehensive remap of all ASCII characters (with the exception of CMD-c and CMD-v):

config.keys = {
  -- regular mappings --
}

-- Swap Cmd <-> Option on macOS
if wezterm.target_triple:match("darwin$") then
        for i = 0, 127 do
                local key = string.char(i)

                for _, mods in ipairs({ "", "|CTRL", "|SHIFT" }) do
                        if mods == "" and (key == "c" or key == "v") then
                                goto continue
                        end
                        for from, to in pairs({ CMD = "OPT", OPT = "CMD" }) do
                                table.insert(config.keys, {
                                        key = key,
                                        mods = from .. mods,
                                        action = act.SendKey({
                                                key = key,
                                                mods = to .. mods,
                                        }),
                                })
                        end
                        ::continue::
                end
        end
end
  • did a full restart of Tmux and WezTerm plus killall tmux wezterm-mux-server - since I've noticed that at least some settings didn't apply until I exited all Tmux sessions and stopped WezTerm Unix domain.

dinvlad avatar Sep 01 '23 20:09 dinvlad