68 def provide_file(session: Session, node_name: Document.Node.Name, text: String): State = |
70 def provide_file(session: Session, node_name: Document.Node.Name, text: String): State = |
69 if (models.isDefinedAt(node_name)) this |
71 if (models.isDefinedAt(node_name)) this |
70 else { |
72 else { |
71 val edit = Text.Edit.insert(0, text) |
73 val edit = Text.Edit.insert(0, text) |
72 val model = File_Model(session, node_name, File_Content(text), pending_edits = List(edit)) |
74 val model = File_Model(session, node_name, File_Content(text), pending_edits = List(edit)) |
|
75 model.watch |
73 copy(models = models + (node_name -> model)) |
76 copy(models = models + (node_name -> model)) |
74 } |
77 } |
75 } |
78 } |
76 |
79 |
77 private val state = Synchronized(State()) // owned by GUI thread |
80 private val state = Synchronized(State()) // owned by GUI thread |
83 def bibtex_entries_iterator(): Iterator[Text.Info[(String, Document_Model)]] = |
86 def bibtex_entries_iterator(): Iterator[Text.Info[(String, Document_Model)]] = |
84 for { |
87 for { |
85 model <- state.value.models_iterator |
88 model <- state.value.models_iterator |
86 Text.Info(range, entry) <- model.bibtex_entries.iterator |
89 Text.Info(range, entry) <- model.bibtex_entries.iterator |
87 } yield Text.Info(range, (entry, model)) |
90 } yield Text.Info(range, (entry, model)) |
|
91 |
|
92 |
|
93 /* sync external files */ |
|
94 |
|
95 def sync_files(changed_files: Set[JFile]): Boolean = |
|
96 { |
|
97 state.change_result(st => |
|
98 { |
|
99 val changed_models = |
|
100 (for { |
|
101 model <- st.file_models_iterator |
|
102 node_name = model.node_name |
|
103 file <- PIDE.resources.node_name_file(node_name) |
|
104 if changed_files(file) |
|
105 text <- PIDE.resources.read_file_content(node_name) |
|
106 if model.content.text != text |
|
107 } yield { |
|
108 val content = Document_Model.File_Content(text) |
|
109 val edits = Text.Edit.replace(0, model.content.text, text) |
|
110 (node_name, model.copy(content = content, pending_edits = model.pending_edits ::: edits)) |
|
111 }).toList |
|
112 if (changed_models.isEmpty) (false, st) |
|
113 else (true, st.copy(models = (st.models /: changed_models)(_ + _))) |
|
114 }) |
|
115 } |
88 |
116 |
89 |
117 |
90 /* syntax */ |
118 /* syntax */ |
91 |
119 |
92 def syntax_changed(names: List[Document.Node.Name]) |
120 def syntax_changed(names: List[Document.Node.Name]) |
311 |
339 |
312 /* snapshot */ |
340 /* snapshot */ |
313 |
341 |
314 def is_stable: Boolean = pending_edits.isEmpty |
342 def is_stable: Boolean = pending_edits.isEmpty |
315 def snapshot(): Document.Snapshot = session.snapshot(node_name, pending_edits) |
343 def snapshot(): Document.Snapshot = session.snapshot(node_name, pending_edits) |
|
344 |
|
345 |
|
346 /* watch file-system content */ |
|
347 |
|
348 def watch: Unit = |
|
349 for (file <- PIDE.resources.node_name_file(node_name)) |
|
350 PIDE.file_watcher.register_parent(file) |
316 } |
351 } |
317 |
352 |
318 case class Buffer_Model(session: Session, node_name: Document.Node.Name, buffer: Buffer) |
353 case class Buffer_Model(session: Session, node_name: Document.Node.Name, buffer: Buffer) |
319 extends Document_Model |
354 extends Document_Model |
320 { |
355 { |
520 |
555 |
521 buffer.removeBufferListener(buffer_listener) |
556 buffer.removeBufferListener(buffer_listener) |
522 init_token_marker() |
557 init_token_marker() |
523 |
558 |
524 val content = Document_Model.File_Content(JEdit_Lib.buffer_text(buffer)) |
559 val content = Document_Model.File_Content(JEdit_Lib.buffer_text(buffer)) |
525 File_Model(session, node_name, content, node_required, |
560 val model = |
526 pending_edits.get_last_perspective, pending_edits.get_edits) |
561 File_Model(session, node_name, content, node_required, |
|
562 pending_edits.get_last_perspective, pending_edits.get_edits) |
|
563 model.watch |
|
564 model |
527 } |
565 } |
528 } |
566 } |