You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Internal function names (e.g., functions using "goto" to mean "issue positional response" or "navigate to")
16
17
17
18
This creates confusion as "goto" means different things: user intent to explore code, server computation of which reference, and low-level cursor positioning.
18
19
@@ -22,60 +23,40 @@ Additionally, "Browsing" as a concept already exists in documentation and the ex
22
23
23
24
Adopt "Browse" as the umbrella term for reference navigation. Unify user command names with server operation names.
24
25
25
-
**Entry points into browsing:**
26
-
27
-
| Current | Proposed |
28
-
|---------|----------|
29
-
|`OLO_PUSH`|`BROWSE_PUSH` or `PUSH_AND_BROWSE`|
30
-
|`OLO_COMPLETION_GOTO`|`COMPLETION_BROWSE`|
31
-
|`OLO_TAG_SEARCH`|`SEARCH_BROWSE`|
32
-
33
-
**Navigation within browsing (shared across all contexts):**
34
-
35
-
| Current | Proposed |
36
-
|---------|----------|
37
-
|`OLO_NEXT`|`BROWSE_NEXT_REFERENCE`|
38
-
|`OLO_PREVIOUS`|`BROWSE_PREVIOUS_REFERENCE`|
39
-
|`OLO_GOTO_DEF`|`BROWSE_GOTO_DEFINITION`|
40
-
|`OLO_POP`|`BROWSE_POP`|
41
-
|`OLO_REF_FILTER_SET`|`BROWSE_SET_FILTER`|
42
-
43
-
**Protocol layer (unchanged):**
44
-
45
-
-`ppcGotoPosition` or rename to `ppcPositionCursor` - low-level editor instruction
46
-
47
26
**Naming pattern:**
48
27
-`BROWSE_*` = navigation within browsing mode
49
28
-`*_BROWSE` = entry point that starts browsing
50
29
51
-
=======
30
+
**Protocol layer:**
31
+
32
+
-`ppcGotoPosition` or rename to `ppcPositionCursor` - low-level editor instruction, distinct from user-level "browse"
33
+
52
34
## Architectural Insight
53
35
54
36
Browsing, Completion, and Search share the same navigation sub-operations but operate on different stacks:
This suggests a common "exploration mode" abstraction with domain-specific entry points but shared navigation semantics. The terminology unification should reflect this pattern - each domain has its entry operation, then uses common navigation verbs.
63
45
64
-
## Consequences
46
+
## Consequences and Risks
65
47
66
48
**Benefits:**
67
49
68
50
- User command name = server operation name (one concept instead of two)
69
51
- "Browse" clearly indicates "exploration mode with back-stack"
70
52
- Distinguishes user intent from low-level cursor positioning
71
53
- Consistent with existing "Browser" terminology in docs
72
-
- Completion, search, and push-based browsing share the same sub-commands
73
54
74
55
**Risks:**
75
56
76
-
- Renaming OLO_* values affects multiple files
77
57
- Emacs function names may need updating for consistency
58
+
- Internal function names using "goto" ambiguously need careful review to determine actual intent
# Separate buffer synchronization from operation dispatch
2
+
3
+
Date: 2026-02-11
4
+
5
+
## Status
6
+
7
+
Draft
8
+
9
+
## Deciders
10
+
11
+
Thomas Nilefalk, Claude (AI pair programmer)
12
+
13
+
## Problem Statement and Context
14
+
15
+
The current server architecture interleaves buffer freshness checking with operation execution. When the editor client sends a request (e.g., BROWSE_NEXT), the operation handler discovers mid-execution that a file is stale, triggers a re-parse, then continues with refreshed data. This design has been a persistent source of bugs, particularly with the "auto-updating" browser stack where pointers become dangling after mid-operation refreshes.
16
+
17
+
The current flow:
18
+
19
+
```
20
+
Client request (with preloaded files for current buffer)
21
+
-> determine operation
22
+
-> during operation, discover staleness
23
+
-> re-parse mid-operation
24
+
-> continue operation with refreshed data
25
+
```
26
+
27
+
Additionally, the Emacs client currently only preloads the current buffer, meaning the server may have stale data for other modified-but-unsaved files.
28
+
29
+
### Relation to internal operations
30
+
31
+
This issue is compounded by the internal operation mechanism where `refactory.c` re-enters the server via `parseBufferUsingServer()` with command-line flags. These internal re-entries also face staleness issues. Separating sync from dispatch would simplify both external and internal operation handling.
32
+
33
+
## Decision Outcome
34
+
35
+
*To be determined.* The direction being explored is:
36
+
37
+
1.**Client sends all modified buffers** with every request, not just the current one. Buffers unchanged since the last request would still be sent but skipped by the server's existing timestamp-based freshness check (the cost is writing to temp files, not re-parsing).
38
+
39
+
2.**Server refreshes on entry**, before operation dispatch. A dedicated "sync phase" at the server entry point updates the in-memory reference database from all preloaded files.
40
+
41
+
3.**Operations assume fresh data.** Individual operation handlers (BROWSE_NEXT, etc.) no longer need staleness checks or mid-operation re-parsing.
42
+
43
+
Proposed flow:
44
+
45
+
```
46
+
Client request (with ALL modified buffers)
47
+
-> sync phase: update reference database from modified files
48
+
-> perform operation on guaranteed-fresh data
49
+
```
50
+
51
+
### Migration path
52
+
53
+
Each step is independently valuable and testable:
54
+
55
+
1. Fix Emacs client to always send all modified buffers (not just the current one)
56
+
2. Hoist the "refresh from preloads" phase to server entry, before operation dispatch
57
+
3. Remove staleness checks from individual operations
58
+
4. The LSP server gets the same "update phase then operate" structure naturally
59
+
60
+
### Alignment with LSP
61
+
62
+
This design aligns with LSP's model where `textDocument/didChange` notifications are separate from operation requests. The sync phase is conceptually equivalent to processing accumulated `didChange` events before handling the actual request.
63
+
64
+
## Consequences and Risks
65
+
66
+
**Benefits:**
67
+
68
+
- Eliminates the class of bugs caused by mid-operation refresh (dangling pointers, inconsistent state)
69
+
- Operation code becomes simpler - can trust its data
70
+
- Easier to test: sync and operations are independently testable
71
+
- Natural fit for LSP server architecture
72
+
- Internal operations (refactory.c re-entries) also benefit from guaranteed-fresh data
73
+
74
+
**Risks:**
75
+
76
+
- Performance: refreshing all modified files on every request may do more work than lazy per-file refresh. In practice, few files change between requests during normal editing.
77
+
- Radical rename scenario (many files modified) could be costly, but users typically save and test frequently during such operations.
78
+
- Requires changes to both client (Emacs) and server.
79
+
80
+
**Open questions:**
81
+
82
+
- What is the actual cost of the client writing all modified buffers to temporary files on every request?
83
+
- Could checksums or sequence numbers optimize the "send all modified buffers" step if disk I/O ever becomes a bottleneck?
84
+
85
+
## Considered Options
86
+
87
+
*To be explored further as this ADR matures from Draft to Proposed.*
0 commit comments