feat: implement window splitting functionality#63
Merged
Conversation
- Add WindowManager and Window structs to manage multiple views - Add Split enum to represent window layout tree (horizontal/vertical splits) - Maintain backward compatibility by keeping existing editor fields - Add sync methods to synchronize window state with editor state - Update resize handler to also resize window manager - All tests pass, no regressions This is the foundation for implementing window splits. The actual split functionality will be implemented in follow-up commits. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
- Add WindowManager with tree-based split layout structure - Implement window splitting actions (SplitHorizontal, SplitVertical) - Add window navigation actions (NextWindow, PreviousWindow) - Support command-line split commands (:split, :vsplit, :close) - Add Vim-style keybindings for window management (Ctrl-w prefix) - Update rendering system to handle multiple windows - Synchronize editor state with active window - Document window management features in CLAUDE.md This provides the foundation for window splitting functionality. Future work includes: - Rendering window borders and separators - Implementing window closing and resizing - Adding visual indicators for active window - Supporting different buffers per window
- Add window-aware rendering system that respects window boundaries - Fix gutter rendering issue in horizontal splits (was being overwritten) - Fix window split targeting (correct window now gets split) - Implement proper window borders with intersection characters (┼, ├, ┤, ┬, ┴) - Add window closing functionality (:close command and Ctrl-w c/q) - Implement directional window navigation (Ctrl-w h/j/k/l) - Support opening different files in splits (:split <file>, :vsplit <file>) - Add coordinate transformation methods for window-aware rendering - Update cursor positioning to work with active window - Reserve space for window separators in layout calculations All windows now render independently with proper visual separation. State synchronization between editor and windows is maintained when switching between windows. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Implement render_overlays_in_window() to handle overlays per window - Add render_diagnostics_in_window() for window-specific diagnostics - Add selected_cells_in_window() for window-aware selections - Overlays now properly respect window boundaries - Line highlights, selections, and diagnostics only render within their window - Only active window shows cursor-related overlays This completes Phase 1.3 of the window implementation plan. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Status line now shows information from the active window - Added window indicator showing current window number and total - Position (line:column) now reflects active window's viewport - Buffer name and dirty state come from active window's buffer The status line now shows "[1/3]" style indicators when multiple windows are open, making it clear which window is active. This completes Phase 4.1 of the window implementation plan. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Added resize_window() method to WindowManager - Implemented smart split ratio adjustment based on resize direction - Window resizing respects parent split orientations - Keybindings: Ctrl-w < (left), > (right), + (down), - (up in config) - Resize amount is configurable (default: 5% per step) - Prevents windows from becoming too small (min 10% ratio) The implementation finds the appropriate split containing the active window and adjusts its ratio accordingly. Resizing is context-aware: - In horizontal splits: Up/Down resizes the split - In vertical splits: Left/Right resizes the split This completes Phase 3.3 of the window implementation plan. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Mouse clicks now activate the window under the cursor - Clicking in a window switches focus to that window - Mouse position is properly translated to window-local coordinates - Scrolling with mouse wheel now activates the window under cursor - Cursor placement respects window boundaries and buffer limits This improves the window management UX by allowing users to click directly on a window to focus it, making multi-window workflows more intuitive. This completes Phase 4.3 of the window implementation plan. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Marked Phase 3.3 (window resizing) as complete - Marked Phase 4.3 (mouse support) as complete - Added note about minimum window size enforcement still needed - All critical window functionality is now implemented The window splitting feature set is now functionally complete with: - Window creation, closing, and navigation - Window-aware rendering (content, overlays, status line) - Window resizing with smart split ratio adjustment - Mouse support for window selection and scrolling - Proper window borders with intersections 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Fixed panic caused by subtracting vtop from cy when cy < vtop - Use saturating_sub to handle underflow gracefully - Use window's local cursor position instead of global editor state - This fixes crashes when cursor is outside the current viewport The issue occurred when switching between windows with different viewport positions, causing cursor coordinates to be out of sync. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Added sync_to_window() after executing actions to ensure window state is updated - Added render call for multi-window mode to make changes immediately visible - This fixes the issue where actions (like cursor movement) weren't visible until switching windows The problem was that actions updated the global editor state but never synced it back to the active window, causing changes to only appear after window switch. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Implement proper T-junction detection for window separators - Add configurable ASCII/Unicode border characters via window_borders_ascii - Rewrite separator rendering to use grid-based approach for accurate intersections - Fix issue where horizontal lines overwrote vertical separator intersections The new implementation correctly detects and renders T-junctions (┬, ┴, ├, ┤) where horizontal and vertical window separators meet. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Handle cases where vertical lines end exactly at horizontal lines - Check for vertical lines that start or end at horizontal separator positions - Add detailed debug logging to trace separator detection - Fix edge cases in intersection detection logic The improved algorithm now correctly detects T-junctions in all split configurations including Ctrl+W s followed by Ctrl+W v, and vice versa. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Use two-pass algorithm: first mark all positions, then determine characters - Explicitly check for T-junctions where vertical lines start/end at horizontal lines - Add support for corner characters (└, ┘, ┌, ┐) for better visual clarity - Fix case where vertical separator meets horizontal separator from below The new algorithm correctly handles all window configurations including: - Horizontal split followed by vertical split of bottom window - Vertical split followed by horizontal split - Complex multi-window layouts with multiple intersections 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Pass 1: Draw all vertical and horizontal lines into a temporary grid - Pass 2: Refine each position based on adjacent cells to select correct junction - Check connections in all four directions (up, down, left, right) - Correctly handle T-junctions, corners, and four-way intersections The new algorithm determines junction characters based on the actual topology of separators in the grid, not on abstract line segments. This fixes all cases including: - Vertical split with horizontal split of one side - Horizontal split with vertical split of one side - Complex multi-window layouts 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Handle all possible connection patterns explicitly - Add exhaustive match patterns for Unicode mode - Improve ASCII mode logic to use correct characters - Add debug logging for junction detection - Remove fallback to '+' character in Unicode mode This should fix the issue where all separators were rendering as '+' characters instead of proper box-drawing characters. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the T-junction rendering issue where intersections between vertical and horizontal window separators were not being detected properly. The issue was that vertical lines were being drawn as separate segments with gaps at horizontal separator positions. Changes: - Refactored separator detection to find continuous vertical/horizontal lines - Vertical separators now span the full height of adjacent windows - Horizontal separators now span the full width of adjacent windows - Added comprehensive logging for debugging intersection detection - This ensures proper T-junction characters (┬, ┴, ├, ┤) are rendered 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Removed unused methods: selected_cells, render_main_content, render_overlays, render_diagnostics, and render_gutter - Fixed incorrect method call in render_overlays_in_window - Fixed clippy warnings: - manual_map: simplified Option::map usage - empty_line_after_doc_comments: removed empty line - assign_op_pattern: use += operator - almost_swapped: fixed current_id tracking logic - only_used_in_recursion: added allow annotations for false positives All code now compiles without warnings and passes clippy checks. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Marked Phase 1 (Window-Aware Rendering) as COMPLETE - Marked Phase 2 (Window Borders and Separators) as COMPLETE - Marked Phase 3 (Window Operations) as COMPLETE - Updated Phase 4 status (status line complete, dialogs TODO) - Added details about all implemented features and fixes - Updated success criteria to reflect completion status - Listed remaining TODO items for future work The window splitting functionality is now feature-complete for the core use cases, with only advanced features like window balancing and window-aware dialogs remaining. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Added missing "-" keybinding for ResizeWindowUp - Fixed resize logic to return true when successfully adjusting ratios - Added comprehensive logging to debug resize operations - Improved comments to clarify resize behavior for each window position The issue was that the resize functions were returning false after successfully adjusting the ratio, which prevented the changes from being applied. Now all resize operations (Ctrl-w <, >, +, -) work correctly for both horizontal and vertical splits. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
- Improved xy_to_char_idx to properly handle newlines in char count - Added bounds checking in Buffer::insert to prevent panics - Added comprehensive logging to trace emoji-related issues - Better handling of line character counts excluding newlines - Added test suite for emoji handling scenarios This should help diagnose and prevent the "char index out of bounds" panic when working with emoji characters. The logging will help identify where cursor positions might be getting miscalculated. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull Request Overview
This PR implements window splitting functionality in Red editor along with improvements to window rendering and configuration. Key changes include:
- The addition of the WindowManager and Split tree structure to handle window layouts and operations (splitting, navigation, closing, resizing).
- Enhancements in the rendering system to support window-aware rendering with proper borders, separators, and cursor positioning.
- Updates to tests and configuration to support the new window management features.
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| window-implementation-plan.md | Updated planning document outlining window-aware rendering and operations. |
| tests/test_emoji_handling.rs | Added tests for emoji handling with window functionality. |
| test_windows.txt | New test file for verifying window splits. |
| test_windows.sh | Bash script to run window split tests. |
| test_config.toml | New configuration entries for window borders and keybindings. |
| src/lib.rs | Added module for window management. |
| src/config.rs | Added configuration option for ASCII window borders. |
| src/buffer.rs | Updated buffer methods to use character indices, with added error logging and newline handling. |
| docs/multi-windows-plan.md | Extended documentation regarding multi-window support. |
| default_config.toml | Updated commented key bindings for window management. |
| CLAUDE.md | Updated documentation with new window management commands and keybindings. |
| .claude/settings.local.json | Minor configuration update for testing. |
Comments suppressed due to low confidence (1)
tests/test_emoji_handling.rs:38
- [nitpick] Verify that the expected cursor position (8) accurately reflects emoji width across different platforms and environments, as character width for emojis can vary.
assert_eq!(x, 8); // "💕 hearts" has 8 characters
Comment on lines
+639
to
+644
| // Handle newline - Ropey includes newlines in char count | ||
| let line_chars_without_newline = if line_chars > 0 && line.char(line_chars - 1) == '\n' { | ||
| line_chars - 1 | ||
| } else { | ||
| line_chars | ||
| }; |
There was a problem hiding this comment.
[nitpick] Consider extracting the logic for computing the number of characters excluding the newline into a separate helper function for improved readability and maintainability.
Suggested change
| // Handle newline - Ropey includes newlines in char count | |
| let line_chars_without_newline = if line_chars > 0 && line.char(line_chars - 1) == '\n' { | |
| line_chars - 1 | |
| } else { | |
| line_chars | |
| }; | |
| // Compute the number of characters excluding the newline | |
| let line_chars_without_newline = count_chars_excluding_newline(&line); |
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
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.
Summary
Changes
Core Window Management
WindowManagerandSplittree structure for managing window layoutssplit/Ctrl-w s) and vertical (vsplit/Ctrl-w v) splittingCtrl-w h/j/k/landCtrl-w w)Ctrl-w c/Ctrl-w q)Ctrl-w +/-/</>)Rendering Improvements
window_borders_asciiconfig optionBug Fixes
Configuration
window_borders_asciioption to use ASCII characters (|,-,+) instead of UnicodeTest Plan
🤖 Generated with Claude Code