gtk_entry_target.go RawHistoryFolder
1package textinput
2
3import (
4 "context"
5
6 "github.com/bnema/dumber/internal/application/port"
7 "github.com/bnema/dumber/internal/logging"
8 "github.com/jwijenbergh/puregotk/v4/gtk"
9)
10
11// GTKEntryTarget implements TextInputTarget for GTK SearchEntry widgets.
12// It uses the Editable interface methods to insert and delete text.
13type GTKEntryTarget struct {
14 entry *gtk.SearchEntry
15}
16
17// Compile-time interface check.
18var _ port.TextInputTarget = (*GTKEntryTarget)(nil)
19
20// NewGTKEntryTarget creates a new GTK entry target for a SearchEntry.
21func NewGTKEntryTarget(entry *gtk.SearchEntry) *GTKEntryTarget {
22 return >KEntryTarget{entry: entry}
23}
24
25// InsertText inserts text at the current cursor position.
26func (t *GTKEntryTarget) InsertText(ctx context.Context, text string) error {
27 log := logging.FromContext(ctx)
28
29 if t.entry == nil {
30 log.Warn().Msg("GTKEntryTarget: entry is nil")
31 return nil
32 }
33
34 // Get current text and cursor position
35 currentText := t.entry.GetText()
36 pos := t.entry.GetPosition()
37
38 // Convert to runes for proper Unicode handling
39 runes := []rune(currentText)
40 textRunes := []rune(text)
41
42 // Clamp position to valid range
43 if pos < 0 {
44 pos = 0
45 }
46 if pos > len(runes) {
47 pos = len(runes)
48 }
49
50 // Build new text with insertion
51 newRunes := make([]rune, 0, len(runes)+len(textRunes))
52 newRunes = append(newRunes, runes[:pos]...)
53 newRunes = append(newRunes, textRunes...)
54 newRunes = append(newRunes, runes[pos:]...)
55
56 // Set new text and cursor position
57 t.entry.SetText(string(newRunes))
58 newPos := pos + len(textRunes)
59 t.entry.SetPosition(newPos)
60
61 log.Debug().
62 Str("text", text).
63 Int("pos", pos).
64 Msg("inserted text into GTK entry")
65
66 return nil
67}
68
69// DeleteBeforeCursor deletes n characters before the cursor position.
70func (t *GTKEntryTarget) DeleteBeforeCursor(ctx context.Context, n int) error {
71 log := logging.FromContext(ctx)
72
73 if t.entry == nil {
74 log.Warn().Msg("GTKEntryTarget: entry is nil")
75 return nil
76 }
77
78 pos := t.entry.GetPosition()
79 if pos < n {
80 n = pos // Don't delete more than available
81 }
82
83 if n <= 0 {
84 return nil
85 }
86
87 // DeleteText takes start and end positions
88 t.entry.DeleteText(pos-n, pos)
89
90 log.Debug().
91 Int("n", n).
92 Int("pos", pos).
93 Msg("deleted text before cursor in GTK entry")
94
95 return nil
96}