-
-
Notifications
You must be signed in to change notification settings - Fork 797
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
add support for vertical and horizontal splits #157
Comments
I understand that "Split-Pane" functionality is something your tiling-window-manager or tools like tmux do best and should be used for. but... blah blah... Windows. being windows-bound I cannot find any tool that provides split pane functionality for terminal applications. I know Windows-Terminal has rudimentary split pane functionality, and currently that is the only reason why I am not fully switching to wezterm. Being able to split panes in wezterm-tabs would be a great usability enhancement for windows users. Even better would be a simple Rust (eg. cross-platform) program outside wezterm providing splitting functionality like tmux for console-programs. |
I've been gradually hacking on this feature in a local branch, and I've reached a point where I have basic functionality in terms of making horizontal or vertical splits. What remains is to make it usable enough to push to master, and for that I need some feedback; I personally haven't made using splits in either tmux or iterm2 part of my workflow, so I don't have a great sense of which functions to prioritize. I think the minimum functionality required is:
Looking at tmux's man page, I can see that is has functions that assign layout modes, rotate panes and tile windows. While I'm not opposed to adding that functionality over time, I'm not sure which of those are essential split functions and which are really uber-power-user functions. Another open question is what should the default key assignments be for some or all of these functions? |
hi Wez, looking really forward to try this feature. Another "split-feature" that comes to my mind:
Not having predefined layouts is OK, I guess. If split-pane is implemented as some subcommand, one could startup wezterm with some predefined panes. I like the way windows terminal does it. (thats the only reason I am currently using it, besides wezterm) (see https://docs.microsoft.com/en-us/windows/terminal/panes, https://docs.microsoft.com/en-us/windows/terminal/command-line-arguments) |
Can you describe the effect that "fullscreen" would have? An important constraint of panes is that they are implemented by splitting things into two parts, so every pane must fit within the space available in its parent. If the fullscreen mode has the effect of hiding everything other than the active pane and making the pane fit the full size of the tab, then that makes for some UI complications because the other panes are no longer present, and their positioning requires a whole other set of calculations. Such a fullscreen pane looks/sounds very much like the existing tab primitive, so I'm leaning towards that as the recommended solution. I can see there being potential for moving panes from one containing tab to another, so another way to envision the "fullscreen" mode is to pop a pane into its own tab, then move it back when you're done. (Hand-waving over how tracking that movement and restoring it works for the moment).
I'm not saying that I won't build them, it's just that there are lots of possibilities and I want to prioritize building the more valuable features first, so I'm looking for feedback on which of these things are important!
Thanks; those are helpful links! |
"Fullscreen" is probably the wrong term here. So for example i want to start wezterm with the default shell and a split-pane -H command. |
This adds an extra level of indirection to the Mux model; previously we allowed for Windows to contain an ordered collection of Tabs, where each Tab represented some kind of pty. This change effectively renames the existing Tab trait to Pane and introduces a new Tab container, so the new model is that a Window contains an ordered collection of Tabs, and each Tab can have a single optional Pane. refs: #157
This expands the data model for Tab so that it can record a binary tree of panes; this allows for conceptually splitting a Pane either horizontally or vertically. None of the other layers know about this concept yet. refs: #157
This commit provides the heart of the split functionality. It adds a couple of key assignments (that are not finalized) for splitting the active pane horizontally or vertically. Clicking in a pane will activate it. Selection is constrained to the active pane. Resizing a window will grow/shrink the right/bottom side of a split. The scrollbar applies to the active split. There's not yet a way to resize a split at all. There's not yet a key assignment for changing the active split. The software renderer doesn't know how to render the splits correctly. refs: #157
This allows moving to an adjacent pane in the specified direction. refs: #157
I've pushed the basic implementation of this to master.
The key bindings are assignable if you prefer to assign them to something different, but I haven't written that up so you'll need to reverse engineer the lua config from the defaults in the code Things I'm considering next in no particular order; feedback is appreciated to help me understand which of these have value to you:
|
Ok, goodbye Windows Terminal 👍 Really loving the panes. |
I don't mind; if an issue can be succinctly described in a comment here then that's fine with me. If it gets a bit involved we can spin it out into a separate issue. |
This is great. The best news of the week 😃 For me here are the P0. All these should be possible by keyboard. Some of these are already possible. tmux window is equivalent to tab.
# pane movements
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
# pane resizing
bind H resize-pane -L 5
bind J resize-pane -D 5
bind K resize-pane -U 5
bind L resize-pane -R 5
# pane resizing
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
set -g mouse on P1:
# Change the prefix to Ctrl+a
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# change the default delay to make it more responsive
set -sg escape-time 1
# Splitting panes
bind \\ split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
# window
bind c new-window -c "#{pane_current_path}" P2:
P3:
# start window index at 1
set -g base-index 1
# start pane index at 1
set -g pane-base-index 1 P4:
https://www.google.com/url?sa=i&url=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F32790061%2Fswitch-between-sessions-in-tmux&psig=AOvVaw0j79hVIH6MfvkvGK9R9-T9&ust=1601050241416000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCJjs54qXguwCFQAAAAAdAAAAABAD
My full tmux config can be seen at https://github.com/prabirshrestha/dotfiles/blob/master/.tmux.conf P5;
I personally never use the session feature of tmux and instead use windows (tabs) for multiple projects which are usually open since I barely restart my machine. I use a dynamic window manager https://awesomewm.org/ on linux and https://github.com/prabirshrestha/dwm-win32 on windows. There is also similar but for terminals. https://www.brain-dump.org/projects/dvtm/ I personally haven't used it but something I have always wanted to try. For dwm-win32 I have been moving to lua so hopefully can fully customize auto layouts by lua. Once you go to dynamic tiling manager everything is unproductive. I'm personally happy as long as I can get tmux style keybindings and splits and tabs and windows which means even if it is not built inside terminal app it is ok to have separate tmux.exe or dvtm.exe. The only problem I think this can have is due to windows terminal being very slow so having it as first class is still better choice. There is https://github.com/prompt-toolkit/pymux which partially works in windows but wasnt stable enough to replace. |
FWIW, some of the features above are already present:
|
Re: Leader key, I split that out into #274 |
This toggles the zoom state for the active pane in the current tab. refs: #157
Can you provide example of changing cwd with new splits and tabs? For example in tmux i have { key = "c", mods = "LEADER", action=wezterm.action{SpawnTab="CurrentPaneDomain", cwd="#{pane_current_path}"}}, |
The default is to pick up the CWD set by OSC 7. You need a little bit of glue in your rc files; here's an excerpt from mine that causes both zsh and bash to emit an updated OSC 7 each time they print the prompt: _dotfiles_urlencode() (
# This is important to make sure string manipulation is handled
# byte-by-byte.
LC_ALL=C
str="$1"
while [ -n "$str" ]; do
safe="${str%%[!a-zA-Z0-9/:_\.\-\!\'\(\)~]*}"
printf "%s" "$safe"
str="${str#"$safe"}"
if [ -n "$str" ]; then
printf "%%%02X" "'$str"
str="${str#?}"
fi
done
)
# OSC 7 is used to specify the cwd in supporting terminals
_dotfiles_osc7 () {
printf "\033]7;file://%s%s\033\\" "${HOSTNAME:-}" "$(_dotfiles_urlencode "${PWD}")"
}
# Run by zsh implicitly and by bash because we set PROMPT_COMMAND; is run
# before the prompt is printed. We use it to reset the window title
function precmd()
{
# _dotfiles_set_window_title "${USER}@${HOSTNAME%%.*}:${PWD/$HOME/~}"
_dotfiles_osc7
}
# tell bash to run precmd before each prompt. zsh does this implicitly.
PROMPT_COMMAND='precmd' On Windows in CMD I use this example from the wezterm docs to have the prompt emit the OSC 7 too: There's presumably a way to make powershell do that too, but I've invested zero time in learning powershell so far. With OSC 7 being emitted, your new tabs and panes will automatically pick up the cwd and you won't need to mention the cwd in your config. |
I will give the bash and cmd a try. In tmux it works without any changes to my bashrc. would be interesting to see how it does though not sure how it would work for cmd. I myself don't use powershell so not worried about it. I'm getting really close to porting my entire tmux config to be exactly the same in wezterm. 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"}},
{ key = "h", mods = "LEADER", action=wezterm.action{ActivatePaneDirection="Left"}},
{ key = "j", mods = "LEADER", action=wezterm.action{ActivatePaneDirection="Down"}},
{ key = "k", mods = "LEADER", action=wezterm.action{ActivatePaneDirection="Up"}},
{ key = "l", mods = "LEADER", action=wezterm.action{ActivatePaneDirection="Right"}},
{ key = "H", mods = "LEADER|SHIFT", action=wezterm.action{AdjustPaneSize={"Left", 5}}},
{ key = "J", mods = "LEADER|SHIFT", action=wezterm.action{AdjustPaneSize={"Down", 5}}},
{ key = "K", mods = "LEADER|SHIFT", action=wezterm.action{AdjustPaneSize={"Up", 5}}},
{ key = "L", mods = "LEADER|SHIFT", action=wezterm.action{AdjustPaneSize={"Right", 5}}},
{ key = "1", mods = "LEADER", action=wezterm.action{ActivateTab=0}},
{ key = "2", mods = "LEADER", action=wezterm.action{ActivateTab=1}},
{ key = "3", mods = "LEADER", action=wezterm.action{ActivateTab=2}},
{ key = "4", mods = "LEADER", action=wezterm.action{ActivateTab=3}},
{ key = "5", mods = "LEADER", action=wezterm.action{ActivateTab=4}},
{ key = "6", mods = "LEADER", action=wezterm.action{ActivateTab=5}},
{ key = "7", mods = "LEADER", action=wezterm.action{ActivateTab=6}},
{ key = "8", mods = "LEADER", action=wezterm.action{ActivateTab=7}},
{ key = "9", mods = "LEADER", action=wezterm.action{ActivateTab=8}},
{ key = "&", mods = "LEADER|SHIFT", action="CloseCurrentTab"},
} Few things I'm currently missing that are P0.
Another thing I noticed is tmux config doesn't seem to requires me adding |
Yeah, this has been on my todo list for a while. The termwiz layer knows how to normalize this away, but these key assignments happen in the gui layer which doesn't have this yet. I'll fix this up. |
When a keypress is ASCII uppercase and SHIFT is held, remove SHIFT from the set of active modifiers. refs: #157 (comment)
What should the value of prompt be to set osc7? Sorry I'm totally new to this. I don't mind changing by bashrc and prompt. What happens if I'm using clink to render custom prompt? |
For Windows/CMD you mean? The bare minimum is to include this text in your prompt env var: There's an example of this in the docs:
I use this with clink, but I don't use a custom prompt: I can't find any documentation for clink, let alone docs on how to do prompts :-/
where |
Should |
Panes don't seem to resize automatically when wezterm size changes causing some panes to be hidden. repro steps:
tmux seems capable of resizing. most likely each pane needs to get a scale factor and when wezterm resize also resize all panes to that particular scale. |
This uses a similar approach to that used by tmux; when resizing, a size delta is computed in each axis and that value is distributed across the splits in that dimension. For a small resize by 1 cell this tends to bias towards adjusting the top/left node. For a large resize (eg: maximizing/restoring) the distribution tends to share across the splits in that dimension, effectively scaling them approximately proportionally, more or less preserving the relative scale of the splits. refs: #157 (comment)
After pane resizing, I can't seem wezterm to work with a tiling manager. with dwm-win32 it always crashes. Most likely both dwm-win32 and wezterm is trying to resize the window. let me know if there is a way to get logs. I don't see much info in event viewer.
|
Can you try setting I wonder if what you're seeing might be related to #276 |
Seems like divide by zero. It is pointing to the follow line Line 479 in c5efd94
#276 could also be the same issue. Was able to use the release build set backtrace on. log
|
Another bug: if you have 2 tabs but only one pane on both, closing current pane seems to crash wezterm.
This is the config I'm using
|
This should make closing panes more consistent and reliable; there were some cases where we wouldn't always terminate the associated process and this improves that. There are also some resize boundary check improvements. refs: #157 (comment) refs: #157 (comment)
latest master fixes both the bugs I reported. thanks for the quick fix. |
found another nit bug.
if you zoom the right pane and unzoom it again it doesn't seem to have the issue. |
The problem was that the pane resizes got optimized away because the tab size doesn't change as part of the zoom operation. We don't need to run the full resize logic for unzoom though, just need to re-apply the size to the unzoomed pane. We don't have a convenient way to do that, so we re-apply the sizes to all of the panes in the tab. refs: #157 (comment)
@DanCardin thanks for reporting that! I can't reproduce it in master following these steps, with
I suspect that there might be something environmental contributing to the differences in what we see, but I'm not sure what! |
When confirmation is enabled, a really basic overlay is rendered over the top of the tab to request confirmation. The default key assignment for CloseCurrentTab now has confirmation enabled. ```lua action=wezterm.action{CloseCurrentTab={confirm=true}} action=wezterm.action{CloseCurrentTab={confirm=false}} ``` refs: #157 refs: #280
I believe this to be fixed in master as of 8d1af90 If you're following https://wezfurlong.org/wezterm/multiplexing.html#connecting-into-windows-subsystem-for-linux then you'll need to change from this: serve_command = ["wsl", "wezterm", "start", "--daemonize", "--front-end", "MuxServer"], to this: serve_command = {"wsl", "wezterm-mux-server", "--daemonize"} I'll update the docs for this when I'm closing to making a release. |
I couldn't trivially reproduce this on master, so it may also be fixed. If not, please file a new issue! I'm going to close this one out as it is getting a bit long and that is making it harder for me to see what is outstanding! |
@wez Any thoughts on expanding this feature to support splitting panes full width (across the entire window) as in tmux-pain-control? |
@rrpolanco please open a new issue describing the functionality you're looking for; this issue is already very long and unmanageable (as well as being closed!) |
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. |
Also allow me to bind keys similar to tmux so I can use ctrl-a, ctrl | to split.
The text was updated successfully, but these errors were encountered: