commit 65237b8

delthas  ·  2023-12-27 13:55:48 +0000 UTC
parent 1ad07b5
Mention pressing escape to close /search
4 files changed,  +51, -24
M app.go
M app.go
+1, -1
1@@ -1027,7 +1027,7 @@ func (app *App) handleIRCEvent(netID string, ev interface{}) {
2 			app.messageBounds[boundKey{netID, ev.Target}] = boundsNew
3 		}
4 	case irc.SearchEvent:
5-		app.win.OpenOverlay()
6+		app.win.OpenOverlay("Press Escape to close the search results")
7 		lines := make([]ui.Line, 0, len(ev.Messages))
8 		for _, m := range ev.Messages {
9 			_, line := app.formatMessage(s, m)
+22, -6
 1@@ -16,6 +16,8 @@ type Completion struct {
 2 
 3 // Editor is the text field where the user writes messages and commands.
 4 type Editor struct {
 5+	colors ConfigColors
 6+
 7 	// text contains the written runes. An empty slice means no text is written.
 8 	text [][]rune
 9 
10@@ -56,8 +58,9 @@ type Editor struct {
11 
12 // NewEditor returns a new Editor.
13 // Call Resize() once before using it.
14-func NewEditor(autoComplete func(cursorIdx int, text []rune) []Completion) Editor {
15+func NewEditor(colors ConfigColors, autoComplete func(cursorIdx int, text []rune) []Completion) Editor {
16 	return Editor{
17+		colors:       colors,
18 		text:         [][]rune{{}},
19 		history:      [][]rune{},
20 		textWidth:    []int{0},
21@@ -452,11 +455,20 @@ func (e *Editor) bumpOldestChange() {
22 	}
23 }
24 
25-func (e *Editor) Draw(screen tcell.Screen, x0, y int) {
26+func (e *Editor) Draw(screen tcell.Screen, x0, y int, hint string) {
27 	st := tcell.StyleDefault
28 
29 	x := x0
30 	i := e.offsetIdx
31+	text := e.text[e.lineIdx]
32+	showCursor := true
33+
34+	if len(text) == 0 && len(hint) > 0 && !e.backsearch {
35+		i = 0
36+		text = []rune(hint)
37+		st = st.Foreground(e.colors.Status)
38+		showCursor = false
39+	}
40 
41 	autoStart := -1
42 	autoEnd := -1
43@@ -466,8 +478,8 @@ func (e *Editor) Draw(screen tcell.Screen, x0, y int) {
44 		autoEnd = e.autoCache[e.autoCacheIdx].EndIdx
45 	}
46 
47-	for i < len(e.text[e.lineIdx]) && x < x0+e.width {
48-		r := e.text[e.lineIdx][i]
49+	for i < len(text) && x < x0+e.width {
50+		r := text[i]
51 		s := st
52 		if e.backsearch && i < e.cursorIdx && i >= e.cursorIdx-len(e.backsearchPattern) {
53 			s = s.Underline(true)
54@@ -533,8 +545,12 @@ func (e *Editor) Draw(screen tcell.Screen, x0, y int) {
55 		}
56 	}
57 
58-	cursorX := x0 + e.textWidth[e.cursorIdx] - e.textWidth[e.offsetIdx]
59-	screen.ShowCursor(cursorX, y)
60+	if showCursor {
61+		cursorX := x0 + e.textWidth[e.cursorIdx] - e.textWidth[e.offsetIdx]
62+		screen.ShowCursor(cursorX, y)
63+	} else {
64+		screen.HideCursor()
65+	}
66 }
67 
68 // runeOffset returns the lowercase version of a rune
+5, -5
 1@@ -51,7 +51,7 @@ func assertEditorEq(t *testing.T, actual, expected Editor) {
 2 }
 3 
 4 func TestOneLetter(t *testing.T) {
 5-	e := NewEditor(nil)
 6+	e := NewEditor(ConfigColors{}, nil)
 7 	e.Resize(5)
 8 	e.PutRune('h')
 9 	assertEditorEq(t, e, Editor{
10@@ -64,7 +64,7 @@ func TestOneLetter(t *testing.T) {
11 }
12 
13 func TestFourLetters(t *testing.T) {
14-	e := NewEditor(nil)
15+	e := NewEditor(ConfigColors{}, nil)
16 	e.Resize(5)
17 	e.PutRune('h')
18 	e.PutRune('e')
19@@ -74,7 +74,7 @@ func TestFourLetters(t *testing.T) {
20 }
21 
22 func TestOneLeft(t *testing.T) {
23-	e := NewEditor(nil)
24+	e := NewEditor(ConfigColors{}, nil)
25 	e.Resize(5)
26 	e.PutRune('h')
27 	e.PutRune('l')
28@@ -86,7 +86,7 @@ func TestOneLeft(t *testing.T) {
29 }
30 
31 func TestOneRem(t *testing.T) {
32-	e := NewEditor(nil)
33+	e := NewEditor(ConfigColors{}, nil)
34 	e.Resize(5)
35 	e.PutRune('h')
36 	e.PutRune('l')
37@@ -98,7 +98,7 @@ func TestOneRem(t *testing.T) {
38 }
39 
40 func TestLeftAndRem(t *testing.T) {
41-	e := NewEditor(nil)
42+	e := NewEditor(ConfigColors{}, nil)
43 	e.Resize(5)
44 	e.PutRune('h')
45 	e.PutRune('l')
+23, -12
 1@@ -6,8 +6,9 @@ import (
 2 	"sync/atomic"
 3 	"time"
 4 
 5-	"git.sr.ht/~delthas/senpai/irc"
 6 	"github.com/gdamore/tcell/v2"
 7+
 8+	"git.sr.ht/~delthas/senpai/irc"
 9 )
10 
11 type Config struct {
12@@ -36,11 +37,12 @@ type UI struct {
13 	exit   atomic.Value // bool
14 	config Config
15 
16-	bs     BufferList
17-	e      Editor
18-	prompt StyledString
19-	status string
20-	title  string
21+	bs          BufferList
22+	e           Editor
23+	prompt      StyledString
24+	status      string
25+	title       string
26+	overlayHint string
27 
28 	channelOffset int
29 	memberClicked int
30@@ -97,7 +99,7 @@ func New(config Config) (ui *UI, err error) {
31 	}()
32 
33 	ui.bs = NewBufferList(config.Colors, ui.config.MergeLine)
34-	ui.e = NewEditor(ui.config.AutoComplete)
35+	ui.e = NewEditor(config.Colors, ui.config.AutoComplete)
36 	ui.Resize()
37 
38 	return
39@@ -263,8 +265,9 @@ func (ui *UI) IsAtTop() bool {
40 	return ui.bs.IsAtTop()
41 }
42 
43-func (ui *UI) OpenOverlay() {
44+func (ui *UI) OpenOverlay(hint string) {
45 	ui.bs.OpenOverlay()
46+	ui.overlayHint = hint
47 }
48 
49 func (ui *UI) CloseOverlay() {
50@@ -489,22 +492,30 @@ func (ui *UI) Draw(members []irc.Member) {
51 		ui.drawStatusBar(ui.channelWidth, h-2, w-ui.channelWidth-ui.memberWidth)
52 	}
53 
54+	prompt := ui.prompt
55+	if ui.bs.HasOverlay() && ui.e.TextLen() == 0 {
56+		prompt = Styled(">", tcell.StyleDefault.Foreground(ui.config.Colors.Prompt))
57+	}
58 	if ui.channelWidth == 0 {
59 		for x := 0; x < 9+ui.config.NickColWidth; x++ {
60 			ui.screen.SetContent(x, h-2, ' ', nil, tcell.StyleDefault)
61 		}
62-		printIdent(ui.screen, 7, h-2, ui.config.NickColWidth, ui.prompt)
63+		printIdent(ui.screen, 7, h-2, ui.config.NickColWidth, prompt)
64 	} else {
65 		for x := ui.channelWidth; x < 9+ui.channelWidth+ui.config.NickColWidth; x++ {
66 			ui.screen.SetContent(x, h-1, ' ', nil, tcell.StyleDefault)
67 		}
68-		printIdent(ui.screen, ui.channelWidth+7, h-1, ui.config.NickColWidth, ui.prompt)
69+		printIdent(ui.screen, ui.channelWidth+7, h-1, ui.config.NickColWidth, prompt)
70 	}
71 
72+	var hint string
73+	if ui.bs.HasOverlay() {
74+		hint = ui.overlayHint
75+	}
76 	if ui.channelWidth == 0 {
77-		ui.e.Draw(ui.screen, 9+ui.config.NickColWidth, h-2)
78+		ui.e.Draw(ui.screen, 9+ui.config.NickColWidth, h-2, hint)
79 	} else {
80-		ui.e.Draw(ui.screen, 9+ui.channelWidth+ui.config.NickColWidth, h-1)
81+		ui.e.Draw(ui.screen, 9+ui.channelWidth+ui.config.NickColWidth, h-1, hint)
82 	}
83 
84 	ui.screen.Show()