200 node_required(model.node_name, toggle = toggle, set = set)) |
200 node_required(model.node_name, toggle = toggle, set = set)) |
201 |
201 |
202 |
202 |
203 /* flushed edits */ |
203 /* flushed edits */ |
204 |
204 |
205 def flush_edits(hidden: Boolean): (Document.Blobs, List[Document.Edit_Text]) = |
205 def flush_edits(hidden: Boolean, purge: Boolean): (Document.Blobs, List[Document.Edit_Text]) = |
206 { |
206 { |
207 GUI_Thread.require {} |
207 GUI_Thread.require {} |
208 |
208 |
209 state.change_result(st => |
209 state.change_result(st => |
210 { |
210 { |
222 } yield edit).toList |
222 } yield edit).toList |
223 |
223 |
224 val file_edits = |
224 val file_edits = |
225 (for { |
225 (for { |
226 model <- st.file_models_iterator |
226 model <- st.file_models_iterator |
227 change <- model.flush_edits(doc_blobs, hidden) |
227 (edits, model1) <- model.flush_edits(doc_blobs, hidden) |
228 } yield change).toList |
228 } yield (edits, model.node_name -> model1)).toList |
229 |
229 |
230 val edits = buffer_edits ::: file_edits.flatMap(_._1) |
230 val model_edits = buffer_edits ::: file_edits.flatMap(_._1) |
231 |
231 |
232 ((doc_blobs, edits), |
232 val purge_edits = |
233 st.copy( |
233 if (purge) { |
234 models = (st.models /: file_edits) { case (ms, (_, m)) => ms + (m.node_name -> m) })) |
234 val purged = |
|
235 (for (model <- st.file_models_iterator) |
|
236 yield (model.node_name -> model.purge_edits(doc_blobs))).toList |
|
237 |
|
238 val imports = |
|
239 { |
|
240 val open_nodes = st.buffer_models_iterator.map(_.node_name).toList |
|
241 val touched_nodes = model_edits.map(_._1) |
|
242 val pending_nodes = for ((node_name, None) <- purged) yield node_name |
|
243 (open_nodes ::: touched_nodes ::: pending_nodes).map((_, Position.none)) |
|
244 } |
|
245 val retain = PIDE.resources.thy_info.dependencies("", imports).deps.map(_.name).toSet |
|
246 |
|
247 for ((node_name, Some(edits)) <- purged; if !retain(node_name); edit <- edits) |
|
248 yield edit |
|
249 } |
|
250 else Nil |
|
251 |
|
252 val st1 = st.copy(models = st.models ++ file_edits.map(_._2) -- purge_edits.map(_._1)) |
|
253 PIDE.file_watcher.purge( |
|
254 (for { |
|
255 model <- st1.file_models_iterator |
|
256 file <- model.file |
|
257 } yield file.getParentFile).toSet) |
|
258 |
|
259 ((doc_blobs, model_edits ::: purge_edits), st1) |
235 }) |
260 }) |
236 } |
261 } |
237 |
262 |
238 |
263 |
239 /* file content */ |
264 /* file content */ |
344 def flush_edits(doc_blobs: Document.Blobs, hidden: Boolean) |
369 def flush_edits(doc_blobs: Document.Blobs, hidden: Boolean) |
345 : Option[(List[Document.Edit_Text], File_Model)] = |
370 : Option[(List[Document.Edit_Text], File_Model)] = |
346 { |
371 { |
347 val (reparse, perspective) = node_perspective(doc_blobs, hidden) |
372 val (reparse, perspective) = node_perspective(doc_blobs, hidden) |
348 if (reparse || pending_edits.nonEmpty || last_perspective != perspective) { |
373 if (reparse || pending_edits.nonEmpty || last_perspective != perspective) { |
349 val edits = node_edits(pending_edits, perspective) |
374 val edits = node_edits(node_header, pending_edits, perspective) |
350 Some((edits, copy(last_perspective = perspective, pending_edits = Nil))) |
375 Some((edits, copy(last_perspective = perspective, pending_edits = Nil))) |
351 } |
376 } |
352 else None |
377 else None |
353 } |
378 } |
|
379 |
|
380 def purge_edits(doc_blobs: Document.Blobs): Option[List[Document.Edit_Text]] = |
|
381 if (node_required || !Document.Node.is_no_perspective_text(last_perspective) || |
|
382 pending_edits.nonEmpty) None |
|
383 else { |
|
384 val text_edits = List(Text.Edit.remove(0, content.text)) |
|
385 Some(node_edits(Document.Node.no_header, text_edits, Document.Node.no_perspective_text)) |
|
386 } |
354 |
387 |
355 |
388 |
356 /* snapshot */ |
389 /* snapshot */ |
357 |
390 |
358 def is_stable: Boolean = pending_edits.isEmpty |
391 def is_stable: Boolean = pending_edits.isEmpty |
463 val edits = get_edits |
496 val edits = get_edits |
464 val (reparse, perspective) = node_perspective(doc_blobs, hidden) |
497 val (reparse, perspective) = node_perspective(doc_blobs, hidden) |
465 if (reparse || edits.nonEmpty || last_perspective != perspective) { |
498 if (reparse || edits.nonEmpty || last_perspective != perspective) { |
466 pending.clear |
499 pending.clear |
467 last_perspective = perspective |
500 last_perspective = perspective |
468 node_edits(edits, perspective) |
501 node_edits(node_header, edits, perspective) |
469 } |
502 } |
470 else Nil |
503 else Nil |
471 } |
504 } |
472 |
505 |
473 def edit(edits: List[Text.Edit]): Unit = synchronized |
506 def edit(edits: List[Text.Edit]): Unit = synchronized |