Skip to content

Add auto column width mode#26

Merged
kdkavanagh merged 2 commits intomasterfrom
column-fit
Mar 26, 2026
Merged

Add auto column width mode#26
kdkavanagh merged 2 commits intomasterfrom
column-fit

Conversation

@kdkavanagh-agent
Copy link
Copy Markdown
Collaborator

Summary

  • Adds a toggleable auto column width mode (press w) that sizes columns based only on the currently visible rows instead of the full dataset
  • Widths update dynamically as rows scroll in/out of view or the terminal is resized
  • Only recomputes when the visible row range (scroll_y, dt_height) actually changes — cursor movement within the same visible area skips recomputation
  • Toggling off restores the original precomputed full-data widths

Test plan

  • 7 unit tests covering toggle, width narrowing, scroll updates, restore on toggle-off, min-width from header name, skip recompute when range unchanged, resize handling
  • 4 snapshot tests: auto width off (baseline), auto width on at top, auto width on scrolled to bottom, toggled off after on
  • All 46 existing tests pass with no regressions
  • make check passes (format, lint, typecheck)

🤖 Generated with Claude Code

Adds a new 'w' keybinding to toggle auto column width mode, which sizes
columns based only on visible rows instead of the full dataset. Widths
update dynamically as rows scroll in/out of view or the terminal is
resized. Only recomputes when the visible row range actually changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kdkavanagh
Copy link
Copy Markdown
Owner

This breaks when all the columns currently displayed have null/no values. The error is:

dt_browser/custom_table.py:627 in render_header_and_table                                                                                                                                                                                                                    │
│                                                                                                                                                                                                                                                                                                                                            │
│   624 │   │   │   │   cursor_col_idx = self.cursor_coordinate.column - self._dt.columns.index(                                                                                                                                                                                                                                             │
│   625 │   │   │   │                                                                                                                                                                                                                                                                                                                        │
│   626 │   │   │   │   cols_before_selected: list[str] = visible_cols[0:cursor_col_idx]                                                                                                                                                                                                                                                     │
│ ❱ 627 │   │   │   │   sel_col = visible_cols[cursor_col_idx]                                                                                                                                                                                                                                                                               │
│   628 │   │   │   │   cols_after_selected = visible_cols[cursor_col_idx + 1 :]                                                                                                                                                                                                                                                             │
│   629 │   │   │   │                                                                                                                                                                                                                                                                                                                        │
│   630 │   │   │   │   rend = rend.select(      

…dth mode

When auto-width recalculates narrower widths (e.g. all-null columns), the
visible column set can shift so cursor_col_idx falls out of bounds. Clamp
the index to prevent the crash.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kdkavanagh-agent
Copy link
Copy Markdown
Collaborator Author

Fixed! The issue was that when auto-width recalculates narrower widths (e.g. for all-null visible columns), the set of visible_cols in render_header_and_table can shift such that cursor_col_idx exceeds the list bounds.

Fix: Added a clamp on cursor_col_idx at line 625 to keep it within [0, len(visible_cols) - 1].

Test: Added test_auto_width_all_null_columns that creates a DataFrame with all-null string columns and enables auto-width mode — confirms no crash and widths are at least header-name length.

All 47 tests pass, make check clean.

@kdkavanagh kdkavanagh merged commit b1ed84b into master Mar 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants