csv_preview: #1 Add CSV preview with live table view and interactive features - #48207
Conversation
Anthony-Eid
left a comment
There was a problem hiding this comment.
This is looking good for an MVP, there are some small changes we should make before merging
Also, this will have to be featured flagged
| workspace.register_action(|workspace, _: &OpenPreview, window, cx| { | ||
| if let Some(editor) = workspace | ||
| .active_item(cx) | ||
| .and_then(|item| item.act_as::<Editor>(cx)) | ||
| .filter(|editor| Self::is_csv_file(editor, cx)) | ||
| { | ||
| let csv_preview = Self::new(&editor, cx); | ||
| workspace.add_item_to_active_pane(Box::new(csv_preview), None, true, window, cx); | ||
| } | ||
| }); |
There was a problem hiding this comment.
OpenPreview action should also check to make sure there are no pre existing item that represent the same csv file in the active pane. In the case that there is a pre existing item Zed should just refocus it
| mod tests { | ||
| use super::*; |
There was a problem hiding this comment.
Not a blocker, but I wonder how hard it would be to add property testing to this parser
…mplementation Doing this now in case we have merge conflicts in the future, they'll be easily to resolve
|
Leaving Codex PR review (we can go through these together to see what feedback is valid) Findings**
Style polish (non-blocking)
|
Anthony-Eid
left a comment
There was a problem hiding this comment.
This is ready for its first iteration in Zed and thus is mergable! Congrats
It's featured flag for now, so we can keep polishing the cvs preview before it's released
…dustries#48207) ## **Description:** **Context:** This PR introduces an initial CSV preview feature for Zed, building upon two previously merged infrastructure PRs: - [zed-industries#46341](zed-industries#46341) - Data table dynamic column support (removed const generics) - [zed-industries#46190](zed-industries#46190) - Variable row height mode for data tables This implementation is based on the [original draft PR zed-industries#44344](zed-industries#44344), which has been carefully decomposed into smaller, reviewable pieces. --- #### **Features Included:** **Core Infrastructure:** - Live CSV parsing with smart debouncing (200ms cooldown) - Performance monitoring with built-in timing metrics (not displayed in UI yet) - Automatic file change detection and re-parsing - Support for quoted fields, multiline cells, and escaped characters **Table Display:** - Variable row height rendering with fallback to uniform mode (switchable via settings) - Draggable column resizing (reusing existing data table infrastructure) - Row identifiers supporting both source line numbers and sequential row numbers - Configurable font rendering (UI font vs monospace) - Tooltips showing full cell content on hover **Interactive Features:** - Column sorting (ascending/descending) with visual indicators **Settings Panel:** - Toggle between variable/uniform row rendering - Font type selection (UI/monospace) - Row identifier type configuration - Debug information display - Multiline cell rendering options --- #### **Features Intentionally Removed for This PR:** To reduce complexity and review scope, the following features were temporarily reverted and will be reintroduced in subsequent PRs: - ❌ Settings pannel with performance metrics overlay - ❌ Cell selection (single, multiple, and range selections) - ❌ Keyboard navigation with arrow keys and selection extension - ❌ Copy functionality supporting CSV, TSV, and Markdown table formats - ❌ Inline cell editing with file persistence - ❌ Viewport following for large datasets - ❌ Column filtering and search capabilities These removals were done via "time-machine" commits that cleanly nuked vertical slices of functionality from the complete implementation. --- **Technical Implementation:** The feature is organized into a dedicated `csv_preview` crate with the following structure: ``` crates/csv_preview/ ├── src/ │ ├── csv_preview.rs # Main view and coordination logic │ ├── parser.rs # CSV parsing and editor integration │ ├── settings.rs # Configuration types and defaults │ ├── table_data_engine.rs # Data transformation logic │ ├── renderer/ # UI rendering modules │ │ ├── preview_view.rs # Main render implementation │ │ ├── render_table.rs # Table component assembly │ │ ├── table_cell.rs # Individual cell rendering │ │ ├── table_header.rs # Header with sorting controls │ │ └── row_identifiers.rs # Line number column │ └── types/ # Core data structures │ ├── table_like_content.rs │ ├── coordinates.rs # Display vs data coordinate systems │ └── table_cell.rs ``` **Key architectural decisions:** - **Dual coordinate system**: Separates data indices from display indices to support sorting/filtering - **Component reuse**: Leverages existing `data_table` infrastructure from the keymap editor --- **Integration:** - Registers `csv::OpenPreview` action (currently without default keybindings) - Follows the same workspace integration pattern as `markdown_preview` and `svg_preview` - Automatically detects `.csv` file extensions - Tab integration with appropriate icons and naming --- **Code Structure Note:** Some code structures, types, and documentation may appear redundant or over-engineered in this initial implementation. This is intentional - the feature was developed as a complete system and then decomposed by functionality rather than being built incrementally. The "extra" infrastructure supports features that were removed for this PR but will be reintroduced in subsequent ones. This approach was chosen over extensive refactoring because: 1. The complete feature took 200+ commits to develop with significant rewrites 2. Clean extraction of vertical slices was more feasible than rebuilding incrementally 3. The end state will utilize all these components, making current "redundancy" temporary I apologize for any inconvenience this may cause during review, but the alternative would have required significant refactoring effort just to make intermediate states "prettier," which seemed counterproductive. --- **Future Work:** This lays the groundwork for upcoming PRs that will reintroduce the removed features: - Cell selection and keyboard navigation - Copy functionality with multiple output formats - Inline editing capabilities with undo/redo - Column filtering and search - TSV and other delimiter support - Improved horizontal scrolling behavior - Settings persistence **Testing:** Includes test fixtures demonstrating multiline cell handling, various column counts, and edge cases. --- **Release Notes:** - N/A This is feature flagged --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
…dustries#48207) ## **Description:** **Context:** This PR introduces an initial CSV preview feature for Zed, building upon two previously merged infrastructure PRs: - [zed-industries#46341](zed-industries#46341) - Data table dynamic column support (removed const generics) - [zed-industries#46190](zed-industries#46190) - Variable row height mode for data tables This implementation is based on the [original draft PR zed-industries#44344](zed-industries#44344), which has been carefully decomposed into smaller, reviewable pieces. --- #### **Features Included:** **Core Infrastructure:** - Live CSV parsing with smart debouncing (200ms cooldown) - Performance monitoring with built-in timing metrics (not displayed in UI yet) - Automatic file change detection and re-parsing - Support for quoted fields, multiline cells, and escaped characters **Table Display:** - Variable row height rendering with fallback to uniform mode (switchable via settings) - Draggable column resizing (reusing existing data table infrastructure) - Row identifiers supporting both source line numbers and sequential row numbers - Configurable font rendering (UI font vs monospace) - Tooltips showing full cell content on hover **Interactive Features:** - Column sorting (ascending/descending) with visual indicators **Settings Panel:** - Toggle between variable/uniform row rendering - Font type selection (UI/monospace) - Row identifier type configuration - Debug information display - Multiline cell rendering options --- #### **Features Intentionally Removed for This PR:** To reduce complexity and review scope, the following features were temporarily reverted and will be reintroduced in subsequent PRs: - ❌ Settings pannel with performance metrics overlay - ❌ Cell selection (single, multiple, and range selections) - ❌ Keyboard navigation with arrow keys and selection extension - ❌ Copy functionality supporting CSV, TSV, and Markdown table formats - ❌ Inline cell editing with file persistence - ❌ Viewport following for large datasets - ❌ Column filtering and search capabilities These removals were done via "time-machine" commits that cleanly nuked vertical slices of functionality from the complete implementation. --- **Technical Implementation:** The feature is organized into a dedicated `csv_preview` crate with the following structure: ``` crates/csv_preview/ ├── src/ │ ├── csv_preview.rs # Main view and coordination logic │ ├── parser.rs # CSV parsing and editor integration │ ├── settings.rs # Configuration types and defaults │ ├── table_data_engine.rs # Data transformation logic │ ├── renderer/ # UI rendering modules │ │ ├── preview_view.rs # Main render implementation │ │ ├── render_table.rs # Table component assembly │ │ ├── table_cell.rs # Individual cell rendering │ │ ├── table_header.rs # Header with sorting controls │ │ └── row_identifiers.rs # Line number column │ └── types/ # Core data structures │ ├── table_like_content.rs │ ├── coordinates.rs # Display vs data coordinate systems │ └── table_cell.rs ``` **Key architectural decisions:** - **Dual coordinate system**: Separates data indices from display indices to support sorting/filtering - **Component reuse**: Leverages existing `data_table` infrastructure from the keymap editor --- **Integration:** - Registers `csv::OpenPreview` action (currently without default keybindings) - Follows the same workspace integration pattern as `markdown_preview` and `svg_preview` - Automatically detects `.csv` file extensions - Tab integration with appropriate icons and naming --- **Code Structure Note:** Some code structures, types, and documentation may appear redundant or over-engineered in this initial implementation. This is intentional - the feature was developed as a complete system and then decomposed by functionality rather than being built incrementally. The "extra" infrastructure supports features that were removed for this PR but will be reintroduced in subsequent ones. This approach was chosen over extensive refactoring because: 1. The complete feature took 200+ commits to develop with significant rewrites 2. Clean extraction of vertical slices was more feasible than rebuilding incrementally 3. The end state will utilize all these components, making current "redundancy" temporary I apologize for any inconvenience this may cause during review, but the alternative would have required significant refactoring effort just to make intermediate states "prettier," which seemed counterproductive. --- **Future Work:** This lays the groundwork for upcoming PRs that will reintroduce the removed features: - Cell selection and keyboard navigation - Copy functionality with multiple output formats - Inline editing capabilities with undo/redo - Column filtering and search - TSV and other delimiter support - Improved horizontal scrolling behavior - Settings persistence **Testing:** Includes test fixtures demonstrating multiline cell handling, various column counts, and edge cases. --- **Release Notes:** - N/A This is feature flagged --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
Extract data table modules into separate files This PR extracts the `tests` and `table_row` modules from `data_table.rs` into separate files to improve code organization. This is preparatory work for the upcoming column width API rework (#2 in the series), where separating mechanical changes from logical changes will make the review easier. The extraction was performed using rust-analyzer's "Extract module to file" command. **Context:** This is part 1 of a 3-PR series improving data table column width handling: 1. **This PR**: Extract modules into separate files (mechanical change) 2. [#51060](#51060) - Introduce width config enum for redistributable column widths (API rework) 3. Implement independently resizable column widths (new feature) The series builds on previously merged infrastructure: - [#46341](#46341) - Data table dynamic column support - [#46190](#46190) - Variable row height mode for data tables Primary beneficiary: CSV preview feature ([#48207](#48207)) Release Notes: - N/A
data_table: Replace column width builder API with `ColumnWidthConfig`
enum
This PR consolidates the data table width configuration API from three
separate builder methods (`.column_widths()`, `.resizable_columns()`,
`.width()`) into a single `.width_config(ColumnWidthConfig)` call. This
makes invalid state combinations unrepresentable and clarifies the two
distinct width management modes.
**What changed:**
- Introduces `ColumnWidthConfig` enum with two variants:
- `Static`: Fixed column widths, no resize handles
- `Redistributable`: Drag-to-resize columns that redistribute space
within a fixed table width
- Introduces `TableResizeBehavior` enum (`None`, `Resizable`,
`MinSize(f32)`) for per-column resize policy
- Renames `TableColumnWidths` → `RedistributableColumnsState` to better
reflect its purpose
- Extracts all width management logic into a new `width_management.rs`
module
- Updates all callers: `csv_preview`, `git_graph`, `keymap_editor`,
`edit_prediction_context_view`
```rust
pub enum ColumnWidthConfig {
/// Static column widths (no resize handles).
Static {
widths: StaticColumnWidths,
/// Controls widths of the whole table.
table_width: Option<DefiniteLength>,
},
/// Redistributable columns — dragging redistributes the fixed available space
/// among columns without changing the overall table width.
Redistributable {
entity: Entity<RedistributableColumnsState>,
table_width: Option<DefiniteLength>,
},
}
```
**Why:**
The old API allowed callers to combine methods incorrectly. The new
enum-based design enforces correct usage at compile time and provides a
clearer path for adding independently resizable columns in PR #3.
**Context:**
This is part 2 of a 3-PR series improving data table column width
handling:
1. [#51059](#51059) - Extract
modules into separate files (mechanical change)
2. **This PR**: Introduce width config enum for redistributable column
widths (API rework)
3. Implement independently resizable column widths (new feature)
The series builds on previously merged infrastructure:
- [#46341](#46341) - Data
table dynamic column support
- [#46190](#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([#48207](#48207))
### Anthony's note
This PR also fixes the table dividers being a couple pixels off, and the
csv preview from having double line rendering for a single column in
some cases.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
This PR adds spreadsheet-style independently resizable columns (dragging
changes total table width) and fixes scrolling issues in variable list
mode.
**What changed:**
- Adds `ResizableColumnsState` struct for independently resizable
columns (spreadsheet-style)
- Adds `ColumnWidthConfig::Resizable` variant for spreadsheet mode
- Adds `DraggedResizableColumn` drag payload type
- Adds `ResizableHeaderInfo` for double-click-to-reset functionality
- Adds `render_resize_handles_resizable` function for resize handles
rendering
- Adds horizontal scroll handle to `TableInteractionState`
- Adds `.on_drag_move::<DraggedResizableColumn>` handler to Table for
drag resizing
**Bug fixes:**
- Fixed missing vertical scrollbar in variable list mode
- Fixed half-broken scrolling in variable list mode (added
.measure_all() to make scrollbar aware of the height of the table)
- Moved vertical scrollbar to be pinned at the right side of the pane
with table — previously it was attached to the table content and was
pushed off-screen when table content was too wide
**API addition:**
```rust
// New variant added:
pub enum ColumnWidthConfig {
Static { widths: StaticColumnWidths, table_width: Option<DefiniteLength> },
Redistributable { entity: Entity<RedistributableColumnsState>, table_width: Option<DefiniteLength> },
Resizable(Entity<ResizableColumnsState>), // NEW: spreadsheet-style
}
```
**Callers updated:**
- csv_preview: Changed from `ColumnWidthConfig::redistributable()` to
use new resizable mode
- git_graph: Added `resizable_info` parameter
**Context:**
This is part 3 of a 3-PR series improving data table column width
handling:
1. [#51059](#51059) - Extract
modules into separate files (mechanical change)
2. [#51120](#51120) -
Introduce width config enum for redistributable column widths (API
rework)
3. **This PR**: Add independently resizable columns + fix variable list
scrolling (new feature + bug fixes)
The series builds on previously merged infrastructure:
- [#46341](#46341) - Data
table dynamic column support
- [#46190](#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([#48207](#48207))
This work is based on the [original draft PR
#44344](#44344), decomposed
into reviewable pieces.
-----
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
data_table: Replace column width builder API with `ColumnWidthConfig`
enum
This PR consolidates the data table width configuration API from three
separate builder methods (`.column_widths()`, `.resizable_columns()`,
`.width()`) into a single `.width_config(ColumnWidthConfig)` call. This
makes invalid state combinations unrepresentable and clarifies the two
distinct width management modes.
**What changed:**
- Introduces `ColumnWidthConfig` enum with two variants:
- `Static`: Fixed column widths, no resize handles
- `Redistributable`: Drag-to-resize columns that redistribute space
within a fixed table width
- Introduces `TableResizeBehavior` enum (`None`, `Resizable`,
`MinSize(f32)`) for per-column resize policy
- Renames `TableColumnWidths` → `RedistributableColumnsState` to better
reflect its purpose
- Extracts all width management logic into a new `width_management.rs`
module
- Updates all callers: `csv_preview`, `git_graph`, `keymap_editor`,
`edit_prediction_context_view`
```rust
pub enum ColumnWidthConfig {
/// Static column widths (no resize handles).
Static {
widths: StaticColumnWidths,
/// Controls widths of the whole table.
table_width: Option<DefiniteLength>,
},
/// Redistributable columns — dragging redistributes the fixed available space
/// among columns without changing the overall table width.
Redistributable {
entity: Entity<RedistributableColumnsState>,
table_width: Option<DefiniteLength>,
},
}
```
**Why:**
The old API allowed callers to combine methods incorrectly. The new
enum-based design enforces correct usage at compile time and provides a
clearer path for adding independently resizable columns in PR zed-industries#3.
**Context:**
This is part 2 of a 3-PR series improving data table column width
handling:
1. [zed-industries#51059](zed-industries#51059) - Extract
modules into separate files (mechanical change)
2. **This PR**: Introduce width config enum for redistributable column
widths (API rework)
3. Implement independently resizable column widths (new feature)
The series builds on previously merged infrastructure:
- [zed-industries#46341](zed-industries#46341) - Data
table dynamic column support
- [zed-industries#46190](zed-industries#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([zed-industries#48207](zed-industries#48207))
### Anthony's note
This PR also fixes the table dividers being a couple pixels off, and the
csv preview from having double line rendering for a single column in
some cases.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
This PR adds spreadsheet-style independently resizable columns (dragging
changes total table width) and fixes scrolling issues in variable list
mode.
**What changed:**
- Adds `ResizableColumnsState` struct for independently resizable
columns (spreadsheet-style)
- Adds `ColumnWidthConfig::Resizable` variant for spreadsheet mode
- Adds `DraggedResizableColumn` drag payload type
- Adds `ResizableHeaderInfo` for double-click-to-reset functionality
- Adds `render_resize_handles_resizable` function for resize handles
rendering
- Adds horizontal scroll handle to `TableInteractionState`
- Adds `.on_drag_move::<DraggedResizableColumn>` handler to Table for
drag resizing
**Bug fixes:**
- Fixed missing vertical scrollbar in variable list mode
- Fixed half-broken scrolling in variable list mode (added
.measure_all() to make scrollbar aware of the height of the table)
- Moved vertical scrollbar to be pinned at the right side of the pane
with table — previously it was attached to the table content and was
pushed off-screen when table content was too wide
**API addition:**
```rust
// New variant added:
pub enum ColumnWidthConfig {
Static { widths: StaticColumnWidths, table_width: Option<DefiniteLength> },
Redistributable { entity: Entity<RedistributableColumnsState>, table_width: Option<DefiniteLength> },
Resizable(Entity<ResizableColumnsState>), // NEW: spreadsheet-style
}
```
**Callers updated:**
- csv_preview: Changed from `ColumnWidthConfig::redistributable()` to
use new resizable mode
- git_graph: Added `resizable_info` parameter
**Context:**
This is part 3 of a 3-PR series improving data table column width
handling:
1. [zed-industries#51059](zed-industries#51059) - Extract
modules into separate files (mechanical change)
2. [zed-industries#51120](zed-industries#51120) -
Introduce width config enum for redistributable column widths (API
rework)
3. **This PR**: Add independently resizable columns + fix variable list
scrolling (new feature + bug fixes)
The series builds on previously merged infrastructure:
- [zed-industries#46341](zed-industries#46341) - Data
table dynamic column support
- [zed-industries#46190](zed-industries#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([zed-industries#48207](zed-industries#48207))
This work is based on the [original draft PR
zed-industries#44344](zed-industries#44344), decomposed
into reviewable pieces.
-----
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
|
Does this effort being in core necessitate closing zed-industries/extensions#476? |
Extract data table modules into separate files This PR extracts the `tests` and `table_row` modules from `data_table.rs` into separate files to improve code organization. This is preparatory work for the upcoming column width API rework (#2 in the series), where separating mechanical changes from logical changes will make the review easier. The extraction was performed using rust-analyzer's "Extract module to file" command. **Context:** This is part 1 of a 3-PR series improving data table column width handling: 1. **This PR**: Extract modules into separate files (mechanical change) 2. [#51060](zed-industries/zed#51060) - Introduce width config enum for redistributable column widths (API rework) 3. Implement independently resizable column widths (new feature) The series builds on previously merged infrastructure: - [#46341](zed-industries/zed#46341) - Data table dynamic column support - [#46190](zed-industries/zed#46190) - Variable row height mode for data tables Primary beneficiary: CSV preview feature ([#48207](zed-industries/zed#48207)) Release Notes: - N/A
data_table: Replace column width builder API with `ColumnWidthConfig`
enum
This PR consolidates the data table width configuration API from three
separate builder methods (`.column_widths()`, `.resizable_columns()`,
`.width()`) into a single `.width_config(ColumnWidthConfig)` call. This
makes invalid state combinations unrepresentable and clarifies the two
distinct width management modes.
**What changed:**
- Introduces `ColumnWidthConfig` enum with two variants:
- `Static`: Fixed column widths, no resize handles
- `Redistributable`: Drag-to-resize columns that redistribute space
within a fixed table width
- Introduces `TableResizeBehavior` enum (`None`, `Resizable`,
`MinSize(f32)`) for per-column resize policy
- Renames `TableColumnWidths` → `RedistributableColumnsState` to better
reflect its purpose
- Extracts all width management logic into a new `width_management.rs`
module
- Updates all callers: `csv_preview`, `git_graph`, `keymap_editor`,
`edit_prediction_context_view`
```rust
pub enum ColumnWidthConfig {
/// Static column widths (no resize handles).
Static {
widths: StaticColumnWidths,
/// Controls widths of the whole table.
table_width: Option<DefiniteLength>,
},
/// Redistributable columns — dragging redistributes the fixed available space
/// among columns without changing the overall table width.
Redistributable {
entity: Entity<RedistributableColumnsState>,
table_width: Option<DefiniteLength>,
},
}
```
**Why:**
The old API allowed callers to combine methods incorrectly. The new
enum-based design enforces correct usage at compile time and provides a
clearer path for adding independently resizable columns in PR zed-industries#3.
**Context:**
This is part 2 of a 3-PR series improving data table column width
handling:
1. [zed-industries#51059](zed-industries#51059) - Extract
modules into separate files (mechanical change)
2. **This PR**: Introduce width config enum for redistributable column
widths (API rework)
3. Implement independently resizable column widths (new feature)
The series builds on previously merged infrastructure:
- [zed-industries#46341](zed-industries#46341) - Data
table dynamic column support
- [zed-industries#46190](zed-industries#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([zed-industries#48207](zed-industries#48207))
### Anthony's note
This PR also fixes the table dividers being a couple pixels off, and the
csv preview from having double line rendering for a single column in
some cases.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
This PR adds spreadsheet-style independently resizable columns (dragging
changes total table width) and fixes scrolling issues in variable list
mode.
**What changed:**
- Adds `ResizableColumnsState` struct for independently resizable
columns (spreadsheet-style)
- Adds `ColumnWidthConfig::Resizable` variant for spreadsheet mode
- Adds `DraggedResizableColumn` drag payload type
- Adds `ResizableHeaderInfo` for double-click-to-reset functionality
- Adds `render_resize_handles_resizable` function for resize handles
rendering
- Adds horizontal scroll handle to `TableInteractionState`
- Adds `.on_drag_move::<DraggedResizableColumn>` handler to Table for
drag resizing
**Bug fixes:**
- Fixed missing vertical scrollbar in variable list mode
- Fixed half-broken scrolling in variable list mode (added
.measure_all() to make scrollbar aware of the height of the table)
- Moved vertical scrollbar to be pinned at the right side of the pane
with table — previously it was attached to the table content and was
pushed off-screen when table content was too wide
**API addition:**
```rust
// New variant added:
pub enum ColumnWidthConfig {
Static { widths: StaticColumnWidths, table_width: Option<DefiniteLength> },
Redistributable { entity: Entity<RedistributableColumnsState>, table_width: Option<DefiniteLength> },
Resizable(Entity<ResizableColumnsState>), // NEW: spreadsheet-style
}
```
**Callers updated:**
- csv_preview: Changed from `ColumnWidthConfig::redistributable()` to
use new resizable mode
- git_graph: Added `resizable_info` parameter
**Context:**
This is part 3 of a 3-PR series improving data table column width
handling:
1. [zed-industries#51059](zed-industries#51059) - Extract
modules into separate files (mechanical change)
2. [zed-industries#51120](zed-industries#51120) -
Introduce width config enum for redistributable column widths (API
rework)
3. **This PR**: Add independently resizable columns + fix variable list
scrolling (new feature + bug fixes)
The series builds on previously merged infrastructure:
- [zed-industries#46341](zed-industries#46341) - Data
table dynamic column support
- [zed-industries#46190](zed-industries#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([zed-industries#48207](zed-industries#48207))
This work is based on the [original draft PR
zed-industries#44344](zed-industries#44344), decomposed
into reviewable pieces.
-----
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
…dustries#48207) ## **Description:** **Context:** This PR introduces an initial CSV preview feature for Zed, building upon two previously merged infrastructure PRs: - [zed-industries#46341](zed-industries#46341) - Data table dynamic column support (removed const generics) - [zed-industries#46190](zed-industries#46190) - Variable row height mode for data tables This implementation is based on the [original draft PR zed-industries#44344](zed-industries#44344), which has been carefully decomposed into smaller, reviewable pieces. --- #### **Features Included:** **Core Infrastructure:** - Live CSV parsing with smart debouncing (200ms cooldown) - Performance monitoring with built-in timing metrics (not displayed in UI yet) - Automatic file change detection and re-parsing - Support for quoted fields, multiline cells, and escaped characters **Table Display:** - Variable row height rendering with fallback to uniform mode (switchable via settings) - Draggable column resizing (reusing existing data table infrastructure) - Row identifiers supporting both source line numbers and sequential row numbers - Configurable font rendering (UI font vs monospace) - Tooltips showing full cell content on hover **Interactive Features:** - Column sorting (ascending/descending) with visual indicators **Settings Panel:** - Toggle between variable/uniform row rendering - Font type selection (UI/monospace) - Row identifier type configuration - Debug information display - Multiline cell rendering options --- #### **Features Intentionally Removed for This PR:** To reduce complexity and review scope, the following features were temporarily reverted and will be reintroduced in subsequent PRs: - ❌ Settings pannel with performance metrics overlay - ❌ Cell selection (single, multiple, and range selections) - ❌ Keyboard navigation with arrow keys and selection extension - ❌ Copy functionality supporting CSV, TSV, and Markdown table formats - ❌ Inline cell editing with file persistence - ❌ Viewport following for large datasets - ❌ Column filtering and search capabilities These removals were done via "time-machine" commits that cleanly nuked vertical slices of functionality from the complete implementation. --- **Technical Implementation:** The feature is organized into a dedicated `csv_preview` crate with the following structure: ``` crates/csv_preview/ ├── src/ │ ├── csv_preview.rs # Main view and coordination logic │ ├── parser.rs # CSV parsing and editor integration │ ├── settings.rs # Configuration types and defaults │ ├── table_data_engine.rs # Data transformation logic │ ├── renderer/ # UI rendering modules │ │ ├── preview_view.rs # Main render implementation │ │ ├── render_table.rs # Table component assembly │ │ ├── table_cell.rs # Individual cell rendering │ │ ├── table_header.rs # Header with sorting controls │ │ └── row_identifiers.rs # Line number column │ └── types/ # Core data structures │ ├── table_like_content.rs │ ├── coordinates.rs # Display vs data coordinate systems │ └── table_cell.rs ``` **Key architectural decisions:** - **Dual coordinate system**: Separates data indices from display indices to support sorting/filtering - **Component reuse**: Leverages existing `data_table` infrastructure from the keymap editor --- **Integration:** - Registers `csv::OpenPreview` action (currently without default keybindings) - Follows the same workspace integration pattern as `markdown_preview` and `svg_preview` - Automatically detects `.csv` file extensions - Tab integration with appropriate icons and naming --- **Code Structure Note:** Some code structures, types, and documentation may appear redundant or over-engineered in this initial implementation. This is intentional - the feature was developed as a complete system and then decomposed by functionality rather than being built incrementally. The "extra" infrastructure supports features that were removed for this PR but will be reintroduced in subsequent ones. This approach was chosen over extensive refactoring because: 1. The complete feature took 200+ commits to develop with significant rewrites 2. Clean extraction of vertical slices was more feasible than rebuilding incrementally 3. The end state will utilize all these components, making current "redundancy" temporary I apologize for any inconvenience this may cause during review, but the alternative would have required significant refactoring effort just to make intermediate states "prettier," which seemed counterproductive. --- **Future Work:** This lays the groundwork for upcoming PRs that will reintroduce the removed features: - Cell selection and keyboard navigation - Copy functionality with multiple output formats - Inline editing capabilities with undo/redo - Column filtering and search - TSV and other delimiter support - Improved horizontal scrolling behavior - Settings persistence **Testing:** Includes test fixtures demonstrating multiline cell handling, various column counts, and edge cases. --- **Release Notes:** - N/A This is feature flagged --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
…stries#51059) Extract data table modules into separate files This PR extracts the `tests` and `table_row` modules from `data_table.rs` into separate files to improve code organization. This is preparatory work for the upcoming column width API rework (zed-industries#2 in the series), where separating mechanical changes from logical changes will make the review easier. The extraction was performed using rust-analyzer's "Extract module to file" command. **Context:** This is part 1 of a 3-PR series improving data table column width handling: 1. **This PR**: Extract modules into separate files (mechanical change) 2. [zed-industries#51060](zed-industries#51060) - Introduce width config enum for redistributable column widths (API rework) 3. Implement independently resizable column widths (new feature) The series builds on previously merged infrastructure: - [zed-industries#46341](zed-industries#46341) - Data table dynamic column support - [zed-industries#46190](zed-industries#46190) - Variable row height mode for data tables Primary beneficiary: CSV preview feature ([zed-industries#48207](zed-industries#48207)) Release Notes: - N/A
data_table: Replace column width builder API with `ColumnWidthConfig`
enum
This PR consolidates the data table width configuration API from three
separate builder methods (`.column_widths()`, `.resizable_columns()`,
`.width()`) into a single `.width_config(ColumnWidthConfig)` call. This
makes invalid state combinations unrepresentable and clarifies the two
distinct width management modes.
**What changed:**
- Introduces `ColumnWidthConfig` enum with two variants:
- `Static`: Fixed column widths, no resize handles
- `Redistributable`: Drag-to-resize columns that redistribute space
within a fixed table width
- Introduces `TableResizeBehavior` enum (`None`, `Resizable`,
`MinSize(f32)`) for per-column resize policy
- Renames `TableColumnWidths` → `RedistributableColumnsState` to better
reflect its purpose
- Extracts all width management logic into a new `width_management.rs`
module
- Updates all callers: `csv_preview`, `git_graph`, `keymap_editor`,
`edit_prediction_context_view`
```rust
pub enum ColumnWidthConfig {
/// Static column widths (no resize handles).
Static {
widths: StaticColumnWidths,
/// Controls widths of the whole table.
table_width: Option<DefiniteLength>,
},
/// Redistributable columns — dragging redistributes the fixed available space
/// among columns without changing the overall table width.
Redistributable {
entity: Entity<RedistributableColumnsState>,
table_width: Option<DefiniteLength>,
},
}
```
**Why:**
The old API allowed callers to combine methods incorrectly. The new
enum-based design enforces correct usage at compile time and provides a
clearer path for adding independently resizable columns in PR zed-industries#3.
**Context:**
This is part 2 of a 3-PR series improving data table column width
handling:
1. [zed-industries#51059](zed-industries#51059) - Extract
modules into separate files (mechanical change)
2. **This PR**: Introduce width config enum for redistributable column
widths (API rework)
3. Implement independently resizable column widths (new feature)
The series builds on previously merged infrastructure:
- [zed-industries#46341](zed-industries#46341) - Data
table dynamic column support
- [zed-industries#46190](zed-industries#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([zed-industries#48207](zed-industries#48207))
### Anthony's note
This PR also fixes the table dividers being a couple pixels off, and the
csv preview from having double line rendering for a single column in
some cases.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
This PR adds spreadsheet-style independently resizable columns (dragging
changes total table width) and fixes scrolling issues in variable list
mode.
**What changed:**
- Adds `ResizableColumnsState` struct for independently resizable
columns (spreadsheet-style)
- Adds `ColumnWidthConfig::Resizable` variant for spreadsheet mode
- Adds `DraggedResizableColumn` drag payload type
- Adds `ResizableHeaderInfo` for double-click-to-reset functionality
- Adds `render_resize_handles_resizable` function for resize handles
rendering
- Adds horizontal scroll handle to `TableInteractionState`
- Adds `.on_drag_move::<DraggedResizableColumn>` handler to Table for
drag resizing
**Bug fixes:**
- Fixed missing vertical scrollbar in variable list mode
- Fixed half-broken scrolling in variable list mode (added
.measure_all() to make scrollbar aware of the height of the table)
- Moved vertical scrollbar to be pinned at the right side of the pane
with table — previously it was attached to the table content and was
pushed off-screen when table content was too wide
**API addition:**
```rust
// New variant added:
pub enum ColumnWidthConfig {
Static { widths: StaticColumnWidths, table_width: Option<DefiniteLength> },
Redistributable { entity: Entity<RedistributableColumnsState>, table_width: Option<DefiniteLength> },
Resizable(Entity<ResizableColumnsState>), // NEW: spreadsheet-style
}
```
**Callers updated:**
- csv_preview: Changed from `ColumnWidthConfig::redistributable()` to
use new resizable mode
- git_graph: Added `resizable_info` parameter
**Context:**
This is part 3 of a 3-PR series improving data table column width
handling:
1. [zed-industries#51059](zed-industries#51059) - Extract
modules into separate files (mechanical change)
2. [zed-industries#51120](zed-industries#51120) -
Introduce width config enum for redistributable column widths (API
rework)
3. **This PR**: Add independently resizable columns + fix variable list
scrolling (new feature + bug fixes)
The series builds on previously merged infrastructure:
- [zed-industries#46341](zed-industries#46341) - Data
table dynamic column support
- [zed-industries#46190](zed-industries#46190) - Variable
row height mode for data tables
Primary beneficiary: CSV preview feature
([zed-industries#48207](zed-industries#48207))
This work is based on the [original draft PR
zed-industries#44344](zed-industries#44344), decomposed
into reviewable pieces.
-----
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
---------
Co-authored-by: Anthony Eid <anthony@zed.dev>
…dustries#48207) ## **Description:** **Context:** This PR introduces an initial CSV preview feature for Zed, building upon two previously merged infrastructure PRs: - [zed-industries#46341](zed-industries#46341) - Data table dynamic column support (removed const generics) - [zed-industries#46190](zed-industries#46190) - Variable row height mode for data tables This implementation is based on the [original draft PR zed-industries#44344](zed-industries#44344), which has been carefully decomposed into smaller, reviewable pieces. --- #### **Features Included:** **Core Infrastructure:** - Live CSV parsing with smart debouncing (200ms cooldown) - Performance monitoring with built-in timing metrics (not displayed in UI yet) - Automatic file change detection and re-parsing - Support for quoted fields, multiline cells, and escaped characters **Table Display:** - Variable row height rendering with fallback to uniform mode (switchable via settings) - Draggable column resizing (reusing existing data table infrastructure) - Row identifiers supporting both source line numbers and sequential row numbers - Configurable font rendering (UI font vs monospace) - Tooltips showing full cell content on hover **Interactive Features:** - Column sorting (ascending/descending) with visual indicators **Settings Panel:** - Toggle between variable/uniform row rendering - Font type selection (UI/monospace) - Row identifier type configuration - Debug information display - Multiline cell rendering options --- #### **Features Intentionally Removed for This PR:** To reduce complexity and review scope, the following features were temporarily reverted and will be reintroduced in subsequent PRs: - ❌ Settings pannel with performance metrics overlay - ❌ Cell selection (single, multiple, and range selections) - ❌ Keyboard navigation with arrow keys and selection extension - ❌ Copy functionality supporting CSV, TSV, and Markdown table formats - ❌ Inline cell editing with file persistence - ❌ Viewport following for large datasets - ❌ Column filtering and search capabilities These removals were done via "time-machine" commits that cleanly nuked vertical slices of functionality from the complete implementation. --- **Technical Implementation:** The feature is organized into a dedicated `csv_preview` crate with the following structure: ``` crates/csv_preview/ ├── src/ │ ├── csv_preview.rs # Main view and coordination logic │ ├── parser.rs # CSV parsing and editor integration │ ├── settings.rs # Configuration types and defaults │ ├── table_data_engine.rs # Data transformation logic │ ├── renderer/ # UI rendering modules │ │ ├── preview_view.rs # Main render implementation │ │ ├── render_table.rs # Table component assembly │ │ ├── table_cell.rs # Individual cell rendering │ │ ├── table_header.rs # Header with sorting controls │ │ └── row_identifiers.rs # Line number column │ └── types/ # Core data structures │ ├── table_like_content.rs │ ├── coordinates.rs # Display vs data coordinate systems │ └── table_cell.rs ``` **Key architectural decisions:** - **Dual coordinate system**: Separates data indices from display indices to support sorting/filtering - **Component reuse**: Leverages existing `data_table` infrastructure from the keymap editor --- **Integration:** - Registers `csv::OpenPreview` action (currently without default keybindings) - Follows the same workspace integration pattern as `markdown_preview` and `svg_preview` - Automatically detects `.csv` file extensions - Tab integration with appropriate icons and naming --- **Code Structure Note:** Some code structures, types, and documentation may appear redundant or over-engineered in this initial implementation. This is intentional - the feature was developed as a complete system and then decomposed by functionality rather than being built incrementally. The "extra" infrastructure supports features that were removed for this PR but will be reintroduced in subsequent ones. This approach was chosen over extensive refactoring because: 1. The complete feature took 200+ commits to develop with significant rewrites 2. Clean extraction of vertical slices was more feasible than rebuilding incrementally 3. The end state will utilize all these components, making current "redundancy" temporary I apologize for any inconvenience this may cause during review, but the alternative would have required significant refactoring effort just to make intermediate states "prettier," which seemed counterproductive. --- **Future Work:** This lays the groundwork for upcoming PRs that will reintroduce the removed features: - Cell selection and keyboard navigation - Copy functionality with multiple output formats - Inline editing capabilities with undo/redo - Column filtering and search - TSV and other delimiter support - Improved horizontal scrolling behavior - Settings persistence **Testing:** Includes test fixtures demonstrating multiline cell handling, various column counts, and edge cases. --- **Release Notes:** - N/A This is feature flagged --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
|
Elite PR |
Description:
Context:
This PR introduces an initial CSV preview feature for Zed, building upon two previously merged infrastructure PRs:
This implementation is based on the original draft PR #44344, which has been carefully decomposed into smaller, reviewable pieces.
Features Included:
Core Infrastructure:
Table Display:
Interactive Features:
Settings Panel:
Features Intentionally Removed for This PR:
To reduce complexity and review scope, the following features were temporarily reverted and will be reintroduced in subsequent PRs:
These removals were done via "time-machine" commits that cleanly nuked vertical slices of functionality from the complete implementation.
Technical Implementation:
The feature is organized into a dedicated
csv_previewcrate with the following structure:Key architectural decisions:
data_tableinfrastructure from the keymap editorIntegration:
csv::OpenPreviewaction (currently without default keybindings)markdown_previewandsvg_preview.csvfile extensionsCode Structure Note:
Some code structures, types, and documentation may appear redundant or over-engineered in this initial implementation. This is intentional - the feature was developed as a complete system and then decomposed by functionality rather than being built incrementally. The "extra" infrastructure supports features that were removed for this PR but will be reintroduced in subsequent ones.
This approach was chosen over extensive refactoring because:
I apologize for any inconvenience this may cause during review, but the alternative would have required significant refactoring effort just to make intermediate states "prettier," which seemed counterproductive.
Future Work:
This lays the groundwork for upcoming PRs that will reintroduce the removed features:
Testing:
Includes test fixtures demonstrating multiline cell handling, various column counts, and edge cases.
Release Notes: