El enfoque que utilizo combina un poco la respuesta de Ashish con la de piec; tengo las flechas alt-izquierda y derecha vinculadas a una pequeña y rápida llamada de shell que mueve la ventana una a la izquierda o a la derecha, a menos que sea la primera o la última ventana, respectivamente. Hice esto porque, cuando emites un swap +1 en la última ventana (o swap -1 en la primera ventana), seguirá intercambiando, en lugar de volver a hacer un bucle como podrías esperar:
0:one 1:two 2:three 3:zero*
Se convierte en
0:zero* 1:two 2:three 3:one
En lugar de
0:zero* 1:one 2:two 3:three
Así, los comandos que uso dejan de funcionar cuando la ventana ha llegado al borde de la lista:
bind-key -n M-Left run-shell 'tmux list-windows | head -n 1 | grep -q active || tmux swap-window -t -1'
bind-key -n M-Right run-shell 'tmux list-windows | tail -n 1 | grep -q active || tmux swap-window -t +1'
Esto se puede combinar fácilmente con base-index y renumber-windows para tener una lista de ventanas que empiece en un número arbitrario y que nunca tenga huecos.
Si estás usando base-index 1 como yo y no crees que vayas a pasar nunca de 999 ventanas, puedes usar un pequeño truco para que ruede correctamente, aunque los comandos se hinchan un poco:
set -g base-index 1
set -g renumber-windows on
bind-key -n M-Left run-shell 'if tmux list-windows | head -n 1 | grep -q active ; then tmux move-window -t 999 \; move-window -r \; refresh-client -S ; else tmux swap-window -t -1 ; fi'
bind-key -n M-Right run-shell 'if tmux list-windows | tail -n 1 | grep -q active ; then tmux move-window -t 0 \; move-window -r \; refresh-client -S ; else tmux swap-window -t +1 ; fi'
Esto funciona moviendo temporalmente la última ventana al índice-0 no utilizado y luego llamando a move-window -r para volver a numerarlas empezando por el 1. Funciona de forma similar cuando se mueve la primera ventana al final; escogiendo un número enorme que nunca se usará, se asegura que cuando move-window -r se dispara de nuevo todo estará numerado como se espera. Si te preguntas por refresh-client -S , es necesario porque a veces, mientras la reordenación de move-window funciona correctamente, la barra de estado no se actualiza hasta que se hacen más cambios. Al forzar un refresco sólo de la barra de estado (-S), se evita esto.
El único problema que puedo encontrar con este enfoque es que swap-window alterará implícitamente la última ventana utilizada a la que se intercambió. Así, si estás en la ventana #1, cambias a la ventana cuatro y la mueves hacia atrás una, encontrarás que tu última ventana usada es la nueva #4 (antes #3) en lugar de la #1. No parece haber una forma de evitar esto.