diff options
author | Robin Jarry <robin@jarry.cc> | 2022-12-27 22:59:10 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-02-20 14:48:42 +0100 |
commit | d2e74cdb91e140b50d14c3a8b315cde272f32587 (patch) | |
tree | 4f4a20c02f60b67d7a8eb967bb45d789a057453b /widgets/status.go | |
parent | 6af06c9dfec03e923589d34187ba8358e3423d5c (diff) | |
download | aerc-d2e74cdb91e140b50d14c3a8b315cde272f32587.tar.gz |
statusline: add column based render format
In the spirit of commit 535300cfdbfc ("config: add columns based index
format"), reuse the column definitions and table widget.
Add automatic translation of render-format to column definitions. Allow
empty columns to be compatible with the %m (mute) flag.
Rename the State object to AccountState to be more precise. Reuse that
object in state.TempateData to expose account state info. Move actual
status line rendering in StatusLine.Draw().
Add new template fields for status specific data:
{{.ConnectionInfo}}
Connection state.
{{.ContentInfo}}
General status information (e.g. filter, search)
{{.StatusInfo}}
Combination of {{.ConnectionInfo}} and {{.StatusInfo}}
{{.TrayInfo}}
General on/off information (e.g. passthrough, threading,
sorting)
{{.PendingKeys}}
Currently pressed key sequence that does not match any key
binding and/or is incomplete.
Display a warning on startup if render-format has been converted to
status-columns.
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tim Culverhouse <tim@timculverhouse.com>
Diffstat (limited to 'widgets/status.go')
-rw-r--r-- | widgets/status.go | 95 |
1 files changed, 60 insertions, 35 deletions
diff --git a/widgets/status.go b/widgets/status.go index 67667016..00877ee2 100644 --- a/widgets/status.go +++ b/widgets/status.go @@ -1,20 +1,24 @@ package widgets import ( + "bytes" "time" "github.com/gdamore/tcell/v2" "github.com/mattn/go-runewidth" "git.sr.ht/~rjarry/aerc/config" + "git.sr.ht/~rjarry/aerc/lib/state" + "git.sr.ht/~rjarry/aerc/lib/templates" "git.sr.ht/~rjarry/aerc/lib/ui" "git.sr.ht/~rjarry/aerc/log" ) type StatusLine struct { - stack []*StatusMessage - fallback StatusMessage - aerc *Aerc + stack []*StatusMessage + aerc *Aerc + acct *AccountView + err string } type StatusMessage struct { @@ -22,51 +26,72 @@ type StatusMessage struct { message string } -func NewStatusLine(uiConfig *config.UIConfig) *StatusLine { - return &StatusLine{ - fallback: StatusMessage{ - style: uiConfig.GetStyle(config.STYLE_STATUSLINE_DEFAULT), - message: "Idle", - }, - } -} - func (status *StatusLine) Invalidate() { ui.Invalidate() } func (status *StatusLine) Draw(ctx *ui.Context) { - line := &status.fallback - if len(status.stack) != 0 { - line = status.stack[len(status.stack)-1] - } - ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', line.style) - pendingKeys := "" - if status.aerc != nil { - for _, pendingKey := range status.aerc.pendingKeys { - pendingKeys += string(pendingKey.Rune) + style := status.uiConfig().GetStyle(config.STYLE_STATUSLINE_DEFAULT) + ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', style) + switch { + case len(status.stack) != 0: + line := status.stack[len(status.stack)-1] + msg := runewidth.Truncate(line.message, ctx.Width(), "") + msg = runewidth.FillRight(msg, ctx.Width()) + ctx.Printf(0, 0, line.style, "%s", msg) + case status.err != "": + msg := runewidth.Truncate(status.err, ctx.Width(), "") + msg = runewidth.FillRight(msg, ctx.Width()) + style := status.uiConfig().GetStyle(config.STYLE_STATUSLINE_ERROR) + ctx.Printf(0, 0, style, "%s", msg) + case status.aerc != nil && status.acct != nil: + var data state.TemplateData + data.SetPendingKeys(status.aerc.pendingKeys) + data.SetState(&status.acct.state) + data.SetAccount(status.acct.acct) + data.SetFolder(status.acct.Directories().Selected()) + msg, _ := status.acct.SelectedMessage() + data.SetInfo(msg, 0, false) + table := ui.NewTable( + ctx.Height(), + config.Statusline.StatusColumns, + config.Statusline.ColumnSeparator, + nil, + func(*ui.Table, int) tcell.Style { return style }, + ) + var buf bytes.Buffer + cells := make([]string, len(table.Columns)) + for c, col := range table.Columns { + err := templates.Render(col.Def.Template, &buf, &data) + if err != nil { + log.Errorf("%s", err) + cells[c] = err.Error() + } else { + cells[c] = buf.String() + } + buf.Reset() } + table.AddRow(cells, nil) + table.Draw(ctx) } - message := runewidth.FillRight(line.message, ctx.Width()-len(pendingKeys)-5) - ctx.Printf(0, 0, line.style, "%s%s", message, pendingKeys) } -func (status *StatusLine) Set(text string) *StatusMessage { - status.fallback = StatusMessage{ - style: status.uiConfig().GetStyle(config.STYLE_STATUSLINE_DEFAULT), - message: text, - } +func (status *StatusLine) Update(acct *AccountView) { + status.acct = acct status.Invalidate() - return &status.fallback } -func (status *StatusLine) SetError(text string) *StatusMessage { - status.fallback = StatusMessage{ - style: status.uiConfig().GetStyle(config.STYLE_STATUSLINE_ERROR), - message: text, +func (status *StatusLine) SetError(err string) { + prev := status.err + status.err = err + if prev != status.err { + status.Invalidate() } - status.Invalidate() - return &status.fallback +} + +func (status *StatusLine) Clear() { + status.SetError("") + status.acct = nil } func (status *StatusLine) Push(text string, expiry time.Duration) *StatusMessage { |