|
| 1 | +# Buffer Migration Audit |
| 2 | + |
| 3 | +This document tracks the migration of fields from EnhancedTuiApp to Buffer via BufferAPI. |
| 4 | + |
| 5 | +## Migration Categories |
| 6 | + |
| 7 | +### ✅ Already in Buffer (via BufferAPI) |
| 8 | +These fields already exist in Buffer and have BufferAPI methods: |
| 9 | + |
| 10 | +- [x] `mode: AppMode` → `get_mode()`, `set_mode()` |
| 11 | +- [x] `status_message: String` → `get_status_message()`, `set_status_message()` |
| 12 | +- [x] `results: Option<QueryResponse>` → `get_results()`, `set_results()` |
| 13 | +- [x] `table_state: TableState` → `get_selected_row()`, `set_selected_row()` |
| 14 | +- [x] `input: Input` → `get_input_value()`, `set_input_value()`, etc. |
| 15 | +- [x] `current_column: usize` → `get_current_column()`, `set_current_column()` |
| 16 | +- [x] `scroll_offset: (usize, usize)` → `get_scroll_offset()`, `set_scroll_offset()` |
| 17 | +- [x] `pinned_columns: Vec<usize>` → `get_pinned_columns()`, `add_pinned_column()`, etc. |
| 18 | +- [x] `compact_mode: bool` → `is_compact_mode()`, `set_compact_mode()` |
| 19 | +- [x] `show_row_numbers: bool` → `is_show_row_numbers()`, `set_show_row_numbers()` |
| 20 | +- [x] `filter_state: FilterState` → `get_filter_pattern()`, `is_filter_active()`, etc. |
| 21 | +- [x] `search_state: SearchState` → `get_search_pattern()`, `get_search_matches()`, etc. |
| 22 | +- [x] `sort_state: SortState` → `get_sort_column()`, `get_sort_order()`, etc. |
| 23 | +- [x] `csv_client: Option<CsvApiClient>` → `get_csv_client()`, `get_csv_client_mut()` |
| 24 | +- [x] `csv_mode: bool` → `is_csv_mode()` |
| 25 | +- [x] `csv_table_name: String` → `get_table_name()` |
| 26 | +- [x] `filtered_data: Option<Vec<Vec<String>>>` → `get_filtered_data()`, `set_filtered_data()` |
| 27 | + |
| 28 | +### ✅ Phase 1: Simple Fields (COMPLETED) |
| 29 | +These are straightforward to migrate and test: |
| 30 | + |
| 31 | +- [x] `edit_mode: EditMode` - How the editor is being used (single/multi-line) |
| 32 | +- [x] `last_results_row: Option<usize>` - Position preservation |
| 33 | +- [x] `last_scroll_offset: (usize, usize)` - Position preservation |
| 34 | +- [x] `case_insensitive: bool` - Search/filter behavior |
| 35 | +- [x] `last_query_source: Option<String>` - Track where query came from |
| 36 | + |
| 37 | +### 🔄 Phase 2: Buffer-Specific Complex State |
| 38 | +These need to move but require more care: |
| 39 | + |
| 40 | +- [ ] `textarea: TextArea<'static>` - Multi-line editor state |
| 41 | +- [ ] `fuzzy_filter_state: FuzzyFilterState` - Fuzzy search state |
| 42 | +- [ ] `column_search_state: ColumnSearchState` - Column search functionality |
| 43 | +- [ ] `column_widths: Vec<u16>` - Display formatting |
| 44 | +- [ ] `column_stats: Option<ColumnStatistics>` - Statistics for current column |
| 45 | +- [ ] `cached_data: Option<Vec<serde_json::Value>>` - Cached query results |
| 46 | +- [ ] `cache_mode: bool` - Whether caching is active |
| 47 | +- [ ] `undo_stack: Vec<(String, usize)>` - Undo history |
| 48 | +- [ ] `redo_stack: Vec<(String, usize)>` - Redo history |
| 49 | +- [ ] `kill_ring: String` - Vim-style yank buffer |
| 50 | +- [ ] `viewport_lock: bool` - Display behavior |
| 51 | +- [ ] `viewport_lock_row: Option<usize>` - Display behavior |
| 52 | +- [ ] `jump_to_row_input: String` - Jump command input |
| 53 | +- [ ] `last_visible_rows: usize` - Display tracking |
| 54 | + |
| 55 | +### 🚫 Should Stay in TUI (Global State) |
| 56 | +These are truly global and shouldn't be in buffers: |
| 57 | + |
| 58 | +- `api_client: ApiClient` - Global API connection |
| 59 | +- `sql_parser: SqlParser` - Global parser |
| 60 | +- `hybrid_parser: HybridParser` - Global parser |
| 61 | +- `config: Config` - User configuration |
| 62 | +- `command_history: CommandHistory` - Global command history |
| 63 | +- `sql_highlighter: SqlHighlighter` - Syntax highlighting |
| 64 | +- `query_cache: Option<QueryCache>` - Global cache |
| 65 | +- `show_help: bool` - UI state |
| 66 | +- `help_scroll: u16` - UI state |
| 67 | +- `debug_text: String` - Debug UI |
| 68 | +- `debug_scroll: u16` - Debug UI |
| 69 | +- `input_scroll_offset: u16` - UI display |
| 70 | +- `selection_mode: SelectionMode` - Global UI preference |
| 71 | +- `yank_mode: Option<char>` - Global clipboard state |
| 72 | +- `last_yanked: Option<(String, String)>` - Global clipboard |
| 73 | +- `completion_state: CompletionState` - UI helper |
| 74 | +- `history_state: HistoryState` - UI helper |
| 75 | +- `buffer_manager: Option<BufferManager>` - The manager itself |
| 76 | +- `current_buffer_name: Option<String>` - Current buffer tracking |
| 77 | + |
| 78 | +## Migration Strategy |
| 79 | + |
| 80 | +### Step 1: Create Compatibility Layer |
| 81 | +For each field we want to migrate, create a method that: |
| 82 | +1. Checks if buffer_manager exists |
| 83 | +2. If yes, use BufferAPI |
| 84 | +3. If no, use direct field access |
| 85 | + |
| 86 | +Example: |
| 87 | +```rust |
| 88 | +fn get_edit_mode(&self) -> EditMode { |
| 89 | + if let Some(buffer) = self.get_current_buffer() { |
| 90 | + buffer.get_edit_mode() |
| 91 | + } else { |
| 92 | + self.edit_mode |
| 93 | + } |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +### Step 2: Update All References |
| 98 | +Search for all direct field accesses and replace with compatibility methods: |
| 99 | +- `self.edit_mode` → `self.get_edit_mode()` |
| 100 | +- `self.edit_mode = x` → `self.set_edit_mode(x)` |
| 101 | + |
| 102 | +### Step 3: Test After Each Migration |
| 103 | +Run the TUI and verify: |
| 104 | +1. Basic navigation works |
| 105 | +2. Editing works |
| 106 | +3. Filtering/searching works |
| 107 | +4. No crashes or unexpected behavior |
| 108 | + |
| 109 | +### Step 4: Move Field to Buffer |
| 110 | +Once all references use the compatibility layer: |
| 111 | +1. Add field to Buffer struct |
| 112 | +2. Add to BufferAPI trait |
| 113 | +3. Implement in Buffer |
| 114 | +4. Remove from EnhancedTuiApp |
| 115 | + |
| 116 | +## Progress Tracking |
| 117 | + |
| 118 | +### Phase 1 Checklist (Simple Fields) |
| 119 | +- [ ] Add `edit_mode` to BufferAPI |
| 120 | +- [ ] Create `get_edit_mode()` / `set_edit_mode()` compatibility methods |
| 121 | +- [ ] Update all `self.edit_mode` references |
| 122 | +- [ ] Test TUI functionality |
| 123 | +- [ ] Move field to Buffer |
| 124 | +- [ ] Repeat for other Phase 1 fields |
| 125 | + |
| 126 | +### Testing Checklist |
| 127 | +After each field migration: |
| 128 | +- [ ] Can open a CSV file |
| 129 | +- [ ] Can type and execute queries |
| 130 | +- [ ] Can navigate results |
| 131 | +- [ ] Can filter results |
| 132 | +- [ ] Can search in results |
| 133 | +- [ ] Can yank/copy data |
| 134 | +- [ ] No crashes or panics |
| 135 | + |
| 136 | +## Notes |
| 137 | + |
| 138 | +- We can merge to master at any point - the compatibility layer ensures nothing breaks |
| 139 | +- Each field migration is independent - we can do them one at a time |
| 140 | +- If something goes wrong, we can easily revert a single field migration |
| 141 | +- The goal is gradual, safe migration, not speed |
0 commit comments