about summary refs log tree commit diff stats
path: root/sandbox
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-06-08 10:16:32 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-06-08 10:16:32 -0700
commit46824f3ee296778a40ed6ee1864928f587d35f82 (patch)
tree1fffecc0840b3d410aab6c9d4aef472939190603 /sandbox
parentb9a78a84cfee93db9f5bc59dfda135f43e38a9b3 (diff)
downloadmu-46824f3ee296778a40ed6ee1864928f587d35f82.tar.gz
3038 - track down a long-standing bug
In some rare situations the editor would join a line with the next when
it should simply wrap to the next screen row. Thanks Caleb and Ella
Couch for finally running into a situation that was easy to reproduce.

The scenario diffs are misleading on this commit. I had to:

a) delete the obsolete 'editor-wraps-cursor-after-inserting-characters'
because it was written back when a line just large enough to fit in a
single line would not wrap:

   |     |  <-- screen boundary
    abcde

These days it will wrap after making room for the wrap indicator:

   |     |  <-- screen boundary
    abcd↩
    e

b) rename editor-wraps-cursor-after-inserting-characters-2 to
editor-wraps-cursor-after-inserting-characters-in-middle-of-line

c) create a new scenario demonstrating the bug:
editor-wraps-cursor-after-inserting-characters-at-end-of-line
Diffstat (limited to 'sandbox')
-rw-r--r--sandbox/002-typing.mu81
1 files changed, 56 insertions, 25 deletions
diff --git a/sandbox/002-typing.mu b/sandbox/002-typing.mu
index 67945110..1c4bae8a 100644
--- a/sandbox/002-typing.mu
+++ b/sandbox/002-typing.mu
@@ -691,12 +691,40 @@ defg]
 after <insert-character-special-case> [
   # if the line wraps at the cursor, move cursor to start of next row
   {
-    # if we're at the column just before the wrap indicator
-    wrap-column:number <- subtract right, 1
+    # if either:
+    # a) we're at the end of the line and at the column of the wrap indicator, or
+    # b) we're not at end of line and just before the column of the wrap indicator
+    wrap-column:number <- copy right
+    before-wrap-column:number <- subtract wrap-column, 1
     at-wrap?:boolean <- greater-or-equal cursor-column, wrap-column
-    break-unless at-wrap?
-    cursor-column <- subtract cursor-column, wrap-column
-    cursor-column <- add cursor-column, left
+    just-before-wrap?:boolean <- greater-or-equal cursor-column, before-wrap-column
+    next:address:duplex-list:character <- next before-cursor
+    # at end of line? next == 0 || next.value == 10/newline
+    at-end-of-line?:boolean <- equal next, 0
+    {
+      break-if at-end-of-line?
+      next-character:character <- get *next, value:offset
+      at-end-of-line? <- equal next-character, 10/newline
+    }
+    # break unless ((eol? and at-wrap?) or (~eol? and just-before-wrap?))
+    move-cursor-to-next-line?:boolean <- copy 0/false
+    {
+      break-if at-end-of-line?
+      move-cursor-to-next-line? <- copy just-before-wrap?
+      # if we're moving the cursor because it's in the middle of a wrapping
+      # line, adjust it to left-most column
+      potential-new-cursor-column:number <- copy left
+    }
+    {
+      break-unless at-end-of-line?
+      move-cursor-to-next-line? <- copy at-wrap?
+      # if we're moving the cursor because it's at the end of a wrapping line,
+      # adjust it to one past the left-most column to make room for the
+      # newly-inserted wrap-indicator
+      potential-new-cursor-column:number <- add left, 1/make-room-for-wrap-indicator
+    }
+    break-unless move-cursor-to-next-line?
+    cursor-column <- copy potential-new-cursor-column
     *editor <- put *editor, cursor-column:offset, cursor-column
     cursor-row <- add cursor-row, 1
     *editor <- put *editor, cursor-row:offset, cursor-row
@@ -710,12 +738,12 @@ after <insert-character-special-case> [
   }
 ]
 
-scenario editor-wraps-cursor-after-inserting-characters [
+scenario editor-wraps-cursor-after-inserting-characters-in-middle-of-line [
   assume-screen 10/width, 5/height
   1:address:array:character <- new [abcde]
   2:address:editor-data <- new-editor 1:address:array:character, screen:address:screen, 0/left, 5/right
   assume-console [
-    left-click 1, 4  # line is full; no wrap icon yet
+    left-click 1, 3  # right before the wrap icon
     type [f]
   ]
   run [
@@ -725,40 +753,43 @@ scenario editor-wraps-cursor-after-inserting-characters [
   ]
   screen-should-contain [
     .          .
-    .abcd↩     .
-    .fe        .
+    .abcf↩     .
+    .de        .
     .┈┈┈┈┈     .
     .          .
   ]
   memory-should-contain [
     3 <- 2  # cursor row
-    4 <- 1  # cursor column
+    4 <- 0  # cursor column
   ]
 ]
 
-scenario editor-wraps-cursor-after-inserting-characters-2 [
+scenario editor-wraps-cursor-after-inserting-characters-at-end-of-line [
+  local-scope
   assume-screen 10/width, 5/height
-  1:address:array:character <- new [abcde]
-  2:address:editor-data <- new-editor 1:address:array:character, screen:address:screen, 0/left, 5/right
+  # create an editor containing two lines
+  contents:address:array:character <- new [abc
+xyz]
+  1:address:editor-data/raw <- new-editor contents, screen, 0/left, 5/right
+  screen-should-contain [
+    .          .
+    .abc       .
+    .xyz       .
+    .          .
+  ]
   assume-console [
-    left-click 1, 3  # right before the wrap icon
-    type [f]
+    left-click 1, 4  # at end of first line
+    type [de]  # trigger wrap
   ]
   run [
-    editor-event-loop screen:address:screen, console:address:console, 2:address:editor-data
-    3:number <- get *2:address:editor-data, cursor-row:offset
-    4:number <- get *2:address:editor-data, cursor-column:offset
+    editor-event-loop screen:address:screen, console:address:console, 1:address:editor-data/raw
   ]
   screen-should-contain [
     .          .
-    .abcf↩     .
-    .de        .
+    .abcd↩     .
+    .e         .
+    .xyz       .
     .┈┈┈┈┈     .
-    .          .
-  ]
-  memory-should-contain [
-    3 <- 2  # cursor row
-    4 <- 0  # cursor column
   ]
 ]
 
'>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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226