114 object pending_edits // owned by Swing thread |
114 object pending_edits // owned by Swing thread |
115 { |
115 { |
116 private val pending = new mutable.ListBuffer[Text.Edit] |
116 private val pending = new mutable.ListBuffer[Text.Edit] |
117 def snapshot(): List[Text.Edit] = pending.toList |
117 def snapshot(): List[Text.Edit] = pending.toList |
118 |
118 |
119 private val delay_flush = Swing_Thread.delay_last(session.input_delay) { |
119 def flush(more_edits: Option[List[Text.Edit]]*) |
120 if (!pending.isEmpty) session.edit_version(List((thy_name, flush()))) |
|
121 } |
|
122 |
|
123 def flush(): List[Text.Edit] = |
|
124 { |
120 { |
125 Swing_Thread.require() |
121 Swing_Thread.require() |
126 val edits = snapshot() |
122 val edits = snapshot() |
127 pending.clear |
123 pending.clear |
128 edits |
124 |
129 } |
125 if (!edits.isEmpty || !more_edits.isEmpty) |
|
126 session.edit_version((Some(edits) :: more_edits.toList).map((thy_name, _))) |
|
127 } |
|
128 |
|
129 def init() |
|
130 { |
|
131 Swing_Thread.require() |
|
132 flush(None, Some(List(Text.Edit.insert(0, Isabelle.buffer_text(buffer))))) |
|
133 } |
|
134 |
|
135 private val delay_flush = |
|
136 Swing_Thread.delay_last(session.input_delay) { flush() } |
130 |
137 |
131 def +=(edit: Text.Edit) |
138 def +=(edit: Text.Edit) |
132 { |
139 { |
133 Swing_Thread.require() |
140 Swing_Thread.require() |
134 pending += edit |
141 pending += edit |
148 |
155 |
149 /* buffer listener */ |
156 /* buffer listener */ |
150 |
157 |
151 private val buffer_listener: BufferListener = new BufferAdapter |
158 private val buffer_listener: BufferListener = new BufferAdapter |
152 { |
159 { |
|
160 override def bufferLoaded(buffer: JEditBuffer) |
|
161 { |
|
162 pending_edits.init() |
|
163 } |
|
164 |
153 override def contentInserted(buffer: JEditBuffer, |
165 override def contentInserted(buffer: JEditBuffer, |
154 start_line: Int, offset: Int, num_lines: Int, length: Int) |
166 start_line: Int, offset: Int, num_lines: Int, length: Int) |
155 { |
167 { |
156 pending_edits += Text.Edit.insert(offset, buffer.getText(offset, length)) |
168 if (!buffer.isLoading) |
|
169 pending_edits += Text.Edit.insert(offset, buffer.getText(offset, length)) |
157 } |
170 } |
158 |
171 |
159 override def preContentRemoved(buffer: JEditBuffer, |
172 override def preContentRemoved(buffer: JEditBuffer, |
160 start_line: Int, offset: Int, num_lines: Int, removed_length: Int) |
173 start_line: Int, offset: Int, num_lines: Int, removed_length: Int) |
161 { |
174 { |
162 pending_edits += Text.Edit.remove(offset, buffer.getText(offset, removed_length)) |
175 if (!buffer.isLoading) |
|
176 pending_edits += Text.Edit.remove(offset, buffer.getText(offset, removed_length)) |
163 } |
177 } |
164 } |
178 } |
165 |
179 |
166 |
180 |
167 /* semantic token marker */ |
181 /* semantic token marker */ |
217 def activate() |
231 def activate() |
218 { |
232 { |
219 buffer.setTokenMarker(token_marker) |
233 buffer.setTokenMarker(token_marker) |
220 buffer.addBufferListener(buffer_listener) |
234 buffer.addBufferListener(buffer_listener) |
221 buffer.propertiesChanged() |
235 buffer.propertiesChanged() |
222 pending_edits += Text.Edit.insert(0, Isabelle.buffer_text(buffer)) |
236 pending_edits.init() |
223 } |
237 } |
224 |
238 |
225 def refresh() |
239 def refresh() |
226 { |
240 { |
227 buffer.setTokenMarker(token_marker) |
241 buffer.setTokenMarker(token_marker) |
228 } |
242 } |
229 |
243 |
230 def deactivate() |
244 def deactivate() |
231 { |
245 { |
|
246 pending_edits.flush() |
232 buffer.setTokenMarker(buffer.getMode.getTokenMarker) |
247 buffer.setTokenMarker(buffer.getMode.getTokenMarker) |
233 buffer.removeBufferListener(buffer_listener) |
248 buffer.removeBufferListener(buffer_listener) |
234 } |
249 } |
235 } |
250 } |