Files
vmux/i3bridge.go
Pierre Martin 9427dd3eda feat(02-02): implement fuzzy match + switch workspace + i3 commander
- FuzzyMatch searches label > branch > cwd (case-insensitive)
- SwitchToWorkspace sends 'workspace number N' via I3Commander interface
- RealI3Commander wraps go.i3wm.org/i3/v4 RunCommand
- 9 tests covering priority, no-match, case-insensitive, errors
2026-03-23 17:45:32 +01:00

67 lines
1.5 KiB
Go

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
}