sql-cli 1.73.0

SQL query tool for CSV/JSON with both interactive TUI and non-interactive CLI modes - perfect for exploration and automation
Documentation
# Input Behavior Analysis

## Current State
The input/text manipulation functions in EnhancedTui are scattered and tightly coupled. Most delegate to BufferManager but the synchronization logic is embedded in the TUI.

## Functions Identified for Extraction

### Pure Text Manipulation (Can be extracted)
These functions manipulate text and cursor position without needing TUI internals:

1. **Word Movement**
   - `move_cursor_word_backward()` - Move cursor back one word
   - `move_cursor_word_forward()` - Move cursor forward one word
   - `jump_to_prev_token()` - Jump to previous SQL token
   - `jump_to_next_token()` - Jump to next SQL token

2. **Text Deletion/Killing**
   - `kill_line()` - Delete from cursor to end of line (Ctrl+K)
   - `kill_line_backward()` - Delete from cursor to start of line (Ctrl+U)
   - `delete_word_backward()` - Delete word before cursor (Ctrl+W)
   - `delete_word_forward()` - Delete word after cursor (Alt+D)

3. **Basic Input Operations**
   - `get_input_text()` - Get current input text
   - `set_input_text(text)` - Set input text
   - `set_input_text_with_cursor(text, cursor)` - Set text and cursor position
   - `get_input_cursor()` - Get cursor position
   - `clear_input()` - Clear input text

### Search/Filter Text Management (Partially extractable)
These manage search patterns but are coupled to mode management:

4. **Search Pattern Management**
   - `handle_column_search_input()` - Manages column search text input
   - `update_column_search()` - Updates column search results
   - Search pattern building (character add/remove)
   - Filter pattern management

## Current Implementation Pattern

```rust
// Current pattern - tightly coupled
fn kill_line(&mut self) {
    if let Some(buffer) = self.buffer_manager.current_mut() {
        buffer.kill_line();  // Delegates to buffer
        
        // Sync for rendering if single-line mode
        if buffer.get_edit_mode() == EditMode::SingleLine {
            let text = buffer.get_input_text();
            let cursor = buffer.get_input_cursor_position();
            self.set_input_text_with_cursor(text, cursor);
            self.cursor_manager.set_position(cursor);
        }
    }
}
```

## Proposed Refactoring Strategy

### Phase 1: Create TextOperation Results
Create result types that describe what happened:

```rust
pub struct TextOperationResult {
    pub new_text: String,
    pub new_cursor_position: usize,
    pub killed_text: Option<String>,  // For kill ring
    pub description: String,
}

pub struct SearchTextResult {
    pub pattern: String,
    pub cursor_position: usize,
    pub action: SearchAction,
}

pub enum SearchAction {
    AddChar(char),
    RemoveChar,
    Clear,
    Execute,
}
```

### Phase 2: Extract Pure Text Operations
Move text manipulation to a separate module that returns results:

```rust
pub trait TextManipulation {
    fn kill_line(&self, text: &str, cursor: usize) -> TextOperationResult;
    fn kill_line_backward(&self, text: &str, cursor: usize) -> TextOperationResult;
    fn delete_word_forward(&self, text: &str, cursor: usize) -> TextOperationResult;
    fn delete_word_backward(&self, text: &str, cursor: usize) -> TextOperationResult;
    fn move_word_forward(&self, text: &str, cursor: usize) -> usize;
    fn move_word_backward(&self, text: &str, cursor: usize) -> usize;
}
```

### Phase 3: Create InputBehavior Trait
Trait that uses the pure text operations:

```rust
pub trait InputBehavior: TextManipulation {
    // Required methods for TUI access
    fn buffer_manager(&mut self) -> &mut BufferManager;
    fn cursor_manager(&mut self) -> &mut CursorManager;
    
    // High-level input operations using TextManipulation
    fn kill_line(&mut self) {
        let (text, cursor) = self.get_current_input();
        let result = TextManipulation::kill_line(&text, cursor);
        self.apply_text_result(result);
    }
    
    // Helper to apply results
    fn apply_text_result(&mut self, result: TextOperationResult) {
        // Update buffer
        // Update cursor
        // Handle kill ring if needed
    }
}
```

## Benefits of This Approach

1. **Separation of Concerns**
   - Pure text manipulation logic separate from TUI
   - Easy to test text operations in isolation
   - Reusable for other input fields

2. **Reduced Coupling**
   - Text operations don't know about TUI internals
   - TUI just applies results
   - Clear data flow

3. **Better Testing**
   - Can unit test text manipulation without TUI
   - Can test cursor movement logic independently
   - Can verify kill ring behavior

## Implementation Order

1. **Start with Word Movement** (simplest)
   - Pure cursor position calculation
   - No text modification
   - Good proof of concept

2. **Then Kill/Delete Operations**
   - Text modification with results
   - Kill ring integration
   - More complex but clear benefits

3. **Finally Search/Filter Patterns**
   - Most complex due to mode interaction
   - May need mode-specific traits
   - Build on lessons from first two

## Challenges to Address

1. **Kill Ring Integration**
   - Currently managed by Buffer
   - Need to return killed text in result
   - Buffer applies to kill ring

2. **Mode-Specific Behavior**
   - Different modes use input differently
   - May need mode-aware text operations
   - Consider mode-specific traits

3. **Undo/Redo Integration**
   - Currently saves state before operations
   - Need to include in result or handle separately
   - Consider command pattern

## Next Steps

1. Create `TextOperationResult` struct
2. Implement pure `TextManipulation` functions
3. Test pure functions independently
4. Create `InputBehavior` trait
5. Refactor TUI to use trait
6. Extract to separate module