tmuxinator / tmuxinator

Manage complex tmux sessions easily

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom layout not created correctly.

andho opened this issue · comments

I created a tmux layout and got this using list-windows:
0: bash* (4 panes) [282x71] [layout b6b8,282x71,0,0{141x71,0,0,3,140x71,142,0[140x35,142,0{70x35,142,0,5,69x35,213,0,7},140x35,142,36,6]}] @2 (active)

Then I put this in my config file:

name: project1                                                                                          
root: ~/dev/projects/project1/apps/backend
windows:                                                                                            
   - editor:                                                                                         
       layout: b6b8,282x71,0,0{141x71,0,0,3,140x71,142,0[140x35,142,0{70x35,142,0,5,69x35,213,0,7},140x35,142,36,6]}
       # Synchronize all panes of this window, can be enabled before or after the pane commands run. 
       # 'before' represents legacy functionality and will be deprecated in a future release, in favour of 'after'
       # synchronize: after                                                                          
       panes:                                                                                        
         - vim                                                                                       
         -                                                                                           
         - task                                                                                      
         - 

Now when I start the project, the top-right most pane is much smaller then the original layout. So I used tmuxinator debug to get the code and tried the line that sets the layout:

tmux select-layout -t project1:0 b6b8,282x71,0,0\{141x71,0,0,3,140x71,142,0\[140x35,142,0\{70x35,142,0,5,69x35,213,0,7\},140x35,142,36,6\]\}

This fixes the layout.

This is on Ubuntu:18.04. Let me know any other info that might be needed.

OS: Ubuntu 18.04.1 LTS
Kernel: 4.15.0-33-generic
Ruby: 2.5.1p57

Output of gem list:

*** LOCAL GEMS ***

bigdecimal (default: 1.3.4)
cmath (default: 1.0.0)
csv (default: 1.0.0)
date (default: 1.0.0)
dbm (default: 1.0.0)
did_you_mean (1.2.0)
erubis (2.7.0)
etc (default: 1.0.0)
fcntl (default: 1.0.0)
fiddle (default: 1.0.0)
fileutils (default: 1.0.2)
gdbm (default: 2.0.0)
io-console (default: 0.4.6)
ipaddr (default: 1.2.0)
json (default: 2.1.0)
minitest (5.10.3)
net-telnet (0.1.1)
openssl (default: 2.1.0)
power_assert (0.2.7)
psych (default: 3.0.2)
rake (12.3.1)
rdoc (default: 6.0.1)
scanf (default: 1.0.0)
sdbm (default: 1.0.0)
stringio (default: 0.0.1)
strscan (default: 1.0.0)
test-unit (3.2.5)
thor (0.19.4)
tmuxinator (0.8.1)
webrick (default: 1.4.2)
zlib (default: 1.0.0)

I'm experiencing the exact same issue, fwiw.

commented

Also having this issue.

Same issue. Ubuntu 18.04

Temporary hack:

name: project                                                                      
root: ~/projects/project                                                 
                                                                                  
windows:                                                                         
  - editor:                                                                      
    layout: e414,317x86,0,0[317x63,0,0,0,317x22,0,64,2]               
    panes:                                                                     
      - $EDITOR                                                                
      - tmux select-layout -t project:0 e414,317x86,0,0\[317x63,0,0,0,317x22,0,64,2\] && 
        clear

I'm experiencing the same issue. The temporary hack works, but it's ugly. Here's my config, without the hack:

windows:
  - editor:
      layout: d37c,380x66,0,0{142x66,0,0,0,237x66,143,0,4}
      panes:
        - guard
        - vim
  - console: #just zsh
  - server: bundle exec rails s
  - logs: tail -f log/development.log

The layout definitely isn't being applied.

Same problem here:

windows:
  - Server:
      layout: 28e2,239x67,0,0{146x67,0,0[146x31,0,0,0,146x35,0,32,1],92x67,147,0[92x15,147,0{38x15,147,0,2,53x15,186,0,3},92x19,147,16,4,92x31,147,36,5]}
      panes:
        - 
        - 
        - 
        - 
        - 
        - 

Upper right panes are restored wrongly.

I just had a quick look at this and it seems to be a result of tmux trying to apply that layout to the session before it's been rendered.

I'll have to chew on it to figure out what the best approach is (possibly using a hook in the generated script/commands? also more than happy to hear suggestions from others!) but for now, a slightly less dirty hack than creating a bogus pane to handle the layout selection would be to use a project hook. I just tested the following using @andho's config and it seems to work consistently, but YMMV:

name: project1
on_project_start: $(sleep 1 && tmux select-layout -t project1:0 b6b8,282x71,0,0\{141x71,0,0,3,140x71,142,0\[140x35,142,0\{70x35,142,0,5,69x35,213,0,7\},140x35,142,36,6\]\}) &
windows:
   - editor:
       layout: b6b8,282x71,0,0{141x71,0,0,3,140x71,142,0[140x35,142,0{70x35,142,0,5,69x35,213,0,7},140x35,142,36,6]}
       # Synchronize all panes of this window, can be enabled before or after the pane commands run.
       # 'before' represents legacy functionality and will be deprecated in a future release, in favour of 'after'
       # synchronize: after
       panes:
         - echo 1
         - echo 2
         - echo 3
         - echo 4

So, it turns out this is a known tmux issue.

The tmuxp project (tmuxinator's Python analogue) works around the issue in a similar manner to what I'd floated above:

    tmux 2.6+ requires that the window be viewed with the client before
    select-layout adjustments can take effect.

    To handle this, this function creates temporary hook for this session to
    iterate through all windows and select the layout.

    In order for layout changes to take effect, a client must at the very
    least be attached to the window (not just the session).

    hook_name is provided to allow this to set to multiple scenarios, such
    as 'client-attached' (which the user attaches the session). You may
    also want 'after-switch-client' for cases where the user loads tmuxp
    sessions inside tmux since tmuxp offers to switch for them.
    
    Also, the hooks are set immediately unbind after they're invoked via -u.

This is not strictly accurate, layouts are applied immediately even if detached (assuming the correct number of panes exist) but they will be adapted to the window size when applied and then resized as normal if the terminal is a different size when attached. Layouts are not sticky, they are applied once when select-layout is used with whatever window size tmux has at that moment. If you know the target terminal size up front you can specify it for detached sessions with -x and -y to new-session, otherwise you will get the default 80x24. Now that window size is independent of session size in 2.9+ it would be possible for tmux to resize the window to the size in the custom layout string when it is applied, but for people with the window-size option set to anything but manual (almost everyone I suspect) it would still be resized to the terminal size when attached.

Same issue. Ubuntu 18.04

Temporary hack:

name: project                                                                      
root: ~/projects/project                                                 
                                                                                  
windows:                                                                         
  - editor:                                                                      
    layout: e414,317x86,0,0[317x63,0,0,0,317x22,0,64,2]               
    panes:                                                                     
      - $EDITOR                                                                
      - tmux select-layout -t project:0 e414,317x86,0,0\[317x63,0,0,0,317x22,0,64,2\] && 
        clear

can the project reference to this in the readme under the https://github.com/tmuxinator/tmuxinator#panes section?
I, personally, think this is the simplest solution till the project decides how they want to deal with this, and as a new user of the project (getting frustrated thinking I was doing something wrong, and then finding this issue) it is the lowest barrier to general knowledge of tmux. Then linking to this one if people need to use all their panes.
I would submit a pull request, but I don't know how receptive this project is to one off small submissions. I also don't know how the project wants to handle this, so just my two cents.

Awesome project though, and thank you so much for putting it together and maintaining it! 😄

If you all don't mind me doing a pr I am more than happy to, let me know if I can help.

I would submit a pull request, but I don't know how receptive this project is to one off small submissions.

This would be most welcome. 👍

So @ethagnawl is everything I talked about including ok? Like a having a quick and easy, and then having a more proper way? Or do you want me to just include the proper way?

@elreydetoda May as well go with the "proper" way.

I am having the same issue on ubuntu wsl on windows 10. Neither of the solutions above work for me. When I list a set of panes, apply them using the two solutions above, then run tmuxinator, all the panes are squashed upwards. See images below and my list-windows output

1: ~* (9 panes) [307x80] [layout cd75,307x80,0,0[307x70,0,0{108x70,0,0,0,99x70,109,0[99x35,109,0,3,99x17,109,36,10,99x16,109,54,11],98x70,209,0[98x17,209,0,6,98x17,209,18,9,98x17,209,36,7,98x16,209,54,8]},307x9,0,71,1]] @0 (active)
# /home/jmcc/.config/tmuxinator/work.yml

name: work
root: ~/PythonScripts/

windows:
  - work:
      layout: cd75,307x80,0,0[307x70,0,0{108x70,0,0,0,99x70,109,0[99x35,109,0,3,99x17,109,36,10,99x16,109,54,11],98x70,209,0[98x17,209,0,6,98x17,209,18,9,98x17,209,36,7,98x16,209,54,8]},307x9,0,71,1]
      panes:
        -
        -
        -
        -
        -
        -
        -
        -
        -

I set this up manually to get the list above:

tmux_want

This is how it looks when I run mux work

tmux_get

I tried both solutions with tmux select-layout ... and it was still loading as in the second image above

@jmccormac01 Does manually running tmux select-layout ... from inside the spawned session solve the problem?

If not, that is very confusing. I have no idea if/how using WSL complicates things or introduces incompatibilities, but I guess it's possible.

If so, you may want to try increasing the (completely arbitrary) sleep length used in the workaround.

It did not, I was about to try again with the longer delay and I stumbled onto another issue with WSL/tmux. The zsh shells are eating crazy amounts of CPU. I wonder if this is causing issues when setting up the layout. See microsoft/WSL#3914 . When I manually set up my layout (which I normally use on my macbook, which is annoyingly in for repair), the zsh terminals consume all my CPU. Sigh.

I just experienced this myself. Is the hook-approach the "de-facto" hack for now?

@KevinSjoberg I suppose so.

Did you ever get a chance to add that note to the README, @elreydetoda? It should be easier to find than this thread. If not, I can do it.

@ethagnawl I've created a pull request. See #722.

Here is my workaround (using tmux 3.1c and tmuxinator 2.0.2 from Debian 11.2 bullseye) :

# some-tmuxinator-project.yml

name: some-tmuxinator-project
root: ~/

on_project_first_start: (sleep 1 && tmux list-windows -F "#{window_id}" | while read WINDOW_ID; do tmux select-layout -t "$WINDOW_ID"; done) &

windows:
# ...

Explanation:

# using on_project_FIRST_start and NOT on_project_start, because the windows shall be laid out according to their initial
# specification only once, i.e. when the tmuxinator session starts for the first time.
# For comparison, on_project_start additionally runs every time a currently detached tmuxinator session gets reattached again
# on consecutive "tmuxinator start $PROJECT", which would destroy any layout customization accomplished since first start.
#
# Explanation:
#
# ( ... ) &
# -> run everything inside the parantheses in background, i.e. fork and continue with tmuxinator startup.
#
# sleep 1 ...
# -> introduce a delay of one second and hope that within this one second tmux has setup its server and this session
# in order to have the subsequent commands work successfully (race condition 1)
#
# ... && tmux list-windows -F "#{window_id}" ...
# -> list the tmux server-unique IDs of all windows within the MOST RECENT session for further processing.
#    If -t is not provided, tmux will default to the most recently active session.
#    In the happy case, the most recent session will be this tmuxinator session currently being set-up.
#    In the unhappy case, within the one-second delay another concurrently running tmux session becomes active,
#    therefore listing that session's windows which shall not be operated on (race condition 2)
#
# ... | while read WINDOW_ID; do tmux select-layout -t "$WINDOW_ID"; done
# -> iterate through all given window_ids, and execute "tmux select-layout -t window_id"
#    In the happy case, this will mean the tmux server will issue the "select-layout" command to each window of this newly created tmux session.
#    When select-layout isn't given a specific "layout-name", it will cause to reapply the target window's previous layout, which happens to be
#    the layout defined in this tmuxinator project configuration

putting parentheses around layout seems to do the trick for me (gentoo, tmuxinator 3.0.5):

 windows:
   - vim:
       panes:
         - vim .
   - work:
       layout: "956d,191x50,0,0[191x8,0,0,1,191x41,0,9{95x41,0,9[95x4,0,9,6,95x36,0,14,10],95x41,96,9[95x20,96,9,7,95x20,96,30,9]}]"
       panes:
         -
         -
         -
         -
         -