wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
17.46k stars 787 forks source link

Add Leader key binding support #274

Closed wez closed 4 years ago

wez commented 4 years ago

A leader key sequence is a kind of "escape" sequence that places the input handler into a mode where additional key combinations can be recognized. A leader sequence may be a simple key press with optional modifiers. The leader typically has a short (configurable) timeout (eg: 1 second) for the leader mode to be active and recognize additional presses, after which the leader mode is cancelled.

@prabirshrestha: I have some questions for you about implementation:

Is this something that you'd want to define globally so that all key bindings require the leader to be pressed before being recognized, or something that you'd want to specify per-binding?

For example, if there was a configuration like this, would it be desirable to treat the leader as an implicit requirement for any of the keys to be recognized, including the default assignments?

return {
   leader = { key="a", mods="CTRL" },
   keys = {
    {key="|", mods="SHIFT", action=wezterm.action{SplitHorizontal={domain="CurrentPaneDomain"}}},
  },
}

or would it be preferable to explicitly opt-in to the leader using syntax something like this, where LEADER is used as a virtual modifier in the mods list:

return {
   leader = { key="a", mods="CTRL" },
   keys = {
    {key="|", mods="SHIFT|LEADER", action=wezterm.action{SplitHorizontal={domain="CurrentPaneDomain"}}},
  },
}

Another possibility is to add an explicit leader specifier on a per-binding basis:

local leader = { key="a", mods="CTRL" };

return {
   keys = {
    {key="|", mods="SHIFT", leader=leader, action=wezterm.action{SplitHorizontal={domain="CurrentPaneDomain"}}},
  },
}
prabirshrestha commented 4 years ago

I prefer to use ctrl+shift+v for paste in terminal. Inside vim I have another key binding that directly paste from system clipboard which is *+p since I need this to work in gvim primarily because windows terminal vim is horribly slow but Linux and Mac is different.

Once I start terminal the next thing I always run is tmux. So instead of using terminal tab or splits I’m using tmux leader bindings to open new window and split panes.

To me I would like an option to register some keys with global leader key and some without it.

Hopefully once wezterm supports splits and global leader key I can get rid of tmux.

prabirshrestha commented 4 years ago

Another option I would like to add is a flag to never register any key bindings and let me do it on my own.

I have noticed that tmux and vim users are very stringent about what config keys they have and they always override and change. My tmux.conf and .vimrc is my settings. It is for me to be productive and not meant for others. I would like to think the same for wezterm.lua.

By default it can be false so folks who are trying out can get the default bindings.

wez commented 4 years ago

Another option I would like to add is a flag to never register any key bindings and let me do it on my own.

This actually exists already but isn't documented:

return {
   disable_default_key_bindings = true,
}
wez commented 4 years ago

Ok, so it sounds like the second option is the way forward?

Specifying the behavior:

return {
   leader = { key="a", mods="CTRL" },
   keys = {
    {key="|", mods="SHIFT|LEADER", action=wezterm.action{SplitHorizontal={domain="CurrentPaneDomain"}}},
  },
}
prabirshrestha commented 4 years ago

That is right. Would need a leader per key binding. Your example includes solves all my needs.

You might also want to support timeout. leader = { key="a", mods="CTRL", timeout=1000}. I think vim waits for around 1000ms. I'm not sure about tmux timeout.

vim has :h <Leader> and :h timeout for details on this.

For test case also try ctrl+a, ctrl+a which should go to beginning of line if the shell has readline bindings enabled if wezterm leader key is ctrl+a.

wez commented 4 years ago

This is now possible in master:

local wezterm = require 'wezterm';

return {
  -- timeout_milliseconds defaults to 1000 and can be omitted
  leader = { key="a", mods="CTRL", timeout_milliseconds=1000 },
  keys = {
    {key="|", mods="LEADER|SHIFT", action=wezterm.action{SplitHorizontal={domain="CurrentPaneDomain"}}},
    -- Send "CTRL-A" to the terminal when pressing CTRL-A, CTRL-A
    {key="a", mods="LEADER|CTRL", action=wezterm.action{SendString="\x01"}},
  }
}
prabirshrestha commented 4 years ago

wow! that was fast.

In the meantime do you know how often aur nightly-bin updates? Waiting for windows build and will try it out there.

wez commented 4 years ago

The "nightly" builds actually run hourly. The linux binaries for AppImage and AUR are derived from the ubuntu16 builds: https://github.com/wez/wezterm/actions?query=workflow%3Aubuntu16_continuous

I think the next set of build should kick off in the next ~15 minutes and take about 20 minutes to complete, so I'd suggest checking back in about 40-60 minutes.

The Windows nightlies will update around the same time frame, or you can download the artifacts from the commit: https://github.com/wez/wezterm/runs/1169104996

prabirshrestha commented 4 years ago

I tried in windows and it works. This is the first erminal emulator that now allows me to mimic tmux bindings.

    leader = { key="a", mods="CTRL" },
    keys = {
        { key = "-", mods = "LEADER", action=wezterm.action{SplitVertical={domain="CurrentPaneDomain"}} },
        { key = "\\", mods = "LEADER", action=wezterm.action{SplitHorizontal={domain="CurrentPaneDomain"}} },
        { key = "z", mods = "LEADER", action="TogglePaneZoomState" },
        { key = "c", mods = "LEADER", action=wezterm.action{SpawnTab="CurrentPaneDomain"}},
    }
github-actions[bot] commented 1 year ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.