-
-
Notifications
You must be signed in to change notification settings - Fork 195
Research multi-buffer inline diff display #598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sinelaw
wants to merge
32
commits into
master
Choose a base branch
from
claude/research-multi-buffer-diff-7b1we
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1f594f3 to
8302855
Compare
Research feasibility of displaying multiple buffers within a single visual pane (tab) for side-by-side diff, unified diff, and 3-way merge views. Key findings: - Existing COMPOSITE_BUFFER_ARCHITECTURE.md provides solid foundation - Proposes phased approach: enhanced virtual buffers → multi-source tokens → full composite buffers with editing - Documents design options, trade-offs, and mapping to existing arch
Full specification for displaying multiple buffers in a single tab: Core data structures: - CompositeBuffer: References multiple source buffers - LineAlignment: Maps display rows to source lines with padding - CompositeViewState: Per-split state with unified scrolling Rendering pipeline: - CompositeRenderer: Handles side-by-side, stacked, unified layouts - Automatic line alignment with padding for diff views - Focus indicator for active pane Input routing: - CompositeInputRouter: Routes events to focused pane's source buffer - Coordinate mapping from display to source positions - Scroll events affect entire composite view Plugin API: - createCompositeBuffer(): Full configuration for layouts - updateCompositeAlignment(): Live refresh on source changes - setCompositeFocus(): Switch between panes Includes complete diff_view.ts plugin example.
Implements the foundation for multi-buffer single-tab views: - src/model/composite_buffer.rs: CompositeBuffer, SourcePane, PaneStyle, LineAlignment with support for diff hunks, and RowType for styling - src/view/composite_view.rs: CompositeViewState with pane focus, unified scrolling, and per-pane cursor tracking - src/view/composite_renderer.rs: CompositeRenderer with side-by-side, stacked, and unified layout modes The composite buffer system enables displaying multiple source buffers within a single tab, supporting use cases like side-by-side diff, unified diff, and 3-way merge views.
Implements CompositeInputRouter for handling keyboard input in composite buffer views: - Scroll navigation (j/k, arrows, page up/down, g/G) - Pane switching (Tab, h/l) - Hunk navigation (n/p, [/]) - Edit routing to source buffers (respects read-only panes) - Display-to-source coordinate mapping - Click-to-pane detection The router translates composite-level input into specific actions that can be applied to the composite view or routed to source buffers.
- Add composite_buffers and composite_view_states fields to Editor - Create separate composite_buffer_actions.rs for management methods - Add methods: create_composite_buffer, close_composite_buffer, get_composite_view_state, composite_scroll, composite_next/prev_hunk - Update get_buffer_display_name to handle composite buffers
Add PluginCommand variants for creating, updating, and closing composite buffers. This enables TypeScript plugins to create side-by-side diff views and other multi-buffer layouts. - Add CreateCompositeBuffer, UpdateCompositeAlignment, CloseCompositeBuffer commands - Add CompositeLayoutConfig, CompositeSourceConfig, CompositePaneStyle types - Add handler methods in composite_buffer_actions.rs - Route new commands in Editor::handle_plugin_command
Add op functions and editor methods for creating and managing composite buffers from TypeScript plugins: - createCompositeBuffer(options): Create a multi-buffer view - updateCompositeAlignment(bufferId, hunks): Update diff alignment - closeCompositeBuffer(bufferId): Close a composite buffer This enables plugins to create side-by-side diff views and other multi-buffer layouts within a single tab.
Add a diff view plugin that demonstrates the composite buffer infrastructure: - Compare current file with git HEAD - Side-by-side view with line alignment - Keybindings for hunk navigation (n/N, [c/]c) - Tab to switch between panes - q/Escape to close This plugin uses createCompositeBuffer() to create a multi-buffer view within a single tab.
Replace the split-based side-by-side diff with composite buffers: - `side_by_side_diff_current_file` now uses createCompositeBuffer - `review_drill_down` now uses createCompositeBuffer - Add activeCompositeDiffState for tracking composite diff views - Proper cleanup on buffer close - Remove separate diff_view.ts (functionality merged into audit_mode) Benefits of composite buffers: - Single tab instead of two splits - Line alignment handled by infrastructure - Synchronized scrolling built-in - Proper OLD|NEW ordering (left=old, right=new)
Connect composite buffers to the main render path: - Add is_composite_buffer flag to EditorState - Register composite buffers with split_view_states for tabs - Add composite_buffers parameter to render_content - Add render_composite_buffer for side-by-side pane rendering - Render each pane with header label and buffer content This enables composite buffers to actually display in the editor instead of showing empty buffers.
- Add event_logs entry for composite buffers to fix panic on 'g' key - Route scroll/movement actions through handle_composite_action - Add cursor_row field to CompositeViewState with movement methods - Highlight current line in composite pane rendering - Fix plugin keybindings: "close_buffer" -> "close", add h/l keys - Pass composite_view_states to render functions for scroll sync
…ring - Add diff_add_bg, diff_remove_bg, diff_modify_bg colors to Theme struct - Add serde defaults for backwards-compatible theme file parsing - Update all 4 built-in themes (dark, light, high_contrast, nostalgia) - Refactor render_composite_buffer to use LineAlignment for proper diff display - Style rows based on RowType (Addition, Deletion, Modification, etc.)
…r view - Add render_composite_scrollbar() for visual scroll position feedback - Pass CompositeViewState to render_composite_buffer for state access - Add cursor_column tracking to CompositeViewState - Add cursor column movement methods (left/right/home/end) with auto-scroll - Render cursor as inverted character at cursor position - Apply horizontal scrolling per-pane using PaneViewport.left_column - Pad content to fill width for consistent diff backgrounds
Create PLAN_composite_rendering_reuse.md documenting: - Current architecture and its coupling to byte-based contexts - Proposed LineRenderer abstraction for per-line rendering - Implementation steps for proper code reuse - Benefits and estimated effort
Updated PLAN_composite_rendering_reuse.md with clean architecture: - Bridge line numbers (composite) to byte offsets (normal pipeline) - build_view_line_from_line() - builds ViewLine from source line number - get_line_highlights() - queries highlighter for line's byte range - render_composite_view_line() - renders with full styling - Reuses: ViewLineIterator, compute_char_style logic, Highlighter, Theme
- CompositeBuffer wraps full EditorStates, not custom rendering - Each pane uses existing render_buffer_in_split() for all features - Chunk-based alignment with markers at boundaries only - Markers auto-adjust on edit, context chunks update line_count - Hunks marked dirty for localized recomputation - Diff highlighting via overlays on pane EditorStates - Unified scroll_display_row derived to per-pane top_byte - Input routing to focused pane's EditorState
The CompositeRenderer struct was defined but never used anywhere in the codebase. The actual composite buffer rendering is done in split_rendering.rs via render_composite_buffer(). This removes dead code as part of the architecture cleanup.
Merged the following fragmented docs into docs/internal/DIFF_VIEW.md: - PLAN_composite_rendering_reuse.md - DIFF_BRANCH_CONTINUATION.md - docs/REVIEW_DIFF_FEATURE.md - docs/COMPOSITE_BUFFER_ARCHITECTURE.md - docs/MULTI_BUFFER_SINGLE_TAB_RESEARCH.md The new document has two parts: 1. UX Design - keyboard shortcuts, visual layout, comment system 2. Architecture/Implementation - dual-mode rendering decision, ChunkAlignment with markers, render_aligned_view_lines design Key design decision: Option E (Dual-Mode Rendering) chosen over full pipeline reuse because aligned diff views need gaps that consecutive line rendering cannot provide.
Refactored render_composite_buffer to use the ViewLine pipeline for proper syntax highlighting in diff views. Key changes: - Build ViewData per pane using build_view_data() to get syntax-highlighted ViewLines with proper token styles - Create source_line -> ViewLine index mapping for each pane - New render_view_line_content() helper that renders ViewLine with: - Per-character syntax highlighting from char_styles - Horizontal scroll support - Cursor rendering - Style accumulation for efficient span generation - Fallback to direct buffer read if ViewLine not found This implements the dual-mode rendering design from DIFF_VIEW.md where composite buffers reuse the ViewLine building infrastructure while having their own aligned rendering loop for gaps.
Fix language detection for virtual buffer names like "*OLD:test_diff.ts*" by stripping surrounding * characters and extracting the actual filename after prefixes like "OLD:" or "NEW:". This enables syntax highlighting in composite/diff views where source buffers are created with decorated names.
- Add visual_mode, selection_anchor_row/column to CompositeViewState - Add selection helpers (start_visual_selection, is_row_selected, etc.) - Add SelectionAction enum to composite router - Handle SelectDown/SelectUp/Copy actions in handle_composite_action - Render selection highlighting with theme.selection_bg - Add selection and copy keybindings to diff-view mode (Shift+j/k, y, Ctrl+c)
- Fix keybinding syntax for diff-view mode (use "J", "K", "C-c", "S-Down") - Route Action::Copy to handle_composite_action for composite buffers - Ensures copy in diff view uses the composite-specific selection logic
Added modifications to test the side-by-side diff functionality: - Modified scrollTest5 with additional text - Added new comment at end of file
…osite view - Simplified diff-view mode to inherit from "normal" mode - Forward navigation/selection actions to focused source buffer instead of reimplementing them in handle_composite_action - Removed duplicate navigation logic, leveraging action_to_events - Only special handling for Copy (needs aligned row mapping) and Close
The previous attempt to forward actions to source buffers didn't work because the composite view needs its own cursor/scroll state for aligned row navigation. Restored explicit handling for: - Arrow key navigation (MoveDown/Up/Left/Right) - Page navigation (MovePageDown/Up) - Document start/end - Scroll actions - Selection with Shift+arrows The diff-view mode still inherits from "normal" for keybindings, but the BufferMode registry doesn't have a "normal" mode defined - this needs to be addressed by explicitly defining keybindings in diff-view.
…play - Add composite_view field to SplitViewState for future view-layer refactoring - Update navigation actions (MoveDown/Up/Left/Right) to sync cursor position with the fake EditorState's primary_cursor_line_number - Update selection actions (SelectDown/Up/Left/Right) similarly - This fixes the status bar showing "Ln 1, Col 1" when navigating in diff view
185c151 to
924e3d0
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
No description provided.