summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/tui/internal/app/app.go39
-rw-r--r--packages/tui/internal/components/chat/editor.go6
-rw-r--r--packages/tui/internal/tui/tui.go43
3 files changed, 46 insertions, 42 deletions
diff --git a/packages/tui/internal/app/app.go b/packages/tui/internal/app/app.go
index cb54aa940..03eb361b7 100644
--- a/packages/tui/internal/app/app.go
+++ b/packages/tui/internal/app/app.go
@@ -22,25 +22,26 @@ import (
)
type App struct {
- Info opencode.App
- Modes []opencode.Mode
- Providers []opencode.Provider
- Version string
- StatePath string
- Config *opencode.Config
- Client *opencode.Client
- State *config.State
- ModeIndex int
- Mode *opencode.Mode
- Provider *opencode.Provider
- Model *opencode.Model
- Session *opencode.Session
- Messages []opencode.MessageUnion
- Commands commands.CommandRegistry
- InitialModel *string
- InitialPrompt *string
- IntitialMode *string
- compactCancel context.CancelFunc
+ Info opencode.App
+ Modes []opencode.Mode
+ Providers []opencode.Provider
+ Version string
+ StatePath string
+ Config *opencode.Config
+ Client *opencode.Client
+ State *config.State
+ ModeIndex int
+ Mode *opencode.Mode
+ Provider *opencode.Provider
+ Model *opencode.Model
+ Session *opencode.Session
+ Messages []opencode.MessageUnion
+ Commands commands.CommandRegistry
+ InitialModel *string
+ InitialPrompt *string
+ IntitialMode *string
+ compactCancel context.CancelFunc
+ IsLeaderSequence bool
}
type SessionSelectedMsg = *opencode.Session
diff --git a/packages/tui/internal/components/chat/editor.go b/packages/tui/internal/components/chat/editor.go
index 2ed2a9079..d5f6facab 100644
--- a/packages/tui/internal/components/chat/editor.go
+++ b/packages/tui/internal/components/chat/editor.go
@@ -242,13 +242,17 @@ func (m *editorComponent) Content(width int) string {
prompt,
m.textarea.View(),
)
+ borderForeground := t.Border()
+ if m.app.IsLeaderSequence {
+ borderForeground = t.Accent()
+ }
textarea = styles.NewStyle().
Background(t.BackgroundElement()).
Width(width).
PaddingTop(1).
PaddingBottom(1).
BorderStyle(lipgloss.ThickBorder()).
- BorderForeground(t.Border()).
+ BorderForeground(borderForeground).
BorderBackground(t.Background()).
BorderLeft(true).
BorderRight(true).
diff --git a/packages/tui/internal/tui/tui.go b/packages/tui/internal/tui/tui.go
index 0a075a146..ce6e72ff8 100644
--- a/packages/tui/internal/tui/tui.go
+++ b/packages/tui/internal/tui/tui.go
@@ -70,17 +70,17 @@ type appModel struct {
showCompletionDialog bool
fileCompletionActive bool
leaderBinding *key.Binding
- isLeaderSequence bool
- toastManager *toast.ToastManager
- interruptKeyState InterruptKeyState
- exitKeyState ExitKeyState
- lastScroll time.Time
- messagesRight bool
- fileViewer fileviewer.Model
- lastMouse tea.Mouse
- fileViewerStart int
- fileViewerEnd int
- fileViewerHit bool
+ // isLeaderSequence bool
+ toastManager *toast.ToastManager
+ interruptKeyState InterruptKeyState
+ exitKeyState ExitKeyState
+ lastScroll time.Time
+ messagesRight bool
+ fileViewer fileviewer.Model
+ lastMouse tea.Mouse
+ fileViewerStart int
+ fileViewerEnd int
+ fileViewerHit bool
}
func (a appModel) Init() tea.Cmd {
@@ -184,9 +184,9 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
// 2. Check for commands that require leader
- if a.isLeaderSequence {
- matches := a.app.Commands.Matches(msg, a.isLeaderSequence)
- a.isLeaderSequence = false
+ if a.app.IsLeaderSequence {
+ matches := a.app.Commands.Matches(msg, a.app.IsLeaderSequence)
+ a.app.IsLeaderSequence = false
if len(matches) > 0 {
return a, util.CmdHandler(commands.ExecuteCommandsMsg(matches))
}
@@ -261,21 +261,21 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// 5. Check for leader key activation
if a.leaderBinding != nil &&
- !a.isLeaderSequence &&
+ !a.app.IsLeaderSequence &&
key.Matches(msg, *a.leaderBinding) {
- a.isLeaderSequence = true
+ a.app.IsLeaderSequence = true
return a, nil
}
// 6 Handle input clear command
inputClearCommand := a.app.Commands[commands.InputClearCommand]
- if inputClearCommand.Matches(msg, a.isLeaderSequence) && a.editor.Length() > 0 {
+ if inputClearCommand.Matches(msg, a.app.IsLeaderSequence) && a.editor.Length() > 0 {
return a, util.CmdHandler(commands.ExecuteCommandMsg(inputClearCommand))
}
// 7. Handle interrupt key debounce for session interrupt
interruptCommand := a.app.Commands[commands.SessionInterruptCommand]
- if interruptCommand.Matches(msg, a.isLeaderSequence) && a.app.IsBusy() {
+ if interruptCommand.Matches(msg, a.app.IsLeaderSequence) && a.app.IsBusy() {
switch a.interruptKeyState {
case InterruptKeyIdle:
// First interrupt key press - start debounce timer
@@ -294,7 +294,7 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
// 8. Handle exit key debounce for app exit when using non-leader command
exitCommand := a.app.Commands[commands.AppExitCommand]
- if exitCommand.Matches(msg, a.isLeaderSequence) {
+ if exitCommand.Matches(msg, a.app.IsLeaderSequence) {
switch a.exitKeyState {
case ExitKeyIdle:
// First exit key press - start debounce timer
@@ -312,10 +312,10 @@ func (a appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
// 9. Check again for commands that don't require leader (excluding interrupt when busy and exit when in debounce)
- matches := a.app.Commands.Matches(msg, a.isLeaderSequence)
+ matches := a.app.Commands.Matches(msg, a.app.IsLeaderSequence)
if len(matches) > 0 {
// Skip interrupt key if we're in debounce mode and app is busy
- if interruptCommand.Matches(msg, a.isLeaderSequence) && a.app.IsBusy() && a.interruptKeyState != InterruptKeyIdle {
+ if interruptCommand.Matches(msg, a.app.IsLeaderSequence) && a.app.IsBusy() && a.interruptKeyState != InterruptKeyIdle {
return a, nil
}
return a, util.CmdHandler(commands.ExecuteCommandsMsg(matches))
@@ -1067,7 +1067,6 @@ func NewModel(app *app.App) tea.Model {
fileProvider: fileProvider,
symbolsProvider: symbolsProvider,
leaderBinding: leaderBinding,
- isLeaderSequence: false,
showCompletionDialog: false,
fileCompletionActive: false,
toastManager: toast.NewToastManager(),