cleanup repo
- SHA
2057ce47f66f17024ac6535e950ecd93f8abf9c3- Parents
-
78ae7e8 - Tree
1ddc1b9
2057ce4
2057ce47f66f17024ac6535e950ecd93f8abf9c378ae7e8
1ddc1b9.gitignoremodified@@ -7,3 +7,7 @@ fac_debug.txt | |||
| 7 | # Temporary files | 7 | # Temporary files |
| 8 | /tmp/ | 8 | /tmp/ |
| 9 | .fac | 9 | .fac |
| 10 | + | ||
| 11 | +# Scratch/notes | ||
| 12 | +old/ | ||
| 13 | +CLAUDE.md | ||
BOOKMARKS.mddeleted@@ -1,51 +0,0 @@ | |||
| 1 | -# Implementation Bookmarks | ||
| 2 | - | ||
| 3 | -Issues that require careful surgical implementation (not simple warning fixes) | ||
| 4 | - | ||
| 5 | ---- | ||
| 6 | - | ||
| 7 | -## 🔖 BOOKMARK #1: Clipboard 1MB Stack Buffer | ||
| 8 | - | ||
| 9 | -**File:** `src/clipboard/clipboard_module.f90` | ||
| 10 | -**Line:** 40 | ||
| 11 | -**Priority:** HIGH (potential stack overflow) | ||
| 12 | - | ||
| 13 | -### Current Issue | ||
| 14 | -```fortran | ||
| 15 | -character(len=1000000) :: buffer ! 1MB buffer for clipboard content | ||
| 16 | -``` | ||
| 17 | - | ||
| 18 | -This allocates 1MB on the stack, which can cause stack overflow crashes. | ||
| 19 | - | ||
| 20 | -### gfortran Warning | ||
| 21 | -``` | ||
| 22 | -Warning: Array 'buffer' at (1) is larger than limit set by '-fmax-stack-var-size=', | ||
| 23 | -moved from stack to static storage. This makes the procedure unsafe when called | ||
| 24 | -recursively, or concurrently from multiple threads. Consider increasing the | ||
| 25 | -'-fmax-stack-var-size=' limit (or use '-frecursive', which implies unlimited | ||
| 26 | -'-fmax-stack-var-size') - or change the code to use an ALLOCATABLE array. | ||
| 27 | -``` | ||
| 28 | - | ||
| 29 | -### Recommended Solution | ||
| 30 | -1. Change to `character(len=:), allocatable :: buffer` | ||
| 31 | -2. Allocate dynamically: `allocate(character(len=needed_size) :: buffer)` | ||
| 32 | -3. Deallocate after use | ||
| 33 | -4. Consider reading clipboard in chunks if very large | ||
| 34 | - | ||
| 35 | -### Affected Functions | ||
| 36 | -- `clipboard_paste()` in `src/clipboard/clipboard_module.f90` | ||
| 37 | - | ||
| 38 | -### Testing Required | ||
| 39 | -- Test pasting small text | ||
| 40 | -- Test pasting large text (>1MB) | ||
| 41 | -- Test multiple paste operations | ||
| 42 | -- Verify no memory leaks | ||
| 43 | - | ||
| 44 | -### Status | ||
| 45 | -⏳ Deferred for careful manual implementation after bulk warning cleanup | ||
| 46 | - | ||
| 47 | ---- | ||
| 48 | - | ||
| 49 | -## Future Bookmarks | ||
| 50 | - | ||
| 51 | -Add additional complex issues here as they're discovered... | ||
BUILD_PARITY.mddeleted@@ -1,97 +0,0 @@ | |||
| 1 | -# Build System Parity | ||
| 2 | - | ||
| 3 | -This document explains how to achieve identical builds between fpm and Makefile. | ||
| 4 | - | ||
| 5 | -## TL;DR | ||
| 6 | - | ||
| 7 | -For identical optimized builds: | ||
| 8 | - | ||
| 9 | -```bash | ||
| 10 | -# Using fpm | ||
| 11 | -fpm build --flag "-O2 -Wall -ffree-line-length-none" | ||
| 12 | - | ||
| 13 | -# Using make | ||
| 14 | -make | ||
| 15 | - | ||
| 16 | -# Or use the unified build script | ||
| 17 | -./build.sh release | ||
| 18 | -``` | ||
| 19 | - | ||
| 20 | -## Build Systems | ||
| 21 | - | ||
| 22 | -facsimile supports two build systems: | ||
| 23 | - | ||
| 24 | -1. **fpm** (Fortran Package Manager) - Modern, dependency-aware | ||
| 25 | -2. **Makefile** - Traditional, platform-specific optimizations | ||
| 26 | - | ||
| 27 | -## Key Differences | ||
| 28 | - | ||
| 29 | -| Aspect | fpm | Makefile | | ||
| 30 | -|--------|-----|----------| | ||
| 31 | -| Dependency Management | Automatic | Manual (order matters) | | ||
| 32 | -| Parallel Build | Safe, automatic | Disabled (.NOTPARALLEL) | | ||
| 33 | -| Compiler Selection | Uses PATH gfortran | Detects Homebrew gfortran on macOS | | ||
| 34 | -| Output Location | `./build/gfortran_*/app/fac` | `./fac` | | ||
| 35 | -| Incremental Builds | Efficient | Basic | | ||
| 36 | -| C Code Handling | Automatic | Explicit gcc compilation | | ||
| 37 | - | ||
| 38 | -## Compiler Flags | ||
| 39 | - | ||
| 40 | -Both systems use the same optimization flags for release builds: | ||
| 41 | - | ||
| 42 | -- `-O2` - Optimization level 2 (good balance of speed and size) | ||
| 43 | -- `-Wall` - Enable all warnings | ||
| 44 | -- `-ffree-line-length-none` - Allow long Fortran lines | ||
| 45 | - | ||
| 46 | -## Binary Size Comparison | ||
| 47 | - | ||
| 48 | -With identical flags, both systems produce nearly identical binaries: | ||
| 49 | - | ||
| 50 | -- Makefile build: ~287KB | ||
| 51 | -- fpm optimized build: ~294KB | ||
| 52 | - | ||
| 53 | -The slight difference (~7KB) is due to: | ||
| 54 | -- Different linking order | ||
| 55 | -- Metadata differences | ||
| 56 | -- Path information | ||
| 57 | - | ||
| 58 | -## Platform-Specific Notes | ||
| 59 | - | ||
| 60 | -### macOS (Apple Silicon) | ||
| 61 | -- Makefile automatically finds Homebrew's gfortran in `/opt/homebrew` | ||
| 62 | -- fpm uses whatever gfortran is in PATH | ||
| 63 | -- Ensure Homebrew's gfortran is in PATH for consistency | ||
| 64 | - | ||
| 65 | -### Linux | ||
| 66 | -- Both systems work identically | ||
| 67 | -- No special configuration needed | ||
| 68 | - | ||
| 69 | -## Debug Builds | ||
| 70 | - | ||
| 71 | -```bash | ||
| 72 | -# fpm debug build | ||
| 73 | -fpm build --flag "-g -Wall -ffree-line-length-none -fbacktrace -fcheck=bounds" | ||
| 74 | - | ||
| 75 | -# Makefile doesn't have debug configuration | ||
| 76 | -# Edit FFLAGS manually if needed | ||
| 77 | -``` | ||
| 78 | - | ||
| 79 | -## Recommendations | ||
| 80 | - | ||
| 81 | -1. **For Development**: Use fpm (better incremental builds) | ||
| 82 | -2. **For Distribution**: | ||
| 83 | - - macOS: Use Makefile (better compiler detection) | ||
| 84 | - - Linux: Either works fine | ||
| 85 | -3. **For CI/CD**: Use fpm with explicit flags | ||
| 86 | - | ||
| 87 | -## Build Script | ||
| 88 | - | ||
| 89 | -Use the provided `build.sh` script for unified building: | ||
| 90 | - | ||
| 91 | -```bash | ||
| 92 | -./build.sh release # Optimized build | ||
| 93 | -./build.sh debug # Debug build (fpm only) | ||
| 94 | -./build.sh clean # Clean build artifacts | ||
| 95 | -``` | ||
| 96 | - | ||
| 97 | -The script automatically detects available build systems and uses appropriate flags for parity. | ||
CLEANUP_SUMMARY.mddeleted@@ -1,102 +0,0 @@ | |||
| 1 | -# Compiler Warning Cleanup Summary | ||
| 2 | - | ||
| 3 | -## Results | ||
| 4 | - | ||
| 5 | -**Initial State:** ~120 compiler warnings from gfortran with pedantic flags | ||
| 6 | -**Final State:** 0 compiler warnings (100% reduction! 🎉) | ||
| 7 | - | ||
| 8 | -## 🏆 PERFECT SCORE: ZERO WARNINGS 🏆 | ||
| 9 | - | ||
| 10 | -## Completed Phases | ||
| 11 | - | ||
| 12 | -### Phase 0: C Code Cleanup | ||
| 13 | -- Fixed 9 warnings in `termios_wrapper.c` | ||
| 14 | - - Added `(void)` to 4 function prototypes | ||
| 15 | - - Added explicit `(tcflag_t)` casts (3 fixes) | ||
| 16 | - - Changed `int` to `ssize_t` for read() return | ||
| 17 | - - Added newline at EOF | ||
| 18 | -- **Result:** 0 warnings in C code | ||
| 19 | - | ||
| 20 | -### Phase 1: Unused Local Variables | ||
| 21 | -- Removed 30 unused local variables across 10 files | ||
| 22 | -- Files cleaned: | ||
| 23 | - - `clipboard_module.f90` (1 variable) | ||
| 24 | - - `yank_stack_module.f90` (1 variable) | ||
| 25 | - - `file_tree_renderer_module.f90` (3 variables) | ||
| 26 | - - `file_tree_module.f90` (2 variables) | ||
| 27 | - - `renderer_module.f90` (3 variables) | ||
| 28 | - - `help_display_module.f90` (1 variable) | ||
| 29 | - - `search_prompt_module.f90` (3 variables) | ||
| 30 | - - `replace_prompt_module.f90` (2 variables) | ||
| 31 | - - `goto_prompt_module.f90` (4 variables) | ||
| 32 | - - `command_handler_module.f90` (9 variables) | ||
| 33 | -- **Result:** 30 warnings eliminated | ||
| 34 | - | ||
| 35 | -### Phase 2: Unused Dummy Arguments | ||
| 36 | -- Removed 5 unused function parameters across 3 modules | ||
| 37 | -- Updated both function signatures AND all call sites | ||
| 38 | -- Files modified: | ||
| 39 | - - `command_handler_module.f90` (3 parameters) | ||
| 40 | - - `input_handler_module.f90` (1 parameter) | ||
| 41 | - - `renderer_module.f90` (1 parameter) | ||
| 42 | -- **Result:** 5 warnings eliminated | ||
| 43 | - | ||
| 44 | -### Phase 3: Dead Code Removal | ||
| 45 | -- Removed 2 completely unused functions | ||
| 46 | -- Files cleaned: | ||
| 47 | - - `renderer_module.f90`: Removed `render_line()` (45 lines) | ||
| 48 | - - `help_display_module.f90`: Removed `display_section()` (24 lines) | ||
| 49 | -- **Result:** 2 warnings eliminated, 69 lines of dead code removed | ||
| 50 | - | ||
| 51 | -### Phase 4: Intrinsic Shadow Fix | ||
| 52 | -- Renamed `getpid()` to `get_process_id()` to avoid shadowing Fortran intrinsic | ||
| 53 | -- Updated function definition and call site in `command_handler_module.f90` | ||
| 54 | -- **Result:** 1 warning eliminated | ||
| 55 | - | ||
| 56 | -### Phase 5: Character Truncation Fix | ||
| 57 | -- Increased `file_path` buffer from 512 to 1024 characters in `file_tree_module.f90` | ||
| 58 | -- Prevents truncation when assigning from 1024-char `line` variable | ||
| 59 | -- **Result:** 1 warning eliminated | ||
| 60 | - | ||
| 61 | -### Phase 6: GNU Extension Format Fix | ||
| 62 | -- Added width specifications to `L` edit descriptors in `file_tree_module.f90` | ||
| 63 | -- Changed `L` to `L1` for standard Fortran compliance | ||
| 64 | -- **Result:** 1 warning eliminated | ||
| 65 | - | ||
| 66 | -### Phase 7: Final Cleanup - Remaining Easy Warnings | ||
| 67 | -- Removed 1 unused variable: `status` from handle_fuss_input | ||
| 68 | -- Removed 2 unused dummy arguments: `line_count` from page_up/down functions | ||
| 69 | -- Removed 4 unused functions (132 lines of dead code): | ||
| 70 | - - `get_line_positions()` (33 lines) | ||
| 71 | - - `toggle_cursor_at_position()` (48 lines) | ||
| 72 | - - `handle_mouse_click()` (21 lines) | ||
| 73 | - - `transpose_characters()` (42 lines) | ||
| 74 | -- **Result:** 9 warnings eliminated | ||
| 75 | - | ||
| 76 | -### Phase 8: 1MB Stack Buffer Fix (ALLOCATABLE Redesign) | ||
| 77 | -- Converted fixed 1MB stack buffer to dynamic heap allocation | ||
| 78 | -- Changed `character(len=1000000) :: buffer` to `character(len=:), allocatable :: buffer` | ||
| 79 | -- Added proper allocation/deallocation in clipboard_module.f90 | ||
| 80 | -- **Benefits:** | ||
| 81 | - - No stack pressure (uses heap instead) | ||
| 82 | - - Thread-safe (no static storage) | ||
| 83 | - - Memory efficient (allocates only what's needed) | ||
| 84 | - - Flexible for future changes | ||
| 85 | -- **Result:** Final warning eliminated ✅ | ||
| 86 | - | ||
| 87 | -## Statistics | ||
| 88 | - | ||
| 89 | -- **Total warnings eliminated:** 120 out of 120 (100% reduction!) | ||
| 90 | -- **Files modified:** 14 Fortran files, 1 C file | ||
| 91 | -- **Lines of code removed:** 201+ lines of dead code | ||
| 92 | -- **Build status:** ✅ Clean compilation with both flang-new and gfortran | ||
| 93 | -- **Warning count with pedantic gfortran flags:** **0** 🎯 | ||
| 94 | - | ||
| 95 | -## Impact | ||
| 96 | - | ||
| 97 | -The codebase is now significantly cleaner: | ||
| 98 | -- ✅ Easier to maintain | ||
| 99 | -- ✅ Faster to understand | ||
| 100 | -- ✅ More standards-compliant | ||
| 101 | -- ✅ Better compiler diagnostics (real issues won't be hidden in noise) | ||
| 102 | -- ✅ Safer (fewer potential bugs from unused code paths) | ||
COMPILER_WARNINGS_AUDIT.mddeleted@@ -1,181 +0,0 @@ | |||
| 1 | -# Compiler Warnings Audit & Resolution Roadmap | ||
| 2 | - | ||
| 3 | -**Date:** 2025-11-05 | ||
| 4 | -**Compiler:** gfortran with `-Wall -Wextra -pedantic -Wunused-variable -Wuninitialized` | ||
| 5 | -**Total Warnings:** ~120+ | ||
| 6 | - | ||
| 7 | ---- | ||
| 8 | - | ||
| 9 | -## Risk Classification | ||
| 10 | - | ||
| 11 | -### 🔴 CRITICAL (Requires Careful Surgery) | ||
| 12 | -**These need sophisticated implementation changes - DO NOT bulk fix** | ||
| 13 | - | ||
| 14 | -1. **src/clipboard/clipboard_module.f90:40** - 1MB stack buffer | ||
| 15 | - - **Issue:** `character(len=1000000) :: buffer` allocates 1MB on stack | ||
| 16 | - - **Risk:** Stack overflow crashes | ||
| 17 | - - **Solution:** Redesign to use ALLOCATABLE array | ||
| 18 | - - **Status:** 🔖 BOOKMARKED for manual surgery | ||
| 19 | - | ||
| 20 | ---- | ||
| 21 | - | ||
| 22 | -## 🟡 LOW RISK (Straightforward Fixes) | ||
| 23 | - | ||
| 24 | -### Category: Format/Standards Issues (3 warnings) | ||
| 25 | - | ||
| 26 | -2. **src/commands/command_handler_module.f90:2352** - Intrinsic shadow | ||
| 27 | - - **Issue:** `function getpid()` shadows intrinsic | ||
| 28 | - - **Fix:** Rename to `get_process_id()` or add explicit INTRINSIC declaration | ||
| 29 | - - **Lines:** 2352 | ||
| 30 | - | ||
| 31 | -3. **src/workspace/file_tree_module.f90:253** - Character truncation | ||
| 32 | - - **Issue:** Assignment truncates 1024 chars to 512 | ||
| 33 | - - **Fix:** Increase destination buffer size or truncate explicitly | ||
| 34 | - - **Lines:** 253 | ||
| 35 | - | ||
| 36 | -4. **src/workspace/file_tree_module.f90:525** - GNU extension | ||
| 37 | - - **Issue:** Missing positive width after L descriptor in format | ||
| 38 | - - **Fix:** Use proper format: `(A,A,A,L1,A,L1)` | ||
| 39 | - - **Lines:** 525 | ||
| 40 | - | ||
| 41 | ---- | ||
| 42 | - | ||
| 43 | -## 🟢 SAFE BULK FIXES | ||
| 44 | - | ||
| 45 | -### Category A: Unused Local Variables (~60 warnings) | ||
| 46 | -**These are safe to remove - no function signature changes** | ||
| 47 | - | ||
| 48 | -#### src/clipboard/yank_stack_module.f90 (1) | ||
| 49 | -- Line 49: `new_entries` - unused allocatable array | ||
| 50 | - | ||
| 51 | -#### src/clipboard/clipboard_module.f90 (1) | ||
| 52 | -- Line 41: `n_read` - unused integer | ||
| 53 | - | ||
| 54 | -#### src/workspace/file_tree_renderer_module.f90 (3) | ||
| 55 | -- Line 116: `i` - unused loop variable | ||
| 56 | -- Line 116: `prefix_len` - unused integer | ||
| 57 | -- Line 22: `visible_items` - unused integer | ||
| 58 | - | ||
| 59 | -#### src/workspace/file_tree_module.f90 (2) | ||
| 60 | -- Line 611: `prev` - unused pointer | ||
| 61 | -- Line 151: `i` - unused integer | ||
| 62 | - | ||
| 63 | -#### src/terminal/renderer_module.f90 (5) | ||
| 64 | -- Line 69: `buffer_pos` - unused integer | ||
| 65 | -- Line 68: `ch` - unused character | ||
| 66 | -- Line 69: `col` - unused integer | ||
| 67 | -- Line 69: `line_start_pos` - unused integer | ||
| 68 | - | ||
| 69 | -#### src/ui/help_display_module.f90 (1) | ||
| 70 | -- Line 101: `section_start` - unused integer | ||
| 71 | - | ||
| 72 | -#### src/ui/search_prompt_module.f90 (3) | ||
| 73 | -- Line 21: `use_regex` - unused module variable (PRIVATE) | ||
| 74 | -- Line 32: `ios` - unused integer | ||
| 75 | -- Line 31: `options_str` - unused character | ||
| 76 | - | ||
| 77 | -#### src/ui/replace_prompt_module.f90 (5) | ||
| 78 | -- Line 133: `should_continue` - unused logical | ||
| 79 | -- Line 22: `found` - unused logical | ||
| 80 | -- Line 23: `found_col` - unused integer | ||
| 81 | -- Line 23: `found_line` - unused integer | ||
| 82 | -- Line 20: `ios` - unused integer | ||
| 83 | - | ||
| 84 | -#### src/ui/goto_prompt_module.f90 (4) | ||
| 85 | -- Line 22: `col_str` - unused allocatable string | ||
| 86 | -- Line 20: `colon_pos` - unused integer | ||
| 87 | -- Line 18: `ios` - unused integer | ||
| 88 | -- Line 22: `line_str` - unused allocatable string | ||
| 89 | - | ||
| 90 | -#### src/commands/command_handler_module.f90 (~35+ unused local variables) | ||
| 91 | -- Line 3906: `status` - unused integer | ||
| 92 | -- Line 3568: `in_word` - unused logical | ||
| 93 | -- Line 3494: `in_word` - unused logical (duplicate name different function) | ||
| 94 | -- Line 2527: `is_alt_click` - unused logical | ||
| 95 | -- Line 2294: `error_msg` - unused character(1024) | ||
| 96 | -- Line 2295: `has_write_permission` - unused logical | ||
| 97 | -- Line 2292: `temp_unit` - unused integer | ||
| 98 | -- Line 1577: `cursors_before` - unused integer | ||
| 99 | -- *(~27 more throughout the file)* | ||
| 100 | - | ||
| 101 | ---- | ||
| 102 | - | ||
| 103 | -### Category B: Unused Dummy Arguments (~15 warnings) | ||
| 104 | -**Safe to remove, but changes function signatures - check call sites** | ||
| 105 | - | ||
| 106 | -#### src/terminal/input_handler_module.f90 (1) | ||
| 107 | -- Line 419: `handle_alt_modified_key()` parameter `first_char` unused | ||
| 108 | - | ||
| 109 | -#### src/terminal/renderer_module.f90 (1) | ||
| 110 | -- Line 943: `render_single_pane()` parameter `buffer` unused | ||
| 111 | - | ||
| 112 | -#### src/commands/command_handler_module.f90 (~13 warnings) | ||
| 113 | -- Line 3453: `extend_selection_page_up()` parameter `line_count` unused | ||
| 114 | -- Line 3295: `extend_selection_up()` parameter `line_count` unused | ||
| 115 | -- Line 3199: `add_cursor_above()` parameter `buffer` unused | ||
| 116 | -- *(~10 more throughout the file)* | ||
| 117 | - | ||
| 118 | ---- | ||
| 119 | - | ||
| 120 | -### Category C: Dead Code (~2 warnings) | ||
| 121 | -**Safe to remove - unused functions** | ||
| 122 | - | ||
| 123 | -#### src/terminal/renderer_module.f90 (1) | ||
| 124 | -- Line 200: `render_line()` - defined but never called | ||
| 125 | - | ||
| 126 | -#### src/ui/help_display_module.f90 (1) | ||
| 127 | -- Line 261: `display_section()` - defined but never called | ||
| 128 | - | ||
| 129 | ---- | ||
| 130 | - | ||
| 131 | -## Resolution Strategy | ||
| 132 | - | ||
| 133 | -### Phase 1: Safe Bulk Fixes (Category A) | ||
| 134 | -- Remove unused local variables | ||
| 135 | -- No signature changes, minimal risk | ||
| 136 | -- Can be done file-by-file systematically | ||
| 137 | -- **Estimated:** 60 simple deletions | ||
| 138 | - | ||
| 139 | -### Phase 2: Function Signature Fixes (Category B) | ||
| 140 | -- Remove unused dummy arguments | ||
| 141 | -- Must verify call sites (use compiler to check) | ||
| 142 | -- Compiler will catch any mistakes | ||
| 143 | -- **Estimated:** 15 parameter removals + call site updates | ||
| 144 | - | ||
| 145 | -### Phase 3: Dead Code Removal (Category C) | ||
| 146 | -- Delete unused functions | ||
| 147 | -- Verify no indirect calls (callbacks, etc.) | ||
| 148 | -- **Estimated:** 2 function deletions | ||
| 149 | - | ||
| 150 | -### Phase 4: Low-Risk Fixes (🟡) | ||
| 151 | -- Fix intrinsic shadow (rename) | ||
| 152 | -- Fix character truncation (increase buffer) | ||
| 153 | -- Fix format descriptor (add width) | ||
| 154 | -- **Estimated:** 3 targeted fixes | ||
| 155 | - | ||
| 156 | -### Phase 5: BOOKMARKED for Surgery (🔴) | ||
| 157 | -- Redesign clipboard buffer to use ALLOCATABLE | ||
| 158 | -- Requires careful testing of clipboard operations | ||
| 159 | -- **Status:** Deferred for manual implementation | ||
| 160 | - | ||
| 161 | ---- | ||
| 162 | - | ||
| 163 | -## Verification Plan | ||
| 164 | - | ||
| 165 | -After each phase: | ||
| 166 | -```bash | ||
| 167 | -make clean | ||
| 168 | -FC=gfortran make dev 2>&1 | tee /tmp/gfortran_warnings.log | ||
| 169 | -grep -i warning /tmp/gfortran_warnings.log | wc -l | ||
| 170 | -``` | ||
| 171 | - | ||
| 172 | -Final target: **0 warnings** (except bookmarked items) | ||
| 173 | - | ||
| 174 | ---- | ||
| 175 | - | ||
| 176 | -## Notes | ||
| 177 | - | ||
| 178 | -- All fixes preserve functionality | ||
| 179 | -- Compiler errors will catch any mistakes in signature changes | ||
| 180 | -- No automated sed/awk scripts - manual edits only | ||
| 181 | -- Bookmark items require design discussion before implementation | ||
PANE-PLAN.mddeleted@@ -1,11 +0,0 @@ | |||
| 1 | -# PANES | ||
| 2 | - | ||
| 3 | -vision for panes: | ||
| 4 | -panes exist within tabs. | ||
| 5 | -we have our existing binds, alt-v, alt-s, to create panes of the same file. they are good we will keep those | ||
| 6 | - | ||
| 7 | - | ||
| 8 | -what we wish to extend is our paradigm for panes within tabs and the file contents. We will support "v" and "s" in fuss mode to open *that file* in a new pane, vertical or horizontal split. | ||
| 9 | -this will require rethinking how we approach panes as previously we only supported the same file for panes. | ||
| 10 | - | ||
| 11 | -Now is also a good time to ensure we force a limit on pane creation as most terminals can only support so many panes realistically | ||
PHASE7_COMPLETE.mddeleted@@ -1,423 +0,0 @@ | |||
| 1 | -# Phase 7: Polish & Testing - COMPLETE ✅ | ||
| 2 | - | ||
| 3 | -**Date Completed**: November 5, 2025 | ||
| 4 | -**Status**: All core features implemented and tested | ||
| 5 | -**Test Results**: 8/8 tests passed ✅ | ||
| 6 | - | ||
| 7 | ---- | ||
| 8 | - | ||
| 9 | -## 🎯 Overview | ||
| 10 | - | ||
| 11 | -Phase 7 focused on error handling, edge case testing, and polishing the workspace system to be production-ready. All critical error scenarios are now handled gracefully with clear user feedback and automatic recovery. | ||
| 12 | - | ||
| 13 | ---- | ||
| 14 | - | ||
| 15 | -## ✅ Completed Features | ||
| 16 | - | ||
| 17 | -### 1. Missing File Handling | ||
| 18 | -**Location**: `src/workspace/workspace_module.f90:490-514` | ||
| 19 | - | ||
| 20 | -**Implementation**: | ||
| 21 | -- Checks file existence before loading each tab | ||
| 22 | -- Shows warning: `"Warning: File not found (skipping): /path/to/file"` | ||
| 23 | -- Pauses 0.8 seconds for user to read warning | ||
| 24 | -- Skips missing files and continues loading others | ||
| 25 | -- Editor remains functional with available files | ||
| 26 | - | ||
| 27 | -**Test Result**: ✅ PASSED (Test 1 & 2) | ||
| 28 | -- Tested with 3 missing files: warnings shown, 2 files loaded successfully | ||
| 29 | -- Tested with all files missing: warnings shown, empty editor started | ||
| 30 | - | ||
| 31 | -**User Impact**: | ||
| 32 | -- No crashes when files are deleted | ||
| 33 | -- Clear feedback about what's missing | ||
| 34 | -- Can continue working with available files | ||
| 35 | - | ||
| 36 | ---- | ||
| 37 | - | ||
| 38 | -### 2. Corrupted workspace.json Handling | ||
| 39 | -**Location**: `src/workspace/workspace_module.f90:409-420` | ||
| 40 | - | ||
| 41 | -**Implementation**: | ||
| 42 | -- Detects when workspace.json can't be opened or parsed | ||
| 43 | -- Shows warning: `"Warning: Could not open workspace.json - using empty workspace"` | ||
| 44 | -- Pauses 1.0 seconds for user awareness | ||
| 45 | -- Automatically initializes fresh workspace | ||
| 46 | -- Creates new valid workspace.json | ||
| 47 | - | ||
| 48 | -**Test Result**: ✅ PASSED (Test 3 & 4) | ||
| 49 | -- Tested with syntax error: warning shown, fresh workspace created | ||
| 50 | -- Tested with empty file: warning shown, fresh workspace created | ||
| 51 | - | ||
| 52 | -**User Impact**: | ||
| 53 | -- Automatic recovery from corruption | ||
| 54 | -- No manual intervention needed | ||
| 55 | -- Can start working immediately | ||
| 56 | - | ||
| 57 | ---- | ||
| 58 | - | ||
| 59 | -### 3. Deleted Workspace Detection | ||
| 60 | -**Locations**: | ||
| 61 | -- `src/fortress/ui/welcome_menu_module.f90:77-117` | ||
| 62 | -- `src/workspace/recents_module.f90:327-354` | ||
| 63 | - | ||
| 64 | -**Implementation**: | ||
| 65 | -- Checks directory existence before loading from favorites/recents | ||
| 66 | -- Shows warning: `"Warning: Workspace no longer exists: /path"` | ||
| 67 | -- Displays "Removing from list..." message | ||
| 68 | -- Automatically removes from favorites or recents list | ||
| 69 | -- Reloads list and adjusts selection | ||
| 70 | -- Pauses 1.0 seconds for user to see messages | ||
| 71 | - | ||
| 72 | -**New Functions**: | ||
| 73 | -```fortran | ||
| 74 | -recents_remove(index, success) ! Remove recent by index | ||
| 75 | -directory_exists(path) ! Check if directory exists | ||
| 76 | -handle_deleted_workspace(...) ! Show warning and cleanup | ||
| 77 | -``` | ||
| 78 | - | ||
| 79 | -**Test Result**: ✅ PASSED (Manual testing) | ||
| 80 | -- Deleted workspace detected correctly | ||
| 81 | -- Removed from list automatically | ||
| 82 | -- User can continue selecting other workspaces | ||
| 83 | - | ||
| 84 | -**User Impact**: | ||
| 85 | -- Self-cleaning lists | ||
| 86 | -- No stale entries | ||
| 87 | -- No manual maintenance required | ||
| 88 | - | ||
| 89 | ---- | ||
| 90 | - | ||
| 91 | -### 4. File Tree Workspace Synchronization | ||
| 92 | -**Location**: `src/commands/command_handler_module.f90:4534-4539` | ||
| 93 | - | ||
| 94 | -**Implementation**: | ||
| 95 | -- After successful workspace switch, refreshes file tree | ||
| 96 | -- Updates to show new workspace root directory | ||
| 97 | -- Updates git repository info | ||
| 98 | -- Maintains consistency between workspace and UI state | ||
| 99 | - | ||
| 100 | -**Code Added**: | ||
| 101 | -```fortran | ||
| 102 | -! Phase 7: Update file tree if it's active after successful workspace switch | ||
| 103 | -if (editor%fuss_mode_active .and. allocated(editor%workspace_path)) then | ||
| 104 | - call refresh_tree_state(tree_state, editor%workspace_path) | ||
| 105 | -end if | ||
| 106 | -``` | ||
| 107 | - | ||
| 108 | -**Test Result**: ✅ PASSED (Manual testing) | ||
| 109 | -- File tree updates correctly after workspace switch | ||
| 110 | -- Shows new workspace root | ||
| 111 | -- Git info updates appropriately | ||
| 112 | - | ||
| 113 | -**User Impact**: | ||
| 114 | -- File tree always reflects current workspace | ||
| 115 | -- No confusion about which workspace you're in | ||
| 116 | -- Better navigation experience | ||
| 117 | - | ||
| 118 | ---- | ||
| 119 | - | ||
| 120 | -## 🧪 Testing Summary | ||
| 121 | - | ||
| 122 | -### Automated Test Suite | ||
| 123 | -**Created**: Comprehensive test infrastructure with 8 edge case scenarios | ||
| 124 | - | ||
| 125 | -**Test Scripts**: | ||
| 126 | -- `backup_configs.sh` - Safe config backup with timestamps | ||
| 127 | -- `restore_configs.sh` - One-command config restoration | ||
| 128 | -- `test_suite_phase7.sh` - Creates 8 test workspaces | ||
| 129 | -- `test_runner.sh` - Automated test execution | ||
| 130 | -- `cleanup_tests.sh` - Test environment cleanup | ||
| 131 | -- `TESTING_GUIDE.md` - Complete testing documentation | ||
| 132 | - | ||
| 133 | -**Test Scenarios**: | ||
| 134 | -1. ✅ Multiple missing files (3/5 missing) | ||
| 135 | -2. ✅ All files missing (0/2 present) | ||
| 136 | -3. ✅ Corrupted JSON (syntax error) | ||
| 137 | -4. ✅ Empty JSON file | ||
| 138 | -5. ✅ UTF-8 filenames (Chinese, Russian, Greek, Emoji) | ||
| 139 | -6. ✅ Symlinks (local and external) | ||
| 140 | -7. ✅ Large workspace (50 files) | ||
| 141 | -8. ✅ Very long paths (11 levels deep) | ||
| 142 | - | ||
| 143 | -**Results**: 8/8 PASSED ✅ | ||
| 144 | -- No crashes detected | ||
| 145 | -- All features working as expected | ||
| 146 | -- Error messages displaying correctly | ||
| 147 | -- Recovery mechanisms functioning | ||
| 148 | - | ||
| 149 | ---- | ||
| 150 | - | ||
| 151 | -## 📊 Code Statistics | ||
| 152 | - | ||
| 153 | -**Files Modified**: 4 | ||
| 154 | -1. `src/workspace/workspace_module.f90` | ||
| 155 | -2. `src/workspace/recents_module.f90` | ||
| 156 | -3. `src/fortress/ui/welcome_menu_module.f90` | ||
| 157 | -4. `src/commands/command_handler_module.f90` | ||
| 158 | - | ||
| 159 | -**Lines of Code Added**: ~180 | ||
| 160 | -- Error handling: ~80 lines | ||
| 161 | -- Helper functions: ~60 lines | ||
| 162 | -- File tree sync: ~10 lines | ||
| 163 | -- Comments/documentation: ~30 lines | ||
| 164 | - | ||
| 165 | -**New Functions**: 3 | ||
| 166 | -```fortran | ||
| 167 | -recents_remove(index, success) | ||
| 168 | -directory_exists(path) | ||
| 169 | -handle_deleted_workspace(path, is_favorite, index) | ||
| 170 | -``` | ||
| 171 | - | ||
| 172 | -**Build Status**: ✅ Clean build, no warnings | ||
| 173 | - | ||
| 174 | ---- | ||
| 175 | - | ||
| 176 | -## 🎁 Benefits Delivered | ||
| 177 | - | ||
| 178 | -### Robustness | ||
| 179 | -- ✅ Handles all common failure scenarios | ||
| 180 | -- ✅ No crashes from missing files | ||
| 181 | -- ✅ No crashes from corrupted configs | ||
| 182 | -- ✅ Graceful degradation when things go wrong | ||
| 183 | - | ||
| 184 | -### User Experience | ||
| 185 | -- ✅ Clear, helpful error messages | ||
| 186 | -- ✅ Automatic recovery (no manual intervention) | ||
| 187 | -- ✅ Self-cleaning lists (favorites/recents) | ||
| 188 | -- ✅ Consistent UI state (file tree synced) | ||
| 189 | - | ||
| 190 | -### Maintainability | ||
| 191 | -- ✅ Well-documented code with Phase 7 comments | ||
| 192 | -- ✅ Comprehensive test suite for regression testing | ||
| 193 | -- ✅ Isolated error handling (no side effects) | ||
| 194 | -- ✅ Easy to extend for future scenarios | ||
| 195 | - | ||
| 196 | ---- | ||
| 197 | - | ||
| 198 | -## 🚀 Production Readiness | ||
| 199 | - | ||
| 200 | -### Error Handling Coverage | ||
| 201 | -- ✅ Missing files | ||
| 202 | -- ✅ Corrupted JSON | ||
| 203 | -- ✅ Deleted directories | ||
| 204 | -- ✅ Empty files | ||
| 205 | -- ✅ UTF-8 characters | ||
| 206 | -- ✅ Symlinks | ||
| 207 | -- ✅ Long paths | ||
| 208 | -- ✅ Large workspaces | ||
| 209 | - | ||
| 210 | -### Performance | ||
| 211 | -- ✅ 50-file workspace loads without issues | ||
| 212 | -- ✅ No performance degradation | ||
| 213 | -- ✅ Warning pauses don't block editor | ||
| 214 | -- ✅ File tree refresh is fast | ||
| 215 | - | ||
| 216 | -### Stability | ||
| 217 | -- ✅ All automated tests passing | ||
| 218 | -- ✅ No crashes in edge cases | ||
| 219 | -- ✅ Proper cleanup on errors | ||
| 220 | -- ✅ Safe fallback behaviors | ||
| 221 | - | ||
| 222 | ---- | ||
| 223 | - | ||
| 224 | -## 📝 Documentation Created | ||
| 225 | - | ||
| 226 | -1. **PHASE7_COMPLETE.md** (this file) | ||
| 227 | - - Complete feature documentation | ||
| 228 | - - Test results | ||
| 229 | - - Code changes summary | ||
| 230 | - | ||
| 231 | -2. **TESTING_GUIDE.md** (in /tmp/) | ||
| 232 | - - Comprehensive testing instructions | ||
| 233 | - - Manual test procedures | ||
| 234 | - - Expected behaviors | ||
| 235 | - - Troubleshooting guide | ||
| 236 | - | ||
| 237 | -3. **Code Comments** | ||
| 238 | - - All new code marked with "Phase 7" comments | ||
| 239 | - - Clear explanation of error handling logic | ||
| 240 | - - Links to relevant issue scenarios | ||
| 241 | - | ||
| 242 | ---- | ||
| 243 | - | ||
| 244 | -## 🎯 Roadmap Completion Status | ||
| 245 | - | ||
| 246 | -From WORKSPACE_ROADMAP.md Phase 6 & 7: | ||
| 247 | - | ||
| 248 | -### Phase 6 Requirements (Revisited) | ||
| 249 | -- ✅ Handle missing files in workspace.json | ||
| 250 | -- ✅ Handle deleted workspace directories | ||
| 251 | -- ✅ Handle corrupted workspace.json | ||
| 252 | -- ✅ Update file tree for workspace mode | ||
| 253 | - | ||
| 254 | -### Phase 7 Requirements | ||
| 255 | -- ✅ Error handling (permissions, disk full, invalid JSON) | ||
| 256 | -- ✅ Edge case testing (symlinks, UTF-8, long paths) | ||
| 257 | -- ✅ Performance testing (large workspaces) | ||
| 258 | -- ✅ Visual polish (warning messages, pauses) | ||
| 259 | -- 🔄 Documentation (in progress - this document) | ||
| 260 | -- ⏭️ User testing (deferred to real-world usage) | ||
| 261 | - | ||
| 262 | ---- | ||
| 263 | - | ||
| 264 | -## 🏆 Success Criteria - ALL MET | ||
| 265 | - | ||
| 266 | -From Phase 7 roadmap: | ||
| 267 | - | ||
| 268 | -- ✅ **All features working smoothly** | ||
| 269 | - - Error handling tested and validated | ||
| 270 | - - File tree synchronization working | ||
| 271 | - - No regressions detected | ||
| 272 | - | ||
| 273 | -- ✅ **No regressions in existing features** | ||
| 274 | - - Single-file mode still works | ||
| 275 | - - All workspace features functional | ||
| 276 | - - Tab/pane system stable | ||
| 277 | - | ||
| 278 | -- ✅ **Performance acceptable on large projects** | ||
| 279 | - - 50-file workspace tested | ||
| 280 | - - No slowdowns detected | ||
| 281 | - - Quick load times | ||
| 282 | - | ||
| 283 | -- ✅ **Documentation complete** | ||
| 284 | - - This completion document | ||
| 285 | - - Testing guide created | ||
| 286 | - - Code well-commented | ||
| 287 | - | ||
| 288 | -- ✅ **Ready for release** | ||
| 289 | - - All core features implemented | ||
| 290 | - - Error handling robust | ||
| 291 | - - Tests passing | ||
| 292 | - - Production-ready codebase | ||
| 293 | - | ||
| 294 | ---- | ||
| 295 | - | ||
| 296 | -## 🎉 What's Been Achieved | ||
| 297 | - | ||
| 298 | -### Core Workspace System (Phases 1-6) | ||
| 299 | -- ✅ Fortress Navigator integration | ||
| 300 | -- ✅ Workspace detection and creation | ||
| 301 | -- ✅ Tab/pane state persistence | ||
| 302 | -- ✅ Backup system | ||
| 303 | -- ✅ Favorites and recents | ||
| 304 | -- ✅ Workspace switching | ||
| 305 | - | ||
| 306 | -### Polish & Error Handling (Phase 7) | ||
| 307 | -- ✅ Missing file handling | ||
| 308 | -- ✅ Corrupted JSON recovery | ||
| 309 | -- ✅ Deleted workspace cleanup | ||
| 310 | -- ✅ File tree synchronization | ||
| 311 | -- ✅ Comprehensive testing | ||
| 312 | -- ✅ Production-ready stability | ||
| 313 | - | ||
| 314 | ---- | ||
| 315 | - | ||
| 316 | -## 🔮 Future Enhancements (Optional) | ||
| 317 | - | ||
| 318 | -These were considered but deemed non-critical: | ||
| 319 | - | ||
| 320 | -### Performance Optimization | ||
| 321 | -- Cache directory existence checks | ||
| 322 | -- Lazy load workspace state | ||
| 323 | -- Optimize JSON parsing | ||
| 324 | -- Reduce file system calls | ||
| 325 | - | ||
| 326 | -**Status**: Not needed - performance is already good | ||
| 327 | - | ||
| 328 | -### Advanced Error Handling | ||
| 329 | -- Permissions errors (disk read-only) | ||
| 330 | -- Disk full scenarios | ||
| 331 | -- Network path handling | ||
| 332 | -- Binary file detection in backups | ||
| 333 | - | ||
| 334 | -**Status**: Edge cases - can be added if users report issues | ||
| 335 | - | ||
| 336 | -### User Testing | ||
| 337 | -- Real-world project testing | ||
| 338 | -- Multiple user feedback | ||
| 339 | -- Usage pattern analysis | ||
| 340 | -- Bug reports from field | ||
| 341 | - | ||
| 342 | -**Status**: Deferred to actual usage | ||
| 343 | - | ||
| 344 | ---- | ||
| 345 | - | ||
| 346 | -## 🎓 Lessons Learned | ||
| 347 | - | ||
| 348 | -### What Worked Well | ||
| 349 | -1. **Incremental Testing**: Creating test scenarios as we built features | ||
| 350 | -2. **Config Backup**: Protecting user data during testing | ||
| 351 | -3. **Clear Warnings**: User-friendly error messages with pauses | ||
| 352 | -4. **Automatic Recovery**: No manual intervention required | ||
| 353 | - | ||
| 354 | -### What Was Challenging | ||
| 355 | -1. **Module Dependencies**: Had to do clean builds occasionally | ||
| 356 | -2. **Terminal Output**: Warning messages need careful timing | ||
| 357 | -3. **Test Isolation**: Ensuring tests don't affect real configs | ||
| 358 | -4. **Edge Case Discovery**: Finding all possible failure scenarios | ||
| 359 | - | ||
| 360 | -### Best Practices Established | ||
| 361 | -1. Always backup configs before testing | ||
| 362 | -2. Add "Phase X" comments to track changes | ||
| 363 | -3. Use consistent warning message format | ||
| 364 | -4. Test error paths as thoroughly as happy paths | ||
| 365 | - | ||
| 366 | ---- | ||
| 367 | - | ||
| 368 | -## 📦 Deliverables | ||
| 369 | - | ||
| 370 | -### Code | ||
| 371 | -- ✅ 4 modified source files | ||
| 372 | -- ✅ ~180 lines of production code | ||
| 373 | -- ✅ 3 new utility functions | ||
| 374 | -- ✅ Well-commented and documented | ||
| 375 | - | ||
| 376 | -### Tests | ||
| 377 | -- ✅ 8 comprehensive test scenarios | ||
| 378 | -- ✅ Automated test runner | ||
| 379 | -- ✅ Config backup/restore system | ||
| 380 | -- ✅ Testing guide documentation | ||
| 381 | - | ||
| 382 | -### Documentation | ||
| 383 | -- ✅ This completion document | ||
| 384 | -- ✅ TESTING_GUIDE.md | ||
| 385 | -- ✅ In-code comments | ||
| 386 | -- ✅ Test scenario descriptions | ||
| 387 | - | ||
| 388 | ---- | ||
| 389 | - | ||
| 390 | -## 🎬 Conclusion | ||
| 391 | - | ||
| 392 | -**Phase 7 is COMPLETE!** ✅ | ||
| 393 | - | ||
| 394 | -The workspace system is now production-ready with: | ||
| 395 | -- Robust error handling for all common scenarios | ||
| 396 | -- Comprehensive test coverage | ||
| 397 | -- Clear user feedback | ||
| 398 | -- Automatic recovery mechanisms | ||
| 399 | -- Self-maintaining data structures | ||
| 400 | -- Excellent performance | ||
| 401 | - | ||
| 402 | -All roadmap objectives for Phase 7 have been met. The codebase is stable, well-tested, and ready for real-world use. | ||
| 403 | - | ||
| 404 | -**Next Steps**: | ||
| 405 | -- Use the workspace system in daily development | ||
| 406 | -- Monitor for any edge cases in real usage | ||
| 407 | -- Collect user feedback | ||
| 408 | -- Make incremental improvements as needed | ||
| 409 | - | ||
| 410 | ---- | ||
| 411 | - | ||
| 412 | -**Status**: ✅ **PRODUCTION READY** | ||
| 413 | -**Quality**: ⭐⭐⭐⭐⭐ Excellent | ||
| 414 | -**Test Coverage**: 100% of error paths tested | ||
| 415 | -**Documentation**: Complete | ||
| 416 | - | ||
| 417 | -🎉 **Congratulations on completing the Workspace Mode implementation!** 🎉 | ||
| 418 | - | ||
| 419 | ---- | ||
| 420 | - | ||
| 421 | -*Generated: November 5, 2025* | ||
| 422 | -*Phase 7 Duration: 1 session* | ||
| 423 | -*Total Workspace Implementation: Phases 1-7 complete* | ||
RELEASE.mddeleted@@ -1,233 +0,0 @@ | |||
| 1 | -# Release Guide | ||
| 2 | - | ||
| 3 | -This guide explains how to create a new release of `fac`. | ||
| 4 | - | ||
| 5 | -## Quick Reference | ||
| 6 | - | ||
| 7 | -```bash | ||
| 8 | -# Check current version | ||
| 9 | -make version | ||
| 10 | - | ||
| 11 | -# Bump version (choose one) | ||
| 12 | -make bump-patch # 0.7.5 -> 0.7.6 (bug fixes) | ||
| 13 | -make bump-minor # 0.7.5 -> 0.8.0 (new features) | ||
| 14 | -make bump-major # 0.7.5 -> 1.0.0 (breaking changes) | ||
| 15 | - | ||
| 16 | -# Build release | ||
| 17 | -make release | ||
| 18 | - | ||
| 19 | -# Follow the checklist printed by make release | ||
| 20 | -``` | ||
| 21 | - | ||
| 22 | -## Detailed Workflow | ||
| 23 | - | ||
| 24 | -### 1. Prepare for Release | ||
| 25 | - | ||
| 26 | -Make sure your working directory is clean and you're on the branch you want to release from (usually `trunk` or `main`): | ||
| 27 | - | ||
| 28 | -```bash | ||
| 29 | -git status | ||
| 30 | -# Should show: working tree clean | ||
| 31 | -``` | ||
| 32 | - | ||
| 33 | -### 2. Decide Version Bump Type | ||
| 34 | - | ||
| 35 | -Follow [Semantic Versioning](https://semver.org/): | ||
| 36 | - | ||
| 37 | -- **Patch** (0.7.5 → 0.7.6): Bug fixes, no new features | ||
| 38 | - ```bash | ||
| 39 | - make bump-patch | ||
| 40 | - ``` | ||
| 41 | - | ||
| 42 | -- **Minor** (0.7.5 → 0.8.0): New features, backwards compatible | ||
| 43 | - ```bash | ||
| 44 | - make bump-minor | ||
| 45 | - ``` | ||
| 46 | - | ||
| 47 | -- **Major** (0.7.5 → 1.0.0): Breaking changes | ||
| 48 | - ```bash | ||
| 49 | - make bump-major | ||
| 50 | - ``` | ||
| 51 | - | ||
| 52 | -This updates the `VERSION` file automatically. | ||
| 53 | - | ||
| 54 | -### 3. Build the Release | ||
| 55 | - | ||
| 56 | -```bash | ||
| 57 | -make release | ||
| 58 | -``` | ||
| 59 | - | ||
| 60 | -This will: | ||
| 61 | -- Clean previous builds | ||
| 62 | -- Generate the version module | ||
| 63 | -- Compile everything | ||
| 64 | -- Show the version | ||
| 65 | -- Display a checklist of next steps | ||
| 66 | - | ||
| 67 | -### 4. Test the Binary | ||
| 68 | - | ||
| 69 | -Before committing, test the new build: | ||
| 70 | - | ||
| 71 | -```bash | ||
| 72 | -# Test basic functionality | ||
| 73 | -./fac scratch_files/regex_test_examples.txt | ||
| 74 | - | ||
| 75 | -# Test version flag | ||
| 76 | -./fac --version | ||
| 77 | - | ||
| 78 | -# Test help | ||
| 79 | -./fac --help | ||
| 80 | -``` | ||
| 81 | - | ||
| 82 | -### 5. Commit and Tag | ||
| 83 | - | ||
| 84 | -If everything works: | ||
| 85 | - | ||
| 86 | -```bash | ||
| 87 | -# Stage changes | ||
| 88 | -git add VERSION | ||
| 89 | - | ||
| 90 | -# Commit | ||
| 91 | -git commit -m "Release v$(cat VERSION)" | ||
| 92 | - | ||
| 93 | -# Create tag | ||
| 94 | -git tag v$(cat VERSION) | ||
| 95 | - | ||
| 96 | -# Push | ||
| 97 | -git push | ||
| 98 | -git push --tags | ||
| 99 | -``` | ||
| 100 | - | ||
| 101 | -### 6. Verify on GitHub | ||
| 102 | - | ||
| 103 | -Check that: | ||
| 104 | -- The tag appears in releases | ||
| 105 | -- The VERSION file is updated in the commit | ||
| 106 | - | ||
| 107 | -## Manual Version Update | ||
| 108 | - | ||
| 109 | -If you prefer to set the version manually: | ||
| 110 | - | ||
| 111 | -```bash | ||
| 112 | -# Edit VERSION file | ||
| 113 | -echo "0.8.0" > VERSION | ||
| 114 | - | ||
| 115 | -# Build | ||
| 116 | -make release | ||
| 117 | -``` | ||
| 118 | - | ||
| 119 | -## Checking Version on Another Machine | ||
| 120 | - | ||
| 121 | -After cloning the repo on a new machine: | ||
| 122 | - | ||
| 123 | -```bash | ||
| 124 | -# Clone | ||
| 125 | -git clone <repo-url> | ||
| 126 | -cd facsimile | ||
| 127 | - | ||
| 128 | -# Check version (no build needed) | ||
| 129 | -cat VERSION | ||
| 130 | - | ||
| 131 | -# Build with that version | ||
| 132 | -make | ||
| 133 | - | ||
| 134 | -# Verify it's embedded | ||
| 135 | -./fac --version | ||
| 136 | -``` | ||
| 137 | - | ||
| 138 | -## Makefile Targets Reference | ||
| 139 | - | ||
| 140 | -| Target | Description | | ||
| 141 | -|--------|-------------| | ||
| 142 | -| `make version` | Show current version from VERSION file | | ||
| 143 | -| `make bump-patch` | Increment patch version (x.x.X) | | ||
| 144 | -| `make bump-minor` | Increment minor version (x.X.0) | | ||
| 145 | -| `make bump-major` | Increment major version (X.0.0) | | ||
| 146 | -| `make release` | Clean build and show release checklist | | ||
| 147 | -| `make all` | Normal build | | ||
| 148 | -| `make clean` | Remove build artifacts | | ||
| 149 | -| `make dev` | Build with all warnings | | ||
| 150 | -| `make debug` | Build with debug symbols | | ||
| 151 | - | ||
| 152 | -## Example Release Workflow | ||
| 153 | - | ||
| 154 | -```bash | ||
| 155 | -# Starting at v0.7.5, want to release bug fix | ||
| 156 | - | ||
| 157 | -# 1. Bump version | ||
| 158 | -$ make bump-patch | ||
| 159 | -Current version: 0.7.5 | ||
| 160 | -Bumping to: 0.7.6 | ||
| 161 | -Updated VERSION file to 0.7.6 | ||
| 162 | -Now run: make clean && make | ||
| 163 | - | ||
| 164 | -# 2. Build release | ||
| 165 | -$ make release | ||
| 166 | -Generating version module... | ||
| 167 | -[... compilation output ...] | ||
| 168 | - | ||
| 169 | -======================================== | ||
| 170 | -Release Build Complete: v0.7.6 | ||
| 171 | -======================================== | ||
| 172 | - | ||
| 173 | -fac version 0.7.6 | ||
| 174 | - | ||
| 175 | -Next steps: | ||
| 176 | -1. Test the binary: ./fac | ||
| 177 | -2. Commit changes: git add VERSION | ||
| 178 | -3. Commit: git commit -m 'Release v0.7.6' | ||
| 179 | -4. Tag: git tag v0.7.6 | ||
| 180 | -5. Push: git push && git push --tags | ||
| 181 | - | ||
| 182 | -# 3. Test | ||
| 183 | -$ ./fac --version | ||
| 184 | -fac version 0.7.6 | ||
| 185 | - | ||
| 186 | -# 4. Commit and tag | ||
| 187 | -$ git add VERSION | ||
| 188 | -$ git commit -m "Release v0.7.6" | ||
| 189 | -$ git tag v0.7.6 | ||
| 190 | -$ git push && git push --tags | ||
| 191 | -``` | ||
| 192 | - | ||
| 193 | -## Troubleshooting | ||
| 194 | - | ||
| 195 | -### Version not updating in binary | ||
| 196 | - | ||
| 197 | -```bash | ||
| 198 | -# Make sure to clean build | ||
| 199 | -make clean && make | ||
| 200 | -``` | ||
| 201 | - | ||
| 202 | -### Wrong version after bump | ||
| 203 | - | ||
| 204 | -```bash | ||
| 205 | -# Check VERSION file | ||
| 206 | -cat VERSION | ||
| 207 | - | ||
| 208 | -# If wrong, edit it manually | ||
| 209 | -echo "0.8.0" > VERSION | ||
| 210 | - | ||
| 211 | -# Rebuild | ||
| 212 | -make clean && make | ||
| 213 | -``` | ||
| 214 | - | ||
| 215 | -### Can't find version module | ||
| 216 | - | ||
| 217 | -The `src/version_module.f90` is auto-generated. If it's missing: | ||
| 218 | - | ||
| 219 | -```bash | ||
| 220 | -# It will be created automatically on next build | ||
| 221 | -make clean && make | ||
| 222 | -``` | ||
| 223 | - | ||
| 224 | -## Single Source of Truth | ||
| 225 | - | ||
| 226 | -The `VERSION` file is the **only** place you need to update the version number. Everything else is automated: | ||
| 227 | - | ||
| 228 | -- ✅ `VERSION` file - **YOU edit this** (or use make bump-*) | ||
| 229 | -- 🤖 `src/version_module.f90` - Auto-generated by Makefile | ||
| 230 | -- 🤖 `./fac --version` output - Uses generated module | ||
| 231 | -- 🤖 `./fac --help` output - Uses generated module | ||
| 232 | - | ||
| 233 | -You never need to edit code to change the version! | ||
TABS_IMPLEMENTATION.mddeleted@@ -1,164 +0,0 @@ | |||
| 1 | -# Tabs Implementation Plan for Facsimile | ||
| 2 | - | ||
| 3 | -## Overview | ||
| 4 | -Add full tab support to facsimile, bridging the gap between GUI and terminal editors. Each tab represents an independent file buffer with its own cursor state and undo history. | ||
| 5 | - | ||
| 6 | -## Requirements | ||
| 7 | - | ||
| 8 | -### Core Features | ||
| 9 | -- [x] Multiple file buffers open simultaneously | ||
| 10 | -- [x] Tab bar at top of screen showing all open tabs | ||
| 11 | -- [x] Active tab highlighted visually | ||
| 12 | -- [x] Each tab maintains independent state: | ||
| 13 | - - Buffer content | ||
| 14 | - - Cursor position(s) | ||
| 15 | - - Undo/redo history | ||
| 16 | - - Viewport position | ||
| 17 | - - File path | ||
| 18 | - | ||
| 19 | -### Keybindings | ||
| 20 | -- [x] `alt-1` through `alt-9`: Jump to tab 1-9 | ||
| 21 | -- [x] `ctrl-alt-left`: Previous tab (with wrap-around) | ||
| 22 | -- [x] `ctrl-alt-right`: Next tab (with wrap-around) | ||
| 23 | -- [x] Check for conflicts with existing bindings (DONE - no conflicts) | ||
| 24 | - | ||
| 25 | -### Fuss Integration | ||
| 26 | -- [x] Opening file in fuss mode creates new tab by default | ||
| 27 | -- [x] New tab becomes active immediately | ||
| 28 | -- [x] Fuss mode persists (already implemented) | ||
| 29 | - | ||
| 30 | -### UI/UX | ||
| 31 | -- [x] Tab bar shows: `[1: file1.txt] [2: file2.f90*] [3: README.md]` | ||
| 32 | -- [x] Active tab uses reverse video (char(27) // '[7m') | ||
| 33 | -- [x] Modified files indicated with `*` suffix | ||
| 34 | -- [x] Tab bar takes 1 row at top | ||
| 35 | -- [x] Adjust editor viewport to account for tab bar (starts at row 2) | ||
| 36 | -- [x] Tab bar updates automatically when switching tabs | ||
| 37 | - | ||
| 38 | -## Architecture Design | ||
| 39 | - | ||
| 40 | -### Data Structures | ||
| 41 | - | ||
| 42 | -#### Tab Type (new) | ||
| 43 | -```fortran | ||
| 44 | -type :: tab_t | ||
| 45 | - character(len=:), allocatable :: filename | ||
| 46 | - type(buffer_t) :: buffer | ||
| 47 | - type(cursor_t), allocatable :: cursors(:) | ||
| 48 | - integer :: active_cursor | ||
| 49 | - integer :: viewport_line | ||
| 50 | - integer :: viewport_column | ||
| 51 | - logical :: modified | ||
| 52 | -end type tab_t | ||
| 53 | -``` | ||
| 54 | - | ||
| 55 | -#### Editor State Updates | ||
| 56 | -```fortran | ||
| 57 | -type(tab_t), allocatable :: tabs(:) | ||
| 58 | -integer :: active_tab_index | ||
| 59 | -integer :: max_tabs = 10 ! Support up to 10 tabs initially | ||
| 60 | -``` | ||
| 61 | - | ||
| 62 | -### File Changes | ||
| 63 | - | ||
| 64 | -#### src/editor_state_module.f90 | ||
| 65 | -- Add tab_t type definition | ||
| 66 | -- Add tabs array and active_tab_index to editor_state_t | ||
| 67 | -- Add procedures: create_tab, switch_tab, close_tab | ||
| 68 | - | ||
| 69 | -#### src/terminal/renderer_module.f90 | ||
| 70 | -- Add render_tab_bar() subroutine | ||
| 71 | -- Adjust main viewport to start at row 2 instead of row 1 | ||
| 72 | -- Update render_screen() to call render_tab_bar() | ||
| 73 | - | ||
| 74 | -#### src/commands/command_handler_module.f90 | ||
| 75 | -- Add alt-1 through alt-9 handlers | ||
| 76 | -- Add ctrl-alt-left/right handlers | ||
| 77 | -- Modify open_file_in_editor() to create new tab | ||
| 78 | -- Add save/restore logic for tab switching | ||
| 79 | - | ||
| 80 | -#### src/buffer_module.f90 | ||
| 81 | -- Ensure buffer can be deep-copied for tab state | ||
| 82 | -- May need clone_buffer() function | ||
| 83 | - | ||
| 84 | -## Implementation Phases | ||
| 85 | - | ||
| 86 | -### Phase 1: Core Tab Infrastructure | ||
| 87 | -1. Define tab_t type | ||
| 88 | -2. Add tabs array to editor state | ||
| 89 | -3. Create basic tab management functions: | ||
| 90 | - - `create_new_tab(editor, filename)` | ||
| 91 | - - `switch_to_tab(editor, tab_index)` | ||
| 92 | - - `get_current_tab(editor)` | ||
| 93 | - | ||
| 94 | -### Phase 2: Tab Bar Rendering | ||
| 95 | -1. Implement `render_tab_bar()` | ||
| 96 | -2. Display tab index and filename | ||
| 97 | -3. Highlight active tab | ||
| 98 | -4. Show modification indicator | ||
| 99 | -5. Adjust viewport for tab bar | ||
| 100 | - | ||
| 101 | -### Phase 3: Navigation Keybindings | ||
| 102 | -1. Parse alt-<number> key sequences | ||
| 103 | -2. Implement tab switching logic | ||
| 104 | -3. Add ctrl-alt-left/right navigation | ||
| 105 | -4. Save/restore cursor and viewport state | ||
| 106 | - | ||
| 107 | -### Phase 4: Fuss Integration | ||
| 108 | -1. Modify `open_file_in_editor()` to create tab | ||
| 109 | -2. Set new tab as active | ||
| 110 | -3. Test opening multiple files from fuss | ||
| 111 | - | ||
| 112 | -### Phase 5: Polish & Documentation | ||
| 113 | -1. Update ctrl-? help menu | ||
| 114 | -2. Test edge cases (max tabs, closing tabs, etc.) | ||
| 115 | -3. Handle unsaved changes warnings | ||
| 116 | -4. Performance testing with many tabs | ||
| 117 | - | ||
| 118 | -## Edge Cases to Handle | ||
| 119 | - | ||
| 120 | -- Opening same file in multiple tabs (allow or prevent?) | ||
| 121 | -- Maximum tab limit (10 initially) | ||
| 122 | -- Tab overflow (show scroll indicator if >10 tabs?) | ||
| 123 | -- Closing active tab (switch to next/previous) | ||
| 124 | -- Closing all tabs (keep at least one empty buffer?) | ||
| 125 | -- Modified file indicator updates | ||
| 126 | -- Tab bar width overflow (truncate long filenames) | ||
| 127 | - | ||
| 128 | -## Testing Plan | ||
| 129 | - | ||
| 130 | -### Manual Tests | ||
| 131 | -1. Create 3 tabs, verify each has independent buffer | ||
| 132 | -2. Switch between tabs with alt-1, alt-2, alt-3 | ||
| 133 | -3. Navigate with ctrl-alt-left/right | ||
| 134 | -4. Open files from fuss, verify new tabs created | ||
| 135 | -5. Modify files in different tabs, verify * indicator | ||
| 136 | -6. Close tabs, verify proper cleanup | ||
| 137 | - | ||
| 138 | -### Integration Tests | ||
| 139 | -1. Tab switching preserves cursor position | ||
| 140 | -2. Tab switching preserves undo history | ||
| 141 | -3. Fuss mode works correctly with multiple tabs open | ||
| 142 | -4. Tab bar updates when files modified | ||
| 143 | -5. Keybindings don't conflict with existing shortcuts | ||
| 144 | - | ||
| 145 | -## Success Criteria | ||
| 146 | - | ||
| 147 | -- [ ] Can open 10 files in separate tabs | ||
| 148 | -- [ ] Each tab maintains independent state | ||
| 149 | -- [ ] Alt-<number> switches tabs instantly | ||
| 150 | -- [ ] Ctrl-alt-left/right cycles through tabs | ||
| 151 | -- [ ] Tab bar clearly shows which tab is active | ||
| 152 | -- [ ] Opening file from fuss creates new tab | ||
| 153 | -- [ ] Modified files show * indicator in tab bar | ||
| 154 | -- [ ] Help menu documents all tab features | ||
| 155 | -- [ ] No performance degradation with 10 tabs open | ||
| 156 | - | ||
| 157 | -## Future Enhancements (Not in Scope) | ||
| 158 | - | ||
| 159 | -- Tab reordering (drag/drop or keyboard) | ||
| 160 | -- Split panes (horizontal/vertical) | ||
| 161 | -- Tab groups or sessions | ||
| 162 | -- Persistent tab state between sessions | ||
| 163 | -- Tab close keybinding (ctrl-w?) | ||
| 164 | -- New empty tab keybinding (ctrl-t?) | ||
TARGET.mddeleted@@ -1,18 +0,0 @@ | |||
| 1 | -# facsimile next targets | ||
| 2 | - | ||
| 3 | -The dream for facsimile is to rival gui editors in terms of featureset | ||
| 4 | -So the full vision for fac involves: | ||
| 5 | -- split panes | ||
| 6 | -- terminal entry binds | ||
| 7 | -- tabs | ||
| 8 | -- better conceptualization of having a "folder open", and better conceptualization of a workspace | ||
| 9 | -- toggleable interactive file tree (my `fuss` implementation so that git is integrated in the editor) | ||
| 10 | - - that is a 30% pane that has my fuss program show the tree with fuss binds supported | ||
| 11 | - | ||
| 12 | -I think the first order of business is some kind of scaffolding to support this workspace-folder paradigm | ||
| 13 | -and then the targets in order will be: | ||
| 14 | -- the fuss file explorer | ||
| 15 | -- tabs for editing | ||
| 16 | -- integrating tabs and fuss binds | ||
| 17 | -- split pane mode | ||
| 18 | -- thinking about how to incorporate execution of in progress files, basically bring up an integrated terminal | ||
TARGETS.mddeleted@@ -1,269 +0,0 @@ | |||
| 1 | -# fac Editor Enhancement Targets | ||
| 2 | - | ||
| 3 | -## 🎯 LSP Enhancements | ||
| 4 | - | ||
| 5 | -### 1. Diagnostics Display ✅ (100% Complete!) | ||
| 6 | -- [x] Parse textDocument/publishDiagnostics notifications | ||
| 7 | -- [x] Store diagnostics per file in editor state | ||
| 8 | -- [x] Display error/warning markers in the gutter | ||
| 9 | -- [x] Show diagnostic messages in status line when cursor on error line | ||
| 10 | -- [x] Add diagnostic severity colors (error=red, warning=yellow, info=blue) | ||
| 11 | -- [x] Create diagnostics panel (Ctrl+Shift+D) to list all issues | ||
| 12 | - | ||
| 13 | -### 2. Real-time Updates (didChange) ✅ (90% Complete!) | ||
| 14 | -- [x] Send textDocument/didChange notifications on buffer edits | ||
| 15 | -- [x] Document sync module with version tracking | ||
| 16 | -- [x] Debounce changes to avoid overwhelming the server (500ms delay) | ||
| 17 | -- [x] Send textDocument/didSave notifications on file save (Ctrl+S) | ||
| 18 | -- [x] Integration with buffer change tracking | ||
| 19 | -- [ ] Update diagnostics in real-time as user types (server-dependent) | ||
| 20 | -- [ ] Implement incremental sync (send only changed portions) | ||
| 21 | - | ||
| 22 | -### 3. Go to Definition ✅ (80% Complete!) | ||
| 23 | -- [x] Implement textDocument/definition request | ||
| 24 | -- [x] Parse LocationLink/Location responses | ||
| 25 | -- [x] Jump to definition location (same file) | ||
| 26 | -- [x] Add jump stack to return to previous location (Alt+,) | ||
| 27 | -- [x] F12 keybinding for go to definition | ||
| 28 | -- [ ] Jump to definition in different file (needs tab opening) | ||
| 29 | -- [ ] Show preview of definition in tooltip if same file | ||
| 30 | - | ||
| 31 | -### 4. Find References (Shift+F12) ✅ (100% Complete!) | ||
| 32 | -- [x] Implement textDocument/references request | ||
| 33 | -- [x] Create references panel showing all occurrences | ||
| 34 | -- [x] Navigate through references with arrow keys | ||
| 35 | -- [x] Show references with line/column information | ||
| 36 | -- [x] Parse and populate references from LSP response with callback integration | ||
| 37 | -- [x] Jump to selected reference with Enter key | ||
| 38 | -- [ ] Load preview context for each reference (enhancement) | ||
| 39 | -- [ ] Group references by file (enhancement) | ||
| 40 | - | ||
| 41 | -### 5. Code Actions & Quick Fixes | ||
| 42 | -- [ ] Request code actions at cursor position | ||
| 43 | -- [ ] Display available actions in popup menu | ||
| 44 | -- [ ] Apply workspace edits from code actions | ||
| 45 | -- [ ] Support quick fixes for diagnostics | ||
| 46 | -- [ ] Add keyboard shortcut (Ctrl+.) | ||
| 47 | - | ||
| 48 | -### 6. Rename Symbol (F2) | ||
| 49 | -- [ ] Implement textDocument/rename request | ||
| 50 | -- [ ] Show rename prompt with current symbol name | ||
| 51 | -- [ ] Apply workspace-wide rename edits | ||
| 52 | -- [ ] Preview changes before applying | ||
| 53 | -- [ ] Handle rename validation | ||
| 54 | - | ||
| 55 | -### 7. Document Symbols Outline (Ctrl+Shift+O) | ||
| 56 | -- [ ] Implement textDocument/documentSymbol request | ||
| 57 | -- [ ] Create outline panel showing document structure | ||
| 58 | -- [ ] Support hierarchical symbol tree | ||
| 59 | -- [ ] Navigate to symbol on selection | ||
| 60 | -- [ ] Show symbol kinds with icons/labels | ||
| 61 | - | ||
| 62 | -### 8. Signature Help | ||
| 63 | -- [ ] Trigger on '(' and ',' characters | ||
| 64 | -- [ ] Show function signature tooltip | ||
| 65 | -- [ ] Highlight current parameter | ||
| 66 | -- [ ] Handle overloaded functions | ||
| 67 | -- [ ] Auto-dismiss when cursor moves away | ||
| 68 | - | ||
| 69 | -### 9. Document Formatting | ||
| 70 | -- [ ] Implement textDocument/formatting request | ||
| 71 | -- [ ] Add format document command (Shift+Alt+F) | ||
| 72 | -- [ ] Support range formatting for selections | ||
| 73 | -- [ ] Handle format-on-save option | ||
| 74 | -- [ ] Respect .editorconfig settings | ||
| 75 | - | ||
| 76 | -### 10. Workspace Symbols (Ctrl+T) | ||
| 77 | -- [ ] Implement workspace/symbol request | ||
| 78 | -- [ ] Create fuzzy search interface | ||
| 79 | -- [ ] Show symbol kind and location | ||
| 80 | -- [ ] Navigate to selected symbol | ||
| 81 | -- [ ] Support incremental search | ||
| 82 | - | ||
| 83 | -## 🔧 Editor Core Improvements | ||
| 84 | - | ||
| 85 | -### 11. Multiple Cursors Enhancement | ||
| 86 | -- [ ] Add cursor at next occurrence (Ctrl+D) | ||
| 87 | -- [ ] Add cursors above/below (Ctrl+Alt+Up/Down) | ||
| 88 | -- [ ] Select all occurrences (Ctrl+Shift+L) | ||
| 89 | -- [ ] Column selection mode (Alt+Shift+drag) | ||
| 90 | -- [ ] Multi-cursor paste handling | ||
| 91 | - | ||
| 92 | -### 12. Search & Replace Improvements | ||
| 93 | -- [ ] Regex search highlighting | ||
| 94 | -- [ ] Search history (up/down in search prompt) | ||
| 95 | -- [ ] Replace preview before applying | ||
| 96 | -- [ ] Search in selection | ||
| 97 | -- [ ] Case-sensitive toggle (Alt+C in search) | ||
| 98 | - | ||
| 99 | -### 13. File Explorer Enhancement | ||
| 100 | -- [ ] File icons based on type | ||
| 101 | -- [ ] Create/delete/rename files from tree | ||
| 102 | -- [ ] Drag and drop support (if terminal supports) | ||
| 103 | -- [ ] Git status indicators in tree | ||
| 104 | -- [ ] Filter/search in tree view | ||
| 105 | - | ||
| 106 | -### 14. Split Pane Features | ||
| 107 | -- [ ] Synchronized scrolling option | ||
| 108 | -- [ ] Diff view between panes | ||
| 109 | -- [ ] Quick pane switching (Ctrl+1/2/3) | ||
| 110 | -- [ ] Save pane layouts | ||
| 111 | -- [ ] Terminal pane support | ||
| 112 | - | ||
| 113 | -### 15. Snippet System | ||
| 114 | -- [ ] Parse VSCode snippet format | ||
| 115 | -- [ ] Tab stops and placeholders | ||
| 116 | -- [ ] Choice elements | ||
| 117 | -- [ ] Variable substitution | ||
| 118 | -- [ ] Custom snippet definitions | ||
| 119 | - | ||
| 120 | -## 🎨 UI/UX Enhancements | ||
| 121 | - | ||
| 122 | -### 16. Theme System | ||
| 123 | -- [ ] Load VSCode themes (JSON format) | ||
| 124 | -- [ ] Theme hot-reload | ||
| 125 | -- [ ] Separate UI and syntax themes | ||
| 126 | -- [ ] High contrast mode | ||
| 127 | -- [ ] Theme picker interface | ||
| 128 | - | ||
| 129 | -### 17. Status Bar Enhancements | ||
| 130 | -- [ ] Clickable status bar items (if terminal supports) | ||
| 131 | -- [ ] LSP server status indicator | ||
| 132 | -- [ ] Git branch and status | ||
| 133 | -- [ ] Encoding and line ending display | ||
| 134 | -- [ ] Language mode selector | ||
| 135 | - | ||
| 136 | -### 18. Command Palette (Ctrl+Shift+P) | ||
| 137 | -- [ ] Fuzzy command search | ||
| 138 | -- [ ] Recent commands | ||
| 139 | -- [ ] Command shortcuts display | ||
| 140 | -- [ ] Extension commands | ||
| 141 | -- [ ] Settings commands | ||
| 142 | - | ||
| 143 | -### 19. Settings UI | ||
| 144 | -- [ ] JSON settings file (~/.fac/settings.json) | ||
| 145 | -- [ ] Settings editor interface | ||
| 146 | -- [ ] Search settings | ||
| 147 | -- [ ] Workspace-specific settings | ||
| 148 | -- [ ] Settings sync | ||
| 149 | - | ||
| 150 | -### 20. Welcome Screen | ||
| 151 | -- [ ] Recent files/projects | ||
| 152 | -- [ ] Quick actions (New, Open, Clone) | ||
| 153 | -- [ ] Tips and tutorials | ||
| 154 | -- [ ] Extension recommendations | ||
| 155 | -- [ ] News/updates section | ||
| 156 | - | ||
| 157 | -## 🚀 Performance & Architecture | ||
| 158 | - | ||
| 159 | -### 21. Performance Optimizations | ||
| 160 | -- [ ] Lazy loading for large files | ||
| 161 | -- [ ] Virtual scrolling for long documents | ||
| 162 | -- [ ] Syntax highlighting caching | ||
| 163 | -- [ ] Incremental rendering | ||
| 164 | -- [ ] Background file indexing | ||
| 165 | - | ||
| 166 | -### 22. Extension System | ||
| 167 | -- [ ] Plugin API definition | ||
| 168 | -- [ ] Lua/Python plugin support | ||
| 169 | -- [ ] Extension marketplace integration | ||
| 170 | -- [ ] Extension settings | ||
| 171 | -- [ ] Extension commands | ||
| 172 | - | ||
| 173 | -### 23. Testing Infrastructure | ||
| 174 | -- [ ] Automated UI testing with expect | ||
| 175 | -- [ ] Performance benchmarks | ||
| 176 | -- [ ] LSP mock server for testing | ||
| 177 | -- [ ] Regression test suite | ||
| 178 | -- [ ] Code coverage reporting | ||
| 179 | - | ||
| 180 | -### 24. Project Management | ||
| 181 | -- [ ] Project-wide search | ||
| 182 | -- [ ] Project settings (.fac/project.json) | ||
| 183 | -- [ ] Build task integration | ||
| 184 | -- [ ] Debug adapter protocol | ||
| 185 | -- [ ] Source control integration | ||
| 186 | - | ||
| 187 | -### 25. Documentation | ||
| 188 | -- [ ] In-editor help system (F1) | ||
| 189 | -- [ ] Interactive tutorial mode | ||
| 190 | -- [ ] Keyboard shortcut cheatsheet | ||
| 191 | -- [ ] API documentation for extensions | ||
| 192 | -- [ ] Video tutorials | ||
| 193 | - | ||
| 194 | -## 📊 Priority Order | ||
| 195 | - | ||
| 196 | -### Phase 1: Core LSP 🚀 (98% Complete!) | ||
| 197 | -1. ✅ Diagnostics Display (100%) | ||
| 198 | -2. ✅ Real-time Updates (didChange/didSave) (90%) | ||
| 199 | -3. ✅ Go to Definition (F12) (80%) | ||
| 200 | -4. ✅ Find References (Shift+F12) (100%) | ||
| 201 | - | ||
| 202 | -### Phase 2: Essential IDE Features ✅ (100% Complete!) | ||
| 203 | -5. ✅ Code Actions & Quick Fixes (Ctrl+.) | ||
| 204 | -6. ✅ Document Symbols Outline (Ctrl+Shift+O) | ||
| 205 | -7. ✅ Signature Help (auto-trigger) | ||
| 206 | -8. ✅ Rename Symbol (F2) | ||
| 207 | - | ||
| 208 | -### Phase 3: Editor Polish (In Progress) | ||
| 209 | -9. ✅ Command Palette (Ctrl+Shift+P) | ||
| 210 | -10. ✅ Multiple Cursors Enhancement (Ctrl+D) - Already complete! | ||
| 211 | -11. ✅ Search & Replace Improvements (100% Complete!) | ||
| 212 | - - ✅ Regex, case-sensitive, whole word toggles | ||
| 213 | - - ✅ Replace one/all, match counter | ||
| 214 | - - ✅ Search history (up/down arrows) | ||
| 215 | - - ✅ Highlight all matches in viewport | ||
| 216 | - - ✅ Search in selection | ||
| 217 | -12. ✅ Document Formatting (Shift+Alt+F) | ||
| 218 | - | ||
| 219 | -### Phase 3: Completed! ✅ | ||
| 220 | -13. ✅ Workspace Symbols (Ctrl+Shift+T) - Fuzzy search all symbols across entire project | ||
| 221 | -14. 🔜 Split Pane Enhancements - Synchronized scrolling, diff view (Moved to trunk) | ||
| 222 | -15. 🔜 Snippet System - Code templates with tab stops (Consider separate branch) | ||
| 223 | - | ||
| 224 | -### Phase 4: Advanced Features | ||
| 225 | -13. Snippet System | ||
| 226 | -14. Theme System | ||
| 227 | -15. Extension System | ||
| 228 | -16. Project Management | ||
| 229 | - | ||
| 230 | -### Phase 5: Professional Features | ||
| 231 | -17. Workspace Symbols | ||
| 232 | -18. Split Pane Features | ||
| 233 | -19. Settings UI | ||
| 234 | -20. Debug Adapter Protocol | ||
| 235 | - | ||
| 236 | -## 🎯 Success Metrics | ||
| 237 | - | ||
| 238 | -- [ ] All LSP features working with at least 3 language servers | ||
| 239 | -- [ ] Performance: <100ms response time for all operations | ||
| 240 | -- [ ] Memory usage: <50MB for typical usage | ||
| 241 | -- [ ] Test coverage: >80% for core modules | ||
| 242 | -- [ ] Documentation: Complete for all user-facing features | ||
| 243 | - | ||
| 244 | -## 📚 Documentation | ||
| 245 | - | ||
| 246 | -**Complete LSP documentation now available!** | ||
| 247 | - | ||
| 248 | -- **[LSP_GUIDE.md](docs/LSP_GUIDE.md)** - Comprehensive guide to all LSP features | ||
| 249 | - - What is LSP and why use it? | ||
| 250 | - - How to install and configure language servers | ||
| 251 | - - Detailed explanation of every LSP feature | ||
| 252 | - - Language-specific setup (Python, JavaScript, Rust, Fortran, Go, C/C++, etc.) | ||
| 253 | - - Troubleshooting common issues | ||
| 254 | - - Tips and tricks for power users | ||
| 255 | - | ||
| 256 | -- **[KEYBINDINGS.md](docs/KEYBINDINGS.md)** - Complete keyboard shortcuts reference | ||
| 257 | - - All LSP keybindings | ||
| 258 | - - File operations, editing, navigation | ||
| 259 | - - Search/replace, tabs/windows | ||
| 260 | - - Panel navigation and special modes | ||
| 261 | - - Quick reference for most useful combos | ||
| 262 | - | ||
| 263 | -## 📝 Notes | ||
| 264 | - | ||
| 265 | -- Each target should include tests and documentation | ||
| 266 | -- Maintain backward compatibility where possible | ||
| 267 | -- Keep terminal compatibility (no GUI dependencies) | ||
| 268 | -- Prioritize user experience and responsiveness | ||
| 269 | -- Consider accessibility (screen reader support) | ||
UTF8_MIGRATION.mddeleted@@ -1,204 +0,0 @@ | |||
| 1 | -# UTF-8 Migration Progress | ||
| 2 | - | ||
| 3 | -**Goal:** Make facsimile fully UTF-8 aware so box-drawing characters (├─│└) and other multi-byte UTF-8 sequences display and edit correctly. | ||
| 4 | - | ||
| 5 | -## Problem | ||
| 6 | -Fortran's string operations work on bytes, not characters. A UTF-8 character like `├` is 3 bytes but should be treated as 1 character and displayed as 1 column. | ||
| 7 | - | ||
| 8 | -**Example:** | ||
| 9 | -- `"Hello"` → 5 bytes, 5 chars, 5 display columns ✓ (works) | ||
| 10 | -- `"├──"` → 9 bytes, 3 chars, 3 display columns ✗ (broken before migration) | ||
| 11 | - | ||
| 12 | -## ✅ Completed | ||
| 13 | - | ||
| 14 | -### 1. Core UTF-8 Infrastructure | ||
| 15 | -- **`src/utils/utf8_module.f90`** - COMPLETE | ||
| 16 | - - ✅ `utf8_char_count()` - Count UTF-8 characters | ||
| 17 | - - ✅ `utf8_char_at()` - Extract character at position | ||
| 18 | - - ✅ `utf8_char_to_byte_index()` - Convert char pos → byte pos | ||
| 19 | - - ✅ `utf8_byte_to_char_index()` - Convert byte pos → char pos | ||
| 20 | - - ✅ `utf8_display_width()` - Calculate screen columns needed | ||
| 21 | - - ✅ `utf8_char_byte_length()` - Get byte length of UTF-8 char | ||
| 22 | - - ✅ Handles 1-4 byte UTF-8 sequences | ||
| 23 | - - ✅ Handles wide characters (CJK = 2 columns) | ||
| 24 | - - ✅ Handles combining characters (0 width) | ||
| 25 | - | ||
| 26 | -### 2. Cursor Semantics | ||
| 27 | -- **`src/editor_state_module.f90`** - COMPLETE | ||
| 28 | - - ✅ Documented: `cursor%column` = UTF-8 character position (NOT byte index) | ||
| 29 | - - ✅ Added detailed comments explaining the semantics | ||
| 30 | - - ✅ Example: In `"├──"`, column=2 refers to second `─` (byte 4) | ||
| 31 | - | ||
| 32 | -### 3. Text Buffer UTF-8 Helpers | ||
| 33 | -- **`src/buffer/text_buffer_module.f90`** - COMPLETE | ||
| 34 | - - ✅ Added `use utf8_module` | ||
| 35 | - - ✅ `buffer_get_line_char_count()` - Get character count of line | ||
| 36 | - - ✅ `buffer_char_at()` - Get character at char position in line | ||
| 37 | - - ✅ `buffer_byte_to_char_col()` - Convert byte col → char col | ||
| 38 | - - ✅ `buffer_char_to_byte_col()` - Convert char col → byte col | ||
| 39 | - | ||
| 40 | -### 4. Basic Cursor Movement | ||
| 41 | -- **`src/commands/command_handler_module.f90`** - PARTIAL | ||
| 42 | - - ✅ `move_cursor_left()` - Uses `buffer_get_line_char_count()` | ||
| 43 | - - ✅ `move_cursor_right()` - Uses `buffer_get_line_char_count()` | ||
| 44 | - - ✅ Both functions now work with character positions | ||
| 45 | - | ||
| 46 | -### 5. Module Imports | ||
| 47 | -- **`src/terminal/renderer_module.f90`** - PARTIAL | ||
| 48 | - - ✅ Added `use utf8_module` | ||
| 49 | - - ✅ Added `buffer_get_line_char_count` to imports | ||
| 50 | - | ||
| 51 | -### 6. Renderer Display (HIGH PRIORITY) | ||
| 52 | -- **`src/terminal/renderer_module.f90`** - COMPLETE | ||
| 53 | - - ✅ `render_line()` - Uses UTF-8 character positions and display width | ||
| 54 | - - ✅ Converts character positions to byte positions for slicing | ||
| 55 | - - ✅ Uses `utf8_display_width()` for padding calculations | ||
| 56 | - - ✅ Cursor screen positioning uses display width calculations | ||
| 57 | - - ✅ Both active and inactive cursors positioned correctly | ||
| 58 | - | ||
| 59 | -**Impact:** UTF-8 characters now display correctly! | ||
| 60 | - | ||
| 61 | -## 📋 TODO (Remaining Work) | ||
| 62 | - | ||
| 63 | -### HIGH PRIORITY - Renderer Fixes | ||
| 64 | -Files: `src/terminal/renderer_module.f90` | ||
| 65 | - | ||
| 66 | -**Specific locations that need fixing:** | ||
| 67 | -- Line 83: `len(line_content)` → needs UTF-8 char count | ||
| 68 | -- Line 208: `len(line)` → needs UTF-8 char count | ||
| 69 | -- Line 219-220: Padding calculation needs display width | ||
| 70 | -- Line 245: `len(line)` → needs UTF-8 char count | ||
| 71 | -- Line 480, 487, 504, 517: Cursor screen position calculations | ||
| 72 | -- Line 570-573, 597-600: Viewport scrolling with character positions | ||
| 73 | -- Line 754: `len(line_content)` → needs UTF-8 char count | ||
| 74 | -- Line 959-960: Viewport range calculation | ||
| 75 | -- Line 1036, 1129, 1136, 1156, 1197: More cursor positioning | ||
| 76 | - | ||
| 77 | -### MEDIUM PRIORITY - Word Movement | ||
| 78 | -Files: `src/commands/command_handler_module.f90` | ||
| 79 | - | ||
| 80 | -Functions to update: | ||
| 81 | -- `move_cursor_word_left()` (line ~1105) | ||
| 82 | -- `move_cursor_word_right()` (line ~1176) | ||
| 83 | -- `extend_selection_word_left()` (line ~3447) | ||
| 84 | -- `extend_selection_word_right()` (line ~3521) | ||
| 85 | -- `delete_word_backward()` (line ~3680) | ||
| 86 | -- `delete_word_forward()` (line ~690) | ||
| 87 | - | ||
| 88 | -**Issue:** Word boundaries detected by byte operations, breaks on UTF-8 | ||
| 89 | - | ||
| 90 | -### MEDIUM PRIORITY - Editing Operations | ||
| 91 | -Files: `src/commands/command_handler_module.f90` | ||
| 92 | - | ||
| 93 | -Functions to update: | ||
| 94 | -- `insert_char()` - Insert at character position | ||
| 95 | -- `delete_char()` - Delete character (not byte) | ||
| 96 | -- `delete_selection()` - Use character positions | ||
| 97 | -- `insert_newline()` - Character position aware | ||
| 98 | -- All text manipulation that uses `line(i:i)` slicing | ||
| 99 | - | ||
| 100 | -**Issue:** Inserting/deleting can break UTF-8 sequences | ||
| 101 | - | ||
| 102 | -### MEDIUM PRIORITY - Selection Operations | ||
| 103 | -Files: `src/commands/command_handler_module.f90` | ||
| 104 | - | ||
| 105 | -Functions to update: | ||
| 106 | -- `extend_selection_left/right/up/down()` - Character boundaries | ||
| 107 | -- `select_word_at_cursor()` - UTF-8 word boundaries | ||
| 108 | -- `get_selected_text()` - Extract text by character positions | ||
| 109 | -- Selection rendering in renderer_module | ||
| 110 | - | ||
| 111 | -**Issue:** Selection ranges use byte positions, breaks UTF-8 | ||
| 112 | - | ||
| 113 | -### LOWER PRIORITY - Search & Find | ||
| 114 | -Files: `src/prompts/*.f90`, `src/commands/command_handler_module.f90` | ||
| 115 | - | ||
| 116 | -Functions to update: | ||
| 117 | -- `find_next_occurrence()` - Search with UTF-8 awareness | ||
| 118 | -- `select_next_match()` - Match by characters | ||
| 119 | -- Search prompt operations | ||
| 120 | - | ||
| 121 | -**Issue:** Pattern matching needs UTF-8 awareness | ||
| 122 | - | ||
| 123 | -### LOWER PRIORITY - Other Operations | ||
| 124 | -Various files: | ||
| 125 | - | ||
| 126 | -- Smart home: Character-based indentation detection | ||
| 127 | -- Go to column: User enters character position | ||
| 128 | -- Transpose characters: Swap UTF-8 characters | ||
| 129 | -- Bracket matching: Find brackets in UTF-8 text | ||
| 130 | -- Line operations (move, duplicate): Should already work | ||
| 131 | - | ||
| 132 | -## Testing Strategy | ||
| 133 | - | ||
| 134 | -### Test Files | ||
| 135 | -- `/tmp/test_unicode.txt` - Box drawing characters | ||
| 136 | -- `/tmp/ctrl_d_pagination_test.txt` - For ctrl-d testing | ||
| 137 | - | ||
| 138 | -### Test Cases | ||
| 139 | -1. **Display:** Open UTF-8 file, verify box chars show correctly | ||
| 140 | -2. **Cursor Movement:** Arrow keys move by character (not byte) | ||
| 141 | -3. **Editing:** Type at UTF-8 char boundaries | ||
| 142 | -4. **Selection:** Select text containing UTF-8 chars | ||
| 143 | -5. **Search:** Find UTF-8 characters with ctrl-d | ||
| 144 | -6. **Word Movement:** Alt-left/right across UTF-8 words | ||
| 145 | - | ||
| 146 | -### Success Criteria | ||
| 147 | -- Box drawing characters (├─│└) display correctly | ||
| 148 | -- Cursor doesn't get "stuck" in middle of UTF-8 sequence | ||
| 149 | -- Typing doesn't corrupt UTF-8 sequences | ||
| 150 | -- Selections work across UTF-8 boundaries | ||
| 151 | -- File saves/loads preserve UTF-8 content | ||
| 152 | - | ||
| 153 | -## Notes | ||
| 154 | - | ||
| 155 | -### Design Decisions | ||
| 156 | -1. **Cursor column = character position** (not byte position) | ||
| 157 | - - More intuitive for users | ||
| 158 | - - Matches behavior of other editors | ||
| 159 | - | ||
| 160 | -2. **Display width vs character count** | ||
| 161 | - - Most chars: 1 char = 1 column | ||
| 162 | - - CJK chars: 1 char = 2 columns | ||
| 163 | - - Combining: 1 char = 0 columns | ||
| 164 | - | ||
| 165 | -3. **Viewport in character positions** | ||
| 166 | - - Viewport uses character positions | ||
| 167 | - - Converted to byte positions when rendering | ||
| 168 | - | ||
| 169 | -### Performance Considerations | ||
| 170 | -- UTF-8 operations have overhead vs byte operations | ||
| 171 | -- Caching line char counts could help | ||
| 172 | -- Most operations stay O(n) in line length | ||
| 173 | - | ||
| 174 | -### Edge Cases to Handle | ||
| 175 | -- Cursor at end of line (column = char_count + 1) | ||
| 176 | -- Empty lines (char_count = 0) | ||
| 177 | -- Files with invalid UTF-8 (treat as bytes) | ||
| 178 | -- Mixed width characters (CJK) | ||
| 179 | -- Combining characters | ||
| 180 | - | ||
| 181 | -## Current Build Status | ||
| 182 | -✅ Builds successfully | ||
| 183 | -✅ UTF-8 module complete and tested (10/10 tests passing) | ||
| 184 | -✅ Basic cursor movement works (character-based, not byte-based) | ||
| 185 | -✅ Display rendering works (box chars render correctly) | ||
| 186 | -✅ Character insertion works at UTF-8 boundaries | ||
| 187 | -⏳ Remaining: viewport, word movement, editing ops, selections | ||
| 188 | - | ||
| 189 | -## Test Results | ||
| 190 | - | ||
| 191 | -### Unit Tests | ||
| 192 | -Created `test/test_utf8_integration.f90` with 10 comprehensive tests: | ||
| 193 | -- ✅ All 10 tests passing | ||
| 194 | -- Covers: char counting, byte↔char conversion, display width, buffer integration | ||
| 195 | - | ||
| 196 | -### Manual Testing | ||
| 197 | -Tested with `/tmp/test_utf8_simple.txt` containing box-drawing chars (├──): | ||
| 198 | -- ✅ Box characters display correctly in editor | ||
| 199 | -- ✅ Cursor moves by CHARACTER positions (not bytes) | ||
| 200 | - - Moving right through `├` (3 bytes) increments column by 1 | ||
| 201 | - - Moving right through `─` (3 bytes) increments column by 1 | ||
| 202 | -- ✅ Character insertion works at correct UTF-8 boundaries | ||
| 203 | - | ||
| 204 | -Last updated: 2025-11-04 | ||
WORKSPACE-FLOW.mddeleted@@ -1,875 +0,0 @@ | |||
| 1 | -# Workspace Mode: User Guide | ||
| 2 | - | ||
| 3 | -**Version**: 1.0 | ||
| 4 | -**Last Updated**: November 5, 2025 | ||
| 5 | -**Status**: Production Ready ✅ | ||
| 6 | - | ||
| 7 | ---- | ||
| 8 | - | ||
| 9 | -## 🎯 What is Workspace Mode? | ||
| 10 | - | ||
| 11 | -Workspace mode transforms `fac` from a single-file editor into a full project workspace manager. When you work in workspace mode, `fac` remembers: | ||
| 12 | - | ||
| 13 | -- All open tabs and files | ||
| 14 | -- Your cursor positions | ||
| 15 | -- Window splits and panes | ||
| 16 | -- File tree state | ||
| 17 | -- Recently opened workspaces | ||
| 18 | -- Your favorite workspaces | ||
| 19 | - | ||
| 20 | -Everything is automatically saved and restored when you return to a workspace. | ||
| 21 | - | ||
| 22 | ---- | ||
| 23 | - | ||
| 24 | -## 🚀 Getting Started | ||
| 25 | - | ||
| 26 | -### Creating a Workspace | ||
| 27 | - | ||
| 28 | -**Method 1: From a Directory** | ||
| 29 | -```bash | ||
| 30 | -# Navigate to your project directory | ||
| 31 | -cd /path/to/my-project | ||
| 32 | - | ||
| 33 | -# Open fac in workspace mode | ||
| 34 | -fac . | ||
| 35 | -``` | ||
| 36 | - | ||
| 37 | -This creates a `.fac/` directory with workspace configuration: | ||
| 38 | -``` | ||
| 39 | -my-project/ | ||
| 40 | - .fac/ | ||
| 41 | - workspace.json # Workspace state | ||
| 42 | - backups/ # Backup files | ||
| 43 | - src/ | ||
| 44 | - README.md | ||
| 45 | -``` | ||
| 46 | - | ||
| 47 | -**Method 2: From the Welcome Menu** | ||
| 48 | -```bash | ||
| 49 | -# Launch fac with no arguments | ||
| 50 | -fac | ||
| 51 | - | ||
| 52 | -# You'll see: | ||
| 53 | -# - Your favorite workspaces | ||
| 54 | -# - Recently opened workspaces | ||
| 55 | -# - Option to browse filesystem | ||
| 56 | -``` | ||
| 57 | - | ||
| 58 | ---- | ||
| 59 | - | ||
| 60 | -## 📂 Workspace Operations | ||
| 61 | - | ||
| 62 | -### Opening a Workspace | ||
| 63 | - | ||
| 64 | -**From Command Line:** | ||
| 65 | -```bash | ||
| 66 | -fac /path/to/workspace | ||
| 67 | -``` | ||
| 68 | - | ||
| 69 | -**From Welcome Menu:** | ||
| 70 | -1. Run `fac` (no arguments) | ||
| 71 | -2. Navigate with ↑/↓ or j/k | ||
| 72 | -3. Press `8` to toggle between favorites and recents | ||
| 73 | -4. Press Enter to open selected workspace | ||
| 74 | -5. Press `b` to browse filesystem with Fortress | ||
| 75 | - | ||
| 76 | -**From Within fac:** | ||
| 77 | -- Press `Ctrl-O` to open Fortress Navigator | ||
| 78 | -- Navigate to a directory | ||
| 79 | -- Press Enter to switch to that workspace | ||
| 80 | - | ||
| 81 | -### Switching Workspaces | ||
| 82 | - | ||
| 83 | -While working in a workspace: | ||
| 84 | - | ||
| 85 | -1. Press `Ctrl-O` to open Fortress Navigator | ||
| 86 | -2. Navigate to a different directory | ||
| 87 | -3. Press Enter on the directory | ||
| 88 | - | ||
| 89 | -What happens automatically: | ||
| 90 | -- ✅ Current workspace state is saved | ||
| 91 | -- ✅ You're prompted to save any modified files | ||
| 92 | -- ✅ New workspace is loaded (or created if new) | ||
| 93 | -- ✅ Tabs and cursor positions are restored | ||
| 94 | -- ✅ File tree updates to new workspace | ||
| 95 | -- ✅ Recent workspaces list is updated | ||
| 96 | - | ||
| 97 | -**Save Prompts:** | ||
| 98 | -``` | ||
| 99 | -Save main.f90? [y/n/c] | ||
| 100 | - y - Save and continue | ||
| 101 | - n - Don't save, continue | ||
| 102 | - c - Cancel workspace switch | ||
| 103 | -``` | ||
| 104 | - | ||
| 105 | ---- | ||
| 106 | - | ||
| 107 | -## ⭐ Favorites & Recents | ||
| 108 | - | ||
| 109 | -### Favorites System | ||
| 110 | - | ||
| 111 | -**Adding a Favorite:** | ||
| 112 | -1. Press `Ctrl-O` to open Fortress Navigator | ||
| 113 | -2. Navigate to the directory you want to favorite | ||
| 114 | -3. Press `f` to add to favorites | ||
| 115 | -4. You'll see: "Added to favorites: project-name" | ||
| 116 | - | ||
| 117 | -**Using Favorites:** | ||
| 118 | -1. Run `fac` (no arguments) to open welcome menu | ||
| 119 | -2. Press `8` if not already on favorites view | ||
| 120 | -3. Navigate to desired favorite | ||
| 121 | -4. Press Enter to open | ||
| 122 | - | ||
| 123 | -**Favorites are stored in:** `~/.config/fac/favorites.json` | ||
| 124 | - | ||
| 125 | -### Recents System | ||
| 126 | - | ||
| 127 | -Workspaces are automatically added to recents when you: | ||
| 128 | -- Open them from command line | ||
| 129 | -- Open them from welcome menu | ||
| 130 | -- Switch to them via Fortress | ||
| 131 | - | ||
| 132 | -**Viewing Recents:** | ||
| 133 | -1. Run `fac` (no arguments) | ||
| 134 | -2. Press `8` to toggle to recents view | ||
| 135 | -3. Most recently used appears first | ||
| 136 | -4. Shows up to 20 recent workspaces | ||
| 137 | - | ||
| 138 | -**Recents are stored in:** `~/.config/fac/recents.json` | ||
| 139 | - | ||
| 140 | -### Self-Cleaning Lists | ||
| 141 | - | ||
| 142 | -If a workspace directory is deleted: | ||
| 143 | -- You'll see: "Warning: Workspace no longer exists: /path" | ||
| 144 | -- It's automatically removed from the list | ||
| 145 | -- No manual cleanup needed | ||
| 146 | - | ||
| 147 | ---- | ||
| 148 | - | ||
| 149 | -## 🌲 File Tree (FUSS Mode) | ||
| 150 | - | ||
| 151 | -### Opening the File Tree | ||
| 152 | - | ||
| 153 | -Press `Ctrl-B` to toggle the file tree sidebar (FUSS mode). | ||
| 154 | - | ||
| 155 | -**What it shows:** | ||
| 156 | -- Current workspace root directory | ||
| 157 | -- All files and subdirectories | ||
| 158 | -- Git status indicators (modified, staged, etc.) | ||
| 159 | -- Current git branch | ||
| 160 | - | ||
| 161 | -**File tree always shows the current workspace root**, even after switching workspaces. | ||
| 162 | - | ||
| 163 | -### Navigating the File Tree | ||
| 164 | - | ||
| 165 | -``` | ||
| 166 | -↑/↓ - Move cursor up/down | ||
| 167 | -k/j - Vim-style navigation | ||
| 168 | -→ - Expand directory / Open file | ||
| 169 | -← - Collapse directory / Go to parent | ||
| 170 | -Enter - Open file in new tab | ||
| 171 | -g - Stage file for commit (git) | ||
| 172 | -u - Unstage file | ||
| 173 | -Ctrl-B - Toggle file tree off | ||
| 174 | -``` | ||
| 175 | - | ||
| 176 | -### Git Integration | ||
| 177 | - | ||
| 178 | -When in a git repository, the file tree shows: | ||
| 179 | -- Modified files (red M) | ||
| 180 | -- Staged files (green A) | ||
| 181 | -- Branch name in header | ||
| 182 | -- Quick staging with `g` key | ||
| 183 | - | ||
| 184 | ---- | ||
| 185 | - | ||
| 186 | -## 🗂️ Tab Management in Workspaces | ||
| 187 | - | ||
| 188 | -### Regular Tabs (Workspace Files) | ||
| 189 | - | ||
| 190 | -Files within the workspace directory: | ||
| 191 | -- Appear with normal tab styling | ||
| 192 | -- Are saved to workspace.json | ||
| 193 | -- Restore when you reopen workspace | ||
| 194 | -- Use relative paths in storage | ||
| 195 | - | ||
| 196 | -### Orphan Tabs (External Files) | ||
| 197 | - | ||
| 198 | -Files outside the workspace directory: | ||
| 199 | -- Appear with grey/dimmed styling | ||
| 200 | -- Are saved to workspace.json | ||
| 201 | -- Also restore when you reopen workspace | ||
| 202 | -- Use absolute paths in storage | ||
| 203 | - | ||
| 204 | -**Creating orphan tabs:** | ||
| 205 | -1. Press `Ctrl-O` to open Fortress | ||
| 206 | -2. Navigate to a file outside workspace | ||
| 207 | -3. Press Enter to open | ||
| 208 | - | ||
| 209 | -Example: | ||
| 210 | -``` | ||
| 211 | -Workspace: /home/user/my-project/ | ||
| 212 | -Regular tab: src/main.f90 (normal style) | ||
| 213 | -Orphan tab: /etc/hosts (grey style) | ||
| 214 | -``` | ||
| 215 | - | ||
| 216 | -### Tab Operations | ||
| 217 | - | ||
| 218 | -``` | ||
| 219 | -Ctrl-N - Next tab | ||
| 220 | -Ctrl-P - Previous tab | ||
| 221 | -Ctrl-W - Close current tab | ||
| 222 | -:e <file> - Open file in new tab | ||
| 223 | -:q - Quit (saves workspace state) | ||
| 224 | -``` | ||
| 225 | - | ||
| 226 | ---- | ||
| 227 | - | ||
| 228 | -## 💾 State Persistence | ||
| 229 | - | ||
| 230 | -### What Gets Saved | ||
| 231 | - | ||
| 232 | -When you quit `fac` in workspace mode: | ||
| 233 | - | ||
| 234 | -**Per Tab:** | ||
| 235 | -- Filename (relative or absolute) | ||
| 236 | -- Cursor position (line and column) | ||
| 237 | -- Viewport position (what's visible) | ||
| 238 | -- Modified flag | ||
| 239 | -- Orphan flag | ||
| 240 | -- Pane layout (if split) | ||
| 241 | - | ||
| 242 | -**Workspace Level:** | ||
| 243 | -- Active tab index | ||
| 244 | -- All tabs (regular and orphan) | ||
| 245 | -- File tree state (open/closed) | ||
| 246 | -- Git repository info | ||
| 247 | - | ||
| 248 | -**Where it's saved:** | ||
| 249 | -``` | ||
| 250 | -<workspace-dir>/.fac/workspace.json | ||
| 251 | -``` | ||
| 252 | - | ||
| 253 | -### What Gets Restored | ||
| 254 | - | ||
| 255 | -When you open a workspace: | ||
| 256 | -- All tabs recreate in same order | ||
| 257 | -- Cursor jumps to saved position | ||
| 258 | -- Viewport scrolls to saved position | ||
| 259 | -- Active tab is selected | ||
| 260 | -- Pane splits restore (if any) | ||
| 261 | -- File tree initializes to workspace root | ||
| 262 | - | ||
| 263 | ---- | ||
| 264 | - | ||
| 265 | -## 🛡️ Error Handling | ||
| 266 | - | ||
| 267 | -### Missing Files | ||
| 268 | - | ||
| 269 | -**Scenario:** A file was in workspace.json but no longer exists | ||
| 270 | - | ||
| 271 | -**What happens:** | ||
| 272 | -``` | ||
| 273 | -Warning: File not found (skipping): /path/to/missing/file.txt | ||
| 274 | -``` | ||
| 275 | -- Warning displays for 0.8 seconds | ||
| 276 | -- File is skipped | ||
| 277 | -- Other files load normally | ||
| 278 | -- Editor continues functioning | ||
| 279 | - | ||
| 280 | -**Why this happens:** | ||
| 281 | -- File was deleted outside fac | ||
| 282 | -- File was moved/renamed | ||
| 283 | -- Drive not mounted (network shares) | ||
| 284 | - | ||
| 285 | -**What to do:** | ||
| 286 | -- Nothing! The workspace adapts automatically | ||
| 287 | -- Use `:e <path>` to re-add the file if it's elsewhere | ||
| 288 | -- Or just continue with available files | ||
| 289 | - | ||
| 290 | -### Corrupted Workspace | ||
| 291 | - | ||
| 292 | -**Scenario:** workspace.json is corrupted or unreadable | ||
| 293 | - | ||
| 294 | -**What happens:** | ||
| 295 | -``` | ||
| 296 | -Warning: Could not open workspace.json - using empty workspace | ||
| 297 | -``` | ||
| 298 | -- Warning displays for 1.0 seconds | ||
| 299 | -- Fresh workspace is created automatically | ||
| 300 | -- You start with a clean slate | ||
| 301 | -- Old (corrupted) file is not deleted | ||
| 302 | - | ||
| 303 | -**Why this happens:** | ||
| 304 | -- Disk error during save | ||
| 305 | -- Manual editing gone wrong | ||
| 306 | -- Filesystem corruption | ||
| 307 | - | ||
| 308 | -**What to do:** | ||
| 309 | -- Nothing! Start fresh automatically | ||
| 310 | -- Check `.fac/workspace.json` if you want to recover manually | ||
| 311 | -- Your actual source files are unaffected | ||
| 312 | - | ||
| 313 | -### Deleted Workspace | ||
| 314 | - | ||
| 315 | -**Scenario:** Workspace directory was deleted | ||
| 316 | - | ||
| 317 | -**What happens (in welcome menu):** | ||
| 318 | -``` | ||
| 319 | -Warning: Workspace no longer exists: /path/to/workspace | ||
| 320 | -Removing from list... | ||
| 321 | -``` | ||
| 322 | -- Warning displays for 1.0 seconds | ||
| 323 | -- Workspace removed from favorites/recents | ||
| 324 | -- List reloads automatically | ||
| 325 | -- You can select another workspace | ||
| 326 | - | ||
| 327 | -**Why this happens:** | ||
| 328 | -- Directory deleted manually | ||
| 329 | -- Drive unmounted | ||
| 330 | -- Network share disconnected | ||
| 331 | - | ||
| 332 | -**What to do:** | ||
| 333 | -- Nothing! Lists clean themselves automatically | ||
| 334 | -- Select a different workspace | ||
| 335 | - | ||
| 336 | ---- | ||
| 337 | - | ||
| 338 | -## 🎮 Complete Keybinding Reference | ||
| 339 | - | ||
| 340 | -### Global (Any Mode) | ||
| 341 | - | ||
| 342 | -``` | ||
| 343 | -Ctrl-O - Open Fortress Navigator | ||
| 344 | -Ctrl-B - Toggle file tree (FUSS mode) | ||
| 345 | -Ctrl-N - Next tab | ||
| 346 | -Ctrl-P - Previous tab | ||
| 347 | -Ctrl-W - Close tab | ||
| 348 | -Ctrl-/ - Help menu | ||
| 349 | -:q - Quit (saves workspace) | ||
| 350 | -:e <file> - Open file in new tab | ||
| 351 | -``` | ||
| 352 | - | ||
| 353 | -### Welcome Menu | ||
| 354 | - | ||
| 355 | -``` | ||
| 356 | -↑/↓ or k/j - Navigate list | ||
| 357 | -Enter - Open selected workspace | ||
| 358 | -8 - Toggle favorites/recents view | ||
| 359 | -b - Browse filesystem | ||
| 360 | -ESC or q - Quit | ||
| 361 | -``` | ||
| 362 | - | ||
| 363 | -### Fortress Navigator | ||
| 364 | - | ||
| 365 | -``` | ||
| 366 | -↑/↓ - Navigate files/directories | ||
| 367 | -→ - Enter directory | ||
| 368 | -← - Go to parent directory | ||
| 369 | -Enter - Open file or switch to workspace | ||
| 370 | -f - Add current directory to favorites | ||
| 371 | -ESC or q - Cancel and return | ||
| 372 | -~ - Jump to home directory | ||
| 373 | -/ - Jump to root directory | ||
| 374 | -``` | ||
| 375 | - | ||
| 376 | -### File Tree (FUSS Mode) | ||
| 377 | - | ||
| 378 | -``` | ||
| 379 | -↑/↓ or k/j - Navigate tree | ||
| 380 | -→ - Expand directory / Open file | ||
| 381 | -← - Collapse directory | ||
| 382 | -Enter - Open file in new tab | ||
| 383 | -g - Stage file (git) | ||
| 384 | -u - Unstage file (git) | ||
| 385 | -Ctrl-B - Close file tree | ||
| 386 | -``` | ||
| 387 | - | ||
| 388 | ---- | ||
| 389 | - | ||
| 390 | -## 🔄 Common Workflows | ||
| 391 | - | ||
| 392 | -### Starting a New Project | ||
| 393 | - | ||
| 394 | -```bash | ||
| 395 | -# 1. Create project directory | ||
| 396 | -mkdir my-project | ||
| 397 | -cd my-project | ||
| 398 | - | ||
| 399 | -# 2. Create some files | ||
| 400 | -echo "program main" > main.f90 | ||
| 401 | - | ||
| 402 | -# 3. Open in workspace mode | ||
| 403 | -fac . | ||
| 404 | - | ||
| 405 | -# 4. Add to favorites (optional) | ||
| 406 | -# Press Ctrl-O, navigate to current dir, press 'f' | ||
| 407 | - | ||
| 408 | -# 5. Work on your project | ||
| 409 | -# All state saves automatically on :q | ||
| 410 | -``` | ||
| 411 | - | ||
| 412 | -### Switching Between Projects | ||
| 413 | - | ||
| 414 | -```bash | ||
| 415 | -# Method 1: From terminal | ||
| 416 | -fac /path/to/project-a | ||
| 417 | -# Work... | ||
| 418 | -# :q to save and quit | ||
| 419 | - | ||
| 420 | -fac /path/to/project-b | ||
| 421 | -# Continue working... | ||
| 422 | - | ||
| 423 | -# Method 2: From within fac | ||
| 424 | -# Press Ctrl-O | ||
| 425 | -# Navigate to project-b | ||
| 426 | -# Press Enter | ||
| 427 | -# fac saves project-a, loads project-b | ||
| 428 | - | ||
| 429 | -# Method 3: From welcome menu | ||
| 430 | -fac | ||
| 431 | -# Select from favorites or recents | ||
| 432 | -``` | ||
| 433 | - | ||
| 434 | -### Opening External Files While in Workspace | ||
| 435 | - | ||
| 436 | -```bash | ||
| 437 | -# You're in workspace: /home/user/my-project/ | ||
| 438 | - | ||
| 439 | -# Press Ctrl-O | ||
| 440 | -# Navigate to /etc/hosts | ||
| 441 | -# Press Enter on hosts | ||
| 442 | - | ||
| 443 | -# Now you have: | ||
| 444 | -# - Tab 1: src/main.f90 (regular tab, normal style) | ||
| 445 | -# - Tab 2: /etc/hosts (orphan tab, grey style) | ||
| 446 | - | ||
| 447 | -# Both tabs save to workspace.json | ||
| 448 | -# Both restore when you reopen workspace | ||
| 449 | -``` | ||
| 450 | - | ||
| 451 | -### Using Git with File Tree | ||
| 452 | - | ||
| 453 | -```bash | ||
| 454 | -# 1. Open workspace with Ctrl-B (file tree visible) | ||
| 455 | - | ||
| 456 | -# 2. Edit some files | ||
| 457 | -# File tree shows "M" next to modified files | ||
| 458 | - | ||
| 459 | -# 3. Stage files for commit | ||
| 460 | -# Navigate to file, press 'g' | ||
| 461 | -# File shows "A" (added/staged) | ||
| 462 | - | ||
| 463 | -# 4. Commit from command mode | ||
| 464 | -:!git commit -m "My commit message" | ||
| 465 | - | ||
| 466 | -# File tree updates to show clean state | ||
| 467 | -``` | ||
| 468 | - | ||
| 469 | -### Working with Multiple Workspaces Daily | ||
| 470 | - | ||
| 471 | -**Morning:** | ||
| 472 | -```bash | ||
| 473 | -fac # Launch welcome menu | ||
| 474 | -# Select "work-project" from recents | ||
| 475 | -# Continue where you left off yesterday | ||
| 476 | -``` | ||
| 477 | - | ||
| 478 | -**Midday:** | ||
| 479 | -```bash | ||
| 480 | -# Press Ctrl-O | ||
| 481 | -# Navigate to "personal-scripts" | ||
| 482 | -# Press Enter to switch | ||
| 483 | -# work-project saves automatically | ||
| 484 | -``` | ||
| 485 | - | ||
| 486 | -**Evening:** | ||
| 487 | -```bash | ||
| 488 | -# Press Ctrl-O | ||
| 489 | -# Navigate to "learning-rust" | ||
| 490 | -# Press Enter to switch | ||
| 491 | -# All workspaces saved | ||
| 492 | -``` | ||
| 493 | - | ||
| 494 | -**Anytime:** | ||
| 495 | -```bash | ||
| 496 | -fac # Shows all recent workspaces sorted by last-used | ||
| 497 | -# Most recent appears first | ||
| 498 | -``` | ||
| 499 | - | ||
| 500 | ---- | ||
| 501 | - | ||
| 502 | -## 📁 File Locations | ||
| 503 | - | ||
| 504 | -### User Configuration | ||
| 505 | - | ||
| 506 | -``` | ||
| 507 | -~/.config/fac/ | ||
| 508 | - favorites.json - Your favorite workspaces | ||
| 509 | - recents.json - Recently opened workspaces (max 20) | ||
| 510 | -``` | ||
| 511 | - | ||
| 512 | -**Fallback location** (if `~/.config/fac/` doesn't exist): | ||
| 513 | -``` | ||
| 514 | -~/.fac/ | ||
| 515 | - favorites.json | ||
| 516 | - recents.json | ||
| 517 | -``` | ||
| 518 | - | ||
| 519 | -### Workspace Configuration | ||
| 520 | - | ||
| 521 | -``` | ||
| 522 | -<workspace-dir>/.fac/ | ||
| 523 | - workspace.json - Workspace state (tabs, cursors, etc.) | ||
| 524 | - backups/ - Backup files (when you quit without saving) | ||
| 525 | -``` | ||
| 526 | - | ||
| 527 | -### What to Commit to Git | ||
| 528 | - | ||
| 529 | -**Do commit:** | ||
| 530 | -- `.fac/` directory (so team shares workspace setup) | ||
| 531 | -- `workspace.json` (optional, team preference) | ||
| 532 | - | ||
| 533 | -**Don't commit:** | ||
| 534 | -- `.fac/backups/` (personal backup files) | ||
| 535 | - | ||
| 536 | -**Add to .gitignore** (if you prefer personal workspaces): | ||
| 537 | -```gitignore | ||
| 538 | -.fac/ | ||
| 539 | -``` | ||
| 540 | - | ||
| 541 | ---- | ||
| 542 | - | ||
| 543 | -## 🎨 Visual Indicators | ||
| 544 | - | ||
| 545 | -### Tab Bar | ||
| 546 | - | ||
| 547 | -``` | ||
| 548 | -┌─────────────────────────────────────────┐ | ||
| 549 | -│ main.f90 │ module.f90 │ /etc/hosts │ | ||
| 550 | -│ (white) (white) (grey) │ | ||
| 551 | -└─────────────────────────────────────────┘ | ||
| 552 | - ↑ ↑ ↑ | ||
| 553 | - Regular Regular Orphan tab | ||
| 554 | - tab tab (outside workspace) | ||
| 555 | -``` | ||
| 556 | - | ||
| 557 | -### File Tree (FUSS Mode) | ||
| 558 | - | ||
| 559 | -``` | ||
| 560 | -┌─────────────────────────┐ | ||
| 561 | -│ my-project (main) │ ← Git branch | ||
| 562 | -├─────────────────────────┤ | ||
| 563 | -│ [>] src/ │ | ||
| 564 | -│ [M] main.f90 │ ← Modified | ||
| 565 | -│ [A] module.f90 │ ← Staged | ||
| 566 | -│ [ ] utils.f90 │ ← Clean | ||
| 567 | -│ [ ] README.md │ | ||
| 568 | -│ [ ] Makefile │ | ||
| 569 | -└─────────────────────────┘ | ||
| 570 | -``` | ||
| 571 | - | ||
| 572 | -### Status Bar | ||
| 573 | - | ||
| 574 | -``` | ||
| 575 | -┌─────────────────────────────────────────┐ | ||
| 576 | -│ ctrl-b:fuss | main.f90 Ln 42, Col 10 │ | ||
| 577 | -│ ↑ │ | ||
| 578 | -│ Workspace indicator │ | ||
| 579 | -└─────────────────────────────────────────┘ | ||
| 580 | -``` | ||
| 581 | - | ||
| 582 | ---- | ||
| 583 | - | ||
| 584 | -## 💡 Tips & Best Practices | ||
| 585 | - | ||
| 586 | -### Workspace Organization | ||
| 587 | - | ||
| 588 | -**✅ Good:** | ||
| 589 | -- One workspace per project | ||
| 590 | -- Keep related files in workspace directory | ||
| 591 | -- Use descriptive project directory names | ||
| 592 | -- Add active projects to favorites | ||
| 593 | - | ||
| 594 | -**❌ Avoid:** | ||
| 595 | -- Creating workspaces in home directory | ||
| 596 | -- Mixing unrelated projects in one workspace | ||
| 597 | -- Too many orphan tabs (reduces workspace benefits) | ||
| 598 | - | ||
| 599 | -### Performance | ||
| 600 | - | ||
| 601 | -**For large projects:** | ||
| 602 | -- Workspaces with 50+ files work fine | ||
| 603 | -- File tree may be slow with 1000+ files | ||
| 604 | -- Consider excluding build directories from workspace | ||
| 605 | - | ||
| 606 | -**Optimization:** | ||
| 607 | -```bash | ||
| 608 | -# Exclude build artifacts | ||
| 609 | -echo "build/" >> .gitignore | ||
| 610 | -echo "*.o" >> .gitignore | ||
| 611 | - | ||
| 612 | -# fac respects .gitignore in file tree | ||
| 613 | -``` | ||
| 614 | - | ||
| 615 | -### Backup Strategy | ||
| 616 | - | ||
| 617 | -`fac` creates backups automatically when you: | ||
| 618 | -- Quit without saving modified files | ||
| 619 | -- Choose "don't save" at quit prompt | ||
| 620 | - | ||
| 621 | -**Restore backups:** | ||
| 622 | -- Backups in `.fac/backups/` | ||
| 623 | -- Prompts on next workspace open | ||
| 624 | -- Can view diff before restoring | ||
| 625 | - | ||
| 626 | -### Team Collaboration | ||
| 627 | - | ||
| 628 | -**If sharing workspaces:** | ||
| 629 | -```bash | ||
| 630 | -# Commit workspace config | ||
| 631 | -git add .fac/workspace.json | ||
| 632 | -git commit -m "Add fac workspace config" | ||
| 633 | - | ||
| 634 | -# Teammates get same tab layout | ||
| 635 | -``` | ||
| 636 | - | ||
| 637 | -**If keeping personal:** | ||
| 638 | -```bash | ||
| 639 | -# Add to .gitignore | ||
| 640 | -echo ".fac/" >> .gitignore | ||
| 641 | - | ||
| 642 | -# Each person has their own workspace state | ||
| 643 | -``` | ||
| 644 | - | ||
| 645 | ---- | ||
| 646 | - | ||
| 647 | -## 🐛 Troubleshooting | ||
| 648 | - | ||
| 649 | -### "Workspace.json" keeps resetting | ||
| 650 | - | ||
| 651 | -**Cause:** Permissions issue or disk full | ||
| 652 | - | ||
| 653 | -**Solution:** | ||
| 654 | -```bash | ||
| 655 | -# Check permissions | ||
| 656 | -ls -la .fac/ | ||
| 657 | - | ||
| 658 | -# Should be writable by you | ||
| 659 | -chmod -R u+w .fac/ | ||
| 660 | - | ||
| 661 | -# Check disk space | ||
| 662 | -df -h . | ||
| 663 | -``` | ||
| 664 | - | ||
| 665 | -### Tabs don't restore | ||
| 666 | - | ||
| 667 | -**Cause:** Paths changed or files moved | ||
| 668 | - | ||
| 669 | -**Solution:** | ||
| 670 | -- Check warning messages on startup | ||
| 671 | -- Files outside workspace may have moved | ||
| 672 | -- Use `:e <path>` to re-add files | ||
| 673 | -- Check `.fac/workspace.json` for old paths | ||
| 674 | - | ||
| 675 | -### File tree doesn't show git info | ||
| 676 | - | ||
| 677 | -**Cause:** Not a git repository | ||
| 678 | - | ||
| 679 | -**Solution:** | ||
| 680 | -```bash | ||
| 681 | -# Initialize git if needed | ||
| 682 | -git init | ||
| 683 | - | ||
| 684 | -# Or just use file tree without git features | ||
| 685 | -# It still shows files, just no status indicators | ||
| 686 | -``` | ||
| 687 | - | ||
| 688 | -### Welcome menu shows old workspaces | ||
| 689 | - | ||
| 690 | -**Cause:** Directories were moved/deleted | ||
| 691 | - | ||
| 692 | -**Solution:** | ||
| 693 | -- Try to open them (will auto-remove if gone) | ||
| 694 | -- Or manually edit `~/.config/fac/recents.json` | ||
| 695 | - | ||
| 696 | -### Workspace switch seems slow | ||
| 697 | - | ||
| 698 | -**Cause:** Many tabs or large files | ||
| 699 | - | ||
| 700 | -**Solution:** | ||
| 701 | -- Normal for first load after switch | ||
| 702 | -- Subsequent switches are cached | ||
| 703 | -- Close unused tabs to speed up | ||
| 704 | - | ||
| 705 | ---- | ||
| 706 | - | ||
| 707 | -## 🆘 Getting Help | ||
| 708 | - | ||
| 709 | -### In-Editor Help | ||
| 710 | - | ||
| 711 | -``` | ||
| 712 | -Ctrl-/ - Show help menu with keybindings | ||
| 713 | -``` | ||
| 714 | - | ||
| 715 | -### Configuration Files | ||
| 716 | - | ||
| 717 | -``` | ||
| 718 | -~/.config/fac/favorites.json - Edit favorites manually | ||
| 719 | -~/.config/fac/recents.json - View/edit recent workspaces | ||
| 720 | -<workspace>/.fac/workspace.json - Workspace state (advanced) | ||
| 721 | -``` | ||
| 722 | - | ||
| 723 | -### Resetting Everything | ||
| 724 | - | ||
| 725 | -**If things get weird:** | ||
| 726 | -```bash | ||
| 727 | -# Backup first! | ||
| 728 | -cp -r ~/.config/fac ~/.config/fac.backup | ||
| 729 | - | ||
| 730 | -# Remove config | ||
| 731 | -rm -rf ~/.config/fac | ||
| 732 | - | ||
| 733 | -# Workspaces remain, but favorites/recents reset | ||
| 734 | -# Workspace state in .fac/ is preserved | ||
| 735 | -``` | ||
| 736 | - | ||
| 737 | -**If a specific workspace is broken:** | ||
| 738 | -```bash | ||
| 739 | -cd /path/to/workspace | ||
| 740 | - | ||
| 741 | -# Backup | ||
| 742 | -cp -r .fac .fac.backup | ||
| 743 | - | ||
| 744 | -# Remove workspace state | ||
| 745 | -rm -rf .fac | ||
| 746 | - | ||
| 747 | -# Next open will create fresh workspace | ||
| 748 | -fac . | ||
| 749 | -``` | ||
| 750 | - | ||
| 751 | ---- | ||
| 752 | - | ||
| 753 | -## 🎓 Advanced Topics | ||
| 754 | - | ||
| 755 | -### Workspace Path Resolution | ||
| 756 | - | ||
| 757 | -`fac` uses absolute paths internally: | ||
| 758 | -```bash | ||
| 759 | -fac . → /home/user/project | ||
| 760 | -fac .. → /home/user | ||
| 761 | -fac ~/code/app → /home/user/code/app | ||
| 762 | -``` | ||
| 763 | - | ||
| 764 | -Relative paths in `workspace.json` are relative to workspace root: | ||
| 765 | -```json | ||
| 766 | -{ | ||
| 767 | - "filename": "src/main.f90" | ||
| 768 | - // Resolves to: /workspace-root/src/main.f90 | ||
| 769 | -} | ||
| 770 | -``` | ||
| 771 | - | ||
| 772 | -### Multiple Panes (Advanced) | ||
| 773 | - | ||
| 774 | -When you split windows (future feature): | ||
| 775 | -- Each pane saved with coordinates | ||
| 776 | -- Cursor position per pane | ||
| 777 | -- All panes restore on workspace load | ||
| 778 | - | ||
| 779 | -### Workspace JSON Schema | ||
| 780 | - | ||
| 781 | -```json | ||
| 782 | -{ | ||
| 783 | - "version": "1.0", | ||
| 784 | - "workspace_path": "/absolute/path/to/workspace", | ||
| 785 | - "last_opened": "2025-01-05T10:30:00Z", | ||
| 786 | - "tabs": [ | ||
| 787 | - { | ||
| 788 | - "filename": "relative/or/absolute/path.f90", | ||
| 789 | - "is_orphan": false, | ||
| 790 | - "modified": false, | ||
| 791 | - "panes": [ | ||
| 792 | - { | ||
| 793 | - "x_start": 0.0, | ||
| 794 | - "y_start": 0.0, | ||
| 795 | - "x_end": 1.0, | ||
| 796 | - "y_end": 1.0, | ||
| 797 | - "filename": "path.f90", | ||
| 798 | - "cursor_line": 42, | ||
| 799 | - "cursor_column": 10, | ||
| 800 | - "viewport_line": 30, | ||
| 801 | - "viewport_column": 1 | ||
| 802 | - } | ||
| 803 | - ], | ||
| 804 | - "active_pane": 1 | ||
| 805 | - } | ||
| 806 | - ], | ||
| 807 | - "active_tab": 1, | ||
| 808 | - "fuss_mode": { | ||
| 809 | - "active": true, | ||
| 810 | - "width": 30 | ||
| 811 | - } | ||
| 812 | -} | ||
| 813 | -``` | ||
| 814 | - | ||
| 815 | ---- | ||
| 816 | - | ||
| 817 | -## 🚀 Quick Reference Card | ||
| 818 | - | ||
| 819 | -``` | ||
| 820 | -╔══════════════════════════════════════════════════════════════╗ | ||
| 821 | -║ FAC WORKSPACE MODE ║ | ||
| 822 | -║ Quick Reference ║ | ||
| 823 | -╚══════════════════════════════════════════════════════════════╝ | ||
| 824 | - | ||
| 825 | -OPEN WORKSPACE: | ||
| 826 | - fac . Current directory | ||
| 827 | - fac /path/to/workspace Specific directory | ||
| 828 | - fac Welcome menu | ||
| 829 | - | ||
| 830 | -NAVIGATION: | ||
| 831 | - Ctrl-O Fortress Navigator | ||
| 832 | - Ctrl-B Toggle file tree | ||
| 833 | - Ctrl-N / Ctrl-P Next/previous tab | ||
| 834 | - | ||
| 835 | -FAVORITES: | ||
| 836 | - Ctrl-O, navigate, 'f' Add to favorites | ||
| 837 | - fac, press '8' View favorites | ||
| 838 | - | ||
| 839 | -SWITCHING: | ||
| 840 | - Ctrl-O, select dir, Enter Switch workspace | ||
| 841 | - | ||
| 842 | -FILE TREE: | ||
| 843 | - Ctrl-B Toggle | ||
| 844 | - ↑↓ or kj Navigate | ||
| 845 | - → Enter Open file | ||
| 846 | - g / u Stage/unstage (git) | ||
| 847 | - | ||
| 848 | -SAVE & QUIT: | ||
| 849 | - :w Save file | ||
| 850 | - :q Quit (saves workspace) | ||
| 851 | - | ||
| 852 | -ORPHAN TABS: | ||
| 853 | - Ctrl-O, navigate outside Open external file | ||
| 854 | - (shows in grey) Visual indicator | ||
| 855 | - | ||
| 856 | -ERROR RECOVERY: | ||
| 857 | - Automatic! Missing files handled | ||
| 858 | - No manual steps Corrupted JSON recovered | ||
| 859 | - Self-cleaning Deleted workspaces removed | ||
| 860 | -``` | ||
| 861 | - | ||
| 862 | ---- | ||
| 863 | - | ||
| 864 | -## 📚 See Also | ||
| 865 | - | ||
| 866 | -- `PHASE7_COMPLETE.md` - Implementation details | ||
| 867 | -- `WORKSPACE_ROADMAP.md` - Original design document | ||
| 868 | -- `README.md` - Main fac documentation | ||
| 869 | -- `:help` in fac - Built-in help | ||
| 870 | - | ||
| 871 | ---- | ||
| 872 | - | ||
| 873 | -**Enjoy your new workspace powers!** 🎉 | ||
| 874 | - | ||
| 875 | -*Happy coding with fac!* 🚀 | ||
WORKSPACE_ROADMAP.mddeleted@@ -1,595 +0,0 @@ | |||
| 1 | -# Workspace Mode Implementation Roadmap | ||
| 2 | - | ||
| 3 | -**Vision**: Transform fac into a workspace-aware editor with persistent state and Fortress-based navigation. | ||
| 4 | - | ||
| 5 | -**Timeline**: 7 phases, estimated 15-20 sessions total | ||
| 6 | - | ||
| 7 | ---- | ||
| 8 | - | ||
| 9 | -## Phase 0: Planning & Design | ||
| 10 | -**Duration**: 1 session | ||
| 11 | -**Objective**: Document architecture and create foundational specs | ||
| 12 | - | ||
| 13 | -### Tasks | ||
| 14 | -- [x] Define workspace data structures | ||
| 15 | -- [ ] Design `.fac/` directory structure | ||
| 16 | -- [ ] Design `~/.config/fac/` structure | ||
| 17 | -- [ ] Create workspace.json schema | ||
| 18 | -- [ ] Create favorites.json schema | ||
| 19 | -- [ ] Document Fortress integration points | ||
| 20 | -- [ ] Plan module dependencies | ||
| 21 | - | ||
| 22 | -### Deliverables | ||
| 23 | -``` | ||
| 24 | -docs/ | ||
| 25 | - workspace_spec.md # Workspace JSON format | ||
| 26 | - fortress_integration.md # How fortress modules integrate | ||
| 27 | - config_spec.md # Config file formats | ||
| 28 | -``` | ||
| 29 | - | ||
| 30 | -### Files to Create | ||
| 31 | -- `docs/workspace_spec.md` | ||
| 32 | -- `docs/fortress_integration.md` | ||
| 33 | -- `docs/config_spec.md` | ||
| 34 | - | ||
| 35 | -### Success Criteria | ||
| 36 | -- ✅ Clear data structure specifications | ||
| 37 | -- ✅ Agreed-upon file formats | ||
| 38 | -- ✅ Module integration plan documented | ||
| 39 | - | ||
| 40 | ---- | ||
| 41 | - | ||
| 42 | -## Phase 1: Fortress Navigator Foundation | ||
| 43 | -**Duration**: 3-4 sessions | ||
| 44 | -**Objective**: Build basic dual-pane file/directory navigator (Ctrl-O) | ||
| 45 | - | ||
| 46 | -### Tasks | ||
| 47 | -- [ ] Copy fortress filesystem modules into fac | ||
| 48 | - - `src/fortress/filesystem/` (directory reading, path handling) | ||
| 49 | -- [ ] Copy fortress terminal modules | ||
| 50 | - - `src/fortress/terminal/` (rendering utilities) | ||
| 51 | -- [ ] Adapt fortress UI for embedded mode | ||
| 52 | - - `src/fortress/ui/` (dual-pane display, navigation) | ||
| 53 | -- [ ] Implement dual-pane rendering | ||
| 54 | - - Left pane: parent directory (30%) | ||
| 55 | - - Right pane: current directory (70%) | ||
| 56 | -- [ ] Add navigation keybindings | ||
| 57 | - - ↑/↓: Move cursor | ||
| 58 | - - →: Enter directory | ||
| 59 | - - ←: Go to parent | ||
| 60 | - - ~/: Jump to home/root | ||
| 61 | - - q: Cancel/exit | ||
| 62 | - - Enter: Select (return selection) | ||
| 63 | -- [ ] Add Ctrl-O keybinding to main editor | ||
| 64 | -- [ ] Modal Fortress UI (takes over screen, returns selection) | ||
| 65 | - | ||
| 66 | -### Files to Create | ||
| 67 | -``` | ||
| 68 | -src/fortress/ | ||
| 69 | - filesystem/ | ||
| 70 | - directory_module.f90 # Read dirs, list files | ||
| 71 | - path_utils_module.f90 # Path manipulation | ||
| 72 | - terminal/ | ||
| 73 | - fortress_render_module.f90 # Rendering utilities | ||
| 74 | - ui/ | ||
| 75 | - dual_pane_module.f90 # Dual-pane display | ||
| 76 | - navigator_module.f90 # Main navigation logic | ||
| 77 | -``` | ||
| 78 | - | ||
| 79 | -### Files to Modify | ||
| 80 | -- `src/commands/command_handler_module.f90` (add Ctrl-O handler) | ||
| 81 | -- `Makefile` (add fortress modules to build) | ||
| 82 | - | ||
| 83 | -### Success Criteria | ||
| 84 | -- ✅ Ctrl-O opens dual-pane navigator | ||
| 85 | -- ✅ Can navigate filesystem | ||
| 86 | -- ✅ Selecting directory returns path | ||
| 87 | -- ✅ Selecting file returns path | ||
| 88 | -- ✅ ESC/q cancels and returns to editor | ||
| 89 | -- ✅ Visual styling matches fac aesthetic | ||
| 90 | - | ||
| 91 | -### Testing Checkpoints | ||
| 92 | -- Navigate to various directories | ||
| 93 | -- Test with long file lists (scrolling) | ||
| 94 | -- Test with deep directory trees | ||
| 95 | -- Test cancellation (ESC) | ||
| 96 | - | ||
| 97 | ---- | ||
| 98 | - | ||
| 99 | -## Phase 2: Workspace Detection & Configuration | ||
| 100 | -**Duration**: 2-3 sessions | ||
| 101 | -**Objective**: Detect workspace directories, create/load workspace configs | ||
| 102 | - | ||
| 103 | -### Tasks | ||
| 104 | -- [ ] Create workspace detection logic | ||
| 105 | - - Check for `.fac/workspace.json` in directory | ||
| 106 | - - Hash path for config file lookup | ||
| 107 | -- [ ] Implement workspace config directory structure | ||
| 108 | - ``` | ||
| 109 | - ~/.config/fac/ | ||
| 110 | - favorites.json | ||
| 111 | - recents.json | ||
| 112 | - .fac/ # In workspace root | ||
| 113 | - workspace.json | ||
| 114 | - backups/ | ||
| 115 | - ``` | ||
| 116 | -- [ ] Create workspace module | ||
| 117 | - - `workspace_init()` - detect or create workspace | ||
| 118 | - - `workspace_load()` - load workspace.json | ||
| 119 | - - `workspace_save()` - save current state | ||
| 120 | - - `workspace_exists()` - check if path has workspace | ||
| 121 | -- [ ] Command line argument parsing | ||
| 122 | - - `fac` (no args) → open Fortress welcome menu | ||
| 123 | - - `fac .` → load/create workspace for cwd | ||
| 124 | - - `fac /path/to/dir` → load/create workspace | ||
| 125 | - - `fac file.txt` → check parent for workspace, else single-file mode | ||
| 126 | -- [ ] Create empty workspace with default state | ||
| 127 | -- [ ] Basic save/load (no tabs/panes yet, just metadata) | ||
| 128 | - | ||
| 129 | -### Files to Create | ||
| 130 | -``` | ||
| 131 | -src/workspace/ | ||
| 132 | - workspace_module.f90 # Core workspace logic | ||
| 133 | - workspace_config_module.f90 # JSON serialization | ||
| 134 | - workspace_detection_module.f90 # Path checking | ||
| 135 | -``` | ||
| 136 | - | ||
| 137 | -### Files to Modify | ||
| 138 | -- `app/main.f90` (parse args, detect workspace mode) | ||
| 139 | -- `src/editor_state_module.f90` (add workspace_path field) | ||
| 140 | - | ||
| 141 | -### Success Criteria | ||
| 142 | -- ✅ `fac .` creates `.fac/workspace.json` | ||
| 143 | -- ✅ `fac /existing/workspace` loads existing config | ||
| 144 | -- ✅ `fac file.txt` works as before (single-file mode) | ||
| 145 | -- ✅ `fac` (no args) opens Fortress welcome (placeholder for now) | ||
| 146 | -- ✅ Workspace state persists across runs | ||
| 147 | - | ||
| 148 | -### Testing Checkpoints | ||
| 149 | -- Create workspace in empty directory | ||
| 150 | -- Load existing workspace | ||
| 151 | -- Verify single-file mode unchanged | ||
| 152 | -- Check `.fac/` directory creation | ||
| 153 | - | ||
| 154 | ---- | ||
| 155 | - | ||
| 156 | -## Phase 3: State Serialization (Tabs & Panes) | ||
| 157 | -**Duration**: 3-4 sessions | ||
| 158 | -**Objective**: Persist and restore all editor state | ||
| 159 | - | ||
| 160 | -### Tasks | ||
| 161 | -- [ ] Design workspace.json schema | ||
| 162 | - ```json | ||
| 163 | - { | ||
| 164 | - "version": "1.0", | ||
| 165 | - "workspace_path": "/home/user/project", | ||
| 166 | - "last_opened": "2025-01-05T10:30:00Z", | ||
| 167 | - "tabs": [ | ||
| 168 | - { | ||
| 169 | - "label": "main.f90", | ||
| 170 | - "panes": [ | ||
| 171 | - { | ||
| 172 | - "file": "src/main.f90", | ||
| 173 | - "cursor": {"line": 42, "col": 10}, | ||
| 174 | - "viewport": {"line": 30, "col": 1}, | ||
| 175 | - "modified": false | ||
| 176 | - } | ||
| 177 | - ], | ||
| 178 | - "split_type": "none|vertical|horizontal", | ||
| 179 | - "active_pane": 0 | ||
| 180 | - } | ||
| 181 | - ], | ||
| 182 | - "orphan_tabs": [ | ||
| 183 | - { | ||
| 184 | - "file": "/etc/hosts", | ||
| 185 | - "cursor": {"line": 1, "col": 1}, | ||
| 186 | - "viewport": {"line": 1, "col": 1} | ||
| 187 | - } | ||
| 188 | - ], | ||
| 189 | - "active_tab": 0, | ||
| 190 | - "fuss_mode": { | ||
| 191 | - "active": true, | ||
| 192 | - "width": 30 | ||
| 193 | - } | ||
| 194 | - } | ||
| 195 | - ``` | ||
| 196 | -- [ ] Implement tab serialization | ||
| 197 | - - Serialize tab list, labels, active index | ||
| 198 | -- [ ] Implement pane serialization | ||
| 199 | - - Serialize pane splits, layout, active pane | ||
| 200 | -- [ ] Implement cursor/viewport serialization | ||
| 201 | - - Save position per file | ||
| 202 | -- [ ] Implement deserialization (reverse of above) | ||
| 203 | -- [ ] Add orphan tab tracking | ||
| 204 | - - Mark tabs as orphan vs workspace | ||
| 205 | - - Different color in tab bar (greyish) | ||
| 206 | -- [ ] Call save on quit | ||
| 207 | -- [ ] Call load on workspace open | ||
| 208 | -- [ ] Handle relative vs absolute paths | ||
| 209 | - - Store workspace files as relative paths | ||
| 210 | - - Store orphan files as absolute paths | ||
| 211 | - | ||
| 212 | -### Files to Create | ||
| 213 | -``` | ||
| 214 | -src/workspace/ | ||
| 215 | - tab_serializer_module.f90 # Tab state save/load | ||
| 216 | - pane_serializer_module.f90 # Pane state save/load | ||
| 217 | -``` | ||
| 218 | - | ||
| 219 | -### Files to Modify | ||
| 220 | -- `src/workspace/workspace_module.f90` (save/load implementation) | ||
| 221 | -- `src/editor_state_module.f90` (add orphan flag to tabs) | ||
| 222 | -- `src/terminal/renderer_module.f90` (orphan tab color) | ||
| 223 | -- `app/main.f90` (call save on quit, load on open) | ||
| 224 | - | ||
| 225 | -### Success Criteria | ||
| 226 | -- ✅ Quit fac with 3 tabs → reopen → 3 tabs restored | ||
| 227 | -- ✅ Split panes → quit → reopen → splits preserved | ||
| 228 | -- ✅ Cursor at line 50 → quit → reopen → cursor at line 50 | ||
| 229 | -- ✅ Orphan tabs show in different color | ||
| 230 | -- ✅ Workspace files use relative paths | ||
| 231 | -- ✅ Orphan files use absolute paths | ||
| 232 | - | ||
| 233 | -### Testing Checkpoints | ||
| 234 | -- Create complex workspace (multiple tabs, splits) | ||
| 235 | -- Edit files, move cursors | ||
| 236 | -- Quit and reopen | ||
| 237 | -- Verify exact state restoration | ||
| 238 | -- Test orphan tab creation via Fortress | ||
| 239 | - | ||
| 240 | ---- | ||
| 241 | - | ||
| 242 | -## Phase 4: Backup System | ||
| 243 | -**Duration**: 2 sessions | ||
| 244 | -**Objective**: Auto-backup dirty buffers, restore with diff option | ||
| 245 | - | ||
| 246 | -### Tasks | ||
| 247 | -- [ ] Create backup directory structure | ||
| 248 | - ``` | ||
| 249 | - .fac/ | ||
| 250 | - backups/ | ||
| 251 | - main.f90.bak | ||
| 252 | - test.f90.bak | ||
| 253 | - .backup-metadata.json | ||
| 254 | - ``` | ||
| 255 | -- [ ] Implement backup on quit | ||
| 256 | - - Detect modified buffers | ||
| 257 | - - Prompt per file: "Save main.f90? [y/n/c]" | ||
| 258 | - - If 'n', create backup file | ||
| 259 | - - Write backup with timestamp in metadata | ||
| 260 | -- [ ] Implement backup detection on open | ||
| 261 | - - Check for backup files in `.fac/backups/` | ||
| 262 | - - Compare timestamps (backup vs disk file) | ||
| 263 | -- [ ] Implement restore prompt | ||
| 264 | - - For each backup: "[r]estore / [i]gnore / [d]iff?" | ||
| 265 | - - 'd' shows diff (use system diff or built-in) | ||
| 266 | -- [ ] Implement diff viewer | ||
| 267 | - - Simple side-by-side or unified diff | ||
| 268 | - - Or shell out to `diff` command | ||
| 269 | -- [ ] Backup cleanup | ||
| 270 | - - Delete backup after successful restore | ||
| 271 | - - Or keep for N days (config option) | ||
| 272 | - | ||
| 273 | -### Files to Create | ||
| 274 | -``` | ||
| 275 | -src/workspace/ | ||
| 276 | - backup_module.f90 # Backup creation/restoration | ||
| 277 | - diff_viewer_module.f90 # Simple diff display (optional) | ||
| 278 | -``` | ||
| 279 | - | ||
| 280 | -### Files to Modify | ||
| 281 | -- `src/workspace/workspace_module.f90` (backup on quit/load) | ||
| 282 | -- `app/main.f90` (call backup logic) | ||
| 283 | - | ||
| 284 | -### Success Criteria | ||
| 285 | -- ✅ Quit with unsaved file → prompted to save | ||
| 286 | -- ✅ Choose 'n' → backup created | ||
| 287 | -- ✅ Reopen workspace → prompted to restore backup | ||
| 288 | -- ✅ 'd' shows diff between backup and disk | ||
| 289 | -- ✅ 'r' restores backup | ||
| 290 | -- ✅ 'i' ignores backup | ||
| 291 | -- ✅ Metadata tracks backup timestamps | ||
| 292 | - | ||
| 293 | -### Testing Checkpoints | ||
| 294 | -- Edit file, don't save, quit | ||
| 295 | -- Verify backup created | ||
| 296 | -- Modify file on disk (external editor) | ||
| 297 | -- Reopen workspace | ||
| 298 | -- Verify diff shows both changes | ||
| 299 | -- Test restore, test ignore | ||
| 300 | - | ||
| 301 | ---- | ||
| 302 | - | ||
| 303 | -## Phase 5: Favorites & Recents | ||
| 304 | -**Duration**: 2 sessions | ||
| 305 | -**Objective**: Track favorite/recent workspaces, Fortress welcome menu | ||
| 306 | - | ||
| 307 | -### Tasks | ||
| 308 | -- [ ] Create favorites system | ||
| 309 | - ``` | ||
| 310 | - ~/.config/fac/ | ||
| 311 | - favorites.json | ||
| 312 | - { | ||
| 313 | - "favorites": [ | ||
| 314 | - {"path": "/home/user/project", "label": "My Project"}, | ||
| 315 | - {"path": "/home/user/scripts", "label": "Scripts"} | ||
| 316 | - ] | ||
| 317 | - } | ||
| 318 | - ``` | ||
| 319 | -- [ ] Create recents system | ||
| 320 | - ``` | ||
| 321 | - ~/.config/fac/ | ||
| 322 | - recents.json | ||
| 323 | - { | ||
| 324 | - "recents": [ | ||
| 325 | - {"path": "/home/user/project", "last_opened": "2025-01-05T10:30:00Z"}, | ||
| 326 | - {"path": "/home/user/other", "last_opened": "2025-01-04T09:15:00Z"} | ||
| 327 | - ] | ||
| 328 | - } | ||
| 329 | - ``` | ||
| 330 | -- [ ] Update recents on workspace open | ||
| 331 | - - Add current workspace to recents | ||
| 332 | - - Keep most recent 10-20 entries | ||
| 333 | -- [ ] Implement Fortress welcome menu | ||
| 334 | - - Press '8' to toggle between favorites/recents view | ||
| 335 | - - Two separate panes/dialogs | ||
| 336 | - - Favorites pane: list favorites, keybind to add/remove ('f') | ||
| 337 | - - Recents pane: list by most recent first | ||
| 338 | - - Navigate with ↑/↓, Enter to select | ||
| 339 | -- [ ] Implement `fac` (no args) behavior | ||
| 340 | - - Launch Fortress welcome menu | ||
| 341 | - - Select favorite/recent → load workspace | ||
| 342 | - - Or navigate filesystem to find new workspace | ||
| 343 | -- [ ] Add keybind in Fortress to add current dir to favorites ('f') | ||
| 344 | -- [ ] Add keybind to remove favorite ('r' or 'x') | ||
| 345 | - | ||
| 346 | -### Files to Create | ||
| 347 | -``` | ||
| 348 | -src/workspace/ | ||
| 349 | - favorites_module.f90 # Manage favorites | ||
| 350 | - recents_module.f90 # Manage recents | ||
| 351 | -src/fortress/ui/ | ||
| 352 | - welcome_menu_module.f90 # Favorites/recents display | ||
| 353 | -``` | ||
| 354 | - | ||
| 355 | -### Files to Modify | ||
| 356 | -- `src/fortress/ui/navigator_module.f90` (add '8' toggle, 'f' favorite) | ||
| 357 | -- `src/workspace/workspace_module.f90` (update recents on open) | ||
| 358 | -- `app/main.f90` (no args → welcome menu) | ||
| 359 | - | ||
| 360 | -### Success Criteria | ||
| 361 | -- ✅ `fac` opens welcome menu with favorites/recents | ||
| 362 | -- ✅ Press '8' toggles between favorites and recents views | ||
| 363 | -- ✅ Selecting from list opens that workspace | ||
| 364 | -- ✅ 'f' in Fortress adds directory to favorites | ||
| 365 | -- ✅ Recents automatically updated on workspace open | ||
| 366 | -- ✅ Most recent workspaces appear first | ||
| 367 | - | ||
| 368 | -### Testing Checkpoints | ||
| 369 | -- Run `fac` with no args | ||
| 370 | -- Verify favorites/recents display | ||
| 371 | -- Add favorite, verify persists | ||
| 372 | -- Open workspace, verify appears in recents | ||
| 373 | -- Toggle between views with '8' | ||
| 374 | - | ||
| 375 | ---- | ||
| 376 | - | ||
| 377 | -## Phase 6: Workspace Switching & Integration | ||
| 378 | -**Duration**: 2-3 sessions | ||
| 379 | -**Objective**: Connect all pieces, handle workspace switching | ||
| 380 | - | ||
| 381 | -### Tasks | ||
| 382 | -- [ ] Implement workspace switching flow | ||
| 383 | - - Ctrl-O in workspace → Fortress navigator | ||
| 384 | - - Select directory → save current workspace | ||
| 385 | - - Load new workspace (or create if new) | ||
| 386 | - - Restore tabs/panes/state | ||
| 387 | -- [ ] Handle orphan tab creation | ||
| 388 | - - Fortress select file → open in new tab | ||
| 389 | - - Mark tab as orphan | ||
| 390 | - - Style with grey/subtle color | ||
| 391 | - - Don't persist orphan tabs in workspace.json | ||
| 392 | - - OR persist in separate "orphan_tabs" array (decided in Phase 3) | ||
| 393 | -- [ ] Implement save prompts on switch | ||
| 394 | - - Before switching workspace | ||
| 395 | - - For each dirty buffer: "Save file? [y/n/c]" | ||
| 396 | - - 'c' cancels workspace switch | ||
| 397 | -- [ ] Handle edge cases | ||
| 398 | - - Missing files in workspace.json | ||
| 399 | - - Show warning: "File not found: src/missing.f90" | ||
| 400 | - - Skip that tab, continue loading others | ||
| 401 | - - Deleted workspace directory | ||
| 402 | - - Detect and remove from recents | ||
| 403 | - - Corrupted workspace.json | ||
| 404 | - - Fallback to empty workspace | ||
| 405 | - - Log error | ||
| 406 | -- [ ] Update file tree (Ctrl-B) for workspace mode | ||
| 407 | - - Show workspace root (not parent of first file) | ||
| 408 | - - Update tree when switching workspaces | ||
| 409 | - | ||
| 410 | -### Files to Modify | ||
| 411 | -- `src/fortress/ui/navigator_module.f90` (return file vs dir) | ||
| 412 | -- `src/workspace/workspace_module.f90` (switch logic) | ||
| 413 | -- `src/commands/command_handler_module.f90` (Ctrl-O handler) | ||
| 414 | -- `src/workspace/file_tree_module.f90` (workspace root) | ||
| 415 | -- `app/main.f90` (orchestrate switching) | ||
| 416 | - | ||
| 417 | -### Success Criteria | ||
| 418 | -- ✅ Ctrl-O from workspace opens Fortress | ||
| 419 | -- ✅ Selecting new directory switches workspace | ||
| 420 | -- ✅ Current workspace saved before switch | ||
| 421 | -- ✅ New workspace loaded with all state | ||
| 422 | -- ✅ Dirty buffers prompt to save before switch | ||
| 423 | -- ✅ Orphan tabs work correctly | ||
| 424 | -- ✅ Missing files handled gracefully | ||
| 425 | -- ✅ File tree shows workspace root | ||
| 426 | - | ||
| 427 | -### Testing Checkpoints | ||
| 428 | -- Create two workspaces with different files | ||
| 429 | -- Switch between them via Fortress | ||
| 430 | -- Verify state saves/loads correctly | ||
| 431 | -- Test with dirty buffers | ||
| 432 | -- Test missing file handling | ||
| 433 | - | ||
| 434 | ---- | ||
| 435 | - | ||
| 436 | -## Phase 7: Polish, Testing & Documentation | ||
| 437 | -**Duration**: 2 sessions | ||
| 438 | -**Objective**: Bug fixes, edge cases, user testing | ||
| 439 | - | ||
| 440 | -### Tasks | ||
| 441 | -- [ ] Performance optimization | ||
| 442 | - - Large workspaces (100+ files) | ||
| 443 | - - Deep directory trees in Fortress | ||
| 444 | -- [ ] Visual polish | ||
| 445 | - - Orphan tab color (grey/subtle) | ||
| 446 | - - Fortress UI styling | ||
| 447 | - - Welcome menu appearance | ||
| 448 | -- [ ] Error handling | ||
| 449 | - - Permissions errors | ||
| 450 | - - Disk full | ||
| 451 | - - Invalid JSON | ||
| 452 | -- [ ] Edge case testing | ||
| 453 | - - Symlinks in workspace | ||
| 454 | - - Very long file paths | ||
| 455 | - - Unicode in filenames/paths | ||
| 456 | - - Binary files in backups | ||
| 457 | -- [ ] Documentation | ||
| 458 | - - Update README.md | ||
| 459 | - - Update --help output | ||
| 460 | - - Create WORKSPACE.md guide | ||
| 461 | - - Add examples | ||
| 462 | -- [ ] User testing | ||
| 463 | - - Real-world projects | ||
| 464 | - - Multiple sessions | ||
| 465 | - - Collect feedback | ||
| 466 | -- [ ] Fix any cursor/rendering bugs that emerge | ||
| 467 | -- [ ] Remove debug logging | ||
| 468 | - | ||
| 469 | -### Files to Create | ||
| 470 | -- `WORKSPACE.md` (user guide) | ||
| 471 | - | ||
| 472 | -### Files to Modify | ||
| 473 | -- `README.md` (document workspace features) | ||
| 474 | -- `app/main.f90` (update --help) | ||
| 475 | - | ||
| 476 | -### Success Criteria | ||
| 477 | -- ✅ All features working smoothly | ||
| 478 | -- ✅ No regressions in existing features | ||
| 479 | -- ✅ Performance acceptable on large projects | ||
| 480 | -- ✅ Documentation complete | ||
| 481 | -- ✅ Ready for release | ||
| 482 | - | ||
| 483 | -### Testing Checkpoints | ||
| 484 | -- Test with Linux kernel source (large workspace) | ||
| 485 | -- Test with multiple nested directories | ||
| 486 | -- Test workspace switching under load | ||
| 487 | -- Test all edge cases | ||
| 488 | -- User acceptance testing | ||
| 489 | - | ||
| 490 | ---- | ||
| 491 | - | ||
| 492 | -## Module Dependency Graph | ||
| 493 | - | ||
| 494 | -``` | ||
| 495 | -app/main.f90 | ||
| 496 | - ├── workspace_module.f90 | ||
| 497 | - │ ├── workspace_config_module.f90 | ||
| 498 | - │ ├── workspace_detection_module.f90 | ||
| 499 | - │ ├── tab_serializer_module.f90 | ||
| 500 | - │ ├── pane_serializer_module.f90 | ||
| 501 | - │ ├── backup_module.f90 | ||
| 502 | - │ ├── favorites_module.f90 | ||
| 503 | - │ └── recents_module.f90 | ||
| 504 | - │ | ||
| 505 | - └── fortress/ | ||
| 506 | - ├── filesystem/ | ||
| 507 | - │ ├── directory_module.f90 | ||
| 508 | - │ └── path_utils_module.f90 | ||
| 509 | - ├── terminal/ | ||
| 510 | - │ └── fortress_render_module.f90 | ||
| 511 | - └── ui/ | ||
| 512 | - ├── dual_pane_module.f90 | ||
| 513 | - ├── navigator_module.f90 | ||
| 514 | - └── welcome_menu_module.f90 | ||
| 515 | -``` | ||
| 516 | - | ||
| 517 | ---- | ||
| 518 | - | ||
| 519 | -## Risk Mitigation | ||
| 520 | - | ||
| 521 | -### Cursor/Rendering Bugs | ||
| 522 | -**Risk**: New pane/tab logic breaks cursor positioning | ||
| 523 | -**Mitigation**: | ||
| 524 | -- Test after each phase | ||
| 525 | -- Keep parity tests from current build | ||
| 526 | -- Incremental changes, test often | ||
| 527 | - | ||
| 528 | -### State Corruption | ||
| 529 | -**Risk**: Corrupted workspace.json breaks workspace | ||
| 530 | -**Mitigation**: | ||
| 531 | -- JSON validation on load | ||
| 532 | -- Fallback to empty workspace | ||
| 533 | -- Keep backup of last-good workspace.json | ||
| 534 | - | ||
| 535 | -### Performance | ||
| 536 | -**Risk**: Large workspaces slow down editor | ||
| 537 | -**Mitigation**: | ||
| 538 | -- Lazy load tabs (don't load all buffers at once) | ||
| 539 | -- Profile and optimize | ||
| 540 | -- Set reasonable limits (e.g., max 50 tabs) | ||
| 541 | - | ||
| 542 | -### Backwards Compatibility | ||
| 543 | -**Risk**: Breaking existing fac usage | ||
| 544 | -**Mitigation**: | ||
| 545 | -- Single-file mode must work unchanged | ||
| 546 | -- Feature flags during development | ||
| 547 | -- Extensive testing of non-workspace mode | ||
| 548 | - | ||
| 549 | ---- | ||
| 550 | - | ||
| 551 | -## Success Metrics | ||
| 552 | - | ||
| 553 | -**Phase Completion:** | ||
| 554 | -- All tasks in phase completed | ||
| 555 | -- Success criteria met | ||
| 556 | -- Tests passing | ||
| 557 | -- No regressions | ||
| 558 | - | ||
| 559 | -**Overall Success:** | ||
| 560 | -- `fac` launches welcome menu | ||
| 561 | -- `fac .` creates/loads workspace | ||
| 562 | -- Ctrl-O navigates to workspaces/files | ||
| 563 | -- Tabs/panes/cursors persist across sessions | ||
| 564 | -- Orphan tabs work as expected | ||
| 565 | -- Favorites/recents work | ||
| 566 | -- Backups restore correctly | ||
| 567 | -- Documentation complete | ||
| 568 | -- No bugs in existing features | ||
| 569 | - | ||
| 570 | ---- | ||
| 571 | - | ||
| 572 | -## Timeline Estimate | ||
| 573 | - | ||
| 574 | -- **Phase 0**: 1 session (4-6 hours) | ||
| 575 | -- **Phase 1**: 3-4 sessions (12-16 hours) | ||
| 576 | -- **Phase 2**: 2-3 sessions (8-12 hours) | ||
| 577 | -- **Phase 3**: 3-4 sessions (12-16 hours) | ||
| 578 | -- **Phase 4**: 2 sessions (8-10 hours) | ||
| 579 | -- **Phase 5**: 2 sessions (8-10 hours) | ||
| 580 | -- **Phase 6**: 2-3 sessions (8-12 hours) | ||
| 581 | -- **Phase 7**: 2 sessions (8-10 hours) | ||
| 582 | - | ||
| 583 | -**Total**: ~15-20 sessions (~60-80 hours) | ||
| 584 | - | ||
| 585 | ---- | ||
| 586 | - | ||
| 587 | -## Next Steps | ||
| 588 | - | ||
| 589 | -1. Review this roadmap | ||
| 590 | -2. Make any adjustments | ||
| 591 | -3. Begin Phase 0 (Planning & Design) | ||
| 592 | -4. Create specification documents | ||
| 593 | -5. Start Phase 1 (Fortress Navigator) | ||
| 594 | - | ||
| 595 | -Ready to proceed? 🚀 | ||
WORKSPACE_TASKS.mddeleted@@ -1,173 +0,0 @@ | |||
| 1 | -# Workspace Mode - Task Tracker | ||
| 2 | - | ||
| 3 | -Quick reference for tracking progress through implementation phases. | ||
| 4 | - | ||
| 5 | -## Current Phase: Phase 4 (Backup System) - Ready to begin! | ||
| 6 | - | ||
| 7 | ---- | ||
| 8 | - | ||
| 9 | -## Phase 0: Planning & Design ✅ | ||
| 10 | -- [x] Define workspace data structures | ||
| 11 | -- [x] Design `.fac/` directory structure | ||
| 12 | -- [x] Design `~/.config/fac/` structure | ||
| 13 | -- [x] Create workspace.json schema | ||
| 14 | -- [x] Create favorites.json schema | ||
| 15 | -- [x] Document Fortress integration points | ||
| 16 | -- [x] Plan module dependencies | ||
| 17 | - | ||
| 18 | -**Deliverables**: `workspace_spec.md`, `fortress_integration.md`, `config_spec.md` ✅ | ||
| 19 | - | ||
| 20 | -**Completed**: 2025-01-05 | ||
| 21 | -**Notes**: All three specification documents created with comprehensive detail: | ||
| 22 | -- workspace_spec.md: Complete JSON schema with validation rules, examples, and test cases | ||
| 23 | -- fortress_integration.md: Module-by-module integration plan with adaptation strategy | ||
| 24 | -- config_spec.md: User config files (favorites/recents/backups) with XDG compliance | ||
| 25 | - | ||
| 26 | ---- | ||
| 27 | - | ||
| 28 | -## Phase 1: Fortress Navigator Foundation ✅ | ||
| 29 | -- [x] Copy fortress filesystem modules | ||
| 30 | -- [x] Copy fortress terminal modules | ||
| 31 | -- [x] Adapt fortress UI for embedded mode | ||
| 32 | -- [x] Implement dual-pane rendering | ||
| 33 | -- [x] Add navigation keybindings | ||
| 34 | -- [x] Add Ctrl-O keybinding to main editor | ||
| 35 | -- [x] Modal Fortress UI | ||
| 36 | - | ||
| 37 | -**Deliverables**: Ctrl-O opens dual-pane file/directory navigator ✅ | ||
| 38 | - | ||
| 39 | -**Completed**: 2025-11-05 | ||
| 40 | -**Notes**: Fortress navigator fully integrated with: | ||
| 41 | -- Dual-pane layout (parent 30% | current 70%) | ||
| 42 | -- Unicode separator (│) | ||
| 43 | -- Smooth navigation (arrows, enter, esc) | ||
| 44 | -- Optimized rendering (no flashing, cached terminal size, conditional redraws) | ||
| 45 | -- Absolute cursor positioning for clean updates | ||
| 46 | -- Scroll margin (3 lines) for better UX | ||
| 47 | -- Files: `src/fortress/filesystem/fortress_fs_module.f90`, `src/fortress/ui/fortress_display_module.f90`, `src/fortress/fortress_navigator_module.f90` | ||
| 48 | - | ||
| 49 | ---- | ||
| 50 | - | ||
| 51 | -## Phase 2: Workspace Detection & Configuration ✅ | ||
| 52 | -- [x] Create workspace detection logic | ||
| 53 | -- [x] Implement workspace config directory structure | ||
| 54 | -- [x] Create workspace module (init/load/save/exists) | ||
| 55 | -- [x] Command line argument parsing | ||
| 56 | -- [x] Create empty workspace with default state | ||
| 57 | -- [x] Basic save/load (metadata only) | ||
| 58 | - | ||
| 59 | -**Deliverables**: `fac .` creates workspace, `fac file.txt` still works ✅ | ||
| 60 | - | ||
| 61 | -**Completed**: 2025-11-05 | ||
| 62 | -**Notes**: Basic workspace infrastructure complete: | ||
| 63 | -- workspace_module.f90 created with detection, init, load, save functions | ||
| 64 | -- Command line parsing updated to detect workspace vs single-file mode | ||
| 65 | -- `fac .` creates `.fac/workspace.json` with proper structure | ||
| 66 | -- `fac /path/to/dir` works for workspace mode | ||
| 67 | -- Single-file mode (`fac file.txt`) unchanged | ||
| 68 | -- Workspace detection searches parent directories for existing workspaces | ||
| 69 | - | ||
| 70 | ---- | ||
| 71 | - | ||
| 72 | -## Phase 3: State Serialization ✅ | ||
| 73 | -- [x] Design workspace.json schema | ||
| 74 | -- [x] Implement tab serialization | ||
| 75 | -- [x] Implement pane serialization | ||
| 76 | -- [x] Implement cursor/viewport serialization | ||
| 77 | -- [x] Implement deserialization | ||
| 78 | -- [x] Add orphan tab tracking | ||
| 79 | -- [x] Call save on quit | ||
| 80 | -- [x] Call load on workspace open | ||
| 81 | -- [x] Handle relative vs absolute paths | ||
| 82 | - | ||
| 83 | -**Deliverables**: Full state persistence across sessions ✅ | ||
| 84 | - | ||
| 85 | -**Completed**: 2025-11-05 | ||
| 86 | -**Notes**: Complete workspace state persistence implemented: | ||
| 87 | -- workspace_save_state() serializes tabs with all panes to JSON | ||
| 88 | -- workspace_restore_state() parses JSON and restores tabs with cursor/viewport | ||
| 89 | -- Panes array saved with coordinates (x_start, y_start, x_end, y_end) | ||
| 90 | -- Orphan tabs styled in gray (ESC[90m) | ||
| 91 | -- Relative paths for workspace files, absolute for orphans | ||
| 92 | -- Modified flag synced from buffer to tab (asterisk display) | ||
| 93 | -- Files: `src/workspace/workspace_module.f90`, `app/main.f90:207` | ||
| 94 | - | ||
| 95 | ---- | ||
| 96 | - | ||
| 97 | -## Phase 4: Backup System ⏸️ | ||
| 98 | -- [ ] Create backup directory structure | ||
| 99 | -- [ ] Implement backup on quit | ||
| 100 | -- [ ] Implement backup detection on open | ||
| 101 | -- [ ] Implement restore prompt with diff | ||
| 102 | -- [ ] Implement diff viewer | ||
| 103 | -- [ ] Backup cleanup | ||
| 104 | - | ||
| 105 | -**Deliverables**: Auto-backup dirty buffers, restore with diff option | ||
| 106 | - | ||
| 107 | ---- | ||
| 108 | - | ||
| 109 | -## Phase 5: Favorites & Recents ⏸️ | ||
| 110 | -- [ ] Create favorites system | ||
| 111 | -- [ ] Create recents system | ||
| 112 | -- [ ] Update recents on workspace open | ||
| 113 | -- [ ] Implement Fortress welcome menu | ||
| 114 | -- [ ] Implement `fac` (no args) behavior | ||
| 115 | -- [ ] Add favorite keybinds in Fortress | ||
| 116 | - | ||
| 117 | -**Deliverables**: `fac` opens welcome menu with favorites/recents | ||
| 118 | - | ||
| 119 | ---- | ||
| 120 | - | ||
| 121 | -## Phase 6: Workspace Switching & Integration ⏸️ | ||
| 122 | -- [ ] Implement workspace switching flow | ||
| 123 | -- [ ] Handle orphan tab creation | ||
| 124 | -- [ ] Implement save prompts on switch | ||
| 125 | -- [ ] Handle edge cases (missing files, etc.) | ||
| 126 | -- [ ] Update file tree for workspace mode | ||
| 127 | - | ||
| 128 | -**Deliverables**: Full workspace switching via Fortress | ||
| 129 | - | ||
| 130 | ---- | ||
| 131 | - | ||
| 132 | -## Phase 7: Polish & Testing ⏸️ | ||
| 133 | -- [ ] Performance optimization | ||
| 134 | -- [ ] Visual polish | ||
| 135 | -- [ ] Error handling | ||
| 136 | -- [ ] Edge case testing | ||
| 137 | -- [ ] Documentation | ||
| 138 | -- [ ] User testing | ||
| 139 | -- [ ] Fix cursor/rendering bugs | ||
| 140 | -- [ ] Remove debug logging | ||
| 141 | - | ||
| 142 | -**Deliverables**: Production-ready workspace mode | ||
| 143 | - | ||
| 144 | ---- | ||
| 145 | - | ||
| 146 | -## Legend | ||
| 147 | -- ⏳ In Progress | ||
| 148 | -- ⏸️ Not Started | ||
| 149 | -- ✅ Complete | ||
| 150 | -- ❌ Blocked | ||
| 151 | - | ||
| 152 | -## Notes | ||
| 153 | - | ||
| 154 | -### 2025-01-05: Phase 0 Complete | ||
| 155 | -- Created comprehensive specification documents for all workspace components | ||
| 156 | -- workspace_spec.md: 565 lines, complete JSON schema with examples and validation | ||
| 157 | -- fortress_integration.md: Detailed module-by-module integration plan | ||
| 158 | -- config_spec.md: User config files specification with XDG compliance | ||
| 159 | -- Ready to begin Phase 1: Fortress Navigator implementation | ||
| 160 | - | ||
| 161 | ---- | ||
| 162 | - | ||
| 163 | -### 2025-11-05: Phase 3 Complete - Pane Serialization Added | ||
| 164 | -- Completed full pane serialization for split views | ||
| 165 | -- workspace_save_state() now saves all panes with coordinates, filenames, cursors | ||
| 166 | -- workspace_restore_state() parses panes array and restores (first pane for now) | ||
| 167 | -- JSON format includes panes array with x_start, y_start, x_end, y_end coordinates | ||
| 168 | -- Modified flag properly synced from buffer to tab (fixed asterisk bug) | ||
| 169 | -- Phase 3 fully complete - ready for Phase 4: Backup System | ||
| 170 | - | ||
| 171 | ---- | ||
| 172 | - | ||
| 173 | -Last Updated: 2025-11-05 | ||
scratch_files/CTRL_R_AND_CURSOR_FIXES.mddeleted@@ -1,197 +0,0 @@ | |||
| 1 | -# Ctrl-R Replace and Cursor Visibility Fixes | ||
| 2 | - | ||
| 3 | -## Issues Fixed | ||
| 4 | - | ||
| 5 | -### Issue 1: Ctrl-R Replace Not Working | ||
| 6 | - | ||
| 7 | -**Problem:** When using Ctrl-F to find a match, then Tab to enter replacement text, then Ctrl-R to replace, nothing happened except the highlight was removed. | ||
| 8 | - | ||
| 9 | -**Test Case:** | ||
| 10 | -``` | ||
| 11 | -1. Ctrl-F → type "Email" → Ctrl-F (finds "Email" on line 4) | ||
| 12 | -2. Tab → type "GMAIL" | ||
| 13 | -3. Ctrl-R | ||
| 14 | -4. BUG: Nothing replaced, highlight removed, cursor invisible ❌ | ||
| 15 | -5. EXPECTED: "Email" → "GMAIL", cursor at end of "GMAIL" ✅ | ||
| 16 | -``` | ||
| 17 | - | ||
| 18 | -**Root Causes:** | ||
| 19 | -1. **Missing pane sync**: The replacement modified `editor%cursors` but didn't sync to `pane%cursors` | ||
| 20 | -2. **Match length calculation**: If `last_match_length` wasn't set, the replacement used 0 as the match length | ||
| 21 | - | ||
| 22 | -**Fixes:** | ||
| 23 | - | ||
| 24 | -**File:** `src/ui/unified_search_module.f90:440-474` | ||
| 25 | - | ||
| 26 | -```fortran | ||
| 27 | -subroutine replace_current_and_advance(editor, buffer) | ||
| 28 | - type(editor_state_t), intent(inout) :: editor | ||
| 29 | - type(buffer_t), intent(inout) :: buffer | ||
| 30 | - integer :: match_len | ||
| 31 | - | ||
| 32 | - if (.not. allocated(current_search_pattern)) return | ||
| 33 | - if (.not. allocated(current_replace_text)) return | ||
| 34 | - | ||
| 35 | - ! If cursor has selection, replace it | ||
| 36 | - if (editor%cursors(editor%active_cursor)%has_selection) then | ||
| 37 | - ! Calculate match length from selection if last_match_length not set | ||
| 38 | - if (last_match_length > 0) then | ||
| 39 | - match_len = last_match_length | ||
| 40 | - else | ||
| 41 | - ! Calculate from selection end - start | ||
| 42 | - match_len = editor%cursors(editor%active_cursor)%column - & | ||
| 43 | - editor%cursors(editor%active_cursor)%selection_start_col | ||
| 44 | - end if | ||
| 45 | - | ||
| 46 | - call perform_replacement(buffer, editor%cursors(editor%active_cursor), & | ||
| 47 | - current_replace_text, match_len) | ||
| 48 | - | ||
| 49 | - ! Clear selection after replacement | ||
| 50 | - editor%cursors(editor%active_cursor)%has_selection = .false. | ||
| 51 | - | ||
| 52 | - ! Sync cursor to pane (important!) ← ADDED THIS | ||
| 53 | - call sync_editor_to_pane(editor) | ||
| 54 | - | ||
| 55 | - ! Re-count matches after replacement | ||
| 56 | - call count_all_matches(buffer, current_search_pattern) | ||
| 57 | - | ||
| 58 | - ! Render to show the replacement (without selection) | ||
| 59 | - call render_screen(buffer, editor) | ||
| 60 | - end if | ||
| 61 | -end subroutine replace_current_and_advance | ||
| 62 | -``` | ||
| 63 | - | ||
| 64 | -**Key changes:** | ||
| 65 | -1. Added `match_len` local variable | ||
| 66 | -2. Calculate match length from selection if `last_match_length` is 0 | ||
| 67 | -3. **Added `sync_editor_to_pane(editor)` call** after replacement | ||
| 68 | -4. This ensures the replacement is visible in the pane system | ||
| 69 | - | ||
| 70 | -### Issue 2: Cursor Invisible After Enter or Ctrl-R | ||
| 71 | - | ||
| 72 | -**Problem:** After pressing Enter to jump to a match or Ctrl-R to replace, the cursor became invisible. | ||
| 73 | - | ||
| 74 | -**Root Cause:** | ||
| 75 | -The cleanup code at the end of `show_unified_search_prompt` was calling `terminal_hide_cursor()`, which hid the cursor before returning to the main editor loop. | ||
| 76 | - | ||
| 77 | -**Fix:** | ||
| 78 | - | ||
| 79 | -**File:** `src/ui/unified_search_module.f90:246-249` | ||
| 80 | - | ||
| 81 | -**Before:** | ||
| 82 | -```fortran | ||
| 83 | -! Clean up | ||
| 84 | -call terminal_hide_cursor() ← BAD! Hides cursor permanently | ||
| 85 | -call terminal_move_cursor(editor%screen_rows, 1) | ||
| 86 | -call terminal_write(repeat(' ', editor%screen_cols)) | ||
| 87 | -``` | ||
| 88 | - | ||
| 89 | -**After:** | ||
| 90 | -```fortran | ||
| 91 | -! Clean up - clear the prompt line | ||
| 92 | -call terminal_move_cursor(editor%screen_rows, 1) | ||
| 93 | -call terminal_write(repeat(' ', editor%screen_cols)) | ||
| 94 | -! Don't hide cursor - let the main render loop handle cursor display | ||
| 95 | -``` | ||
| 96 | - | ||
| 97 | -**Rationale:** | ||
| 98 | -- The main editor render loop is responsible for cursor visibility | ||
| 99 | -- Modal prompts should not permanently hide the cursor | ||
| 100 | -- Other prompt modules follow this pattern (they hide during prompt but show when done) | ||
| 101 | - | ||
| 102 | -## Testing | ||
| 103 | - | ||
| 104 | -### Test 1: Basic Replace | ||
| 105 | -```bash | ||
| 106 | -./fac scratch_files/regex_test_examples.txt | ||
| 107 | -``` | ||
| 108 | -1. Ctrl-F → type "Email" → Ctrl-F (finds first "Email") | ||
| 109 | -2. Tab → type "GMAIL" | ||
| 110 | -3. Press Ctrl-R | ||
| 111 | -4. **Expected:** | ||
| 112 | - - ✅ "Email" replaced with "GMAIL" | ||
| 113 | - - ✅ Cursor visible at end of "GMAIL" | ||
| 114 | - - ✅ No highlight | ||
| 115 | - - ✅ Match count updated | ||
| 116 | - | ||
| 117 | -### Test 2: Multiple Replacements | ||
| 118 | -1. Ctrl-F → "Email" → Ctrl-F (finds first) | ||
| 119 | -2. Tab → "GMAIL" | ||
| 120 | -3. Ctrl-R (replaces first) | ||
| 121 | -4. **Expected:** Cursor at end of "GMAIL", visible ✅ | ||
| 122 | -5. Ctrl-F (finds second "Email") | ||
| 123 | -6. Ctrl-R (replaces second) | ||
| 124 | -7. **Expected:** Cursor at end of second "GMAIL", visible ✅ | ||
| 125 | - | ||
| 126 | -### Test 3: Regex Replace | ||
| 127 | -1. Ctrl-F → Alt-R → "[0-9]+" → Ctrl-F (finds "123") | ||
| 128 | -2. Tab → "NUM" | ||
| 129 | -3. Ctrl-R | ||
| 130 | -4. **Expected:** | ||
| 131 | - - ✅ "123" replaced with "NUM" | ||
| 132 | - - ✅ Cursor visible at end of "NUM" | ||
| 133 | - - ✅ Variable-length match handled correctly | ||
| 134 | - | ||
| 135 | -### Test 4: Enter Key Cursor | ||
| 136 | -1. Ctrl-F → "Email" → Ctrl-F (finds match) | ||
| 137 | -2. Press Enter | ||
| 138 | -3. **Expected:** | ||
| 139 | - - ✅ Cursor visible at start of "Email" | ||
| 140 | - - ✅ No highlight | ||
| 141 | - - ✅ Cursor style unchanged | ||
| 142 | - | ||
| 143 | -## Related Issues Fixed | ||
| 144 | - | ||
| 145 | -These fixes also ensure: | ||
| 146 | -1. ✅ Replacements work with both regex and literal patterns | ||
| 147 | -2. ✅ Match length calculated correctly even if search state incomplete | ||
| 148 | -3. ✅ Cursor remains visible throughout search/replace workflow | ||
| 149 | -4. ✅ Pane system stays synchronized with editor state | ||
| 150 | - | ||
| 151 | -## Technical Notes | ||
| 152 | - | ||
| 153 | -### Why Two Match Length Calculations? | ||
| 154 | - | ||
| 155 | -The `last_match_length` module variable is set by `find_next_match()`: | ||
| 156 | -- For regex: The actual matched length (may differ from pattern) | ||
| 157 | -- For literal: `len(pattern)` | ||
| 158 | - | ||
| 159 | -But if the user presses Ctrl-R without searching first (or if state is corrupted), we fallback to calculating from the selection: | ||
| 160 | -```fortran | ||
| 161 | -match_len = cursor%column - cursor%selection_start_col | ||
| 162 | -``` | ||
| 163 | - | ||
| 164 | -This makes the replacement more robust. | ||
| 165 | - | ||
| 166 | -### Cursor Visibility Pattern | ||
| 167 | - | ||
| 168 | -Modal prompts should: | ||
| 169 | -1. ✅ Clear prompt area on exit | ||
| 170 | -2. ❌ NOT hide cursor permanently | ||
| 171 | -3. ✅ Let main render loop handle cursor display | ||
| 172 | - | ||
| 173 | -The main editor loop calls `terminal_show_cursor()` as needed during rendering. | ||
| 174 | - | ||
| 175 | -## Files Modified | ||
| 176 | - | ||
| 177 | -1. `src/ui/unified_search_module.f90`: | ||
| 178 | - - Lines 440-474: Fixed `replace_current_and_advance` | ||
| 179 | - - Added match length calculation | ||
| 180 | - - Added `sync_editor_to_pane` call | ||
| 181 | - - Lines 246-249: Removed permanent cursor hide | ||
| 182 | - | ||
| 183 | -## Build | ||
| 184 | - | ||
| 185 | -```bash | ||
| 186 | -make clean && make | ||
| 187 | -``` | ||
| 188 | - | ||
| 189 | -Build completed successfully with no errors. | ||
| 190 | - | ||
| 191 | -## Summary | ||
| 192 | - | ||
| 193 | -Both issues were manifestations of the same root problem: **incomplete state synchronization**. The editor has multiple layers (cursor state, pane state, terminal state) that must stay synchronized. These fixes ensure: | ||
| 194 | - | ||
| 195 | -1. Replacements sync to pane system → visible changes | ||
| 196 | -2. Cursor visibility managed correctly → visible cursor | ||
| 197 | -3. Match lengths calculated robustly → correct replacements | ||
scratch_files/CTRL_R_FIX_BUFFER_SYNC.mddeleted@@ -1,101 +0,0 @@ | |||
| 1 | -# Ctrl-R Replace Buffer Synchronization Fix | ||
| 2 | - | ||
| 3 | -## The Bug | ||
| 4 | - | ||
| 5 | -When using Ctrl-F to search for "Email" on line 4, then Ctrl-R to replace it with "GMAIL": | ||
| 6 | -- Wrong text was replaced (e.g., "Regex" on line 1 instead of "Email" on line 4) | ||
| 7 | -- Pressing ESC would cause the replacement to revert | ||
| 8 | -- Selection would reappear on the original match | ||
| 9 | - | ||
| 10 | -## Root Cause Analysis | ||
| 11 | - | ||
| 12 | -The issue was a **buffer synchronization problem** between the pane system and the main event loop. | ||
| 13 | - | ||
| 14 | -### The Flow That Caused the Bug: | ||
| 15 | - | ||
| 16 | -1. **Main loop** (main.f90:106-108): Copy pane's buffer → `buffer` parameter | ||
| 17 | - ```fortran | ||
| 18 | - call copy_buffer(buffer, editor%tabs(...) %panes(status)%buffer) | ||
| 19 | - ``` | ||
| 20 | - | ||
| 21 | -2. **Ctrl-F search**: Finds "Email" on line 4 in `buffer` copy, sets selection | ||
| 22 | - | ||
| 23 | -3. **User presses Ctrl-R** | ||
| 24 | - | ||
| 25 | -4. **`replace_current_and_advance`** (unified_search_module.f90:515-518): | ||
| 26 | - - Modifies **pane's buffer directly** | ||
| 27 | - - Does NOT modify the `buffer` parameter | ||
| 28 | - ```fortran | ||
| 29 | - call perform_replacement(editor%tabs(tab_idx)%panes(pane_idx)%buffer, ...) | ||
| 30 | - ``` | ||
| 31 | - | ||
| 32 | -5. **Exit `show_unified_search_prompt`** | ||
| 33 | - | ||
| 34 | -6. **Main loop** (main.f90:122-123): Copy `buffer` parameter → pane's buffer | ||
| 35 | - ```fortran | ||
| 36 | - call copy_buffer(editor%tabs(...) %panes(status)%buffer, buffer) | ||
| 37 | - ``` | ||
| 38 | - - ❌ **This OVERWRITES the pane's buffer with the old, unmodified `buffer` parameter!** | ||
| 39 | - - Our replacement is lost! | ||
| 40 | - | ||
| 41 | -## The Fix | ||
| 42 | - | ||
| 43 | -**File:** `src/ui/unified_search_module.f90:520-522` | ||
| 44 | - | ||
| 45 | -After performing the replacement on the pane's buffer, immediately copy it back to the parameter buffer: | ||
| 46 | - | ||
| 47 | -```fortran | ||
| 48 | -! Perform replacement on pane's buffer with pane's cursor | ||
| 49 | -call perform_replacement(editor%tabs(tab_idx)%panes(pane_idx)%buffer, & | ||
| 50 | - editor%tabs(tab_idx)%panes(pane_idx)%cursors(...), & | ||
| 51 | - current_replace_text, match_len) | ||
| 52 | - | ||
| 53 | -! CRITICAL: Copy pane buffer back to parameter buffer so main loop doesn't overwrite | ||
| 54 | -! The main loop copies buffer -> pane buffer after we return, so we must sync them | ||
| 55 | -call copy_buffer(buffer, editor%tabs(tab_idx)%panes(pane_idx)%buffer) | ||
| 56 | -``` | ||
| 57 | - | ||
| 58 | -## Why This Works | ||
| 59 | - | ||
| 60 | -Now both buffers are synchronized: | ||
| 61 | -1. We modify pane's buffer (contains the replacement) | ||
| 62 | -2. We copy pane's buffer → `buffer` parameter (now both have the replacement) | ||
| 63 | -3. Main loop copies `buffer` → pane's buffer (no-op, both already in sync) | ||
| 64 | -4. Replacement persists! ✅ | ||
| 65 | - | ||
| 66 | -## Testing | ||
| 67 | - | ||
| 68 | -```bash | ||
| 69 | -./fac scratch_files/regex_test_examples.txt | ||
| 70 | -``` | ||
| 71 | - | ||
| 72 | -1. Ctrl-F → type "Email" → Ctrl-F (finds "Email" on line 4) ✅ | ||
| 73 | -2. Tab → type "GMAIL" | ||
| 74 | -3. Ctrl-R | ||
| 75 | -4. **Expected:** | ||
| 76 | - - ✅ "Email" on line 4 replaced with "GMAIL" (NOT wrong text on wrong line) | ||
| 77 | - - ✅ Cursor at end of "GMAIL" | ||
| 78 | - - ✅ Pressing ESC does NOT revert the change | ||
| 79 | - - ✅ No strange selection reappearing | ||
| 80 | - | ||
| 81 | -## Related Architecture Notes | ||
| 82 | - | ||
| 83 | -The main event loop uses a **buffer synchronization pattern**: | ||
| 84 | -- Before each command: Copy active pane's buffer → main `buffer` | ||
| 85 | -- Process command using `buffer` | ||
| 86 | -- After command: Copy main `buffer` → active pane's buffer | ||
| 87 | - | ||
| 88 | -This pattern ensures: | ||
| 89 | -1. Commands can work with a single `buffer` parameter | ||
| 90 | -2. Pane-specific state is preserved | ||
| 91 | -3. Changes propagate to all instances of the same file | ||
| 92 | - | ||
| 93 | -**However**, when commands modify the pane's buffer directly (bypassing the `buffer` parameter), they MUST sync back to the parameter buffer before returning, or the main loop will overwrite their changes. | ||
| 94 | - | ||
| 95 | -## Lesson Learned | ||
| 96 | - | ||
| 97 | -When working with multi-layered state systems (editor state → tab state → pane state → buffer state): | ||
| 98 | -- Always identify which is the "source of truth" for each operation | ||
| 99 | -- Ensure modifications propagate to all necessary layers | ||
| 100 | -- Watch out for synchronization code that might overwrite your changes | ||
| 101 | -- Add comments explaining critical sync points | ||
scratch_files/CURSOR_POSITION_FIX.mddeleted@@ -1,159 +0,0 @@ | |||
| 1 | -# Cursor Position Fix for Enter Key | ||
| 2 | - | ||
| 3 | -## Issue | ||
| 4 | - | ||
| 5 | -When pressing Enter after finding a search match, the cursor was positioned incorrectly (line 3 col 0 instead of line 4 at the match). | ||
| 6 | - | ||
| 7 | -### Expected Behavior | ||
| 8 | -1. **Ctrl-F + Enter**: Cursor should be at the **START** of the matched text | ||
| 9 | -2. **Ctrl-R**: Cursor should be at the **END** of the replacement text | ||
| 10 | - | ||
| 11 | -### Actual Behavior (Before Fix) | ||
| 12 | -- When Enter was pressed, the cursor remained at the **END** of the match | ||
| 13 | -- This is because during search, the cursor is positioned at the end to show the selection | ||
| 14 | -- The Enter key handler just exited without repositioning the cursor | ||
| 15 | - | ||
| 16 | -## Root Cause | ||
| 17 | - | ||
| 18 | -When a match is found, the code creates a selection like this: | ||
| 19 | -```fortran | ||
| 20 | -! Start of match | ||
| 21 | -editor%cursors(editor%active_cursor)%selection_start_line = found_line | ||
| 22 | -editor%cursors(editor%active_cursor)%selection_start_col = found_col | ||
| 23 | - | ||
| 24 | -! End of match (cursor positioned here to show selection) | ||
| 25 | -editor%cursors(editor%active_cursor)%column = found_col + match_length | ||
| 26 | -``` | ||
| 27 | - | ||
| 28 | -The cursor was left at `found_col + match_length` (the end), but users expect it at `found_col` (the start) when pressing Enter. | ||
| 29 | - | ||
| 30 | -## Solution | ||
| 31 | - | ||
| 32 | -Updated the Enter key handler (lines 210-224) to: | ||
| 33 | -1. Move cursor to the **START** of the selection | ||
| 34 | -2. Clear the selection (so it's just a cursor, not a highlight) | ||
| 35 | -3. Render the screen to show the new cursor position | ||
| 36 | - | ||
| 37 | -```fortran | ||
| 38 | -else if (ch == 13 .or. ch == 10) then ! Enter - accept current match and exit | ||
| 39 | - ! Move cursor to START of match (not end) | ||
| 40 | - if (editor%cursors(editor%active_cursor)%has_selection) then | ||
| 41 | - editor%cursors(editor%active_cursor)%line = & | ||
| 42 | - editor%cursors(editor%active_cursor)%selection_start_line | ||
| 43 | - editor%cursors(editor%active_cursor)%column = & | ||
| 44 | - editor%cursors(editor%active_cursor)%selection_start_col | ||
| 45 | - editor%cursors(editor%active_cursor)%desired_column = & | ||
| 46 | - editor%cursors(editor%active_cursor)%selection_start_col | ||
| 47 | - ! Clear selection so cursor is at start, not selecting | ||
| 48 | - editor%cursors(editor%active_cursor)%has_selection = .false. | ||
| 49 | - ! Render to show cursor at correct position | ||
| 50 | - call render_screen(buffer, editor) | ||
| 51 | - end if | ||
| 52 | - exit | ||
| 53 | -``` | ||
| 54 | - | ||
| 55 | -## Behavior Summary | ||
| 56 | - | ||
| 57 | -### Enter Key (RET:go) | ||
| 58 | -1. Moves cursor to START of match | ||
| 59 | -2. Clears the selection highlight | ||
| 60 | -3. Re-renders to show cursor at correct position | ||
| 61 | -4. Exits search prompt | ||
| 62 | - | ||
| 63 | -**Example:** | ||
| 64 | -``` | ||
| 65 | -Search for "Email" → finds and highlights "Email" | ||
| 66 | -Press Enter → cursor positioned on the "E" of "Email" | ||
| 67 | -Ready to edit from the start of the match | ||
| 68 | -``` | ||
| 69 | - | ||
| 70 | -### Ctrl-R (Replace) | ||
| 71 | -1. Replaces the selected text with replacement text | ||
| 72 | -2. Cursor positioned at END of replacement (after last character) | ||
| 73 | -3. Clears selection | ||
| 74 | -4. Re-renders to show the replacement | ||
| 75 | - | ||
| 76 | -**Example:** | ||
| 77 | -``` | ||
| 78 | -Find "test" → highlights "test" | ||
| 79 | -Replace with "example" | ||
| 80 | -Cursor positioned after "example" (at the 'e' position) | ||
| 81 | -``` | ||
| 82 | - | ||
| 83 | -## Testing | ||
| 84 | - | ||
| 85 | -### Test Case 1: Basic Enter | ||
| 86 | -```bash | ||
| 87 | -./fac scratch_files/regex_test_examples.txt | ||
| 88 | -``` | ||
| 89 | -1. Ctrl-F → type "Email" | ||
| 90 | -2. Ctrl-F → highlights first "Email" on line 4 | ||
| 91 | -3. Press Enter | ||
| 92 | -4. **Expected:** Cursor on line 4, column at "E" of "Email" ✅ | ||
| 93 | -5. **Expected:** No selection/highlight ✅ | ||
| 94 | - | ||
| 95 | -### Test Case 2: Regex Match + Enter | ||
| 96 | -``` | ||
| 97 | -1. Ctrl-F → Alt-R → type "[0-9]+" | ||
| 98 | -2. Ctrl-F → highlights "123" | ||
| 99 | -3. Press Enter | ||
| 100 | -4. **Expected:** Cursor at the "1" of "123" ✅ | ||
| 101 | -``` | ||
| 102 | - | ||
| 103 | -### Test Case 3: Replace Behavior | ||
| 104 | -``` | ||
| 105 | -1. Ctrl-F → type "foo" | ||
| 106 | -2. Tab → type "bar" | ||
| 107 | -3. Ctrl-F → highlights first "foo" | ||
| 108 | -4. Ctrl-R → replaces with "bar" | ||
| 109 | -5. **Expected:** Cursor after "bar" (at position where next char would go) ✅ | ||
| 110 | -``` | ||
| 111 | - | ||
| 112 | -### Test Case 4: Multiple Matches + Enter | ||
| 113 | -``` | ||
| 114 | -1. Ctrl-F → type "test" | ||
| 115 | -2. Ctrl-F → first "test" highlighted | ||
| 116 | -3. Ctrl-F → second "test" highlighted | ||
| 117 | -4. Ctrl-F → third "test" highlighted | ||
| 118 | -5. Press Enter | ||
| 119 | -6. **Expected:** Cursor at start of third "test" ✅ | ||
| 120 | -``` | ||
| 121 | - | ||
| 122 | -## Design Rationale | ||
| 123 | - | ||
| 124 | -### Why START for Enter? | ||
| 125 | -- User is saying "take me to this match so I can work with it" | ||
| 126 | -- Starting from the beginning is most natural for editing | ||
| 127 | -- Allows typing immediately to replace the text | ||
| 128 | -- Consistent with "go to" semantics | ||
| 129 | - | ||
| 130 | -### Why END for Replace? | ||
| 131 | -- After replacement, user likely wants to continue editing forward | ||
| 132 | -- Cursor at end allows immediate typing to append | ||
| 133 | -- Standard behavior in most editors | ||
| 134 | -- Allows chaining edits naturally | ||
| 135 | - | ||
| 136 | -### Why Clear Selection? | ||
| 137 | -- Enter means "accept and exit search mode" | ||
| 138 | -- Keeping the highlight is confusing when not in search mode | ||
| 139 | -- User can easily re-select if needed (Shift+arrows, etc.) | ||
| 140 | -- Clean visual state after exiting search | ||
| 141 | - | ||
| 142 | -## Files Modified | ||
| 143 | - | ||
| 144 | -- `src/ui/unified_search_module.f90` (lines 210-224) | ||
| 145 | - - Enter key handler now repositions cursor to selection start | ||
| 146 | - - Clears selection after repositioning | ||
| 147 | - - Renders screen to show new cursor position | ||
| 148 | - | ||
| 149 | -## Verification | ||
| 150 | - | ||
| 151 | -The `perform_replacement` function already correctly positions the cursor at the end of the replacement text (line 551), so no changes were needed there. | ||
| 152 | - | ||
| 153 | -## Build | ||
| 154 | - | ||
| 155 | -```bash | ||
| 156 | -make clean && make | ||
| 157 | -``` | ||
| 158 | - | ||
| 159 | -Build completed successfully with no errors. | ||
scratch_files/ENTER_KEY_FEATURE.mddeleted@@ -1,159 +0,0 @@ | |||
| 1 | -# Enter Key Feature in Unified Search | ||
| 2 | - | ||
| 3 | -## Feature: Press Enter to Jump to Match | ||
| 4 | - | ||
| 5 | -### What It Does | ||
| 6 | -When you have a highlighted search match, pressing **Enter** (Return) will: | ||
| 7 | -1. Close the search prompt | ||
| 8 | -2. Leave the cursor positioned at the current match | ||
| 9 | -3. Keep the selection active (so you can see what was matched) | ||
| 10 | -4. Allow you to immediately start editing at that location | ||
| 11 | - | ||
| 12 | -### Usage | ||
| 13 | - | ||
| 14 | -#### Basic Search and Jump | ||
| 15 | -``` | ||
| 16 | -1. Press Ctrl-F to open search | ||
| 17 | -2. Type your search pattern (e.g., "test") | ||
| 18 | -3. Press Ctrl-F to find first match → [highlighted] | ||
| 19 | -4. Press Ctrl-F again to find next match → [highlighted] | ||
| 20 | -5. Press Enter → closes prompt, cursor at match | ||
| 21 | -6. Start typing to replace the selection, or press arrow key to deselect | ||
| 22 | -``` | ||
| 23 | - | ||
| 24 | -#### Regex Search and Jump | ||
| 25 | -``` | ||
| 26 | -1. Press Ctrl-F to open search | ||
| 27 | -2. Press Alt-R to enable regex mode | ||
| 28 | -3. Type regex pattern (e.g., "[0-9]+") | ||
| 29 | -4. Press Ctrl-F to find first match → [highlighted] | ||
| 30 | -5. Press Enter → closes prompt, cursor at the number | ||
| 31 | -6. Can now edit, delete, or replace the matched text | ||
| 32 | -``` | ||
| 33 | - | ||
| 34 | -### Workflow Examples | ||
| 35 | - | ||
| 36 | -#### Example 1: Find and Edit | ||
| 37 | -``` | ||
| 38 | -Goal: Find "TODO" and change it to "DONE" | ||
| 39 | - | ||
| 40 | -Ctrl-F → type "TODO" → Ctrl-F → [finds "TODO", highlighted] | ||
| 41 | -Enter → [prompt closes, "TODO" still selected] | ||
| 42 | -Type "DONE" → [replaces "TODO" with "DONE"] | ||
| 43 | -``` | ||
| 44 | - | ||
| 45 | -#### Example 2: Browse Multiple Matches | ||
| 46 | -``` | ||
| 47 | -Goal: Review all function calls to decide which to edit | ||
| 48 | - | ||
| 49 | -Ctrl-F → type "calculate(" → Ctrl-F → [finds first call] | ||
| 50 | -Ctrl-F → [finds second call] | ||
| 51 | -Ctrl-F → [finds third call] ← This is the one I want! | ||
| 52 | -Enter → [stays at third call] | ||
| 53 | -Edit the function call... | ||
| 54 | -``` | ||
| 55 | - | ||
| 56 | -#### Example 3: Regex Pattern Selection | ||
| 57 | -``` | ||
| 58 | -Goal: Find an email address and copy it | ||
| 59 | - | ||
| 60 | -Ctrl-F → Alt-R → type "[a-z]+@[a-z]+\.[a-z]+" | ||
| 61 | -Ctrl-F → [finds "user@example.com", highlighted] | ||
| 62 | -Enter → [closes prompt, email still selected] | ||
| 63 | -Ctrl-C → [copy the email to clipboard] | ||
| 64 | -``` | ||
| 65 | - | ||
| 66 | -### Key Behavior | ||
| 67 | - | ||
| 68 | -**What happens to the selection?** | ||
| 69 | -- The matched text remains **selected/highlighted** after pressing Enter | ||
| 70 | -- This allows you to immediately: | ||
| 71 | - - Type to replace it | ||
| 72 | - - Ctrl-C to copy it | ||
| 73 | - - Delete to remove it | ||
| 74 | - - Arrow key to deselect and keep it | ||
| 75 | - | ||
| 76 | -**Alternative: ESC vs Enter** | ||
| 77 | -- **ESC**: Closes prompt, clears selection, returns to where you were before search | ||
| 78 | -- **Enter**: Closes prompt, keeps selection, stays at current match | ||
| 79 | - | ||
| 80 | -### UI Changes | ||
| 81 | - | ||
| 82 | -The search prompt now shows: | ||
| 83 | -``` | ||
| 84 | -[f]:pattern /[r]:replacement [options] (1/5) RET:go ESC:exit | ||
| 85 | - ^^^^^^ | ||
| 86 | - NEW! | ||
| 87 | -``` | ||
| 88 | - | ||
| 89 | -**RET:go** = Press Return/Enter to go to the current match | ||
| 90 | - | ||
| 91 | -### Code Changes | ||
| 92 | - | ||
| 93 | -**File:** `src/ui/unified_search_module.f90` | ||
| 94 | - | ||
| 95 | -**Line 184-187:** Added Enter key handler | ||
| 96 | -```fortran | ||
| 97 | -else if (ch == 13 .or. ch == 10) then ! Enter - accept current match and exit | ||
| 98 | - ! Keep the cursor at the current match position | ||
| 99 | - ! If there's a selection, keep it (user can clear with ESC or arrow keys) | ||
| 100 | - exit | ||
| 101 | -``` | ||
| 102 | - | ||
| 103 | -**Line 265 & 270:** Updated prompt text to show "RET:go ESC:exit" | ||
| 104 | - | ||
| 105 | -### Testing | ||
| 106 | - | ||
| 107 | -#### Test 1: Basic Enter | ||
| 108 | -```bash | ||
| 109 | -./fac scratch_files/test_highlight.txt | ||
| 110 | -``` | ||
| 111 | -1. Ctrl-F → type "test" → Ctrl-F (finds first) | ||
| 112 | -2. Press Enter | ||
| 113 | -3. **Expected:** Prompt closes, "test" is still selected, cursor ready | ||
| 114 | - | ||
| 115 | -#### Test 2: Multiple Matches | ||
| 116 | -1. Ctrl-F → type "test" → Ctrl-F (finds first) | ||
| 117 | -2. Ctrl-F (finds second) | ||
| 118 | -3. Ctrl-F (finds third) | ||
| 119 | -4. Press Enter | ||
| 120 | -5. **Expected:** Stays at third match, selected | ||
| 121 | - | ||
| 122 | -#### Test 3: Regex Match | ||
| 123 | -1. Ctrl-F → Alt-R → type "[0-9]+" | ||
| 124 | -2. Ctrl-F (finds "123") | ||
| 125 | -3. Press Enter | ||
| 126 | -4. **Expected:** "123" selected, ready to edit | ||
| 127 | - | ||
| 128 | -#### Test 4: Enter vs ESC | ||
| 129 | -1. Ctrl-F → type "test" → Ctrl-F | ||
| 130 | -2. Try ESC → **Expected:** Clears selection, returns cursor | ||
| 131 | -3. Ctrl-F → type "test" → Ctrl-F | ||
| 132 | -4. Try Enter → **Expected:** Keeps selection, stays at match | ||
| 133 | - | ||
| 134 | -### Benefits | ||
| 135 | - | ||
| 136 | -1. **Faster editing**: Jump to a match and immediately start editing | ||
| 137 | -2. **Visual confirmation**: Selection shows exactly what matched (important for regex!) | ||
| 138 | -3. **Flexible workflow**: Choose whether to keep searching (Ctrl-F) or commit (Enter) | ||
| 139 | -4. **Copy matches**: Select a regex match, press Enter, press Ctrl-C to copy | ||
| 140 | - | ||
| 141 | -### Related Commands | ||
| 142 | - | ||
| 143 | -- **Ctrl-F**: Search/Find next | ||
| 144 | -- **Ctrl-R**: Replace current match | ||
| 145 | -- **Ctrl-A**: Replace all matches | ||
| 146 | -- **Alt-R**: Toggle regex mode | ||
| 147 | -- **Alt-C**: Toggle case sensitivity | ||
| 148 | -- **Alt-W**: Toggle whole word matching | ||
| 149 | -- **Tab**: Switch between find/replace fields | ||
| 150 | -- **Enter**: Jump to current match (close prompt) | ||
| 151 | -- **ESC**: Exit search (clear selection) | ||
| 152 | - | ||
| 153 | -## Build | ||
| 154 | - | ||
| 155 | -```bash | ||
| 156 | -make clean && make | ||
| 157 | -``` | ||
| 158 | - | ||
| 159 | -Build completed successfully with no errors. | ||
scratch_files/PANE_SYNC_FIX.mddeleted@@ -1,150 +0,0 @@ | |||
| 1 | -# Pane Cursor Synchronization Fix | ||
| 2 | - | ||
| 3 | -## Issue | ||
| 4 | - | ||
| 5 | -When pressing Enter after finding a match with Ctrl-F, the cursor would jump to the wrong location (e.g., line 3 col 0 instead of line 4 where "Email" was found). | ||
| 6 | - | ||
| 7 | -### Test Case | ||
| 8 | -``` | ||
| 9 | -1. Open scratch_files/regex_test_examples.txt | ||
| 10 | -2. Press Ctrl-F | ||
| 11 | -3. Type "Email" | ||
| 12 | -4. Press Ctrl-F to find first match on line 4 | ||
| 13 | -5. Press Enter | ||
| 14 | -6. BUG: Cursor jumps to line 3 col 0 ❌ | ||
| 15 | -7. EXPECTED: Cursor on line 4 at the "E" of "Email" ✅ | ||
| 16 | -``` | ||
| 17 | - | ||
| 18 | -## Root Cause | ||
| 19 | - | ||
| 20 | -The facsimile editor uses a **pane system** where cursor state is duplicated in two places: | ||
| 21 | - | ||
| 22 | -1. **`editor%cursors`** - The "working" cursor used during editing operations | ||
| 23 | -2. **`pane%cursors`** - The pane's copy of cursors for rendering | ||
| 24 | - | ||
| 25 | -When the unified search modified the cursor position in the Enter handler: | ||
| 26 | -```fortran | ||
| 27 | -editor%cursors(editor%active_cursor)%line = selection_start_line | ||
| 28 | -editor%cursors(editor%active_cursor)%column = selection_start_col | ||
| 29 | -``` | ||
| 30 | - | ||
| 31 | -It was only updating `editor%cursors`. The pane system still had the old cursor position in `pane%cursors`, which is what gets used for rendering after the search function returns! | ||
| 32 | - | ||
| 33 | -## Solution | ||
| 34 | - | ||
| 35 | -Called `sync_editor_to_pane(editor)` after modifying the cursor in the Enter handler. This function copies the cursor state from `editor%cursors` to `pane%cursors`. | ||
| 36 | - | ||
| 37 | -### Code Changes | ||
| 38 | - | ||
| 39 | -**File:** `src/ui/unified_search_module.f90` | ||
| 40 | - | ||
| 41 | -**Line 4:** Added import | ||
| 42 | -```fortran | ||
| 43 | -use editor_state_module, only: editor_state_t, cursor_t, sync_editor_to_pane | ||
| 44 | -``` | ||
| 45 | - | ||
| 46 | -**Lines 210-224:** Updated Enter handler | ||
| 47 | -```fortran | ||
| 48 | -else if (ch == 13 .or. ch == 10) then ! Enter - accept current match and exit | ||
| 49 | - ! Move cursor to START of match (not end) | ||
| 50 | - if (editor%cursors(editor%active_cursor)%has_selection) then | ||
| 51 | - editor%cursors(editor%active_cursor)%line = & | ||
| 52 | - editor%cursors(editor%active_cursor)%selection_start_line | ||
| 53 | - editor%cursors(editor%active_cursor)%column = & | ||
| 54 | - editor%cursors(editor%active_cursor)%selection_start_col | ||
| 55 | - editor%cursors(editor%active_cursor)%desired_column = & | ||
| 56 | - editor%cursors(editor%active_cursor)%selection_start_col | ||
| 57 | - ! Clear selection so cursor is at start, not selecting | ||
| 58 | - editor%cursors(editor%active_cursor)%has_selection = .false. | ||
| 59 | - ! Sync cursor back to pane (important for pane system!) | ||
| 60 | - call sync_editor_to_pane(editor) | ||
| 61 | - end if | ||
| 62 | - exit | ||
| 63 | -``` | ||
| 64 | - | ||
| 65 | -## What `sync_editor_to_pane` Does | ||
| 66 | - | ||
| 67 | -From `src/editor_state_module.f90:767-800`: | ||
| 68 | - | ||
| 69 | -```fortran | ||
| 70 | -subroutine sync_editor_to_pane(editor) | ||
| 71 | - ! ... | ||
| 72 | - ! Copy editor state back to pane | ||
| 73 | - if (allocated(pane%cursors)) deallocate(pane%cursors) | ||
| 74 | - if (allocated(editor%cursors) .and. size(editor%cursors) > 0) then | ||
| 75 | - allocate(pane%cursors(size(editor%cursors))) | ||
| 76 | - pane%cursors = editor%cursors ! <-- This is the key line! | ||
| 77 | - pane%active_cursor = min(editor%active_cursor, size(editor%cursors)) | ||
| 78 | - ! ... | ||
| 79 | - end if | ||
| 80 | - pane%viewport_line = editor%viewport_line | ||
| 81 | - pane%viewport_column = editor%viewport_column | ||
| 82 | -end subroutine | ||
| 83 | -``` | ||
| 84 | - | ||
| 85 | -It copies: | ||
| 86 | -- All cursor positions and states from `editor%cursors` → `pane%cursors` | ||
| 87 | -- Active cursor index | ||
| 88 | -- Viewport position | ||
| 89 | - | ||
| 90 | -## Why This Matters | ||
| 91 | - | ||
| 92 | -The pane system architecture means that: | ||
| 93 | -1. Operations work on `editor%cursors` (the active working copy) | ||
| 94 | -2. Rendering reads from `pane%cursors` (the pane's display copy) | ||
| 95 | -3. These must be kept in sync! | ||
| 96 | - | ||
| 97 | -Other parts of the codebase (like `command_handler_module.f90`) call `sync_editor_to_pane` after modifying cursor state. The unified search needed to do the same. | ||
| 98 | - | ||
| 99 | -## Testing | ||
| 100 | - | ||
| 101 | -### Test 1: Basic Enter | ||
| 102 | -```bash | ||
| 103 | -./fac scratch_files/regex_test_examples.txt | ||
| 104 | -``` | ||
| 105 | -1. Ctrl-F → "Email" → Ctrl-F | ||
| 106 | -2. Press Enter | ||
| 107 | -3. **Expected:** Cursor at "E" of "Email" on line 4 ✅ | ||
| 108 | - | ||
| 109 | -### Test 2: Multiple Matches | ||
| 110 | -1. Ctrl-F → "Email" → Ctrl-F (first match) | ||
| 111 | -2. Ctrl-F (second match) | ||
| 112 | -3. Ctrl-F (third match) | ||
| 113 | -4. Press Enter | ||
| 114 | -5. **Expected:** Cursor at start of third "Email" ✅ | ||
| 115 | - | ||
| 116 | -### Test 3: Regex Match | ||
| 117 | -1. Ctrl-F → Alt-R → "[0-9]+" → Ctrl-F | ||
| 118 | -2. Finds "123" | ||
| 119 | -3. Press Enter | ||
| 120 | -4. **Expected:** Cursor at "1" of "123" ✅ | ||
| 121 | - | ||
| 122 | -### Test 4: After Replacement | ||
| 123 | -1. Ctrl-F → "test" → Tab → "example" | ||
| 124 | -2. Ctrl-F (finds "test") | ||
| 125 | -3. Ctrl-R (replaces with "example") | ||
| 126 | -4. **Expected:** Cursor at end of "example" ✅ | ||
| 127 | -5. **Note:** Ctrl-R already calls sync internally | ||
| 128 | - | ||
| 129 | -## Related Issues Fixed | ||
| 130 | - | ||
| 131 | -This also ensures that: | ||
| 132 | -- Selection state is properly synchronized | ||
| 133 | -- Viewport adjustments work correctly | ||
| 134 | -- Multiple cursors (if implemented) would sync properly | ||
| 135 | -- Any future cursor modifications in search will work correctly | ||
| 136 | - | ||
| 137 | -## Lessons Learned | ||
| 138 | - | ||
| 139 | -When modifying cursor state in the editor: | ||
| 140 | -1. ✅ Always check if pane system is active | ||
| 141 | -2. ✅ Call `sync_editor_to_pane` after cursor modifications | ||
| 142 | -3. ✅ Look for similar sync calls in other parts of the codebase as examples | ||
| 143 | - | ||
| 144 | -## Build | ||
| 145 | - | ||
| 146 | -```bash | ||
| 147 | -make clean && make | ||
| 148 | -``` | ||
| 149 | - | ||
| 150 | -Build completed successfully with no errors. | ||
scratch_files/README.mddeleted@@ -1,69 +0,0 @@ | |||
| 1 | -# Scratch Files Directory | ||
| 2 | - | ||
| 3 | -This directory contains test files and examples used during development of the Facsimile editor. | ||
| 4 | - | ||
| 5 | -## Regex Testing | ||
| 6 | - | ||
| 7 | -- **`regex_test_examples.txt`** - Comprehensive test file with realistic examples for regex pattern matching | ||
| 8 | -- **`regex_test_patterns.md`** - Documentation of regex patterns to test with the examples file | ||
| 9 | - | ||
| 10 | -## Test Files | ||
| 11 | - | ||
| 12 | -Various test files used during feature development: | ||
| 13 | - | ||
| 14 | -- `ctrl_d_demo.txt` - Ctrl-D functionality testing | ||
| 15 | -- `cursor_test.txt` - Cursor movement and positioning tests | ||
| 16 | -- `demo.txt` - General demo file | ||
| 17 | -- `help_test.txt` - Help menu testing | ||
| 18 | -- `pane_nav_test.txt` - Pane navigation testing | ||
| 19 | -- `pane_test.txt` - Multi-pane functionality tests | ||
| 20 | -- `test_*.txt` - Various feature-specific test files | ||
| 21 | - | ||
| 22 | -## Test Scripts | ||
| 23 | - | ||
| 24 | -Shell scripts for automated testing: | ||
| 25 | - | ||
| 26 | -- `test_cursor_fixes.sh` - Cursor behavior tests | ||
| 27 | -- `test_help_menu.sh` - Help menu automated tests | ||
| 28 | -- `test_new_pane_selection.sh` - Pane selection tests | ||
| 29 | -- `test_pane_navigation.sh` - Pane navigation automation | ||
| 30 | -- `test_panes.sh` - Multi-pane feature tests | ||
| 31 | -- `test_shift_selection.sh` - Text selection tests | ||
| 32 | - | ||
| 33 | -## Usage | ||
| 34 | - | ||
| 35 | -### Testing Regex Functionality | ||
| 36 | - | ||
| 37 | -1. Open the regex test file: | ||
| 38 | - ```bash | ||
| 39 | - ./fac scratch_files/regex_test_examples.txt | ||
| 40 | - ``` | ||
| 41 | - | ||
| 42 | -2. Press `Ctrl-F` to open unified search | ||
| 43 | - | ||
| 44 | -3. Press `Alt-R` to toggle regex mode ON (indicator shows `[R]EGEX`) | ||
| 45 | - | ||
| 46 | -4. Try patterns from `regex_test_patterns.md`, such as: | ||
| 47 | - - `[0-9]+` - Find all numbers | ||
| 48 | - - `[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}` - Find email addresses | ||
| 49 | - - `https?://[a-zA-Z0-9./-]+` - Find URLs | ||
| 50 | - - `\[(ERROR|WARN|INFO|DEBUG)\]` - Find log levels | ||
| 51 | - | ||
| 52 | -5. Test search navigation with `Ctrl-N` (next) and `Ctrl-P` (previous) | ||
| 53 | - | ||
| 54 | -6. Test replace functionality with regex patterns | ||
| 55 | - | ||
| 56 | -### General Testing | ||
| 57 | - | ||
| 58 | -The other test files can be opened directly to test specific features: | ||
| 59 | -```bash | ||
| 60 | -./fac scratch_files/cursor_test.txt | ||
| 61 | -./fac scratch_files/pane_test.txt | ||
| 62 | -# etc. | ||
| 63 | -``` | ||
| 64 | - | ||
| 65 | -## Notes | ||
| 66 | - | ||
| 67 | -- These files are for testing and development purposes | ||
| 68 | -- Feel free to modify or add new test cases | ||
| 69 | -- Automated test scripts may require `expect` to be installed | ||
scratch_files/SEARCH_REPLACE_FIXES.mddeleted@@ -1,164 +0,0 @@ | |||
| 1 | -# Search and Replace Bug Fixes | ||
| 2 | - | ||
| 3 | -## Issues Fixed | ||
| 4 | - | ||
| 5 | -### Issue 1: Found matches not highlighted | ||
| 6 | -**Problem:** When pressing Ctrl-F to search, matches were found but not visually highlighted. | ||
| 7 | - | ||
| 8 | -**Root Cause:** The `search_forward` function was using `len(current_search_pattern)` to calculate the selection end position, which doesn't work correctly for regex patterns where the match length can differ from the pattern length. | ||
| 9 | - | ||
| 10 | -**Fix:** Updated `search_forward` to check if regex mode is enabled and use `last_match_length` (which is set by `find_next_match`) instead of the pattern length. | ||
| 11 | - | ||
| 12 | -**File:** `src/ui/unified_search_module.f90:382-387` | ||
| 13 | - | ||
| 14 | -```fortran | ||
| 15 | -! Use last_match_length for regex (which was set by find_next_match) | ||
| 16 | -if (use_regex .and. last_match_length > 0) then | ||
| 17 | - editor%cursors(editor%active_cursor)%column = found_col + last_match_length | ||
| 18 | -else | ||
| 19 | - editor%cursors(editor%active_cursor)%column = found_col + len(current_search_pattern) | ||
| 20 | -end if | ||
| 21 | -``` | ||
| 22 | - | ||
| 23 | -### Issue 2: Ctrl-R replace behavior | ||
| 24 | -**Problem:** After pressing Ctrl-R to replace current match, the editor would: | ||
| 25 | -- Keep the selection/highlight active | ||
| 26 | -- Immediately jump to the next match | ||
| 27 | - | ||
| 28 | -**Expected Behavior:** After replacement: | ||
| 29 | -- Clear the selection/highlight | ||
| 30 | -- Leave cursor at the end of the replacement text | ||
| 31 | -- Don't automatically jump to next match | ||
| 32 | - | ||
| 33 | -**Fix:** Modified `replace_current_and_advance` to: | ||
| 34 | -1. Perform the replacement | ||
| 35 | -2. Clear the selection (`has_selection = .false.`) | ||
| 36 | -3. Re-count matches (to update the match counter) | ||
| 37 | -4. Removed the call to `search_forward` that was jumping to next match | ||
| 38 | - | ||
| 39 | -**File:** `src/ui/unified_search_module.f90:396-414` | ||
| 40 | - | ||
| 41 | -```fortran | ||
| 42 | -subroutine replace_current_and_advance(editor, buffer) | ||
| 43 | - type(editor_state_t), intent(inout) :: editor | ||
| 44 | - type(buffer_t), intent(inout) :: buffer | ||
| 45 | - | ||
| 46 | - if (.not. allocated(current_search_pattern)) return | ||
| 47 | - if (.not. allocated(current_replace_text)) return | ||
| 48 | - | ||
| 49 | - ! If cursor has selection, replace it | ||
| 50 | - if (editor%cursors(editor%active_cursor)%has_selection) then | ||
| 51 | - call perform_replacement(buffer, editor%cursors(editor%active_cursor), & | ||
| 52 | - current_replace_text, last_match_length) | ||
| 53 | - | ||
| 54 | - ! Clear selection after replacement | ||
| 55 | - editor%cursors(editor%active_cursor)%has_selection = .false. | ||
| 56 | - | ||
| 57 | - ! Re-count matches after replacement | ||
| 58 | - call count_all_matches(buffer, current_search_pattern) | ||
| 59 | - end if | ||
| 60 | -end subroutine replace_current_and_advance | ||
| 61 | -``` | ||
| 62 | - | ||
| 63 | -## How to Test | ||
| 64 | - | ||
| 65 | -### Test 1: Search Highlighting | ||
| 66 | - | ||
| 67 | -```bash | ||
| 68 | -./fac scratch_files/test_search_replace.txt | ||
| 69 | -``` | ||
| 70 | - | ||
| 71 | -1. Press `Ctrl-F` to open search | ||
| 72 | -2. Type `test` and press Enter | ||
| 73 | -3. **Expected:** The first occurrence of "test" should be highlighted (reverse video) | ||
| 74 | -4. Press `Ctrl-F` again to find next | ||
| 75 | -5. **Expected:** Each match should be highlighted | ||
| 76 | - | ||
| 77 | -### Test 2: Regex Search Highlighting | ||
| 78 | - | ||
| 79 | -1. Press `Ctrl-F` to open search | ||
| 80 | -2. Press `Alt-R` to enable regex mode | ||
| 81 | -3. Type `[0-9]+` (finds number sequences) | ||
| 82 | -4. Press Enter | ||
| 83 | -5. **Expected:** "123" should be highlighted | ||
| 84 | -6. Press `Ctrl-F` for next | ||
| 85 | -7. **Expected:** "456" should be highlighted (not "23" or just "1") | ||
| 86 | - | ||
| 87 | -### Test 3: Basic Replace | ||
| 88 | - | ||
| 89 | -1. Press `Ctrl-F` to open search | ||
| 90 | -2. Type `foo` in find field | ||
| 91 | -3. Press Tab to switch to replace field | ||
| 92 | -4. Type `bar` in replace field | ||
| 93 | -5. Press Enter to search and highlight first "foo" | ||
| 94 | -6. Press `Ctrl-R` to replace | ||
| 95 | -7. **Expected:** | ||
| 96 | - - "foo" → "bar" | ||
| 97 | - - Highlight removed | ||
| 98 | - - Cursor at position after "bar" | ||
| 99 | - - Editor does NOT jump to next "foo" | ||
| 100 | -8. Press `Ctrl-F` to manually find next "foo" | ||
| 101 | -9. Press `Ctrl-R` to replace again | ||
| 102 | - | ||
| 103 | -### Test 4: Regex Replace (Variable Length) | ||
| 104 | - | ||
| 105 | -1. Press `Ctrl-F`, enable regex with `Alt-R` | ||
| 106 | -2. Find field: `test[0-9]+` | ||
| 107 | -3. Replace field: `REPLACED` | ||
| 108 | -4. Press Enter to find "test123" | ||
| 109 | -5. **Expected:** All 7 characters highlighted | ||
| 110 | -6. Press `Ctrl-R` to replace | ||
| 111 | -7. **Expected:** | ||
| 112 | - - "test123" → "REPLACED" | ||
| 113 | - - Cursor at end of "REPLACED" | ||
| 114 | - - No selection/highlight | ||
| 115 | - - Match count decreases | ||
| 116 | - | ||
| 117 | -## Workflow Improvements | ||
| 118 | - | ||
| 119 | -### Before Fix | ||
| 120 | -``` | ||
| 121 | -Ctrl-F → find → [highlighted] → Ctrl-R → [jumps to next, still highlighted] | ||
| 122 | -``` | ||
| 123 | -User has to manually clear selection to position cursor | ||
| 124 | - | ||
| 125 | -### After Fix | ||
| 126 | -``` | ||
| 127 | -Ctrl-F → find → [highlighted] → Ctrl-R → [no highlight, cursor at end] | ||
| 128 | -``` | ||
| 129 | -Clean replacement, cursor ready for editing | ||
| 130 | - | ||
| 131 | -### Replace Workflow | ||
| 132 | -``` | ||
| 133 | -1. Ctrl-F → search for pattern | ||
| 134 | -2. Tab → switch to replace field | ||
| 135 | -3. Type replacement text | ||
| 136 | -4. Enter → find first match (highlighted) | ||
| 137 | -5. Ctrl-R → replace (clears highlight, stays in place) | ||
| 138 | -6. Ctrl-F → find next match | ||
| 139 | -7. Ctrl-R → replace | ||
| 140 | -8. Repeat 6-7 as needed | ||
| 141 | -``` | ||
| 142 | - | ||
| 143 | -Or for replace all: | ||
| 144 | -``` | ||
| 145 | -1. Ctrl-F → search for pattern | ||
| 146 | -2. Tab → switch to replace field | ||
| 147 | -3. Type replacement text | ||
| 148 | -4. Ctrl-A → replace all matches at once | ||
| 149 | -``` | ||
| 150 | - | ||
| 151 | -## Related Files | ||
| 152 | - | ||
| 153 | -- `src/ui/unified_search_module.f90` - Main search/replace implementation | ||
| 154 | -- `src/terminal/renderer_module.f90` - Handles selection rendering (reverse video) | ||
| 155 | -- `src/utils/regex_module.f90` - Regex pattern matching | ||
| 156 | -- `src/utils/regex_wrapper.c` - POSIX regex C bindings | ||
| 157 | - | ||
| 158 | -## Build | ||
| 159 | - | ||
| 160 | -```bash | ||
| 161 | -make clean && make | ||
| 162 | -``` | ||
| 163 | - | ||
| 164 | -Build completed successfully with no warnings or errors. | ||
scratch_files/SEARCH_STATE_FIX.mddeleted@@ -1,151 +0,0 @@ | |||
| 1 | -# Search State Pollution Bug Fix | ||
| 2 | - | ||
| 3 | -## Issue | ||
| 4 | -When changing search patterns or toggling search options (case sensitivity, whole word, regex), the search would use stale state from the previous search, causing matches to appear at incorrect locations. | ||
| 5 | - | ||
| 6 | -### Reproduction Steps | ||
| 7 | -1. Enable regex mode (Alt-R) | ||
| 8 | -2. Search for a regex pattern (e.g., `[0-9]+`) | ||
| 9 | -3. Press Ctrl-F to find first match | ||
| 10 | -4. Backspace to clear pattern | ||
| 11 | -5. Type a new literal pattern (e.g., "Email") | ||
| 12 | -6. Press Ctrl-F to search | ||
| 13 | -7. **Bug:** The highlight appears at the wrong location | ||
| 14 | - | ||
| 15 | -### Root Cause | ||
| 16 | -The code tracked whether a search was "active" with `search_mode_active`, which determined whether pressing Ctrl-F would: | ||
| 17 | -- Start a new search (if `search_mode_active = .false.`) | ||
| 18 | -- Find the next match (if `search_mode_active = .true.`) | ||
| 19 | - | ||
| 20 | -**The problem:** When you changed the search pattern or options, `search_mode_active` stayed `true`, so pressing Ctrl-F would call `search_forward` (find next) instead of `perform_search` (new search). | ||
| 21 | - | ||
| 22 | -`search_forward` doesn't recompile regex patterns or reset search state, leading to: | ||
| 23 | -- Using the old compiled regex instead of the new pattern | ||
| 24 | -- Incorrect match lengths from previous searches | ||
| 25 | -- Highlights appearing at wrong positions | ||
| 26 | - | ||
| 27 | -## Solution | ||
| 28 | - | ||
| 29 | -Added change detection that resets `search_mode_active` when the search parameters change. | ||
| 30 | - | ||
| 31 | -### New Module Variables | ||
| 32 | - | ||
| 33 | -```fortran | ||
| 34 | -! Track last search parameters to detect changes | ||
| 35 | -character(len=:), allocatable :: last_search_pattern | ||
| 36 | -logical :: last_case_sensitive = .false. | ||
| 37 | -logical :: last_whole_word = .false. | ||
| 38 | -logical :: last_use_regex = .false. | ||
| 39 | -``` | ||
| 40 | - | ||
| 41 | -### Change Detection Logic | ||
| 42 | - | ||
| 43 | -In the Ctrl-F handler (line 144-154): | ||
| 44 | - | ||
| 45 | -```fortran | ||
| 46 | -! Check if search parameters changed - if so, reset search mode | ||
| 47 | -if (search_mode_active) then | ||
| 48 | - if (.not. allocated(last_search_pattern) .or. & | ||
| 49 | - current_search_pattern /= last_search_pattern .or. & | ||
| 50 | - case_sensitive .neqv. last_case_sensitive .or. & | ||
| 51 | - whole_word .neqv. last_whole_word .or. & | ||
| 52 | - use_regex .neqv. last_use_regex) then | ||
| 53 | - ! Parameters changed - treat as new search | ||
| 54 | - search_mode_active = .false. | ||
| 55 | - end if | ||
| 56 | -end if | ||
| 57 | -``` | ||
| 58 | - | ||
| 59 | -**Note:** Used `.neqv.` (not equivalent) for logical comparisons instead of `/=` (Fortran requirement). | ||
| 60 | - | ||
| 61 | -### Save Parameters After Search | ||
| 62 | - | ||
| 63 | -After performing a new search (line 162-168): | ||
| 64 | - | ||
| 65 | -```fortran | ||
| 66 | -! Save current parameters | ||
| 67 | -if (allocated(last_search_pattern)) deallocate(last_search_pattern) | ||
| 68 | -allocate(character(len=len(current_search_pattern)) :: last_search_pattern) | ||
| 69 | -last_search_pattern = current_search_pattern | ||
| 70 | -last_case_sensitive = case_sensitive | ||
| 71 | -last_whole_word = whole_word | ||
| 72 | -last_use_regex = use_regex | ||
| 73 | -``` | ||
| 74 | - | ||
| 75 | -### Cleanup | ||
| 76 | - | ||
| 77 | -Updated `clear_search_pattern()` to reset tracking variables (line 615-634). | ||
| 78 | - | ||
| 79 | -## Testing | ||
| 80 | - | ||
| 81 | -### Test Case 1: Pattern Change | ||
| 82 | -``` | ||
| 83 | -1. Open scratch_files/test_search_state.txt | ||
| 84 | -2. Ctrl-F → Alt-R (enable regex) → type "[0-9]+" | ||
| 85 | -3. Ctrl-F → highlights "123" | ||
| 86 | -4. Backspace all, type "Email" | ||
| 87 | -5. Ctrl-F → should highlight first "Email" correctly ✅ | ||
| 88 | -``` | ||
| 89 | - | ||
| 90 | -### Test Case 2: Regex Toggle | ||
| 91 | -``` | ||
| 92 | -1. Ctrl-F → type "test" | ||
| 93 | -2. Ctrl-F → finds "test" (literal) | ||
| 94 | -3. Alt-R (enable regex) → pattern unchanged but mode changed | ||
| 95 | -4. Ctrl-F → should restart search from beginning ✅ | ||
| 96 | -``` | ||
| 97 | - | ||
| 98 | -### Test Case 3: Case Sensitivity Toggle | ||
| 99 | -``` | ||
| 100 | -1. Ctrl-F → type "email" | ||
| 101 | -2. Ctrl-F → finds "email" (case insensitive) | ||
| 102 | -3. Alt-C (enable case sensitivity) → pattern unchanged but case changed | ||
| 103 | -4. Ctrl-F → should restart search, not find "Email" ✅ | ||
| 104 | -``` | ||
| 105 | - | ||
| 106 | -### Test Case 4: No Change (Normal Cycling) | ||
| 107 | -``` | ||
| 108 | -1. Ctrl-F → type "test" | ||
| 109 | -2. Ctrl-F → finds first "test" | ||
| 110 | -3. Ctrl-F → finds second "test" (no parameter change) | ||
| 111 | -4. Ctrl-F → finds third "test" (cycling works) ✅ | ||
| 112 | -``` | ||
| 113 | - | ||
| 114 | -## Technical Notes | ||
| 115 | - | ||
| 116 | -### Fortran Logical Comparison | ||
| 117 | -Cannot use `/=` for logical values. Must use: | ||
| 118 | -- `.eqv.` for equivalence (like `==`) | ||
| 119 | -- `.neqv.` for non-equivalence (like `!=`) | ||
| 120 | - | ||
| 121 | -### String Comparison | ||
| 122 | -Can use standard `/=` for character strings. | ||
| 123 | - | ||
| 124 | -### Allocation Checking | ||
| 125 | -`allocated(last_search_pattern)` returns `.false.` on first search, which correctly triggers "treat as new search". | ||
| 126 | - | ||
| 127 | -## Files Modified | ||
| 128 | - | ||
| 129 | -- `src/ui/unified_search_module.f90`: | ||
| 130 | - - Added tracking variables (lines 37-41) | ||
| 131 | - - Added change detection (lines 144-154) | ||
| 132 | - - Added parameter saving (lines 162-168) | ||
| 133 | - - Updated cleanup (lines 615-634) | ||
| 134 | - | ||
| 135 | -## Build | ||
| 136 | - | ||
| 137 | -```bash | ||
| 138 | -make clean && make | ||
| 139 | -``` | ||
| 140 | - | ||
| 141 | -Build completed successfully with no errors. | ||
| 142 | - | ||
| 143 | -## Impact | ||
| 144 | - | ||
| 145 | -This fix ensures that: | ||
| 146 | -1. ✅ Changing search patterns always starts a fresh search | ||
| 147 | -2. ✅ Toggling search options (Alt-R, Alt-C, Alt-W) restarts search | ||
| 148 | -3. ✅ Normal search cycling (Ctrl-F repeatedly) still works | ||
| 149 | -4. ✅ Regex compilation happens when needed | ||
| 150 | -5. ✅ Match highlights appear at correct positions | ||
| 151 | -6. ✅ No state pollution between different searches | ||
scratch_files/UNTITLED.txtdeleted@@ -1,1 +0,0 @@ | |||
| 1 | -asdf | ||
scratch_files/VERSION_AND_HELP_FLAGS.mddeleted@@ -1,127 +0,0 @@ | |||
| 1 | -# Version and Help Flags Implementation | ||
| 2 | - | ||
| 3 | -## Overview | ||
| 4 | - | ||
| 5 | -Added command-line argument support for `--version`, `-v`, `--help`, and `-h` flags with version pulled from a single source of truth. | ||
| 6 | - | ||
| 7 | -## Implementation | ||
| 8 | - | ||
| 9 | -### Single Source of Truth | ||
| 10 | - | ||
| 11 | -**VERSION file**: Contains just the version number (e.g., `0.7.5`) | ||
| 12 | -- Located at project root | ||
| 13 | -- Easy to update in one place | ||
| 14 | -- Read by Makefile during build | ||
| 15 | - | ||
| 16 | -### Auto-Generated Version Module | ||
| 17 | - | ||
| 18 | -**Makefile changes**: | ||
| 19 | -```makefile | ||
| 20 | -VERSION := $(shell cat VERSION 2>/dev/null || echo "unknown") | ||
| 21 | - | ||
| 22 | -# Generate version module before building | ||
| 23 | -src/version_module.f90: VERSION | ||
| 24 | - @echo "Generating version module..." | ||
| 25 | - @echo "module version_module" > $@ | ||
| 26 | - @echo " implicit none" >> $@ | ||
| 27 | - @echo " character(len=*), parameter :: VERSION = '$(VERSION)'" >> $@ | ||
| 28 | - @echo "end module version_module" >> $@ | ||
| 29 | -``` | ||
| 30 | - | ||
| 31 | -This generates `src/version_module.f90` which is compiled into the binary. | ||
| 32 | - | ||
| 33 | -### Main Program Changes | ||
| 34 | - | ||
| 35 | -**app/main.f90**: | ||
| 36 | -- Added `use version_module` to import VERSION constant | ||
| 37 | -- Added argument parsing for `--version`, `-v`, `--help`, `-h` | ||
| 38 | -- Added `print_help()` subroutine with comprehensive key bindings reference | ||
| 39 | - | ||
| 40 | -## Usage | ||
| 41 | - | ||
| 42 | -```bash | ||
| 43 | -# Show version | ||
| 44 | -./fac --version | ||
| 45 | -./fac -v | ||
| 46 | - | ||
| 47 | -# Show help | ||
| 48 | -./fac --help | ||
| 49 | -./fac -h | ||
| 50 | - | ||
| 51 | -# Open file (works as before) | ||
| 52 | -./fac myfile.txt | ||
| 53 | - | ||
| 54 | -# Open empty editor (works as before) | ||
| 55 | -./fac | ||
| 56 | -``` | ||
| 57 | - | ||
| 58 | -## Output Examples | ||
| 59 | - | ||
| 60 | -### Version | ||
| 61 | -``` | ||
| 62 | -$ ./fac -v | ||
| 63 | -fac version 0.7.5 | ||
| 64 | -``` | ||
| 65 | - | ||
| 66 | -### Help | ||
| 67 | -``` | ||
| 68 | -$ ./fac -h | ||
| 69 | -fac - Fortran text editor | ||
| 70 | -Version: 0.7.5 | ||
| 71 | - | ||
| 72 | -Usage: | ||
| 73 | - fac [filename] Open a file for editing | ||
| 74 | - fac Start with empty buffer | ||
| 75 | - fac --version, -v Show version information | ||
| 76 | - fac --help, -h Show this help message | ||
| 77 | - | ||
| 78 | -Key Bindings: | ||
| 79 | - Ctrl-Q Quit | ||
| 80 | - Ctrl-S Save | ||
| 81 | - Ctrl-F Find/Replace (unified prompt) | ||
| 82 | - ... | ||
| 83 | -``` | ||
| 84 | - | ||
| 85 | -## Updating Version | ||
| 86 | - | ||
| 87 | -To update the version for a new release: | ||
| 88 | - | ||
| 89 | -1. Update the VERSION file: | ||
| 90 | - ```bash | ||
| 91 | - echo "0.8.0" > VERSION | ||
| 92 | - ``` | ||
| 93 | - | ||
| 94 | -2. Rebuild: | ||
| 95 | - ```bash | ||
| 96 | - make clean && make | ||
| 97 | - ``` | ||
| 98 | - | ||
| 99 | -3. The new version is automatically included in the binary. | ||
| 100 | - | ||
| 101 | -4. Optionally, create a git tag: | ||
| 102 | - ```bash | ||
| 103 | - git tag v0.8.0 | ||
| 104 | - git push --tags | ||
| 105 | - ``` | ||
| 106 | - | ||
| 107 | -## Benefits | ||
| 108 | - | ||
| 109 | -✅ **Single source of truth**: Version defined once in VERSION file | ||
| 110 | -✅ **No manual sync needed**: Makefile auto-generates the module | ||
| 111 | -✅ **Standard flags**: Follows Unix conventions (`-h`, `-v`) | ||
| 112 | -✅ **Comprehensive help**: Shows all key bindings in one place | ||
| 113 | -✅ **Clean build**: Generated file cleaned by `make clean` | ||
| 114 | - | ||
| 115 | -## Files Modified | ||
| 116 | - | ||
| 117 | -- `VERSION` (new): Version number | ||
| 118 | -- `Makefile`: Added version module generation | ||
| 119 | -- `app/main.f90`: Added argument parsing and help | ||
| 120 | -- `src/version_module.f90` (auto-generated): Not tracked in git | ||
| 121 | - | ||
| 122 | -## Files to Track in Git | ||
| 123 | - | ||
| 124 | -- ✅ `VERSION` - The source of truth | ||
| 125 | -- ✅ `Makefile` - Build logic | ||
| 126 | -- ✅ `app/main.f90` - Argument handling | ||
| 127 | -- ❌ `src/version_module.f90` - Auto-generated, add to `.gitignore` | ||
scratch_files/ctrl_d_demo.txtdeleted@@ -1,64 +0,0 @@ | |||
| 1 | -================================================== | ||
| 2 | - CTRL-D DEMONSTRATION - SELECT NEXT MATCH | ||
| 3 | -================================================== | ||
| 4 | - | ||
| 5 | -🎯 VSCode-Style Multiple Selection with Ctrl-D! | ||
| 6 | - | ||
| 7 | -HOW IT WORKS: | ||
| 8 | -1. Place cursor on any word | ||
| 9 | -2. Press Ctrl-D to select the current word | ||
| 10 | -3. Press Ctrl-D again to select the next occurrence | ||
| 11 | -4. Keep pressing to add more matches | ||
| 12 | -5. Type to replace all selected instances! | ||
| 13 | - | ||
| 14 | -TEST EXAMPLE 1 - Variable Renaming: | ||
| 15 | ----------------------------------------- | ||
| 16 | -function test() { | ||
| 17 | - var count = 0; | ||
| 18 | - count = count + 1; | ||
| 19 | - console.log(count); | ||
| 20 | - return count; | ||
| 21 | -} | ||
| 22 | - | ||
| 23 | -Try it: Place cursor on "count" and hit Ctrl-D multiple times, | ||
| 24 | -then type "total" to rename all instances! | ||
| 25 | - | ||
| 26 | -TEST EXAMPLE 2 - Multiple Words: | ||
| 27 | ----------------------------------------- | ||
| 28 | -The quick brown fox jumps over the lazy dog. | ||
| 29 | -The quick brown fox runs fast. | ||
| 30 | -The quick brown fox is clever. | ||
| 31 | - | ||
| 32 | -Place cursor on "quick" and use Ctrl-D to select all, | ||
| 33 | -then change them all at once! | ||
| 34 | - | ||
| 35 | -TEST EXAMPLE 3 - Code Refactoring: | ||
| 36 | ----------------------------------------- | ||
| 37 | -user.name = "John"; | ||
| 38 | -user.age = 30; | ||
| 39 | -user.email = "john@example.com"; | ||
| 40 | -user.active = true; | ||
| 41 | -user.lastLogin = Date.now(); | ||
| 42 | - | ||
| 43 | -Select all "user" instances with Ctrl-D and rename to "customer"! | ||
| 44 | - | ||
| 45 | -FEATURES: | ||
| 46 | -✅ Selects current word on first Ctrl-D | ||
| 47 | -✅ Finds next match on subsequent Ctrl-D | ||
| 48 | -✅ Each selection has its own cursor | ||
| 49 | -✅ All selections are highlighted | ||
| 50 | -✅ Typing replaces all selections simultaneously | ||
| 51 | -✅ Arrow keys clear selections | ||
| 52 | -✅ Status bar shows cursor count | ||
| 53 | - | ||
| 54 | -COMBINING WITH OTHER FEATURES: | ||
| 55 | -- After selecting with Ctrl-D, you can: | ||
| 56 | - - Type to replace all | ||
| 57 | - - Use Ctrl-K to kill all selected text | ||
| 58 | - - Use Ctrl-C to copy (current line for now) | ||
| 59 | - - Click elsewhere to cancel | ||
| 60 | - | ||
| 61 | -================================================== | ||
| 62 | -Ctrl-D completes the VSCode experience in Facsimile! | ||
| 63 | -All 22 original keybinds are now implemented! 🎉 | ||
| 64 | -================================================== | ||
scratch_files/cursor_test.txtdeleted@@ -1,48 +0,0 @@ | |||
| 1 | -Cursor Position Test File | ||
| 2 | -========================= | ||
| 3 | - | ||
| 4 | -Test 1: Line Numbers and Cursor Alignment | ||
| 5 | ------------------------------------------- | ||
| 6 | -Place cursor at the start of each line. The cursor should appear | ||
| 7 | -right after the line number area, not on top of the line numbers. | ||
| 8 | - | ||
| 9 | -Line 7: Short line | ||
| 10 | -Line 8: A slightly longer line with more content | ||
| 11 | -Line 9: Test cursor positioning at different columns | ||
| 12 | -Line 10: Move cursor to different positions on this line | ||
| 13 | - | ||
| 14 | -Test 2: Selection with Alt-Shift-Right | ||
| 15 | ---------------------------------------- | ||
| 16 | -Position cursor at start of each word and press Alt-Shift-Right. | ||
| 17 | -It should select the CURRENT word, not the next word. | ||
| 18 | - | ||
| 19 | -word1 word2 word3 word4 word5 word6 | ||
| 20 | -shortword longword mediumword w x y z | ||
| 21 | -testing selection accuracy here | ||
| 22 | - | ||
| 23 | -Test 3: Pane Split Testing | ||
| 24 | --------------------------- | ||
| 25 | -1. Press Alt-V to split vertically | ||
| 26 | -2. Cursor should be visible in the active pane | ||
| 27 | -3. Cursor position should respect line number area | ||
| 28 | -4. Arrow keys should work normally | ||
| 29 | - | ||
| 30 | -Test 4: Multiple Panes | ||
| 31 | ----------------------- | ||
| 32 | -1. Create multiple panes with Alt-V and Alt-S | ||
| 33 | -2. Navigate between panes with Alt-H/J/K/L | ||
| 34 | -3. Verify cursor stays in correct position | ||
| 35 | -4. Verify line numbers display correctly in all panes | ||
| 36 | - | ||
| 37 | -Test lines for scrolling: | ||
| 38 | -Line 32: Lorem ipsum dolor sit amet, consectetur adipiscing elit | ||
| 39 | -Line 33: Sed do eiusmod tempor incididunt ut labore et dolore magna | ||
| 40 | -Line 34: Ut enim ad minim veniam, quis nostrud exercitation ullamco | ||
| 41 | -Line 35: Laboris nisi ut aliquip ex ea commodo consequat duis aute | ||
| 42 | -Line 36: Irure dolor in reprehenderit in voluptate velit esse cillum | ||
| 43 | -Line 37: Dolore eu fugiat nulla pariatur excepteur sint occaecat | ||
| 44 | -Line 38: Cupidatat non proident, sunt in culpa qui officia deserunt | ||
| 45 | -Line 39: Mollit anim id est laborum sed ut perspiciatis unde omnis | ||
| 46 | -Line 40: Iste natus error sit voluptatem accusantium doloremque | ||
| 47 | -Line 41: Laudantium totam rem aperiam eaque ipsa quae ab illo | ||
| 48 | -Line 42: End of test content | ||
scratch_files/demo.txtdeleted@@ -1,48 +0,0 @@ | |||
| 1 | -================================================== | ||
| 2 | - FACSIMILE EDITOR - FEATURE DEMO | ||
| 3 | -================================================== | ||
| 4 | - | ||
| 5 | -TEST QUOTE CYCLING (place cursor inside and press ctrl-'): | ||
| 6 | -"This text is in double quotes" | ||
| 7 | -'This text is in single quotes' | ||
| 8 | -`This text is in backticks` | ||
| 9 | - | ||
| 10 | -TEST BRACKET REMOVAL (place cursor inside and press ctrl-opt-backspace): | ||
| 11 | -(Remove these parentheses) | ||
| 12 | -[Remove these square brackets] | ||
| 13 | -{Remove these curly braces} | ||
| 14 | - | ||
| 15 | -TEST WORD JUMPING (use alt-left/right): | ||
| 16 | -The quick brown fox jumps over the lazy dog | ||
| 17 | - | ||
| 18 | -TEST LINE MANIPULATION: | ||
| 19 | -Line 1 - Move me with alt-up/down | ||
| 20 | -Line 2 - Duplicate me with alt-shift-up/down | ||
| 21 | -Line 3 - I stay in place | ||
| 22 | - | ||
| 23 | -TEST CLIPBOARD OPERATIONS: | ||
| 24 | -Copy this line with ctrl-c | ||
| 25 | -Cut this line with ctrl-x | ||
| 26 | -Then paste with ctrl-v | ||
| 27 | - | ||
| 28 | -TEST YANK STACK: | ||
| 29 | -Kill this forward with ctrl-k (from cursor) | ||
| 30 | -Kill this backward with ctrl-u (from cursor) | ||
| 31 | -Then yank back with ctrl-y | ||
| 32 | - | ||
| 33 | -PROGRAMMING EXAMPLE: | ||
| 34 | -function calculate(x, y) { | ||
| 35 | - return (x + y) * 2; | ||
| 36 | -} | ||
| 37 | - | ||
| 38 | -const result = calculate(5, 10); | ||
| 39 | -console.log("Result is: " + result); | ||
| 40 | - | ||
| 41 | -================================================== | ||
| 42 | -All implemented keybinds work! Try them out: | ||
| 43 | -- Navigation: arrows, ctrl-a/e, alt-left/right | ||
| 44 | -- Editing: ctrl-k/u/y, ctrl-x/c/v | ||
| 45 | -- Line ops: alt-up/down, alt-shift-up/down | ||
| 46 | -- Special: ctrl-', ctrl-opt-backspace | ||
| 47 | -- File: ctrl-s (save), ctrl-q (quit) | ||
| 48 | -================================================== | ||
scratch_files/help_test.txtdeleted@@ -1,19 +0,0 @@ | |||
| 1 | -Help Menu Test | ||
| 2 | -============== | ||
| 3 | - | ||
| 4 | -Press ctrl-? (ctrl-shift-/) to open the help menu. | ||
| 5 | - | ||
| 6 | -The help menu shows all 38 keybindings organized by category: | ||
| 7 | -- Navigation | ||
| 8 | -- Selection | ||
| 9 | -- Editing | ||
| 10 | -- Clipboard | ||
| 11 | -- Lines | ||
| 12 | -- Multiple Cursors | ||
| 13 | -- Special | ||
| 14 | -- File | ||
| 15 | -- Help | ||
| 16 | - | ||
| 17 | -Press any key to close the help menu and return to editing. | ||
| 18 | - | ||
| 19 | -Try it now: ctrl-? | ||
scratch_files/pane_test.txtdeleted@@ -1,20 +0,0 @@ | |||
| 1 | -This is a test file for testing pane functionality. | ||
| 2 | -Line 2 | ||
| 3 | -Line 3 | ||
| 4 | -Line 4 | ||
| 5 | -Line 5 | ||
| 6 | -Line 6 | ||
| 7 | -Line 7 | ||
| 8 | -Line 8 | ||
| 9 | -Line 9 | ||
| 10 | -Line 10 | ||
| 11 | -Line 11 | ||
| 12 | -Line 12 | ||
| 13 | -Line 13 | ||
| 14 | -Line 14 | ||
| 15 | -Line 15 | ||
| 16 | -Line 16 | ||
| 17 | -Line 17 | ||
| 18 | -Line 18 | ||
| 19 | -Line 19 | ||
| 20 | -Line 20 | ||
scratch_files/quick_test.txtdeleted@@ -1,9 +0,0 @@ | |||
| 1 | -Quick test for new features: | ||
| 2 | - | ||
| 3 | -1. Test shift selection: place cursor here and hold shift+right | ||
| 4 | -2. Test word deletion: delete this word with alt+d | ||
| 5 | -3. Test transpose: fix this typo "teh" with ctrl-t | ||
| 6 | -4. Test ctrl-h as backspace | ||
| 7 | -5. Test ctrl-w to delete word backward | ||
| 8 | - | ||
| 9 | -Success! All Phase 2 features are ready to use. | ||
scratch_files/regex_test_examples.txtdeleted@@ -1,139 +0,0 @@ | |||
| 1 | -# Regex Test Examples | ||
| 2 | -# This file contains various text patterns for testing regex search functionality | ||
| 3 | - | ||
| 4 | -## Email Addresses | ||
| 5 | -Contact us at support@example.com or sales@company.org | ||
| 6 | -Bug reports: bugs@opensource.dev | ||
| 7 | -Personal: john.doe@gmail.com, jane_smith@yahoo.co.uk | ||
| 8 | -Invalid: notanemail@, @missing.com, missing@ | ||
| 9 | - | ||
| 10 | -## Phone Numbers | ||
| 11 | -Call us: (555) 123-4567 | ||
| 12 | -International: +1-800-555-0199 | ||
| 13 | -Alternative format: 555.867.5309 | ||
| 14 | -No separators: 5551234567 | ||
| 15 | -European style: +44 20 7946 0958 | ||
| 16 | - | ||
| 17 | -## URLs and Paths | ||
| 18 | -Visit https://www.example.com for more info | ||
| 19 | -HTTP site: http://legacy.site.org/old/path | ||
| 20 | -File paths: /usr/local/bin/editor | ||
| 21 | -Windows: C:\Users\Documents\file.txt | ||
| 22 | -Relative: ./src/utils/regex_module.f90 | ||
| 23 | -Git remote: git@github.com:user/repo.git | ||
| 24 | - | ||
| 25 | -## Dates and Times | ||
| 26 | -Meeting on 2024-01-15 at 14:30 | ||
| 27 | -Format: 01/15/2024, 15-Jan-2024 | ||
| 28 | -ISO 8601: 2024-01-15T14:30:00Z | ||
| 29 | -Timestamp: 1705329000 | ||
| 30 | - | ||
| 31 | -## Numbers and Currency | ||
| 32 | -Price: $49.99, €39.50, £29.99 | ||
| 33 | -Scientific: 1.23e-4, 6.022E23 | ||
| 34 | -Hex: 0xFF00AB, #3399CC | ||
| 35 | -Binary: 0b101010, bits: 101010 | ||
| 36 | -Percentages: 75%, 0.5%, 100.0% | ||
| 37 | - | ||
| 38 | -## Code Patterns | ||
| 39 | -function calculate_total(items, tax_rate) | ||
| 40 | -let result = api.fetchData() | ||
| 41 | -const MAX_RETRIES = 3 | ||
| 42 | -if (count > 0 && status == "active") | ||
| 43 | -TODO: Fix this edge case | ||
| 44 | -FIXME: Memory leak here | ||
| 45 | -BUG: Crashes on empty input | ||
| 46 | - | ||
| 47 | -## IP Addresses and MAC | ||
| 48 | -Server: 192.168.1.100 | ||
| 49 | -IPv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | ||
| 50 | -MAC: 00:1A:2B:3C:4D:5E | ||
| 51 | -Localhost: 127.0.0.1 | ||
| 52 | - | ||
| 53 | -## Log Entries | ||
| 54 | -[ERROR] 2024-01-15 10:23:45 Connection timeout | ||
| 55 | -[WARN] Database query slow (1.2s) | ||
| 56 | -[INFO] User login successful: user_id=12345 | ||
| 57 | -[DEBUG] Cache hit ratio: 0.85 | ||
| 58 | - | ||
| 59 | -## Version Numbers | ||
| 60 | -v1.2.3, version 2.10.4-beta | ||
| 61 | -Semver: 0.0.1-alpha+build.123 | ||
| 62 | -Package: lodash@4.17.21 | ||
| 63 | -Node: node-v18.12.0 | ||
| 64 | - | ||
| 65 | -## HTML/XML Tags | ||
| 66 | -<div class="container" id="main"> | ||
| 67 | -<p>This is a paragraph.</p> | ||
| 68 | -</div> | ||
| 69 | -<!-- Comment block --> | ||
| 70 | -Self-closing: <img src="photo.jpg" /> | ||
| 71 | - | ||
| 72 | -## Markdown Patterns | ||
| 73 | -# Heading 1 | ||
| 74 | -## Heading 2 | ||
| 75 | -**bold text** and *italic text* | ||
| 76 | -[link text](https://example.com) | ||
| 77 | - | ||
| 78 | -`inline code` and ```code block``` | ||
| 79 | - | ||
| 80 | -## Variables and Identifiers | ||
| 81 | -var userName = "John" | ||
| 82 | -int MAX_COUNT = 100 | ||
| 83 | -private String _internalValue | ||
| 84 | -snake_case_variable | ||
| 85 | -camelCaseVariable | ||
| 86 | -PascalCaseClass | ||
| 87 | -CONSTANT_VALUE | ||
| 88 | - | ||
| 89 | -## Whitespace Patterns | ||
| 90 | -Multiple spaces here | ||
| 91 | - Tab separated values | ||
| 92 | -Mixed spaces and tabs | ||
| 93 | -Trailing whitespace at end | ||
| 94 | -Leading whitespace | ||
| 95 | - | ||
| 96 | -## Word Boundaries | ||
| 97 | -The cat sat on the mat | ||
| 98 | -Category, cathedral, concatenate (don't match just 'cat') | ||
| 99 | -Test test123 testing | ||
| 100 | -Match 'test' as whole word only | ||
| 101 | - | ||
| 102 | -## Repeated Patterns | ||
| 103 | -Ha ha ha ha ha! | ||
| 104 | -123-456-789-012 | ||
| 105 | -one, two, three, four, five | ||
| 106 | -AAA BBB CCC DDD EEE | ||
| 107 | - | ||
| 108 | -## Case Variations | ||
| 109 | -UPPERCASE text here | ||
| 110 | -lowercase text here | ||
| 111 | -MixedCase TeXt HeRe | ||
| 112 | -CamelCase PascalCase snake_case SCREAMING_SNAKE_CASE | ||
| 113 | - | ||
| 114 | -## Special Characters | ||
| 115 | -Price range: $10-$50 | ||
| 116 | -Email: user+tag@domain.com | ||
| 117 | -Regex chars: . * + ? ^ $ ( ) [ ] { } | \ | ||
| 118 | -Quotes: "double" and 'single' | ||
| 119 | -Parentheses: (nested (groups) here) | ||
| 120 | - | ||
| 121 | -## File Extensions | ||
| 122 | -script.sh, document.pdf, image.png | ||
| 123 | -Source: main.f90, utils.c, header.h | ||
| 124 | -Archive: data.tar.gz, backup.zip | ||
| 125 | -Hidden: .gitignore, .env, .bashrc | ||
| 126 | - | ||
| 127 | -## Common Patterns | ||
| 128 | -UUID: 550e8400-e29b-41d4-a716-446655440000 | ||
| 129 | -Git SHA: a1b2c3d4e5f6789012345678901234567890abcd | ||
| 130 | -Base64: SGVsbG8gV29ybGQh== | ||
| 131 | -Credit card: 4532-1234-5678-9010 (test number) | ||
| 132 | - | ||
| 133 | -## Edge Cases | ||
| 134 | -Empty line follows: | ||
| 135 | - | ||
| 136 | -Line with only spaces: | ||
| 137 | -Numbers: 0, -1, +42, 3.14159 | ||
| 138 | -Special: ñoño, café, 日本語 | ||
| 139 | -Emoji test: 🎉 🚀 ✅ (might not work with POSIX) | ||
scratch_files/regex_test_patterns.mddeleted@@ -1,172 +0,0 @@ | |||
| 1 | -# Regex Test Patterns | ||
| 2 | - | ||
| 3 | -This document lists regex patterns to test with `regex_test_examples.txt` | ||
| 4 | - | ||
| 5 | -## Basic Patterns | ||
| 6 | - | ||
| 7 | -### Email Addresses | ||
| 8 | -**Pattern:** `[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}` | ||
| 9 | -**Should match:** All valid emails in the Email Addresses section | ||
| 10 | -**Should NOT match:** The invalid email examples | ||
| 11 | - | ||
| 12 | -### Phone Numbers (US Format) | ||
| 13 | -**Pattern:** `\([0-9]{3}\) [0-9]{3}-[0-9]{4}` | ||
| 14 | -**Matches:** `(555) 123-4567` | ||
| 15 | - | ||
| 16 | -**Pattern:** `\+?[0-9]{1,3}[- ]?[0-9]{3}[- .]?[0-9]{3,4}[- .]?[0-9]{4}` | ||
| 17 | -**Matches:** Most phone number formats | ||
| 18 | - | ||
| 19 | -### URLs | ||
| 20 | -**Pattern:** `https?://[a-zA-Z0-9./-]+` | ||
| 21 | -**Matches:** HTTP and HTTPS URLs | ||
| 22 | - | ||
| 23 | -**Pattern:** `[a-z]+@[a-z]+\.[a-z]+:[a-z]+/[a-z]+\.git` | ||
| 24 | -**Matches:** Git URLs like `git@github.com:user/repo.git` | ||
| 25 | - | ||
| 26 | -### IP Addresses (simple) | ||
| 27 | -**Pattern:** `[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}` | ||
| 28 | -**Matches:** Basic IPv4 addresses | ||
| 29 | - | ||
| 30 | -### File Paths | ||
| 31 | -**Pattern:** `/[a-zA-Z0-9/_.-]+` | ||
| 32 | -**Matches:** Unix-style absolute paths | ||
| 33 | - | ||
| 34 | -**Pattern:** `\./[a-zA-Z0-9/_.-]+` | ||
| 35 | -**Matches:** Relative paths starting with ./ | ||
| 36 | - | ||
| 37 | -## Date and Time Patterns | ||
| 38 | - | ||
| 39 | -### ISO Date | ||
| 40 | -**Pattern:** `[0-9]{4}-[0-9]{2}-[0-9]{2}` | ||
| 41 | -**Matches:** `2024-01-15` | ||
| 42 | - | ||
| 43 | -### ISO DateTime | ||
| 44 | -**Pattern:** `[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z?` | ||
| 45 | -**Matches:** ISO 8601 timestamps | ||
| 46 | - | ||
| 47 | -### Time | ||
| 48 | -**Pattern:** `[0-9]{2}:[0-9]{2}(:[0-9]{2})?` | ||
| 49 | -**Matches:** Times like `14:30` or `14:30:00` | ||
| 50 | - | ||
| 51 | -## Number Patterns | ||
| 52 | - | ||
| 53 | -### Integers | ||
| 54 | -**Pattern:** `[0-9]+` | ||
| 55 | -**Matches:** Any sequence of digits | ||
| 56 | - | ||
| 57 | -### Decimals | ||
| 58 | -**Pattern:** `[0-9]+\.[0-9]+` | ||
| 59 | -**Matches:** Numbers with decimal points | ||
| 60 | - | ||
| 61 | -### Currency | ||
| 62 | -**Pattern:** `[$€£][0-9]+\.[0-9]{2}` | ||
| 63 | -**Matches:** Currency amounts like `$49.99` | ||
| 64 | - | ||
| 65 | -### Hex Colors | ||
| 66 | -**Pattern:** `#[0-9A-Fa-f]{6}` | ||
| 67 | -**Matches:** Hex colors like `#3399CC` | ||
| 68 | - | ||
| 69 | -### Scientific Notation | ||
| 70 | -**Pattern:** `[0-9]+\.[0-9]+[eE][+-]?[0-9]+` | ||
| 71 | -**Matches:** Numbers like `1.23e-4` | ||
| 72 | - | ||
| 73 | -## Code Patterns | ||
| 74 | - | ||
| 75 | -### Function Calls | ||
| 76 | -**Pattern:** `[a-zA-Z_][a-zA-Z0-9_]*\(` | ||
| 77 | -**Matches:** Function names followed by opening parenthesis | ||
| 78 | - | ||
| 79 | -### TODO/FIXME Comments | ||
| 80 | -**Pattern:** `(TODO|FIXME|BUG):` | ||
| 81 | -**Matches:** Common code markers | ||
| 82 | - | ||
| 83 | -### Constants (SCREAMING_SNAKE_CASE) | ||
| 84 | -**Pattern:** `[A-Z][A-Z0-9_]+` | ||
| 85 | -**Matches:** Constants like `MAX_RETRIES` | ||
| 86 | - | ||
| 87 | -### camelCase | ||
| 88 | -**Pattern:** `[a-z]+([A-Z][a-z]+)+` | ||
| 89 | -**Matches:** camelCase identifiers | ||
| 90 | - | ||
| 91 | -## Log Patterns | ||
| 92 | - | ||
| 93 | -### Log Levels | ||
| 94 | -**Pattern:** `\[(ERROR|WARN|INFO|DEBUG)\]` | ||
| 95 | -**Matches:** Log level tags | ||
| 96 | - | ||
| 97 | -### Timestamps in Logs | ||
| 98 | -**Pattern:** `[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}` | ||
| 99 | -**Matches:** Full timestamp in logs | ||
| 100 | - | ||
| 101 | -## Version Patterns | ||
| 102 | - | ||
| 103 | -### Semantic Version | ||
| 104 | -**Pattern:** `v?[0-9]+\.[0-9]+\.[0-9]+` | ||
| 105 | -**Matches:** Basic semver like `1.2.3` or `v2.0.1` | ||
| 106 | - | ||
| 107 | -### With Pre-release | ||
| 108 | -**Pattern:** `[0-9]+\.[0-9]+\.[0-9]+(-[a-z]+)?` | ||
| 109 | -**Matches:** Versions with optional pre-release tag | ||
| 110 | - | ||
| 111 | -## HTML/Markdown Patterns | ||
| 112 | - | ||
| 113 | -### HTML Tags | ||
| 114 | -**Pattern:** `<[a-z]+[^>]*>` | ||
| 115 | -**Matches:** Opening HTML tags | ||
| 116 | - | ||
| 117 | -**Pattern:** `</[a-z]+>` | ||
| 118 | -**Matches:** Closing HTML tags | ||
| 119 | - | ||
| 120 | -### Markdown Headers | ||
| 121 | -**Pattern:** `^##? .*$` | ||
| 122 | -**Matches:** Markdown H1 or H2 headers | ||
| 123 | - | ||
| 124 | -### Markdown Links | ||
| 125 | -**Pattern:** `\[[^\]]+\]\([^)]+\)` | ||
| 126 | -**Matches:** Markdown link syntax | ||
| 127 | - | ||
| 128 | -## Advanced Patterns | ||
| 129 | - | ||
| 130 | -### UUID | ||
| 131 | -**Pattern:** `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}` | ||
| 132 | -**Matches:** UUIDs | ||
| 133 | - | ||
| 134 | -### Git SHA (short) | ||
| 135 | -**Pattern:** `[0-9a-f]{7,40}` | ||
| 136 | -**Matches:** Git commit hashes | ||
| 137 | - | ||
| 138 | -### Word Boundaries | ||
| 139 | -**Pattern:** `\bcat\b` | ||
| 140 | -**Matches:** "cat" as whole word only (not in "category") | ||
| 141 | -**Note:** POSIX uses `[[:<:]]cat[[:>:]]` for word boundaries | ||
| 142 | - | ||
| 143 | -### Repeated Patterns | ||
| 144 | -**Pattern:** `(ha )+` | ||
| 145 | -**Matches:** One or more "ha " sequences | ||
| 146 | - | ||
| 147 | -### Alternation | ||
| 148 | -**Pattern:** `(TODO|FIXME|BUG|HACK)` | ||
| 149 | -**Matches:** Any of the code markers | ||
| 150 | - | ||
| 151 | -## Testing Tips | ||
| 152 | - | ||
| 153 | -1. **Start simple**: Test basic patterns like `[0-9]+` first | ||
| 154 | -2. **Test escaping**: Patterns with `\.` `\*` `\+` etc. | ||
| 155 | -3. **Test anchors**: Use `^` and `$` for line start/end | ||
| 156 | -4. **Test quantifiers**: `*` (0+), `+` (1+), `?` (0-1), `{n,m}` | ||
| 157 | -5. **Test character classes**: `[abc]`, `[^abc]`, `[a-z]` | ||
| 158 | -6. **Test case sensitivity**: Toggle with Alt-C | ||
| 159 | -7. **Test replacement**: Try replacing matches with regex enabled | ||
| 160 | - | ||
| 161 | -## Quick Test Sequence | ||
| 162 | - | ||
| 163 | -1. Open file: `./fac scratch_files/regex_test_examples.txt` | ||
| 164 | -2. Press `Ctrl-F` to open search | ||
| 165 | -3. Press `Alt-R` to enable regex mode | ||
| 166 | -4. Try these in order: | ||
| 167 | - - `[0-9]+` - Find all number sequences | ||
| 168 | - - `@[a-z]+\.[a-z]+` - Find email domains | ||
| 169 | - - `\(.*\)` - Find text in parentheses | ||
| 170 | - - `^##` - Find markdown H2 headers | ||
| 171 | - - `[A-Z]{3,}` - Find uppercase sequences (3+ letters) | ||
| 172 | - - `v?[0-9]+\.[0-9]+\.[0-9]+` - Find version numbers | ||
scratch_files/test.txtdeleted@@ -1,1 +0,0 @@ | |||
| 1 | -Drag select this text | ||
scratch_files/test_cursor_and_arrows.txtdeleted@@ -1,43 +0,0 @@ | |||
| 1 | -Test File for Cursor Visibility and Arrow Keys in Panes | ||
| 2 | -======================================================== | ||
| 3 | - | ||
| 4 | -This file tests the two main issues that were fixed: | ||
| 5 | -1. Cursor visibility in panes | ||
| 6 | -2. Arrow keys working after splitting panes | ||
| 7 | - | ||
| 8 | -Test Instructions: | ||
| 9 | ------------------- | ||
| 10 | - | ||
| 11 | -1. Open this file in the editor | ||
| 12 | -2. Press Alt-V to split the pane vertically | ||
| 13 | -3. Verify that you can see the cursor (it should be visible!) | ||
| 14 | -4. Test arrow keys: | ||
| 15 | - - Up arrow should move cursor up | ||
| 16 | - - Down arrow should move cursor down | ||
| 17 | - - Left arrow should move cursor left | ||
| 18 | - - Right arrow should move cursor right | ||
| 19 | -5. Press Ctrl-Shift-Left to navigate to left pane | ||
| 20 | -6. Verify the cursor is visible in the left pane | ||
| 21 | -7. Test arrow keys again in the left pane | ||
| 22 | -8. Press Alt-S to split horizontally | ||
| 23 | -9. Test arrow keys in the new pane | ||
| 24 | -10. Navigate between panes with Ctrl-Shift-Arrow keys | ||
| 25 | - | ||
| 26 | -Expected Results: | ||
| 27 | ------------------ | ||
| 28 | -- Cursor should always be visible in the active pane | ||
| 29 | -- Arrow keys should work normally in all panes | ||
| 30 | -- Navigation between panes should work smoothly | ||
| 31 | -- Each pane should maintain independent cursor position | ||
| 32 | - | ||
| 33 | -Additional Test Lines: | ||
| 34 | -Line 1: Lorem ipsum dolor sit amet | ||
| 35 | -Line 2: consectetur adipiscing elit | ||
| 36 | -Line 3: sed do eiusmod tempor incididunt | ||
| 37 | -Line 4: ut labore et dolore magna aliqua | ||
| 38 | -Line 5: Ut enim ad minim veniam | ||
| 39 | -Line 6: quis nostrud exercitation ullamco | ||
| 40 | -Line 7: laboris nisi ut aliquip ex ea commodo | ||
| 41 | -Line 8: consequat. Duis aute irure dolor | ||
| 42 | -Line 9: in reprehenderit in voluptate velit | ||
| 43 | -Line 10: esse cillum dolore eu fugiat nulla | ||
scratch_files/test_cursor_fixes.shdeleted@@ -1,37 +0,0 @@ | |||
| 1 | -#!/bin/bash | ||
| 2 | - | ||
| 3 | -echo "Testing Cursor Positioning Fixes" | ||
| 4 | -echo "================================" | ||
| 5 | -echo | ||
| 6 | -echo "This test verifies that cursor positioning works correctly with:" | ||
| 7 | -echo "1. Line numbers - cursor should not overlap with line numbers" | ||
| 8 | -echo "2. Panes - cursor should be visible and positioned correctly" | ||
| 9 | -echo "3. Selections - Alt-Shift-Right should select current word, not next" | ||
| 10 | -echo | ||
| 11 | -echo "Tests to perform:" | ||
| 12 | -echo "-----------------" | ||
| 13 | -echo | ||
| 14 | -echo "TEST 1: Basic Cursor Position" | ||
| 15 | -echo " - Move cursor to start of lines (press Home or Ctrl-A)" | ||
| 16 | -echo " - Cursor should appear AFTER the line numbers, not on them" | ||
| 17 | -echo | ||
| 18 | -echo "TEST 2: Selection Accuracy" | ||
| 19 | -echo " - Position cursor at start of a word" | ||
| 20 | -echo " - Press Alt-Shift-Right" | ||
| 21 | -echo " - Should select the CURRENT word under cursor" | ||
| 22 | -echo | ||
| 23 | -echo "TEST 3: Pane Splits" | ||
| 24 | -echo " - Press Alt-V to split vertically" | ||
| 25 | -echo " - Cursor should be visible" | ||
| 26 | -echo " - Arrow keys should work" | ||
| 27 | -echo " - Cursor should respect line number boundaries" | ||
| 28 | -echo | ||
| 29 | -echo "TEST 4: Pane Navigation" | ||
| 30 | -echo " - Create multiple panes (Alt-V, Alt-S)" | ||
| 31 | -echo " - Navigate with Alt-H (left), Alt-L (right), Alt-K (up), Alt-J (down)" | ||
| 32 | -echo " - Or use Ctrl-Shift-Arrows if not conflicting" | ||
| 33 | -echo | ||
| 34 | -echo "Press Enter to start testing..." | ||
| 35 | -read | ||
| 36 | - | ||
| 37 | -./build/gfortran_*/app/fac cursor_test.txt | ||
scratch_files/test_help_hint.txtdeleted@@ -1,20 +0,0 @@ | |||
| 1 | -Test File for Help Hint in Status Bar | ||
| 2 | -====================================== | ||
| 3 | - | ||
| 4 | -Check the status bar at the bottom of the screen. | ||
| 5 | -You should see: | ||
| 6 | - | ||
| 7 | -Left side: ctrl-b:fuss | filename [modified] | ||
| 8 | -Center: ctrl-/:help | ||
| 9 | -Right side: Ln X, Col Y | ||
| 10 | - | ||
| 11 | -The help hint tells users they can press ctrl-/ to see keybindings. | ||
| 12 | - | ||
| 13 | -Try it: | ||
| 14 | -- Press ctrl-/ to see the help screen | ||
| 15 | -- Press any key to return to editing | ||
| 16 | - | ||
| 17 | -Note: The README has also been updated with: | ||
| 18 | -- Enhanced pane management section with better organization | ||
| 19 | -- Clear note that ctrl-/ is the reliable keybinding for help | ||
| 20 | -- Vim-style navigation keys (alt-h/j/k/l) documented | ||
scratch_files/test_highlight.txtdeleted@@ -1,8 +0,0 @@ | |||
| 1 | -Test file for search highlighting. | ||
| 2 | - | ||
| 3 | -The word test appears here. | ||
| 4 | -And test appears again. | ||
| 5 | -One more test for good measure. | ||
| 6 | - | ||
| 7 | -Testing regex: 123 456 789 | ||
| 8 | -More numbers: 42 100 999 | ||
scratch_files/test_new_pane_selection.shdeleted@@ -1,35 +0,0 @@ | |||
| 1 | -#!/bin/bash | ||
| 2 | - | ||
| 3 | -echo "Testing Shift Selection in NEWLY CREATED Panes" | ||
| 4 | -echo "===============================================" | ||
| 5 | -echo | ||
| 6 | -echo "ISSUE: Shift-arrow selection works in original pane but not in newly created panes" | ||
| 7 | -echo | ||
| 8 | -echo "FIX APPLIED:" | ||
| 9 | -echo "1. Ensured cursor state is synced before splitting" | ||
| 10 | -echo "2. Deep copy all cursor fields when creating new pane" | ||
| 11 | -echo "3. Initialize cursor properly if not allocated" | ||
| 12 | -echo | ||
| 13 | -echo "TEST STEPS:" | ||
| 14 | -echo "-----------" | ||
| 15 | -echo "1. Open the test file" | ||
| 16 | -echo "2. Press Alt-V to create a vertical split" | ||
| 17 | -echo " - You are now in the NEW RIGHT PANE" | ||
| 18 | -echo "3. Test shift selection in NEW pane:" | ||
| 19 | -echo " - Shift-Right: Should select text character by character" | ||
| 20 | -echo " - Shift-Left: Should select backward" | ||
| 21 | -echo " - Alt-Shift-Right: Should select current word" | ||
| 22 | -echo "4. Navigate back to left pane (Alt-H or Ctrl-Shift-Left)" | ||
| 23 | -echo "5. Verify selection still works in original pane" | ||
| 24 | -echo "6. Create a horizontal split (Alt-S)" | ||
| 25 | -echo "7. Test selection in the new bottom pane" | ||
| 26 | -echo | ||
| 27 | -echo "EXPECTED RESULTS:" | ||
| 28 | -echo "- Shift selection should work in ALL panes" | ||
| 29 | -echo "- Both original and newly created panes" | ||
| 30 | -echo "- Each pane maintains independent selection state" | ||
| 31 | -echo | ||
| 32 | -echo "Press Enter to start testing..." | ||
| 33 | -read | ||
| 34 | - | ||
| 35 | -./build/gfortran_*/app/fac test_shift_selection.txt | ||
scratch_files/test_panes.shdeleted@@ -1,30 +0,0 @@ | |||
| 1 | -#!/bin/bash | ||
| 2 | - | ||
| 3 | -echo "Testing Facsimile Pane Functionality" | ||
| 4 | -echo "=====================================" | ||
| 5 | -echo | ||
| 6 | -echo "This test will open the editor with the pane_test.txt file" | ||
| 7 | -echo "You can test the following:" | ||
| 8 | -echo | ||
| 9 | -echo "1. Press Alt-V to split the view vertically" | ||
| 10 | -echo "2. Press Alt-S to split the view horizontally" | ||
| 11 | -echo "3. Press Alt-Q to close the active pane only" | ||
| 12 | -echo "4. Press Ctrl-W to close pane (then tab when last pane)" | ||
| 13 | -echo "5. Visual indicators:" | ||
| 14 | -echo " - Active pane: Normal background, cursor visible" | ||
| 15 | -echo " - Inactive panes: Dark gray background (color 234)" | ||
| 16 | -echo " - Separator: Solid vertical line between panes" | ||
| 17 | -echo " - Current line in active pane: Highlighted (color 237)" | ||
| 18 | -echo "" | ||
| 19 | -echo "6. Behavior:" | ||
| 20 | -echo " - Each pane has independent scrolling" | ||
| 21 | -echo " - Cursor stays within active pane boundaries" | ||
| 22 | -echo " - Empty lines show '~' indicator" | ||
| 23 | -echo " - Full pane height is utilized for content" | ||
| 24 | -echo "" | ||
| 25 | -echo "Note: Alt keys avoid conflicts with terminal and browser shortcuts" | ||
| 26 | -echo | ||
| 27 | -echo "Press Enter to start the test..." | ||
| 28 | -read | ||
| 29 | - | ||
| 30 | -./fac pane_test.txt | ||
scratch_files/test_scrollable_help.txtdeleted@@ -1,43 +0,0 @@ | |||
| 1 | -Scrollable Help Menu Test | ||
| 2 | -========================== | ||
| 3 | - | ||
| 4 | -The help menu (ctrl-/) now has these improvements: | ||
| 5 | - | ||
| 6 | -1. SCROLLABLE PAGER | ||
| 7 | - - Navigate with arrow keys (↑↓) or vim keys (j/k) | ||
| 8 | - - Page Up/Page Down for faster scrolling | ||
| 9 | - - Home/End to jump to top/bottom | ||
| 10 | - - Quit with 'q' or ESC | ||
| 11 | - - Shows scroll position at bottom | ||
| 12 | - | ||
| 13 | -2. NEWLY ADDED KEYBINDINGS | ||
| 14 | - - tab/shift-tab for tab switching (was missing!) | ||
| 15 | - - alt-0 for jumping to tab 10 | ||
| 16 | - - esc for clearing selection | ||
| 17 | - - ctrl-t for transpose characters | ||
| 18 | - - alt-shift-' for removing brackets/quotes | ||
| 19 | - - Better organization of special characters bindings | ||
| 20 | - | ||
| 21 | -3. COMPLETE SECTIONS | ||
| 22 | - All sections now have their full keybindings: | ||
| 23 | - - NAVIGATION (11 bindings) | ||
| 24 | - - SELECTION (6 bindings) | ||
| 25 | - - EDITING (11 bindings) | ||
| 26 | - - CLIPBOARD (3 bindings) | ||
| 27 | - - LINES (2 bindings) | ||
| 28 | - - SEARCH & REPLACE (7 bindings) | ||
| 29 | - - MULTIPLE CURSORS (3 bindings) | ||
| 30 | - - SPECIAL (5 bindings) | ||
| 31 | - - TABS (7 bindings) | ||
| 32 | - - PANES (6 bindings) | ||
| 33 | - - GIT (9 bindings in fuss mode) | ||
| 34 | - - FILE (3 bindings) | ||
| 35 | - | ||
| 36 | -Try it now: | ||
| 37 | -1. Press ctrl-/ to open help | ||
| 38 | -2. Use j/k or arrows to scroll line by line | ||
| 39 | -3. Use PageDown to scroll faster | ||
| 40 | -4. Press q or ESC to exit | ||
| 41 | - | ||
| 42 | -On smaller terminals, you can now see ALL keybindings | ||
| 43 | -by scrolling, instead of having them cut off! | ||
scratch_files/test_search_replace.txtdeleted@@ -1,18 +0,0 @@ | |||
| 1 | -Testing search and replace functionality. | ||
| 2 | - | ||
| 3 | -Test 1: Basic search highlighting | ||
| 4 | -The word test appears multiple times in this test file. | ||
| 5 | -We need to test that the search highlights the test correctly. | ||
| 6 | - | ||
| 7 | -Test 2: Regex search highlighting | ||
| 8 | -Numbers: 123, 456, 789 | ||
| 9 | -Emails: test@example.com, user@domain.org | ||
| 10 | -URLs: https://www.example.com | ||
| 11 | - | ||
| 12 | -Test 3: Replace behavior | ||
| 13 | -Replace these: foo foo foo | ||
| 14 | -After pressing ctrl-r on foo, cursor should be at end of replacement. | ||
| 15 | - | ||
| 16 | -Test 4: Variable length regex replace | ||
| 17 | -Words: test123, test456, test789 | ||
| 18 | -Replace test[0-9]+ with "replaced" - cursor should be at end. | ||
scratch_files/test_search_state.txtdeleted@@ -1,16 +0,0 @@ | |||
| 1 | -Test file for search state pollution bug. | ||
| 2 | - | ||
| 3 | -First paragraph with numbers: 123 456 789 | ||
| 4 | -Second paragraph with numbers: 100 200 300 | ||
| 5 | - | ||
| 6 | -Email addresses in this file: | ||
| 7 | -test@example.com | ||
| 8 | -user@domain.org | ||
| 9 | -admin@site.net | ||
| 10 | - | ||
| 11 | -More text with the word Email repeated: | ||
| 12 | -Email is important. | ||
| 13 | -Send me an Email. | ||
| 14 | -Check your Email inbox. | ||
| 15 | - | ||
| 16 | -Final paragraph with more numbers: 42 99 1000 | ||
scratch_files/test_shift_selection.shdeleted@@ -1,40 +0,0 @@ | |||
| 1 | -#!/bin/bash | ||
| 2 | - | ||
| 3 | -echo "Testing Shift Selection in Pane Mode" | ||
| 4 | -echo "=====================================" | ||
| 5 | -echo | ||
| 6 | -echo "ISSUE REPORTED: Shift selection doesn't work in pane mode" | ||
| 7 | -echo | ||
| 8 | -echo "FIX APPLIED: Added sync_editor_to_pane() calls after all" | ||
| 9 | -echo "selection operations to sync cursor/selection state with panes" | ||
| 10 | -echo | ||
| 11 | -echo "Tests to perform:" | ||
| 12 | -echo "-----------------" | ||
| 13 | -echo | ||
| 14 | -echo "1. BASIC SELECTION IN PANES:" | ||
| 15 | -echo " - Press Alt-V to split vertically" | ||
| 16 | -echo " - Use Shift+Arrow keys to select text" | ||
| 17 | -echo " - Selection should work normally" | ||
| 18 | -echo | ||
| 19 | -echo "2. WORD SELECTION:" | ||
| 20 | -echo " - Position cursor at start of a word" | ||
| 21 | -echo " - Press Alt-Shift-Right" | ||
| 22 | -echo " - Should select the CURRENT word" | ||
| 23 | -echo | ||
| 24 | -echo "3. LINE SELECTION:" | ||
| 25 | -echo " - Shift-Home: Select to start of line" | ||
| 26 | -echo " - Shift-End: Select to end of line" | ||
| 27 | -echo | ||
| 28 | -echo "4. NAVIGATION WITH SELECTION:" | ||
| 29 | -echo " - Make a selection in one pane" | ||
| 30 | -echo " - Navigate to another pane (Alt-H/J/K/L)" | ||
| 31 | -echo " - Original pane should maintain selection" | ||
| 32 | -echo | ||
| 33 | -echo "5. CLEAR SELECTION:" | ||
| 34 | -echo " - Press ESC to clear selection" | ||
| 35 | -echo " - Selection should be cleared" | ||
| 36 | -echo | ||
| 37 | -echo "Press Enter to start testing..." | ||
| 38 | -read | ||
| 39 | - | ||
| 40 | -./build/gfortran_*/app/fac test_shift_selection.txt | ||
scratch_files/test_shift_selection.txtdeleted@@ -1,58 +0,0 @@ | |||
| 1 | -Shift Selection Test File | ||
| 2 | -========================= | ||
| 3 | - | ||
| 4 | -Test shift selection in panes: | ||
| 5 | - | ||
| 6 | -1. Open this file | ||
| 7 | -2. Press Alt-V to split vertically | ||
| 8 | -3. Test the following shift selections: | ||
| 9 | - | ||
| 10 | -Basic Shift Selection Tests | ||
| 11 | ----------------------------- | ||
| 12 | -Shift-Right: Should select character by character | ||
| 13 | -Shift-Left: Should select backward | ||
| 14 | -Shift-Up: Should select to line above | ||
| 15 | -Shift-Down: Should select to line below | ||
| 16 | - | ||
| 17 | -Word Selection Tests | ||
| 18 | --------------------- | ||
| 19 | -Alt-Shift-Right: Should select current word | ||
| 20 | -Alt-Shift-Left: Should select word backward | ||
| 21 | - | ||
| 22 | -word1 word2 word3 word4 word5 | ||
| 23 | -short longword medium tiny huge | ||
| 24 | -testing selection accuracy here | ||
| 25 | - | ||
| 26 | -Line Selection Tests | ||
| 27 | --------------------- | ||
| 28 | -Shift-Home or Ctrl-Shift-A: Select to start of line | ||
| 29 | -Shift-End or Ctrl-Shift-E: Select to end of line | ||
| 30 | - | ||
| 31 | -Page Selection Tests | ||
| 32 | --------------------- | ||
| 33 | -Shift-PageUp: Select page up | ||
| 34 | -Shift-PageDown: Select page down | ||
| 35 | - | ||
| 36 | -Clear Selection Test | ||
| 37 | --------------------- | ||
| 38 | -ESC: Should clear selection | ||
| 39 | - | ||
| 40 | -Navigation Between Panes | ||
| 41 | ------------------------- | ||
| 42 | -Alt-H/J/K/L or Ctrl-Shift-Arrows: Navigate panes | ||
| 43 | -Each pane should maintain its own selection state | ||
| 44 | - | ||
| 45 | -Test lines for scrolling: | ||
| 46 | -Line 38: Lorem ipsum dolor sit amet | ||
| 47 | -Line 39: Consectetur adipiscing elit | ||
| 48 | -Line 40: Sed do eiusmod tempor incididunt | ||
| 49 | -Line 41: Ut labore et dolore magna aliqua | ||
| 50 | -Line 42: Ut enim ad minim veniam | ||
| 51 | -Line 43: Quis nostrud exercitation ullamco | ||
| 52 | -Line 44: Laboris nisi ut aliquip ex ea | ||
| 53 | -Line 45: Commodo consequat duis aute | ||
| 54 | -Line 46: Irure dolor in reprehenderit | ||
| 55 | -Line 47: In voluptate velit esse cillum | ||
| 56 | -Line 48: Dolore eu fugiat nulla pariatur | ||
| 57 | -Line 49: Excepteur sint occaecat cupidatat | ||
| 58 | -Line 50: End of test file | ||