markdown · 8141 bytes Raw Blame History

Workspace Mode - Vision & Design Decisions

This document captures the key design decisions and vision for workspace mode.


Vision Summary

Transform fac into a workspace-aware editor where:

  • Workspace = directory + persistent editor state (tabs, panes, positions)
  • Fortress = navigator UI for finding workspaces and files
  • State persists across sessions
  • Single-file mode still works unchanged

Key Concepts

Workspace

A workspace is created when opening a directory:

fac .                    # Open cwd as workspace
fac ~/projects/myapp     # Open that directory as workspace
fac                      # Opens Fortress welcome menu

Workspace contains:

  • Tabs and which files are open
  • Pane splits and layouts
  • Cursor positions per file
  • Viewport scroll positions
  • Fuss mode state (open/closed)
  • Dirty buffer backups

Persisted in: .fac/workspace.json in workspace root

Fortress Navigator (Ctrl-O)

Dual-pane file/directory browser for:

  1. Opening new workspaces - navigate to directory, press Enter
  2. Opening orphan files - navigate to file (outside workspace), press Enter

Features:

  • Dual-pane display (parent 30% | current 70%)
  • Navigate with arrow keys
  • Enter on directory → switch to that workspace
  • Enter on file → open as orphan tab in current workspace
  • '8' key → toggle between favorites and recents view
  • 'f' key → add current directory to favorites
  • ESC/q → cancel and return

Orphan Tabs

Files opened from outside the workspace via Fortress:

  • Displayed in greyish/subtle color in tab bar
  • NOT persisted in workspace state
  • If closed, hard to reopen (need Fortress again)
  • Similar to VSCode's non-workspace files

Favorites & Recents

Stored in ~/.config/fac/:

  • favorites.json - manually marked favorite workspaces
  • recents.json - automatically tracked recent workspaces (last 10-20)
  • Press '8' in Fortress to toggle between favorites/recents view

File Structure

Workspace Root

~/projects/myapp/
  .fac/
    workspace.json       # Editor state (tabs, panes, positions)
    backups/             # Dirty buffer backups
      main.f90.bak
      test.f90.bak
      .backup-metadata.json
  src/
    main.f90
    ...

User Config

~/.config/fac/
  favorites.json         # User-marked favorites
  recents.json          # Auto-tracked recent workspaces

Command Line Behavior

Command Behavior
fac Open Fortress welcome menu (favorites/recents)
fac . Open cwd as workspace (create if new)
fac ~/dir Open that directory as workspace
fac file.txt Single-file mode (check parent for workspace)

Key Workflows

1. Start Working on Project

cd ~/projects/myapp
fac .
# Opens workspace (or creates if first time)
# Restores tabs/panes from last session

2. Switch to Another Project

While in fac:

Ctrl-O
# Navigate to ~/projects/other-project
# Press Enter
# Saves current workspace state
# Opens new workspace with its state

3. Open Orphan File

While in fac workspace:

Ctrl-O
# Navigate to /etc/hosts (outside workspace)
# Press Enter
# Opens in new tab (grey color, not persisted)

4. Quick Edit Single File

fac /etc/hosts
# Single-file mode (no workspace)
# Works like current fac

Design Decisions

1. Orphan Tabs

  • Visual: Greyish/subtle color in tab bar
  • Persistence: NOT saved in workspace.json
  • Rationale: Similar to VSCode - you can open any file, but it won't be restored next session

2. Favorites vs Recents

  • Both available, like VSCode
  • Toggle with '8' key between views
  • Favorites: Manual (user adds with 'f' key)
  • Recents: Automatic (last 10-20 opened workspaces)

3. Workspace Discovery

  • fac with no args → Fortress welcome menu
  • fac path → Try to load workspace from that path
  • Silent creation (no prompt) when creating new workspace

4. Backup Strategy

  • On quit: Prompt to save dirty buffers
  • If 'n': Create backup in .fac/backups/
  • On open: Detect backups, prompt to restore
  • Options: [r]estore / [i]gnore / [d]iff
  • Always show diff option for safety

5. Storage Location

  • Workspace state: .fac/workspace.json in workspace root
    • Rationale: Self-contained, obvious location, easy to delete
  • User config: ~/.config/fac/
    • Rationale: Standard XDG location for user preferences

6. File Paths in workspace.json

  • Workspace files: Relative paths (e.g., src/main.f90)
  • Orphan files: Absolute paths (e.g., /etc/hosts)
  • Rationale: Workspace portable if directory moves

7. Missing Files

  • Behavior: Show warning, skip that tab, continue loading
  • Warning: "File not found: src/missing.f90"
  • Rationale: Don't block workspace load due to one missing file

8. Fortress Integration

  • Copy Fortress modules into fac (not shell out)
  • Use: Filesystem, terminal, UI modules
  • Omit: Git integration (fuss menu has this), multiselect (for now)
  • Rationale: Single binary, no Python dependency, full control

State Persistence

What Gets Saved in workspace.json

✅ Tab list with file paths ✅ Pane splits and layouts ✅ Cursor positions per file ✅ Viewport scroll positions per file ✅ Active tab index ✅ Active pane per tab ✅ Fuss mode state (open/closed, width)

❌ Orphan tabs (not persisted) ❌ Undo history (too large, unnecessary) ❌ Search history (not critical) ❌ Yank stack (session-specific)

workspace.json Schema

{
  "version": "1.0",
  "workspace_path": "/home/user/project",
  "last_opened": "2025-01-05T10:30:00Z",
  "tabs": [
    {
      "label": "main.f90",
      "panes": [
        {
          "file": "src/main.f90",
          "cursor": {"line": 42, "col": 10},
          "viewport": {"line": 30, "col": 1},
          "modified": false
        }
      ],
      "split_type": "none|vertical|horizontal",
      "active_pane": 0
    }
  ],
  "active_tab": 0,
  "fuss_mode": {
    "active": true,
    "width": 30
  }
}

Fortress Keybindings

  • ↑/↓: Move cursor
  • : Enter directory
  • : Go to parent
  • ~: Jump to home directory
  • /: Jump to root directory
  • Enter: Select (directory = switch workspace, file = open as orphan)
  • q/ESC: Cancel and return to editor

Favorites & Recents

  • 8: Toggle between favorites and recents view
  • f: Add current directory to favorites
  • r/x: Remove favorite (in favorites view)

Future (not Phase 1)

  • s: Fuzzy search with fzf (maybe later)
  • .: Toggle dotfiles (maybe later)

Backwards Compatibility

Critical: Single-file mode must work unchanged

  • fac file.txt behaves exactly as before
  • Ctrl-B shows parent directory tree
  • No workspace created
  • No persistence

Testing: Extensive regression tests for non-workspace mode


Open Questions / Future Enhancements

Not in Initial Implementation

  • Fuzzy search within workspace (fzf integration)
  • Multiselect in Fortress
  • Git indicators in Fortress (fuss menu has this)
  • Multiple workspaces open simultaneously
  • Workspace templates
  • Per-workspace editor settings

Maybe Later

  • Workspace sharing (commit .fac/ to git?)
  • Remote workspaces
  • Workspace import/export
  • Workspace groups

Success Criteria

The implementation is successful when:

  • fac launches Fortress welcome menu
  • fac . creates/loads workspace seamlessly
  • ✅ Ctrl-O navigates to workspaces and files
  • ✅ All tabs, panes, positions persist across sessions
  • ✅ Orphan tabs work and are visually distinct
  • ✅ Favorites and recents track correctly
  • ✅ Backups save/restore with diff option
  • ✅ Single-file mode works unchanged
  • ✅ No regressions in existing features
  • ✅ Documentation is complete

References

  • See WORKSPACE_ROADMAP.md for implementation phases
  • See WORKSPACE_TASKS.md for task tracking
  • See workspace_spec.md for technical specifications (Phase 0 deliverable)

Last Updated: 2025-01-05

View source
1 # Workspace Mode - Vision & Design Decisions
2
3 This document captures the key design decisions and vision for workspace mode.
4
5 ---
6
7 ## Vision Summary
8
9 Transform `fac` into a workspace-aware editor where:
10 - **Workspace** = directory + persistent editor state (tabs, panes, positions)
11 - **Fortress** = navigator UI for finding workspaces and files
12 - State persists across sessions
13 - Single-file mode still works unchanged
14
15 ---
16
17 ## Key Concepts
18
19 ### Workspace
20 A workspace is created when opening a directory:
21 ```bash
22 fac . # Open cwd as workspace
23 fac ~/projects/myapp # Open that directory as workspace
24 fac # Opens Fortress welcome menu
25 ```
26
27 **Workspace contains:**
28 - Tabs and which files are open
29 - Pane splits and layouts
30 - Cursor positions per file
31 - Viewport scroll positions
32 - Fuss mode state (open/closed)
33 - Dirty buffer backups
34
35 **Persisted in:** `.fac/workspace.json` in workspace root
36
37 ### Fortress Navigator (Ctrl-O)
38 Dual-pane file/directory browser for:
39 1. **Opening new workspaces** - navigate to directory, press Enter
40 2. **Opening orphan files** - navigate to file (outside workspace), press Enter
41
42 **Features:**
43 - Dual-pane display (parent 30% | current 70%)
44 - Navigate with arrow keys
45 - Enter on directory → switch to that workspace
46 - Enter on file → open as orphan tab in current workspace
47 - '8' key → toggle between favorites and recents view
48 - 'f' key → add current directory to favorites
49 - ESC/q → cancel and return
50
51 ### Orphan Tabs
52 Files opened from outside the workspace via Fortress:
53 - Displayed in **greyish/subtle color** in tab bar
54 - NOT persisted in workspace state
55 - If closed, hard to reopen (need Fortress again)
56 - Similar to VSCode's non-workspace files
57
58 ### Favorites & Recents
59 Stored in `~/.config/fac/`:
60 - **favorites.json** - manually marked favorite workspaces
61 - **recents.json** - automatically tracked recent workspaces (last 10-20)
62 - Press '8' in Fortress to toggle between favorites/recents view
63
64 ---
65
66 ## File Structure
67
68 ### Workspace Root
69 ```
70 ~/projects/myapp/
71 .fac/
72 workspace.json # Editor state (tabs, panes, positions)
73 backups/ # Dirty buffer backups
74 main.f90.bak
75 test.f90.bak
76 .backup-metadata.json
77 src/
78 main.f90
79 ...
80 ```
81
82 ### User Config
83 ```
84 ~/.config/fac/
85 favorites.json # User-marked favorites
86 recents.json # Auto-tracked recent workspaces
87 ```
88
89 ---
90
91 ## Command Line Behavior
92
93 | Command | Behavior |
94 |---------|----------|
95 | `fac` | Open Fortress welcome menu (favorites/recents) |
96 | `fac .` | Open cwd as workspace (create if new) |
97 | `fac ~/dir` | Open that directory as workspace |
98 | `fac file.txt` | Single-file mode (check parent for workspace) |
99
100 ---
101
102 ## Key Workflows
103
104 ### 1. Start Working on Project
105 ```bash
106 cd ~/projects/myapp
107 fac .
108 # Opens workspace (or creates if first time)
109 # Restores tabs/panes from last session
110 ```
111
112 ### 2. Switch to Another Project
113 While in fac:
114 ```
115 Ctrl-O
116 # Navigate to ~/projects/other-project
117 # Press Enter
118 # Saves current workspace state
119 # Opens new workspace with its state
120 ```
121
122 ### 3. Open Orphan File
123 While in fac workspace:
124 ```
125 Ctrl-O
126 # Navigate to /etc/hosts (outside workspace)
127 # Press Enter
128 # Opens in new tab (grey color, not persisted)
129 ```
130
131 ### 4. Quick Edit Single File
132 ```bash
133 fac /etc/hosts
134 # Single-file mode (no workspace)
135 # Works like current fac
136 ```
137
138 ---
139
140 ## Design Decisions
141
142 ### 1. Orphan Tabs
143 - **Visual**: Greyish/subtle color in tab bar
144 - **Persistence**: NOT saved in workspace.json
145 - **Rationale**: Similar to VSCode - you can open any file, but it won't be restored next session
146
147 ### 2. Favorites vs Recents
148 - **Both available**, like VSCode
149 - **Toggle with '8' key** between views
150 - **Favorites**: Manual (user adds with 'f' key)
151 - **Recents**: Automatic (last 10-20 opened workspaces)
152
153 ### 3. Workspace Discovery
154 - `fac` with no args → Fortress welcome menu
155 - `fac path` → Try to load workspace from that path
156 - Silent creation (no prompt) when creating new workspace
157
158 ### 4. Backup Strategy
159 - **On quit**: Prompt to save dirty buffers
160 - **If 'n'**: Create backup in `.fac/backups/`
161 - **On open**: Detect backups, prompt to restore
162 - **Options**: [r]estore / [i]gnore / [d]iff
163 - **Always show diff option** for safety
164
165 ### 5. Storage Location
166 - **Workspace state**: `.fac/workspace.json` in workspace root
167 - Rationale: Self-contained, obvious location, easy to delete
168 - **User config**: `~/.config/fac/`
169 - Rationale: Standard XDG location for user preferences
170
171 ### 6. File Paths in workspace.json
172 - **Workspace files**: Relative paths (e.g., `src/main.f90`)
173 - **Orphan files**: Absolute paths (e.g., `/etc/hosts`)
174 - **Rationale**: Workspace portable if directory moves
175
176 ### 7. Missing Files
177 - **Behavior**: Show warning, skip that tab, continue loading
178 - **Warning**: "File not found: src/missing.f90"
179 - **Rationale**: Don't block workspace load due to one missing file
180
181 ### 8. Fortress Integration
182 - **Copy Fortress modules into fac** (not shell out)
183 - **Use**: Filesystem, terminal, UI modules
184 - **Omit**: Git integration (fuss menu has this), multiselect (for now)
185 - **Rationale**: Single binary, no Python dependency, full control
186
187 ---
188
189 ## State Persistence
190
191 ### What Gets Saved in workspace.json
192 ✅ Tab list with file paths
193 ✅ Pane splits and layouts
194 ✅ Cursor positions per file
195 ✅ Viewport scroll positions per file
196 ✅ Active tab index
197 ✅ Active pane per tab
198 ✅ Fuss mode state (open/closed, width)
199
200 ❌ Orphan tabs (not persisted)
201 ❌ Undo history (too large, unnecessary)
202 ❌ Search history (not critical)
203 ❌ Yank stack (session-specific)
204
205 ### workspace.json Schema
206 ```json
207 {
208 "version": "1.0",
209 "workspace_path": "/home/user/project",
210 "last_opened": "2025-01-05T10:30:00Z",
211 "tabs": [
212 {
213 "label": "main.f90",
214 "panes": [
215 {
216 "file": "src/main.f90",
217 "cursor": {"line": 42, "col": 10},
218 "viewport": {"line": 30, "col": 1},
219 "modified": false
220 }
221 ],
222 "split_type": "none|vertical|horizontal",
223 "active_pane": 0
224 }
225 ],
226 "active_tab": 0,
227 "fuss_mode": {
228 "active": true,
229 "width": 30
230 }
231 }
232 ```
233
234 ---
235
236 ## Fortress Keybindings
237
238 ### Navigation
239 - `↑/↓`: Move cursor
240 - `→`: Enter directory
241 - `←`: Go to parent
242 - `~`: Jump to home directory
243 - `/`: Jump to root directory
244 - `Enter`: Select (directory = switch workspace, file = open as orphan)
245 - `q/ESC`: Cancel and return to editor
246
247 ### Favorites & Recents
248 - `8`: Toggle between favorites and recents view
249 - `f`: Add current directory to favorites
250 - `r/x`: Remove favorite (in favorites view)
251
252 ### Future (not Phase 1)
253 - `s`: Fuzzy search with fzf (maybe later)
254 - `.`: Toggle dotfiles (maybe later)
255
256 ---
257
258 ## Backwards Compatibility
259
260 **Critical**: Single-file mode must work unchanged
261 - `fac file.txt` behaves exactly as before
262 - Ctrl-B shows parent directory tree
263 - No workspace created
264 - No persistence
265
266 **Testing**: Extensive regression tests for non-workspace mode
267
268 ---
269
270 ## Open Questions / Future Enhancements
271
272 ### Not in Initial Implementation
273 - Fuzzy search within workspace (fzf integration)
274 - Multiselect in Fortress
275 - Git indicators in Fortress (fuss menu has this)
276 - Multiple workspaces open simultaneously
277 - Workspace templates
278 - Per-workspace editor settings
279
280 ### Maybe Later
281 - Workspace sharing (commit .fac/ to git?)
282 - Remote workspaces
283 - Workspace import/export
284 - Workspace groups
285
286 ---
287
288 ## Success Criteria
289
290 The implementation is successful when:
291 -`fac` launches Fortress welcome menu
292 -`fac .` creates/loads workspace seamlessly
293 - ✅ Ctrl-O navigates to workspaces and files
294 - ✅ All tabs, panes, positions persist across sessions
295 - ✅ Orphan tabs work and are visually distinct
296 - ✅ Favorites and recents track correctly
297 - ✅ Backups save/restore with diff option
298 - ✅ Single-file mode works unchanged
299 - ✅ No regressions in existing features
300 - ✅ Documentation is complete
301
302 ---
303
304 ## References
305
306 - See `WORKSPACE_ROADMAP.md` for implementation phases
307 - See `WORKSPACE_TASKS.md` for task tracking
308 - See `workspace_spec.md` for technical specifications (Phase 0 deliverable)
309
310 ---
311
312 Last Updated: 2025-01-05