Exit Tmuxinator Session Safely


These days I’m trying out a different working setup using vim, tmux and tmuxinator. One of the drawbacks I couldn’t find any solution for is how to safely quit a running session, such that running programs are quit before they get killed.

The two most important articles I found on the web are Exit tmuxinator project session · Issue #92 where the problem is raised as an issue without providing a solution for it up to now, and Pragmatic Forums | Ending all sessions. The latter one defines very briefly how a quit would work.

What we already have when using tmuxinator is a yaml file for the project, like the following:

×
# ~/.tmuxinator/myapp.yml

name: myapp
root: ~/Projects/myapp

windows:
  - editor:
      layout: main-vertical
      panes:
        - vim
        - bundle exec guard
  - server:
      layout: even-horizontal
      panes:
        - shell
        - tail -f log/development.log

As long as there is no official way to set up post commands (in addition to the pre command we can define), I define my own syntax and hide it behind comments.

×
# # exit commands:
# # exit: window pane keys
# exit: editor 1 Escape :q! Enter
# exit: editor 2 e Enter
# exit: server 2 C-c

The first lines are comments meant to be comments. I’m hiding them behind two hash characters so they don’t get parsed by the emux script below. Th next lines define the necessary match sequence # exit: followed by the window name and the pane number, as well as the keys to be sent to the pane.

Here’s the shutdown script I named emux:

×
#!/bin/bash
#
# kill current tmux(inator) session safely
#
# read and parse tmuxinator config
# send keys to panes
# kill session

# Add lines of the following form to tmuxinator config
# # exit: <window> <pane> <keys>...
# e.g. to stop guard in server pane 1, kill the tail in pane 2 and quit vim:
# # exit: server 1 e Enter
# # exit: server 2 C-c
# # exit: editor 1 Escape :q! Enter

SESSION=$(tmux display-message -p "#S")

OIFS=$IFS
IFS=$'\n'

for line in $(grep '^# exit:' ~/.tmuxinator/$SESSION.yml); do
  IFS=' '
  elems=($line)
  window="${elems[2]}"
  pane=${elems[3]}
  unset 'elems[0]'
  unset 'elems[1]'
  unset 'elems[2]'
  unset 'elems[3]'
  cmd="${elems[*]}"
  echo "tmux send-keys -t $SESSION:$window.$pane $cmd"
done
IFS=$OIFS

tmux kill-session

Put somewhere into the path, to end the current tmux(inator) session, simply call emux from a shell within it.


Es gibt noch keine Kommentare