Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions internal/plugins/tdmonitor/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os/exec"
"time"

"github.com/atotto/clipboard"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/marcus/td/pkg/monitor"
Expand Down Expand Up @@ -119,6 +120,11 @@ func (p *Plugin) Init(ctx *plugin.Context) error {

p.model = model

// Use sidecar's clipboard (atotto/clipboard) instead of td's built-in one.
// td's copyToClipboard doesn't handle WSL (tries xclip/xsel only);
// atotto/clipboard falls through to clip.exe on WSL.
model.ClipboardFn = clipboard.WriteAll

// Register TD bindings with sidecar's keymap (single source of truth)
if ctx.Keymap != nil && model.Keymap != nil {
for _, b := range model.Keymap.ExportBindings() {
Expand Down
39 changes: 39 additions & 0 deletions internal/plugins/tdmonitor/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tdmonitor
import (
"log/slog"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
Expand Down Expand Up @@ -158,6 +159,44 @@ func TestInitWithValidDatabase(t *testing.T) {
p.Stop()
}

func TestInitSetsClipboardFn(t *testing.T) {
// Create a temp directory with a td database so we don't depend on
// the repo having one.
tmpDir, err := os.MkdirTemp("", "tdmonitor-clipboard-*")
if err != nil {
t.Fatalf("failed to create temp dir: %v", err)
}
defer func() { _ = os.RemoveAll(tmpDir) }()

// Initialize td in the temp directory
cmd := exec.Command("td", "init")
cmd.Dir = tmpDir
if out, err := cmd.CombinedOutput(); err != nil {
t.Skipf("td init failed (td not installed?): %s: %v", out, err)
}

p := New()
ctx := &plugin.Context{
WorkDir: tmpDir,
Logger: slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})),
}

if err := p.Init(ctx); err != nil {
t.Fatalf("Init failed: %v", err)
}
defer p.Stop()

if p.model == nil {
t.Fatal("model should be created when database exists")
}

// ClipboardFn must be set so sidecar's clipboard (atotto/clipboard) is used
// instead of td's built-in one, which doesn't handle WSL.
if p.model.ClipboardFn == nil {
t.Error("model.ClipboardFn should be set to sidecar's clipboard implementation")
}
}

func TestDiagnosticsWithDatabase(t *testing.T) {
projectRoot := findProjectRootWithDB(t)

Expand Down