fix(infra): tmux_swap_window_into_console base-index-agnostico
La funcion direccionaba panes por indice literal ("console.0",
"windowID.0", filtro pane_index != "0"). El socket aislado de fleetview
(tmux -L fleet) hereda ~/.tmux.conf, asi que con `pane-base-index 1`
(config muy comun) el primer pane es el indice 1 y no existe el 0:
join-pane fallaba con "can't find pane: 0" tras haber hecho ya el
break-pane, dejando la sesion fleet con las windows desperdigadas y sin
el sidebar de la TUI.
Ahora resuelve el pane sidebar como el de MENOR pane_index y opera
siempre por pane_id (estable e inmune al base-index). Helpers nuevos:
tmuxConsolePanes, tmuxFirstPaneID, tmuxPanesSorted, tmuxSidebarWidth.
Tests actualizados a base-index-agnostico (localizan el sidebar por
menor indice, no por "0") y el default de ancho del sidebar pasa de 47
a 52 para coincidir con launch_fleetclaude.
Bump v1.0.0 -> v1.0.1 + Capability growth log.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,23 +4,31 @@ package infra
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// TmuxSwapWindowIntoConsole trae el primer pane de <windowID> al pane derecho
|
||||
// de la window "console" de <session> (al lado del pane 0 = la TUI), parkeando
|
||||
// el Claude que estuviera a la derecha en su propia window (detached, sin robar
|
||||
// foco), y re-fija el ancho del pane 0 (TUI) a 40 columnas.
|
||||
// de la window "console" de <session> (al lado del pane sidebar = la TUI),
|
||||
// parkeando el Claude que estuviera a la derecha en su propia window (detached,
|
||||
// sin robar foco), y re-fija el ancho del pane sidebar al que tuviera antes.
|
||||
//
|
||||
// Contrato de la window console:
|
||||
// - pane indice 0 = siempre la TUI fleetview (no se toca).
|
||||
// - pane MAS A LA IZQUIERDA (menor pane_index) = siempre la TUI fleetview.
|
||||
// - cualquier otro pane en console = el Claude activo (puede no haber ninguno).
|
||||
//
|
||||
// Idempotente: si <windowID> ES ya la window console, no hace nada. Si el Claude
|
||||
// objetivo ya esta en console, tampoco rompe nada (el break-pane se aplica al
|
||||
// pane derecho que estuviera; si no lo hay, se salta). Opera SIEMPRE sobre el
|
||||
// socket aislado pasado como parametro (tmux -L <socket>).
|
||||
// NOTA base-index: el socket aislado (tmux -L <socket>) sigue leyendo
|
||||
// ~/.tmux.conf, asi que si el usuario tiene `pane-base-index 1` (muy comun) el
|
||||
// primer pane es el indice 1, no 0. Por eso esta funcion NUNCA referencia panes
|
||||
// por indice literal "0": resuelve el pane sidebar como el de MENOR pane_index y
|
||||
// opera siempre por pane_id, que es estable e inmune al base-index. Targetear
|
||||
// "console.0" rompia con "can't find pane: 0" en esas configuraciones.
|
||||
//
|
||||
// Idempotente: si <windowID> ES ya la window console, no hace nada salvo
|
||||
// re-fijar el ancho del sidebar. Si el Claude objetivo ya esta en console,
|
||||
// tampoco rompe nada. Opera SIEMPRE sobre el socket aislado pasado como
|
||||
// parametro (tmux -L <socket>).
|
||||
func TmuxSwapWindowIntoConsole(socket, session, windowID string) error {
|
||||
if socket == "" {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: socket vacio")
|
||||
@@ -32,13 +40,11 @@ func TmuxSwapWindowIntoConsole(socket, session, windowID string) error {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: windowID vacio")
|
||||
}
|
||||
|
||||
consoleTarget := session + ":console"
|
||||
|
||||
// Capturar el ancho ACTUAL del pane 0 (la TUI) antes de tocar nada, para
|
||||
// preservarlo tras el break/join (que redistribuyen el espacio). Así el ancho
|
||||
// del sidebar lo decide quien creó la sesión (launch_kittyclaude), no un valor
|
||||
// fijo aquí.
|
||||
width := tmuxPane0Width(socket, session)
|
||||
// Capturar el ancho ACTUAL del pane sidebar (la TUI) antes de tocar nada,
|
||||
// para preservarlo tras el break/join (que redistribuyen el espacio). Asi el
|
||||
// ancho del sidebar lo decide quien creo la sesion (launch_fleetclaude), no un
|
||||
// valor fijo aqui.
|
||||
width := tmuxSidebarWidth(socket, session)
|
||||
|
||||
// Caso borde: si windowID ya ES la window console, no hay nada que hacer.
|
||||
// Resolvemos el window_id real de console y lo comparamos con el pedido.
|
||||
@@ -51,30 +57,18 @@ func TmuxSwapWindowIntoConsole(socket, session, windowID string) error {
|
||||
return tmuxResizeConsoleTUI(socket, session, width)
|
||||
}
|
||||
|
||||
// 1. Localiza el pane derecho actual de console (cualquier pane con indice != 0).
|
||||
out, stderr, err := runTmux(socket, "list-panes", "-t", consoleTarget, "-F", "#{pane_index} #{pane_id}")
|
||||
// 1. Localiza el pane sidebar (TUI, menor indice) y el pane derecho actual
|
||||
// (cualquier otro) de console, ambos por pane_id.
|
||||
tuiPaneID, rightPaneID, err := tmuxConsolePanes(socket, session)
|
||||
if err != nil {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: list-panes de %q: %w (%s)", consoleTarget, err, stderr)
|
||||
return err
|
||||
}
|
||||
if tuiPaneID == "" {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: console sin panes en %q", session)
|
||||
}
|
||||
|
||||
var rightPaneID string
|
||||
for _, line := range strings.Split(strings.TrimSpace(out), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 2 {
|
||||
continue
|
||||
}
|
||||
if fields[0] != "0" {
|
||||
rightPaneID = fields[1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Si existe un pane no-0 en console, sacarlo a su propia window (parking),
|
||||
// detached y sin cambiar foco.
|
||||
// 2. Si existe un pane no-sidebar en console, sacarlo a su propia window
|
||||
// (parking), detached y sin cambiar foco.
|
||||
if rightPaneID != "" {
|
||||
if _, stderr, err := runTmux(socket, "break-pane", "-d", "-s", rightPaneID); err != nil {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: break-pane de %q: %w (%s)", rightPaneID, err, stderr)
|
||||
@@ -84,14 +78,19 @@ func TmuxSwapWindowIntoConsole(socket, session, windowID string) error {
|
||||
// 3. Traer el primer pane de windowID a la derecha de la TUI (-h = split
|
||||
// horizontal, lado a lado). join-pane requiere que origen y destino sean
|
||||
// windows distintas (ya garantizado: consoleID != windowID arriba).
|
||||
src := windowID + ".0"
|
||||
dst := consoleTarget + ".0"
|
||||
if _, stderr, err := runTmux(socket, "join-pane", "-h", "-s", src, "-t", dst); err != nil {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: join-pane %q -> %q: %w (%s)", src, dst, err, stderr)
|
||||
srcPaneID, err := tmuxFirstPaneID(socket, windowID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, stderr, err := runTmux(socket, "join-pane", "-h", "-s", srcPaneID, "-t", tuiPaneID); err != nil {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: join-pane %q -> %q: %w (%s)", srcPaneID, tuiPaneID, err, stderr)
|
||||
}
|
||||
|
||||
// 4. Re-fijar el ancho del pane 0 (TUI) al que tenia antes del swap.
|
||||
return tmuxResizeConsoleTUI(socket, session, width)
|
||||
// 4. Re-fijar el ancho del pane sidebar (TUI) al que tenia antes del swap.
|
||||
if _, stderr, err := runTmux(socket, "resize-pane", "-t", tuiPaneID, "-x", strconv.Itoa(width)); err != nil {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: resize-pane de %q a %d col: %w (%s)", tuiPaneID, width, err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// tmuxConsoleWindowID resuelve el window_id (ej "@3") de la window llamada
|
||||
@@ -113,36 +112,102 @@ func tmuxConsoleWindowID(socket, session string) (string, error) {
|
||||
return "", fmt.Errorf("tmux_swap_window_into_console: window 'console' no encontrada en %q", session)
|
||||
}
|
||||
|
||||
// tmuxPane0Width devuelve el ancho a preservar para el pane 0 (la TUI). Solo
|
||||
// tiene sentido leer el ancho actual si console ya tiene >1 pane (TUI + Claude);
|
||||
// con un único pane, el pane 0 es full-width y no representa el sidebar, así que
|
||||
// se usa el default (47 columnas).
|
||||
func tmuxPane0Width(socket, session string) int {
|
||||
const def = 52
|
||||
out, _, err := runTmux(socket, "list-panes", "-t", session+":console", "-F", "#{pane_index} #{pane_width}")
|
||||
// tmuxConsolePanes devuelve el pane_id del sidebar (pane de MENOR pane_index =
|
||||
// la TUI) y el pane_id del primer pane no-sidebar (el Claude actual, si lo hay)
|
||||
// de la window console. rightPaneID es "" si console solo tiene el sidebar.
|
||||
// Inmune al base-index porque ordena por pane_index numerico, no asume "0".
|
||||
func tmuxConsolePanes(socket, session string) (tuiPaneID, rightPaneID string, err error) {
|
||||
panes, err := tmuxPanesSorted(socket, session+":console")
|
||||
if err != nil {
|
||||
return def
|
||||
return "", "", fmt.Errorf("tmux_swap_window_into_console: %w", err)
|
||||
}
|
||||
lines := strings.Split(strings.TrimSpace(out), "\n")
|
||||
if len(lines) <= 1 {
|
||||
return def
|
||||
if len(panes) == 0 {
|
||||
return "", "", nil
|
||||
}
|
||||
for _, l := range lines {
|
||||
f := strings.Fields(strings.TrimSpace(l))
|
||||
if len(f) >= 2 && f[0] == "0" {
|
||||
if n, e := strconv.Atoi(f[1]); e == nil && n > 0 {
|
||||
return n
|
||||
tuiPaneID = panes[0].id
|
||||
if len(panes) > 1 {
|
||||
rightPaneID = panes[1].id
|
||||
}
|
||||
return tuiPaneID, rightPaneID, nil
|
||||
}
|
||||
|
||||
// tmuxFirstPaneID devuelve el pane_id del primer pane (menor pane_index) de la
|
||||
// window <windowID>.
|
||||
func tmuxFirstPaneID(socket, windowID string) (string, error) {
|
||||
panes, err := tmuxPanesSorted(socket, windowID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("tmux_swap_window_into_console: %w", err)
|
||||
}
|
||||
if len(panes) == 0 {
|
||||
return "", fmt.Errorf("tmux_swap_window_into_console: window %q sin panes", windowID)
|
||||
}
|
||||
return panes[0].id, nil
|
||||
}
|
||||
|
||||
type tmuxPaneRef struct {
|
||||
index int
|
||||
id string
|
||||
width int
|
||||
}
|
||||
|
||||
// tmuxPanesSorted lista los panes de <target> ordenados por pane_index
|
||||
// ascendente. El primero es el mas a la izquierda/arriba (el sidebar en
|
||||
// console).
|
||||
func tmuxPanesSorted(socket, target string) ([]tmuxPaneRef, error) {
|
||||
out, stderr, err := runTmux(socket, "list-panes", "-t", target, "-F", "#{pane_index} #{pane_id} #{pane_width}")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list-panes de %q: %w (%s)", target, err, stderr)
|
||||
}
|
||||
var panes []tmuxPaneRef
|
||||
for _, line := range strings.Split(strings.TrimSpace(out), "\n") {
|
||||
fields := strings.Fields(strings.TrimSpace(line))
|
||||
if len(fields) < 2 {
|
||||
continue
|
||||
}
|
||||
idx, e := strconv.Atoi(fields[0])
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
ref := tmuxPaneRef{index: idx, id: fields[1]}
|
||||
if len(fields) >= 3 {
|
||||
if w, e := strconv.Atoi(fields[2]); e == nil {
|
||||
ref.width = w
|
||||
}
|
||||
}
|
||||
panes = append(panes, ref)
|
||||
}
|
||||
sort.Slice(panes, func(i, j int) bool { return panes[i].index < panes[j].index })
|
||||
return panes, nil
|
||||
}
|
||||
|
||||
// tmuxSidebarWidth devuelve el ancho a preservar para el pane sidebar (la TUI).
|
||||
// Solo tiene sentido leer el ancho actual si console ya tiene >1 pane (TUI +
|
||||
// Claude); con un unico pane, el sidebar es full-width y no representa el ancho
|
||||
// real del sidebar, asi que se usa el default.
|
||||
func tmuxSidebarWidth(socket, session string) int {
|
||||
const def = 52
|
||||
panes, err := tmuxPanesSorted(socket, session+":console")
|
||||
if err != nil || len(panes) <= 1 {
|
||||
return def
|
||||
}
|
||||
if w := panes[0].width; w > 0 {
|
||||
return w
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
// tmuxResizeConsoleTUI fija el ancho del pane 0 de console a width columnas.
|
||||
// tmuxResizeConsoleTUI fija el ancho del pane sidebar de console a width
|
||||
// columnas, resolviendo su pane_id (no asume el indice 0).
|
||||
func tmuxResizeConsoleTUI(socket, session string, width int) error {
|
||||
target := session + ":console.0"
|
||||
if _, stderr, err := runTmux(socket, "resize-pane", "-t", target, "-x", strconv.Itoa(width)); err != nil {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: resize-pane de %q a %d col: %w (%s)", target, width, err, stderr)
|
||||
tuiPaneID, _, err := tmuxConsolePanes(socket, session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tuiPaneID == "" {
|
||||
return nil // console sin panes: nada que redimensionar
|
||||
}
|
||||
if _, stderr, err := runTmux(socket, "resize-pane", "-t", tuiPaneID, "-x", strconv.Itoa(width)); err != nil {
|
||||
return fmt.Errorf("tmux_swap_window_into_console: resize-pane de %q a %d col: %w (%s)", tuiPaneID, width, err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ name: tmux_swap_window_into_console
|
||||
kind: function
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "1.0.0"
|
||||
version: "1.0.1"
|
||||
purity: impure
|
||||
signature: "func TmuxSwapWindowIntoConsole(socket, session, windowID string) error"
|
||||
description: "Conmuta que Claude esta a la derecha de la TUI fleetview en una sesion tmux de un socket aislado (tmux -L <socket>). Trae el primer pane de <windowID> al pane derecho de la window 'console' (al lado del pane 0 = la TUI), parkea en su propia window el Claude que estuviera a la derecha (detached, sin robar foco) y re-fija el ancho del pane 0 a 40 columnas. Idempotente: si el objetivo ya es la window console no hace nada. Capa de control tmux de la app TUI fleetview."
|
||||
description: "Conmuta que Claude esta a la derecha de la TUI fleetview en una sesion tmux de un socket aislado (tmux -L <socket>). Trae el primer pane de <windowID> al pane derecho de la window 'console' (al lado del pane sidebar = la TUI), parkea en su propia window el Claude que estuviera a la derecha (detached, sin robar foco) y re-fija el ancho del sidebar al que tuviera antes (default 52 col). El sidebar se resuelve como el pane de MENOR pane_index y se opera por pane_id, NO por indice literal 0: inmune a `pane-base-index 1` del ~/.tmux.conf del usuario. Idempotente: si el objetivo ya es la window console solo re-aplica el ancho. Capa de control tmux de la app TUI fleetview."
|
||||
tags: [claude-fleet, infra, tmux, claude, fleet, tui]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
@@ -21,12 +21,12 @@ params:
|
||||
desc: "Sesion tmux que contiene la window 'console' (ej 'fleet'). El pane 0 de console es la TUI; el resto, el Claude activo."
|
||||
- name: "windowID"
|
||||
desc: "window_id (@N) de la window cuyo primer pane se quiere traer a la derecha de la TUI. Tipicamente el devuelto por tmux_new_claude_window o por tmux_map_claude_panes."
|
||||
output: "nil en exito. Error si socket/session/windowID vienen vacios, si la window 'console' no existe en la sesion, o si alguno de los comandos tmux (list-panes, break-pane, join-pane, resize-pane) falla. El estado final de console: pane 0 = TUI (40 col) + pane derecho = el Claude de windowID."
|
||||
output: "nil en exito. Error si socket/session/windowID vienen vacios, si la window 'console' no existe en la sesion, o si alguno de los comandos tmux (list-panes, break-pane, join-pane, resize-pane) falla. El estado final de console: pane sidebar (menor indice) = TUI (52 col por default) + pane derecho = el Claude de windowID."
|
||||
tested: true
|
||||
tests: ["TestTmuxSwapWindowIntoConsole", "TestTmuxSwapWindowIntoConsoleParksPrevious", "TestTmuxSwapWindowIntoConsoleEmptyArgs"]
|
||||
test_file_path: "functions/infra/tmux_swap_window_into_console_test.go"
|
||||
file_path: "functions/infra/tmux_swap_window_into_console.go"
|
||||
notes: "Build tag //go:build !windows. Comparte runTmux con tmux_new_claude_window y tmux_map_claude_panes (mismo paquete infra). Secuencia interna: (1) list-panes de console y localiza el pane no-0 actual; (2) break-pane -d de ese pane si existe (parking); (3) join-pane -h del primer pane de windowID a console.0 (lado a lado); (4) resize-pane -x 40 del pane 0. Caso borde: si windowID ya ES la window console, solo re-aplica el resize. break-pane requiere que la window destino sea distinta del origen, garantizado por la comprobacion consoleID != windowID."
|
||||
notes: "Build tag //go:build !windows. Comparte runTmux con tmux_new_claude_window y tmux_map_claude_panes (mismo paquete infra). Secuencia interna: (1) list-panes de console ordenados por pane_index, sidebar = menor indice (TUI), right = primer pane no-sidebar; (2) break-pane -d del right si existe (parking); (3) join-pane -h del primer pane de windowID a la derecha del sidebar (por pane_id); (4) resize-pane -x <ancho> del sidebar por pane_id. Caso borde: si windowID ya ES la window console, solo re-aplica el resize. TODO targeting es por pane_id, NUNCA por indice literal 0 (rompia con 'can't find pane: 0' bajo pane-base-index 1 que el socket aislado hereda de ~/.tmux.conf). break-pane requiere que la window destino sea distinta del origen, garantizado por la comprobacion consoleID != windowID."
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
@@ -52,9 +52,14 @@ Cada vez que el usuario conmuta en fleetview que Claude quiere ver a la derecha.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Idempotente: si el Claude objetivo ya es la window console, solo re-aplica el ancho de 40 col; no rompe nada.
|
||||
- El pane indice 0 de console es SIEMPRE la TUI y nunca se mueve ni se parkea: la funcion solo toca el pane derecho (indice != 0).
|
||||
- Idempotente: si el Claude objetivo ya es la window console, solo re-aplica el ancho del sidebar; no rompe nada.
|
||||
- El pane sidebar de console (el de MENOR pane_index) es SIEMPRE la TUI y nunca se mueve ni se parkea: la funcion solo toca el pane derecho (cualquier otro pane).
|
||||
- NO asume que el sidebar es el indice 0. El socket aislado (`tmux -L <socket>`) hereda `~/.tmux.conf`, asi que con `pane-base-index 1` (muy comun) el primer pane es el indice 1. Targetear `console.0` rompia con `can't find pane: 0` y dejaba console a medias (break ya hecho, join fallido). Por eso todo el targeting es por `pane_id`.
|
||||
- `join-pane` exige que la window origen sea distinta de console; la funcion lo comprueba (consoleID != windowID) y si coinciden no hace el join.
|
||||
- `break-pane -d` saca el Claude anterior a su propia window detached: sigue vivo y parkeado, no se mata.
|
||||
- El ancho de 40 col se re-fija SIEMPRE al final (incluso en el caso borde) para que la TUI no se reduzca tras el reflow del split.
|
||||
- El ancho del sidebar se re-fija SIEMPRE al final (incluso en el caso borde) para que la TUI no se reduzca tras el reflow del split.
|
||||
- Opera SIEMPRE sobre el socket aislado (`tmux -L <socket>`). Build tag `//go:build !windows`.
|
||||
|
||||
## Capability growth log
|
||||
|
||||
- v1.0.1 (2026-06-17) — fix: resuelve el pane sidebar por menor `pane_index` y opera por `pane_id` en vez de `console.0`/indice 0. Antes rompia con `can't find pane: 0` bajo `pane-base-index 1` (el socket aislado hereda ~/.tmux.conf), dejando la sesion fleet con las windows desperdigadas y sin sidebar. Tests actualizados a base-index-agnostico; default de ancho del sidebar 47 -> 52 (coincide con launch_fleetclaude).
|
||||
|
||||
@@ -62,30 +62,38 @@ func TestTmuxSwapWindowIntoConsole(t *testing.T) {
|
||||
t.Fatalf("TmuxSwapWindowIntoConsole: %v", err)
|
||||
}
|
||||
|
||||
// Tras el swap: console tiene 2 panes y el pane 0 mide 47 columnas (default
|
||||
// del sidebar, ya que la console arrancó con un solo pane full-width).
|
||||
// Tras el swap: console tiene 2 panes y el sidebar (pane de MENOR indice)
|
||||
// mide 52 columnas (default del sidebar, ya que la console arrancó con un
|
||||
// solo pane full-width). Se localiza por menor pane_index, NO por indice
|
||||
// literal "0": bajo `pane-base-index 1` (que el socket hereda de
|
||||
// ~/.tmux.conf) el primer pane es el indice 1.
|
||||
panes := consolePanes(t, socket, session)
|
||||
if len(panes) != 2 {
|
||||
t.Fatalf("console deberia tener 2 panes tras swap, tiene %d: %v", len(panes), panes)
|
||||
}
|
||||
var width0 int
|
||||
found0 := false
|
||||
minIdx, sidebarWidth, found := -1, 0, false
|
||||
for _, line := range panes {
|
||||
f := strings.Fields(line)
|
||||
if len(f) >= 3 && f[0] == "0" {
|
||||
found0 = true
|
||||
w, err := strconv.Atoi(f[2])
|
||||
if err != nil {
|
||||
t.Fatalf("ancho del pane 0 no numerico: %q", f[2])
|
||||
}
|
||||
width0 = w
|
||||
if len(f) < 3 {
|
||||
continue
|
||||
}
|
||||
idx, err := strconv.Atoi(f[0])
|
||||
if err != nil {
|
||||
t.Fatalf("pane_index no numerico: %q", f[0])
|
||||
}
|
||||
w, err := strconv.Atoi(f[2])
|
||||
if err != nil {
|
||||
t.Fatalf("ancho de pane no numerico: %q", f[2])
|
||||
}
|
||||
if !found || idx < minIdx {
|
||||
minIdx, sidebarWidth, found = idx, w, true
|
||||
}
|
||||
}
|
||||
if !found0 {
|
||||
t.Fatal("no se encontro el pane 0 en console")
|
||||
if !found {
|
||||
t.Fatal("no se encontro ningun pane en console")
|
||||
}
|
||||
if width0 != 47 {
|
||||
t.Errorf("ancho del pane 0 = %d, esperado 47", width0)
|
||||
if sidebarWidth != 52 {
|
||||
t.Errorf("ancho del sidebar (pane menor indice = %d) = %d, esperado 52", minIdx, sidebarWidth)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user