package main import ( "fmt" "strings" i3 "go.i3wm.org/i3/v4" ) // I3Commander abstrait i3.RunCommand pour testabilite. type I3Commander interface { RunCommand(command string) ([]i3.CommandResult, error) } // RealI3Commander utilise go.i3wm.org/i3/v4 directement. type RealI3Commander struct{} func (c RealI3Commander) RunCommand(cmd string) ([]i3.CommandResult, error) { return i3.RunCommand(cmd) } // FuzzyMatch trouve la premiere session matchant query dans : label > branche > cwd. // Case-insensitive. Retourne nil si aucun match. func FuzzyMatch(query string, sessions []SessionInfo) *SessionInfo { q := strings.ToLower(query) // Priorite 1 : label for i := range sessions { if sessions[i].Label != "" && strings.Contains(strings.ToLower(sessions[i].Label), q) { return &sessions[i] } } // Priorite 2 : branche git for i := range sessions { if strings.Contains(strings.ToLower(sessions[i].GitBranch), q) { return &sessions[i] } } // Priorite 3 : cwd for i := range sessions { if strings.Contains(strings.ToLower(sessions[i].Cwd), q) { return &sessions[i] } } return nil } // SwitchToWorkspace bascule vers le workspace indique via i3 IPC. func SwitchToWorkspace(commander I3Commander, wsName string) error { cmd := fmt.Sprintf("workspace number %s", wsName) results, err := commander.RunCommand(cmd) if err != nil { return fmt.Errorf("i3 RunCommand: %w", err) } for _, r := range results { if !r.Success { return fmt.Errorf("i3 workspace switch failed: %s", r.Error) } } return nil }