Documentation

teamocil is the oldest tool on these pages. It does one small thing, it has done it the same way for years and its README fits on one screen. If it works for you, keep using it. I am not here to convince anyone. But if you want to try a .glaze file, and you already have a ~/.teamocil/ directory, this page translates a layout into a profile block by block. There is less here than on the other migration pages, because a teamocil layout has fewer keys, and I would rather translate the ones in its README than guess at the ones that are not.

A typical layout

A teamocil layout with the usual parts:

~/.teamocil/daemon-run.yml YAML
name: daemon-run

windows:
  - name: editor
    root: ~/runs/arasaka
    layout: main-vertical
    focus: true
    options:
      main-pane-width: 120
    panes:
      - commands:
          - npm install
          - npm run dev
        focus: true
      - nvim .
  - name: logs
    root: ~/runs/arasaka/logs
    layout: even-horizontal
    panes:
      - tail -f dev.log
      - htop

The same workspace as a profile, saved as ~/runs/arasaka/.glaze:

.glaze HCL
session {
  name               = "daemon-run"
  starting_directory = "~/runs/arasaka"

  window {
    name   = "editor"
    layout = "main-vertical"
    focus  = true

    options = {
      "main-pane-width" = "120"
    }

    pane {
      commands = ["npm install", "npm run dev"]
      focus    = true
    }

    pane {
      commands = ["nvim ."]
    }
  }

  window {
    name               = "logs"
    layout             = "even-horizontal"
    starting_directory = "logs"

    pane {
      commands = ["tail -f dev.log"]
    }

    pane {
      commands = ["htop"]
    }
  }
}

The translation table

teamocilglazeNotes
namesession.nameGlazier replaces ., :, $ and a backslash with - and shows a warning.
windows[].namewindow.nameteamocil requires it. The default in Glazier is default.
windows[].rootwindow.starting_directory, or once on the sessionA window without a directory uses the directory of the session. ~ expands. A relative path is relative to the directory of the profile.
layoutwindow.layoutThe same five tmux presets. A raw layout string also works in both tools.
windows[].focusfocus = true on the window
windows[].optionswindow.optionsteamocil uses set-window-option. Glazier sets each option where tmux keeps it. See below.
panes[] as a stringpane.commandsA list with one command.
panes[].commandspane.commandsA list, in order. Glazier waits for each command except the last.
panes[].focusfocus = true on the pane
teamocil daemon-runglaze up
teamocil --layout pathglaze up --profile-path path
teamocil --herenoneSee below.
tmux kill-session -t daemon-runglaze downA session that is not running causes no error.

The five layout presets are tmux presets in both tools: even-horizontal, even-vertical, main-horizontal, main-vertical and tiled. The default in Glazier is tiled.

What does not map one to one

--here. teamocil can build a layout in the window you are in, inside the session you are in. Glazier always creates a session of its own. Inside tmux, up switches your client to the new session, and when a session with that name already exists, up leaves it alone unless you pass --clear. If you live in one large session and add windows to it as you go, Glazier does not do that, and I have no clever answer for you. See glaze up.

options and when they apply. teamocil sets a window option with set-window-option. Glazier asks tmux where it keeps an option and sets it there, so a session option such as history-limit in a window block goes to the session with a warning. Glazier also applies window options before it runs the pane commands. That matters for one option. With synchronize-panes on, tmux types each command line into every pane of the window, a command runs twice and a pane reports a missing buffer. So:

warning

Do not set synchronize-panes in options on a window whose panes have commands.

Set it on a window whose panes have no commands, or turn it on by hand after up with tmux set-option -w synchronize-panes on. See Hooks and options.

The things teamocil does not have. The other migration pages spend a paragraph each on a per-pane pre-command and a before-session hook. teamocil has neither, so there is nothing to translate. The profile does give you a session block, and it is the place for the things a layout could not hold: one starting_directory for every window, envs for the variables that every shell should inherit and commands that run in the active pane after the session exists. See Session and Environment.

Differences in the workflow

  • teamocil keeps layouts in ~/.teamocil/. Glazier looks for .glaze in the current directory, then in $GLAZE_PATH, or where --profile-path points. A profile lives with the project, so it goes into the repository. See Profile resolution.
  • teamocil lists and edits layouts with --list and --edit. Glazier has no editor command, and glaze ls lists running sessions, not profiles. See glaze ls.
  • Glazier has typed variable blocks and --var flags, so one profile serves many projects. See One profile for many projects.
  • Glazier waits for each pane command except the last with tmux wait-for, so npm install finishes before npm run dev starts. There are no fixed sleeps. See Run commands reliably.

Check the translation

Run glaze format --validate before the first glaze up. It decodes the profile and reports each problem that it can find, with the file and the line, before tmux starts:

Console
$ glaze format --validate --stdout > /dev/null
Error: Invalid layout specified

  on /home/v/runs/arasaka/.glaze line 9, in session:
   9:     layout = "main-diagonal"

The layout value of "main-diagonal" is not a supported preset
(even-horizontal, even-vertical, main-horizontal, main-vertical, tiled) nor a
valid tmux layout string.

the glaze profile contains errors

Without --stdout, format also rewrites the profile into the canonical form, which is a fine first step for a file you just typed by hand. See glaze format.

Two files, same workspace. Keep the one you prefer.