diff options
Diffstat (limited to 'gui/internal/ui/highlight.go')
| -rw-r--r-- | gui/internal/ui/highlight.go | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/gui/internal/ui/highlight.go b/gui/internal/ui/highlight.go new file mode 100644 index 0000000..8a4acd4 --- /dev/null +++ b/gui/internal/ui/highlight.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package ui + +import ( + "github.com/diamondburned/gotk4/pkg/gtk/v4" + + "krino/gui/internal/model" +) + +// The colours a configuration is painted in. They are chosen to read on a +// light and a dark theme alike, since the window follows whatever GTK theme +// is in use (his request, 2026-09-16). +var spanColours = map[model.SpanKind]string{ + model.SpanComment: "#8b8b8b", + model.SpanString: "#2e8b57", + model.SpanHead: "#3584e4", + model.SpanAction: "#c06014", + model.SpanParen: "#9a9a9a", +} + +// highlighter paints a configuration in a TextView. +type highlighter struct { + buf *gtk.TextBuffer + tags map[model.SpanKind]*gtk.TextTag + on bool +} + +// newHighlighter registers one tag per kind, once per buffer. +func newHighlighter(buf *gtk.TextBuffer) *highlighter { + h := &highlighter{buf: buf, tags: map[model.SpanKind]*gtk.TextTag{}, on: true} + table := buf.TagTable() + names := map[model.SpanKind]string{ + model.SpanComment: "krino-comment", + model.SpanString: "krino-string", + model.SpanHead: "krino-head", + model.SpanAction: "krino-action", + model.SpanParen: "krino-paren", + } + for kind, name := range names { + t := gtk.NewTextTag(name) + t.SetObjectProperty("foreground", spanColours[kind]) + if kind == model.SpanComment { + t.SetObjectProperty("style", 2) // PANGO_STYLE_ITALIC + } + table.Add(t) + h.tags[kind] = t + } + return h +} + +// setEnabled turns the colours on or off. +func (h *highlighter) setEnabled(on bool) { + h.on = on + if !on { + h.clear() + } +} + +// clear takes every colour off the buffer. +func (h *highlighter) clear() { + start, end := h.buf.Bounds() + h.buf.RemoveAllTags(start, end) +} + +// paint colours the text now in the buffer. +func (h *highlighter) paint(text string) { + h.clear() + if !h.on { + return + } + for _, s := range model.Spans(text) { + if tag, ok := h.tags[s.Kind]; ok { + h.buf.ApplyTag(tag, h.buf.IterAtOffset(s.From), h.buf.IterAtOffset(s.To)) + } + } +} |
