turbo-editors/turbo-corepublic Fork 0
d662cebdb65b319885da903daf7eff9ab1bfbb78
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

🛟 Updated. 28d5985 · on d662cebdb65b319885da903daf7eff9ab1bfbb78 · k33g · 19h ago
marks.go · 85 lines · 2.9 KBGo Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Marks in the gutter: a character beside a line saying something is wrong
// with it.

package editor

import "codeberg.org/turbo-editors/turbo-core/theme"

// Severity is how serious a mark is.
//
// This is the editor's own type, not the language server's, and deliberately
// so: this package colours and draws text, and knows nothing about protocols.
// Whoever holds the diagnostics translates them into these on the way in.
//
//	view.SetMarks(map[int]editor.Severity{41: editor.MarkError})
type Severity int

// The severities a mark may have, in the order a line's worst one is chosen.
const (
	// MarkNone is the zero value: a line with nothing wrong with it.
	MarkNone Severity = iota
	MarkHint
	MarkInformation
	MarkWarning
	MarkError
)

// markGlyphs are what each severity draws. They are single characters from the
// range every terminal font has, because the gutter has exactly one column to
// spare and a glyph that renders as a box is worse than a letter.
var markGlyphs = map[Severity]rune{
	MarkError:       '×',
	MarkWarning:     '!',
	MarkInformation: 'i',
	MarkHint:        '·',
}

// markStyles are the theme keys each severity is drawn in.
var markStyles = map[Severity]string{
	MarkError:       theme.KeyDiagnosticError,
	MarkWarning:     theme.KeyDiagnosticWarning,
	MarkInformation: theme.KeyDiagnosticInfo,
	MarkHint:        theme.KeyDiagnosticInfo,
}

// SetMarks says which lines have something wrong with them, keyed by
// zero-based line number.
//
// Passing nil clears them, which is what a file with nothing wrong wants.
//
//	view.SetMarks(map[int]editor.Severity{0: editor.MarkWarning, 12: editor.MarkError})
func (v *View) SetMarks(marks map[int]Severity) { v.marks = marks }

// Marks returns what SetMarks was given.
func (v *View) Marks() map[int]Severity { return v.marks }

// markOf returns the severity to draw beside a line, and whether there is one.
func (v *View) markOf(line int) (Severity, bool) {
	severity, marked := v.marks[line]
	if !marked || severity == MarkNone {
		return MarkNone, false
	}
	return severity, true
}

// drawMark paints the mark for a line, in the column that separates the line
// numbers from the text.
//
// That column rather than a new one: the gutter is already `digits + 1` wide,
// the +1 being the separator, so a mark costs no layout and nothing has to be
// recomputed — not the text's left edge, not the cursor's screen column, not
// the column a mouse click lands on.
//
// The consequence is that hiding the line numbers hides the marks. The
// alternative — a one-column gutter appearing when the numbers are off — would
// make the text jump sideways the moment a server reported anything.
func (v *View) drawMark(p *Painter, th *theme.Theme, row, line int) {
	if !v.lineNumbers {
		return
	}
	severity, marked := v.markOf(line)
	if !marked {
		return
	}
	p.Text(v.gutterWidth()-1, row, string(markGlyphs[severity]), th.Style(markStyles[severity]))
}