on main help sign in
Merge pull request #2191 from charmbracelet/charm-1152-sessions-dialog-is-too-big
d320f12Ayman Bagabas
internal/ui/dialog/commands.go+7−11
@@ -27,9 +27,7 @@ type CommandType uint
27func (c CommandType) String() string { return []string{"System", "User", "MCP"}[c] }
27func (c CommandType) String() string { return []string{"System", "User", "MCP"}[c] }
28
28
29const (
29const (
30− sidebarCompactModeBreakpoint = 120
30+ sidebarCompactModeBreakpoint = 120
31− defaultCommandsDialogMaxHeight = 20
32− defaultCommandsDialogMaxWidth = 70
33)
31)
34
32
35const (
33const (
@@ -155,19 +153,17 @@ func (c *Commands) HandleMsg(msg tea.Msg) Action {
155 c.list.Focus()
153 c.list.Focus()
156 if c.list.IsSelectedFirst() {
154 if c.list.IsSelectedFirst() {
157 c.list.SelectLast()
155 c.list.SelectLast()
158− c.list.ScrollToBottom()
156+ } else {
159− break
157+ c.list.SelectPrev()
160 }
158 }
161− c.list.SelectPrev()
162 c.list.ScrollToSelected()
159 c.list.ScrollToSelected()
163 case key.Matches(msg, c.keyMap.Next):
160 case key.Matches(msg, c.keyMap.Next):
164 c.list.Focus()
161 c.list.Focus()
165 if c.list.IsSelectedLast() {
162 if c.list.IsSelectedLast() {
166 c.list.SelectFirst()
163 c.list.SelectFirst()
167− c.list.ScrollToTop()
164+ } else {
168− break
165+ c.list.SelectNext()
169 }
166 }
170− c.list.SelectNext()
171 c.list.ScrollToSelected()
167 c.list.ScrollToSelected()
172 case key.Matches(msg, c.keyMap.Select):
168 case key.Matches(msg, c.keyMap.Select):
173 if selectedItem := c.list.SelectedItem(); selectedItem != nil {
169 if selectedItem := c.list.SelectedItem(); selectedItem != nil {
@@ -240,8 +236,8 @@ func commandsRadioView(sty *styles.Styles, selected CommandType, hasUserCmds boo
240// Draw implements [Dialog].
236// Draw implements [Dialog].
241func (c *Commands) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor {
237func (c *Commands) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor {
242 t := c.com.Styles
238 t := c.com.Styles
243− width := max(0, min(defaultCommandsDialogMaxWidth, area.Dx()-t.Dialog.View.GetHorizontalBorderSize()))
239+ width := max(0, min(defaultDialogMaxWidth, area.Dx()-t.Dialog.View.GetHorizontalBorderSize()))
244− height := max(0, min(defaultCommandsDialogMaxHeight, area.Dy()-t.Dialog.View.GetVerticalBorderSize()))
240+ height := max(0, min(defaultDialogHeight, area.Dy()-t.Dialog.View.GetVerticalBorderSize()))
245 if area.Dx() != c.windowWidth && c.selected == SystemCommands {
241 if area.Dx() != c.windowWidth && c.selected == SystemCommands {
246 c.windowWidth = area.Dx()
242 c.windowWidth = area.Dx()
247 // since some items in the list depend on width (e.g. toggle sidebar command),
243 // since some items in the list depend on width (e.g. toggle sidebar command),
internal/ui/dialog/dialog.go+2−2
@@ -11,9 +11,9 @@ import (
11// Dialog sizing constants.
11// Dialog sizing constants.
12const (
12const (
13 // defaultDialogMaxWidth is the maximum width for standard dialogs.
13 // defaultDialogMaxWidth is the maximum width for standard dialogs.
14− defaultDialogMaxWidth = 120
14+ defaultDialogMaxWidth = 70
15 // defaultDialogHeight is the default height for standard dialogs.
15 // defaultDialogHeight is the default height for standard dialogs.
16− defaultDialogHeight = 30
16+ defaultDialogHeight = 20
17 // titleContentHeight is the height of the title content line.
17 // titleContentHeight is the height of the title content line.
18 titleContentHeight = 1
18 titleContentHeight = 1
19 // inputContentHeight is the height of the input content line.
19 // inputContentHeight is the height of the input content line.
internal/ui/dialog/models.go+4−6
@@ -174,19 +174,17 @@ func (m *Models) HandleMsg(msg tea.Msg) Action {
174 m.list.Focus()
174 m.list.Focus()
175 if m.list.IsSelectedFirst() {
175 if m.list.IsSelectedFirst() {
176 m.list.SelectLast()
176 m.list.SelectLast()
177− m.list.ScrollToBottom()
177+ } else {
178− break
178+ m.list.SelectPrev()
179 }
179 }
180− m.list.SelectPrev()
181 m.list.ScrollToSelected()
180 m.list.ScrollToSelected()
182 case key.Matches(msg, m.keyMap.Next):
181 case key.Matches(msg, m.keyMap.Next):
183 m.list.Focus()
182 m.list.Focus()
184 if m.list.IsSelectedLast() {
183 if m.list.IsSelectedLast() {
185 m.list.SelectFirst()
184 m.list.SelectFirst()
186− m.list.ScrollToTop()
185+ } else {
187− break
186+ m.list.SelectNext()
188 }
187 }
189− m.list.SelectNext()
190 m.list.ScrollToSelected()
188 m.list.ScrollToSelected()
191 case key.Matches(msg, m.keyMap.Select, m.keyMap.Edit):
189 case key.Matches(msg, m.keyMap.Select, m.keyMap.Edit):
192 selectedItem := m.list.SelectedItem()
190 selectedItem := m.list.SelectedItem()
internal/ui/dialog/sessions.go+7−9
@@ -190,19 +190,17 @@ func (s *Session) HandleMsg(msg tea.Msg) Action {
190 s.list.Focus()
190 s.list.Focus()
191 if s.list.IsSelectedFirst() {
191 if s.list.IsSelectedFirst() {
192 s.list.SelectLast()
192 s.list.SelectLast()
193− s.list.ScrollToBottom()
193+ } else {
194− break
194+ s.list.SelectPrev()
195 }
195 }
196− s.list.SelectPrev()
197 s.list.ScrollToSelected()
196 s.list.ScrollToSelected()
198 case key.Matches(msg, s.keyMap.Next):
197 case key.Matches(msg, s.keyMap.Next):
199 s.list.Focus()
198 s.list.Focus()
200 if s.list.IsSelectedLast() {
199 if s.list.IsSelectedLast() {
201 s.list.SelectFirst()
200 s.list.SelectFirst()
202− s.list.ScrollToTop()
201+ } else {
203− break
202+ s.list.SelectNext()
204 }
203 }
205− s.list.SelectNext()
206 s.list.ScrollToSelected()
204 s.list.ScrollToSelected()
207 case key.Matches(msg, s.keyMap.Select):
205 case key.Matches(msg, s.keyMap.Select):
208 if item := s.list.SelectedItem(); item != nil {
206 if item := s.list.SelectedItem(); item != nil {
@@ -231,9 +229,9 @@ func (s *Session) Cursor() *tea.Cursor {
231// Draw implements [Dialog].
229// Draw implements [Dialog].
232func (s *Session) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor {
230func (s *Session) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor {
233 t := s.com.Styles
231 t := s.com.Styles
234− width := max(0, min(defaultDialogMaxWidth, area.Dx()))
232+ width := max(0, min(defaultDialogMaxWidth, area.Dx()-t.Dialog.View.GetHorizontalBorderSize()))
235− height := max(0, min(defaultDialogHeight, area.Dy()))
233+ height := max(0, min(defaultDialogHeight, area.Dy()-t.Dialog.View.GetVerticalBorderSize()))
236− innerWidth := width - t.Dialog.View.GetHorizontalFrameSize() - 2
234+ innerWidth := width - t.Dialog.View.GetHorizontalFrameSize()
237 heightOffset := t.Dialog.Title.GetVerticalFrameSize() + titleContentHeight +
235 heightOffset := t.Dialog.Title.GetVerticalFrameSize() + titleContentHeight +
238 t.Dialog.InputPrompt.GetVerticalFrameSize() + inputContentHeight +
236 t.Dialog.InputPrompt.GetVerticalFrameSize() + inputContentHeight +
239 t.Dialog.HelpView.GetVerticalFrameSize() +
237 t.Dialog.HelpView.GetVerticalFrameSize() +
internal/ui/dialog/sessions_item.go+2−2
@@ -137,7 +137,7 @@ func renderItem(t ListItemStyles, title string, info string, focused bool, width
137 infoWidth = lipgloss.Width(infoText)
137 infoWidth = lipgloss.Width(infoText)
138 }
138 }
139
139
140− title = ansi.Truncate(title, max(0, lineWidth-infoWidth), "")
140+ title = ansi.Truncate(title, max(0, lineWidth-infoWidth), "…")
141 titleWidth := lipgloss.Width(title)
141 titleWidth := lipgloss.Width(title)
142 gap := strings.Repeat(" ", max(0, lineWidth-titleWidth-infoWidth))
142 gap := strings.Repeat(" ", max(0, lineWidth-titleWidth-infoWidth))
143 content := title
143 content := title
@@ -154,7 +154,7 @@ func renderItem(t ListItemStyles, title string, info string, focused bool, width
154 // because we can control the underline start and stop more
154 // because we can control the underline start and stop more
155 // precisely via [ansi.AttrUnderline] and [ansi.AttrNoUnderline]
155 // precisely via [ansi.AttrUnderline] and [ansi.AttrNoUnderline]
156 // which only affect the underline attribute without interfering
156 // which only affect the underline attribute without interfering
157− // with other style
157+ // with other style attributes.
158 parts = append(parts,
158 parts = append(parts,
159 ansi.NewStyle().Underline(true).String(),
159 ansi.NewStyle().Underline(true).String(),
160 ansi.Cut(title, start, stop+1),
160 ansi.Cut(title, start, stop+1),