1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
# mojibake — High-Level Requirements
Software Level: **DAL-C** (DO-178C)
Scope: the file buffer component, its configuration, and the removal of the
template widgets.
ID scheme: `MJB-HLR-nnn`. Low-level requirements deriving from these are in
[llr.md](llr.md); requirements the implementation needed that these did not
anticipate are in [derived.md](derived.md). Traceability is in
[../traceability/trace.md](../traceability/trace.md).
---
## File loading and representation
**MJB-HLR-001 — File load from command line**
The editor shall accept an optional file path as a positional command-line
argument and load its contents into the buffer. When no path is supplied the
editor shall present an empty buffer. When the path does not exist the editor
shall present an empty buffer associated with that path, so that a subsequent
write creates the file.
**MJB-HLR-002 — Character encoding and byte order mark**
The editor shall detect a byte order mark on load, decode the file contents
using the detected encoding, and record both the encoding and the presence of
the BOM so that a subsequent write reproduces them. In the absence of a BOM the
editor shall decode as UTF-8.
Where the encoding is declared by a byte order mark and is not UTF-8, byte
sequences invalid in that encoding shall be decoded to replacement characters
and shall not terminate the editor; the declared encoding makes such a
substitution reproducible on write.
**UTF-8 is an exception to the preceding paragraph.** Content decoded as UTF-8,
whether declared by a byte order mark or assumed in its absence, shall be
validated strictly. A file containing an invalid UTF-8 sequence shall be
**refused**, with a diagnostic identifying the offset at which validation
failed, and shall leave the file unmodified. Repairing such content would write
the repair back over the user's data on the next save.
**MJB-HLR-003 — Line ending detection and preservation**
The editor shall detect the predominant line ending of a loaded file (LF, CRLF
or CR), record it, and reproduce that line ending on write. A file whose line
ending cannot be determined shall use the platform default.
**MJB-HLR-004 — Rope text storage**
The editor shall hold buffer text in a rope structure indexed by byte offset,
such that insertion and deletion cost does not scale with total file size.
## Selection and cursor
**MJB-HLR-005 — Selection model**
The editor shall represent the cursor as a selection range with an anchor and a
head, both byte offsets into the rope. Ranges shall be half-open — inclusive of
the lower bound and exclusive of the upper bound — regardless of whether the
head precedes or follows the anchor. The visible block cursor shall occupy one
grapheme cluster inward from the head.
## Motion
**MJB-HLR-006 — Character and line motions**
The editor shall provide, in normal mode, motions by one grapheme cluster left
and right and by one line up and down, bound by default to `h`, `l`, `k` and
`j`. Motions shall not move outside the buffer bounds.
**MJB-HLR-007 — Word motions select**
The editor shall provide next-word-start, previous-word-start and
next-word-end motions bound by default to `w`, `b` and `e`. Consistent with
Helix and unlike Vim, each shall leave a selection spanning the traversed text
rather than a collapsed cursor, so that a subsequent operator acts on that
selection without operator-pending state.
**MJB-HLR-008 — Goto commands**
The editor shall provide goto commands for start of file, end of file, start of
line and end of line, bound by default to the two-key sequences `gg`, `ge`,
`gh` and `gl`. Multi-key sequences shall resolve deterministically and shall not
depend on the interval between keystrokes.
## Modification
**MJB-HLR-009 — Insert-mode entry**
The editor shall enter insert mode via commands that place the cursor before the
selection, after the selection, at the first character of the line, at the end
of the line, and on a newly opened line below or above the current line — bound
by default to `i`, `a`, `I`, `A`, `o` and `O`.
**MJB-HLR-010 — Text modification**
The editor shall delete the current selection on `d` and shall delete the
current selection and enter insert mode on `c`. In insert mode the editor shall
insert typed printable characters at the cursor and shall delete the preceding
character on backspace.
**MJB-HLR-011 — Undo and redo**
The editor shall express every buffer modification as a transaction and shall
retain the inverse of each applied transaction, such that `u` reverts the most
recent modification and `U` reapplies it. Undo when no modification remains and
redo when no reverted modification remains shall be no-ops and shall not be
errors.
## Presentation
**MJB-HLR-012 — Viewport pagination**
The editor shall render only those lines intersecting the visible viewport. The
work performed per frame shall be proportional to the viewport height and shall
not scale with the number of lines in the buffer.
**MJB-HLR-013 — Scrolling and paging**
The editor shall keep the cursor within the viewport, maintaining a configurable
scroll-off margin from the top and bottom edges, clamped so that the margin
never exceeds half the viewport. The editor shall provide half-viewport paging
bound by default to `Ctrl-u` and `Ctrl-d` and full-viewport paging bound by
default to `Ctrl-b` and `Ctrl-f`; each shall move the cursor together with the
viewport.
**MJB-HLR-019 — Single-widget presentation**
The buffer shall be the only widget the editor presents. The frame-rate counter
and the placeholder widget inherited from the application template shall be
removed, together with their registrations and configuration, leaving no
unreachable code.
## Configuration and input
**MJB-HLR-014 — TOML configuration**
The editor shall read its configuration from TOML. No other configuration format
shall be accepted, and no parser for another format shall remain in the
dependency graph.
**MJB-HLR-015 — Config-driven modal keymap**
Key bindings shall be defined in configuration and scoped by editor mode, with
the bindings required by MJB-HLR-006 through MJB-HLR-013 supplied as built-in
defaults that user configuration overrides per binding. The keymap shall support
multi-key sequences, and shall support modes in which an unbound printable key
carries a default meaning rather than being discarded.
**MJB-HLR-016 — Command mode**
The editor shall provide a command line entered with `:` supporting at minimum
write, quit, write-and-quit, force-quit and force-write, using the command names
and aliases of Helix.
## Robustness
**MJB-HLR-017 — File write**
The editor shall write buffer contents to the associated path on command. The
write shall preserve a symbolic link target rather than replacing the link,
shall preserve file permissions, shall refuse to write a read-only path, and
shall restore the previous contents if the write fails partway.
**MJB-HLR-018 — Error handling**
The editor shall not terminate abnormally in response to malformed input,
malformed configuration, or a failed file operation. Such conditions shall be
reported to the user and the editor shall remain usable.
|