diff options
Diffstat (limited to 'internal/tui/components/core/status.go')
| -rw-r--r-- | internal/tui/components/core/status.go | 90 |
1 files changed, 73 insertions, 17 deletions
diff --git a/internal/tui/components/core/status.go b/internal/tui/components/core/status.go index 93ba34507..089dffa2c 100644 --- a/internal/tui/components/core/status.go +++ b/internal/tui/components/core/status.go @@ -1,21 +1,25 @@ package core import ( + "fmt" + "strings" "time" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/kujtimiihoxha/termai/internal/config" "github.com/kujtimiihoxha/termai/internal/llm/models" + "github.com/kujtimiihoxha/termai/internal/lsp" + "github.com/kujtimiihoxha/termai/internal/lsp/protocol" "github.com/kujtimiihoxha/termai/internal/tui/styles" "github.com/kujtimiihoxha/termai/internal/tui/util" - "github.com/kujtimiihoxha/termai/internal/version" ) type statusCmp struct { info util.InfoMsg width int messageTTL time.Duration + lspClients map[string]*lsp.Client } // clearMessageCmd is a command that clears status messages after a timeout @@ -47,20 +51,18 @@ func (m statusCmp) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } -var ( - versionWidget = styles.Padded.Background(styles.DarkGrey).Foreground(styles.Text).Render(version.Version) - helpWidget = styles.Padded.Background(styles.Grey).Foreground(styles.Text).Render("? help") -) +var helpWidget = styles.Padded.Background(styles.ForgroundMid).Foreground(styles.BackgroundDarker).Bold(true).Render("ctrl+? help") func (m statusCmp) View() string { - status := styles.Padded.Background(styles.Grey).Foreground(styles.Text).Render("? help") + status := helpWidget + diagnostics := styles.Padded.Background(styles.BackgroundDarker).Render(m.projectDiagnostics()) if m.info.Msg != "" { infoStyle := styles.Padded. Foreground(styles.Base). - Width(m.availableFooterMsgWidth()) + Width(m.availableFooterMsgWidth(diagnostics)) switch m.info.Type { case util.InfoTypeInfo: - infoStyle = infoStyle.Background(styles.Blue) + infoStyle = infoStyle.Background(styles.BorderColor) case util.InfoTypeWarn: infoStyle = infoStyle.Background(styles.Peach) case util.InfoTypeError: @@ -68,7 +70,7 @@ func (m statusCmp) View() string { } // Truncate message if it's longer than available width msg := m.info.Msg - availWidth := m.availableFooterMsgWidth() - 10 + availWidth := m.availableFooterMsgWidth(diagnostics) - 10 if len(msg) > availWidth && availWidth > 0 { msg = msg[:availWidth] + "..." } @@ -76,27 +78,81 @@ func (m statusCmp) View() string { } else { status += styles.Padded. Foreground(styles.Base). - Background(styles.LightGrey). - Width(m.availableFooterMsgWidth()). + Background(styles.BackgroundDim). + Width(m.availableFooterMsgWidth(diagnostics)). Render("") } + status += diagnostics status += m.model() - status += versionWidget return status } -func (m statusCmp) availableFooterMsgWidth() int { - // -2 to accommodate padding - return max(0, m.width-lipgloss.Width(helpWidget)-lipgloss.Width(versionWidget)-lipgloss.Width(m.model())) +func (m *statusCmp) projectDiagnostics() string { + errorDiagnostics := []protocol.Diagnostic{} + warnDiagnostics := []protocol.Diagnostic{} + hintDiagnostics := []protocol.Diagnostic{} + infoDiagnostics := []protocol.Diagnostic{} + for _, client := range m.lspClients { + for _, d := range client.GetDiagnostics() { + for _, diag := range d { + switch diag.Severity { + case protocol.SeverityError: + errorDiagnostics = append(errorDiagnostics, diag) + case protocol.SeverityWarning: + warnDiagnostics = append(warnDiagnostics, diag) + case protocol.SeverityHint: + hintDiagnostics = append(hintDiagnostics, diag) + case protocol.SeverityInformation: + infoDiagnostics = append(infoDiagnostics, diag) + } + } + } + } + + if len(errorDiagnostics) == 0 && len(warnDiagnostics) == 0 && len(hintDiagnostics) == 0 && len(infoDiagnostics) == 0 { + return "No diagnostics" + } + + diagnostics := []string{} + + if len(errorDiagnostics) > 0 { + errStr := lipgloss.NewStyle().Foreground(styles.Error).Render(fmt.Sprintf("%s %d", styles.ErrorIcon, len(errorDiagnostics))) + diagnostics = append(diagnostics, errStr) + } + if len(warnDiagnostics) > 0 { + warnStr := lipgloss.NewStyle().Foreground(styles.Warning).Render(fmt.Sprintf("%s %d", styles.WarningIcon, len(warnDiagnostics))) + diagnostics = append(diagnostics, warnStr) + } + if len(hintDiagnostics) > 0 { + hintStr := lipgloss.NewStyle().Foreground(styles.Text).Render(fmt.Sprintf("%s %d", styles.HintIcon, len(hintDiagnostics))) + diagnostics = append(diagnostics, hintStr) + } + if len(infoDiagnostics) > 0 { + infoStr := lipgloss.NewStyle().Foreground(styles.Peach).Render(fmt.Sprintf("%s %d", styles.InfoIcon, len(infoDiagnostics))) + diagnostics = append(diagnostics, infoStr) + } + + return strings.Join(diagnostics, " ") +} + +func (m statusCmp) availableFooterMsgWidth(diagnostics string) int { + return max(0, m.width-lipgloss.Width(helpWidget)-lipgloss.Width(m.model())-lipgloss.Width(diagnostics)) } func (m statusCmp) model() string { - model := models.SupportedModels[config.Get().Model.Coder] + cfg := config.Get() + + coder, ok := cfg.Agents[config.AgentCoder] + if !ok { + return "Unknown" + } + model := models.SupportedModels[coder.Model] return styles.Padded.Background(styles.Grey).Foreground(styles.Text).Render(model.Name) } -func NewStatusCmp() tea.Model { +func NewStatusCmp(lspClients map[string]*lsp.Client) tea.Model { return &statusCmp{ messageTTL: 10 * time.Second, + lspClients: lspClients, } } |
