1use std::collections::BTreeMap;
5use std::sync::Arc;
6use std::sync::atomic::{AtomicU64, Ordering};
7use std::time::{Duration, Instant};
8
9use crate::action::{Action, ActionError};
10use crate::buffer::{Buffer, BufferId, FileMeta, LineEdit};
11use crate::changeset::{Bias, ChangeSet};
12use crate::history::Transaction;
13use crate::position::{ByteOffset, byte_to_line_col, line_col_to_byte};
14use crate::resolve::{Resolved, resolve, resolve_search};
15use crate::selection::{Selection, SelectionSet};
16use crate::view::{View, ViewId};
17
18pub trait Clock: Send {
20 fn now(&self) -> Duration;
21}
22
23pub struct SystemClock {
24 origin: Instant,
25}
26
27impl Default for SystemClock {
28 fn default() -> Self {
29 Self {
30 origin: Instant::now(),
31 }
32 }
33}
34
35impl Clock for SystemClock {
36 fn now(&self) -> Duration {
37 self.origin.elapsed()
38 }
39}
40
41#[derive(Clone, Default)]
43pub struct ManualClock(Arc<AtomicU64>);
44
45impl ManualClock {
46 pub fn advance(&self, d: Duration) {
47 self.0.fetch_add(d.as_millis() as u64, Ordering::Relaxed);
48 }
49}
50
51impl Clock for ManualClock {
52 fn now(&self) -> Duration {
53 Duration::from_millis(self.0.load(Ordering::Relaxed))
54 }
55}
56
57#[derive(Clone, Debug)]
58pub struct Settings {
59 pub tab_width: usize,
60 pub use_spaces: bool,
62}
63
64impl Default for Settings {
65 fn default() -> Self {
66 Self {
67 tab_width: 4,
68 use_spaces: false,
69 }
70 }
71}
72
73pub struct Editor {
74 buffers: BTreeMap<BufferId, Buffer>,
75 views: BTreeMap<ViewId, View>,
76 next_id: u64,
77 pub settings: Settings,
78 clock: Box<dyn Clock>,
79 recording: Option<Vec<Action>>,
80}
81
82impl Default for Editor {
83 fn default() -> Self {
84 Self::with_clock(Box::new(SystemClock::default()))
85 }
86}
87
88impl Editor {
89 pub fn new() -> Self {
90 Self::default()
91 }
92
93 pub fn with_clock(clock: Box<dyn Clock>) -> Self {
94 Self {
95 buffers: BTreeMap::new(),
96 views: BTreeMap::new(),
97 next_id: 1,
98 settings: Settings::default(),
99 clock,
100 recording: None,
101 }
102 }
103
104 fn fresh_id(&mut self) -> u64 {
105 let id = self.next_id;
106 self.next_id += 1;
107 id
108 }
109
110 pub fn add_buffer(&mut self, text: &str, meta: FileMeta) -> BufferId {
111 let id = BufferId(self.fresh_id());
112 self.buffers.insert(id, Buffer::new(id, text, meta));
113 id
114 }
115
116 pub fn add_view(&mut self, buffer: BufferId) -> Result<ViewId, ActionError> {
117 if !self.buffers.contains_key(&buffer) {
118 return Err(ActionError::UnknownBuffer(buffer));
119 }
120 let id = ViewId(self.fresh_id());
121 self.views.insert(id, View::new(id, buffer));
122 Ok(id)
123 }
124
125 pub fn remove_view(&mut self, view: ViewId) -> Option<View> {
126 self.views.remove(&view)
127 }
128
129 pub fn remove_buffer(&mut self, buffer: BufferId) -> Option<Buffer> {
131 self.views.retain(|_, v| v.buffer() != buffer);
132 self.buffers.remove(&buffer)
133 }
134
135 pub fn buffer(&self, id: BufferId) -> Option<&Buffer> {
136 self.buffers.get(&id)
137 }
138
139 pub fn buffer_mut(&mut self, id: BufferId) -> Option<&mut Buffer> {
140 self.buffers.get_mut(&id)
141 }
142
143 pub fn view(&self, id: ViewId) -> Option<&View> {
144 self.views.get(&id)
145 }
146
147 pub fn view_mut(&mut self, id: ViewId) -> Option<&mut View> {
148 self.views.get_mut(&id)
149 }
150
151 pub fn buffers(&self) -> impl Iterator<Item = &Buffer> {
152 self.buffers.values()
153 }
154
155 pub fn buffers_mut(&mut self) -> impl Iterator<Item = &mut Buffer> {
156 self.buffers.values_mut()
157 }
158
159 pub fn views(&self) -> impl Iterator<Item = &View> {
160 self.views.values()
161 }
162
163 pub fn views_of(&self, buffer: BufferId) -> impl Iterator<Item = &View> {
164 self.views.values().filter(move |v| v.buffer() == buffer)
165 }
166
167 pub fn start_recording(&mut self) {
168 self.recording = Some(Vec::new());
169 }
170
171 pub fn is_recording(&self) -> bool {
172 self.recording.is_some()
173 }
174
175 pub fn stop_recording(&mut self) -> Vec<Action> {
176 self.recording.take().unwrap_or_default()
177 }
178
179 pub fn recorded(&self) -> Option<&[Action]> {
181 self.recording.as_deref()
182 }
183
184 pub(crate) fn take_recording(&mut self) -> Option<Vec<Action>> {
185 self.recording.take()
186 }
187
188 pub(crate) fn restore_recording(&mut self, recording: Option<Vec<Action>>) {
189 self.recording = recording;
190 }
191
192 pub fn begin_undo_group(&mut self, view: ViewId) -> Result<(), ActionError> {
195 let (buffer, _) = self.lookup(view)?;
196 self.buffers
197 .get_mut(&buffer)
198 .ok_or(ActionError::UnknownBuffer(buffer))?
199 .history
200 .begin_group();
201 Ok(())
202 }
203
204 pub fn end_undo_group(&mut self, view: ViewId) -> Result<(), ActionError> {
205 let (buffer, _) = self.lookup(view)?;
206 self.buffers
207 .get_mut(&buffer)
208 .ok_or(ActionError::UnknownBuffer(buffer))?
209 .history
210 .end_group();
211 Ok(())
212 }
213
214 fn lookup(&self, view: ViewId) -> Result<(BufferId, &View), ActionError> {
215 let v = self
216 .views
217 .get(&view)
218 .ok_or(ActionError::UnknownView(view))?;
219 if !self.buffers.contains_key(&v.buffer()) {
220 return Err(ActionError::UnknownBuffer(v.buffer()));
221 }
222 Ok((v.buffer(), v))
223 }
224
225 pub fn apply(&mut self, view: ViewId, action: Action) -> Result<(), ActionError> {
229 let (buffer_id, _) = self.lookup(view)?;
230 match &action {
231 Action::Undo => self.undo(view, buffer_id),
232 Action::Redo => self.redo(view, buffer_id),
233 _ => {
234 let resolved = self.resolve_in(view, buffer_id, &action)??;
235 self.commit(view, buffer_id, resolved)?;
236 }
237 }
238 if let Some(rec) = &mut self.recording
239 && action.is_recordable()
240 {
241 rec.push(action);
242 }
243 Ok(())
244 }
245
246 fn resolve_in(
249 &self,
250 view: ViewId,
251 buffer_id: BufferId,
252 action: &Action,
253 ) -> Result<Result<Resolved, ActionError>, ActionError> {
254 let buffer = self
255 .buffers
256 .get(&buffer_id)
257 .ok_or(ActionError::UnknownBuffer(buffer_id))?;
258 let sels = &self
259 .views
260 .get(&view)
261 .ok_or(ActionError::UnknownView(view))?
262 .selections;
263 Ok(match action {
264 Action::Find { .. }
265 | Action::Replace { .. }
266 | Action::ReplaceAll { .. }
267 | Action::SelectAllMatches(_) => resolve_search(action, &buffer.doc, sels),
268 _ => Ok(resolve(action, &buffer.doc, sels, &self.settings)),
269 })
270 }
271
272 fn commit(
275 &mut self,
276 view: ViewId,
277 buffer_id: BufferId,
278 resolved: Resolved,
279 ) -> Result<(), ActionError> {
280 match resolved {
281 Resolved::Selections(sels) => {
282 if let Some(b) = self.buffers.get_mut(&buffer_id) {
283 b.history.break_coalescing();
284 }
285 self.set_selections(view, sels);
286 }
287 Resolved::Edit {
288 changes,
289 after,
290 kind,
291 } => {
292 let now = self.clock.now();
293 let before = self.views[&view].selections.clone();
294 let Some(buffer) = self.buffers.get_mut(&buffer_id) else {
295 return Err(ActionError::UnknownBuffer(buffer_id));
296 };
297 let inverse = changes.invert(&buffer.doc);
298 apply_changes(buffer, &changes);
299 let rev_before = buffer.revision;
300 let rev_after = buffer.next_revision;
301 buffer.next_revision += 1;
302 buffer.revision = rev_after;
303 buffer.history.push(
304 Transaction {
305 changes: changes.clone(),
306 inverse,
307 before,
308 after: after.clone(),
309 },
310 kind,
311 rev_before,
312 rev_after,
313 now,
314 );
315 self.set_selections(view, after);
316 self.map_other_views(buffer_id, view, &changes);
317 }
318 }
319 Ok(())
320 }
321
322 pub fn reload_buffer(
326 &mut self,
327 buffer: BufferId,
328 text: &str,
329 meta: FileMeta,
330 ) -> Result<(), ActionError> {
331 let view = self
332 .views_of(buffer)
333 .next()
334 .map(View::id)
335 .ok_or(ActionError::UnknownBuffer(buffer))?;
336 let b = self
337 .buffers
338 .get(&buffer)
339 .ok_or(ActionError::UnknownBuffer(buffer))?;
340 if b.doc.to_string() != text {
341 let new_doc = crate::text::Document::new(text);
342 let remap = |p: ByteOffset| {
343 let lc = byte_to_line_col(&b.doc, p);
344 let mut q = line_col_to_byte(&new_doc, lc);
345 while !new_doc.is_char_boundary(q) {
346 q.0 -= 1;
347 }
348 q
349 };
350 let after = self.views[&view]
351 .selections
352 .map(|s| Selection::new(remap(s.anchor), remap(s.head)));
353 let changes = ChangeSet::new(
354 b.doc.len(),
355 vec![crate::changeset::Edit::new(
356 ByteOffset(0),
357 b.doc.len(),
358 text,
359 )],
360 );
361 self.commit(
362 view,
363 buffer,
364 Resolved::Edit {
365 changes,
366 after,
367 kind: crate::history::EditKind::Other,
368 },
369 )?;
370 }
371 if let Some(b) = self.buffers.get_mut(&buffer) {
372 b.meta = meta;
373 b.mark_saved();
374 }
375 Ok(())
376 }
377
378 fn undo(&mut self, view: ViewId, buffer_id: BufferId) {
379 let Some(buffer) = self.buffers.get_mut(&buffer_id) else {
380 return;
381 };
382 let Some(step) = buffer.history.pop_undo() else {
383 return;
384 };
385 let inverses: Vec<ChangeSet> = step.txns.iter().rev().map(|t| t.inverse.clone()).collect();
386 for inv in &inverses {
387 apply_changes(buffer, inv);
388 }
389 buffer.revision = step.rev_before;
390 let sels = step.txns[0].before.clone();
391 buffer.history.push_redo(step);
392 self.set_selections(view, sels);
393 for inv in &inverses {
394 self.map_other_views(buffer_id, view, inv);
395 }
396 }
397
398 fn redo(&mut self, view: ViewId, buffer_id: BufferId) {
399 let Some(buffer) = self.buffers.get_mut(&buffer_id) else {
400 return;
401 };
402 let Some(step) = buffer.history.pop_redo() else {
403 return;
404 };
405 let changes: Vec<ChangeSet> = step.txns.iter().map(|t| t.changes.clone()).collect();
406 for cs in &changes {
407 apply_changes(buffer, cs);
408 }
409 buffer.revision = step.rev_after;
410 let sels = step.txns[step.txns.len() - 1].after.clone();
411 buffer.history.push_undo(step);
412 self.set_selections(view, sels);
413 for cs in &changes {
414 self.map_other_views(buffer_id, view, cs);
415 }
416 }
417
418 fn set_selections(&mut self, view: ViewId, sels: SelectionSet) {
419 if let Some(v) = self.views.get_mut(&view) {
420 v.selections = sels;
421 }
422 }
423
424 fn map_other_views(&mut self, buffer: BufferId, except: ViewId, changes: &ChangeSet) {
427 for v in self.views.values_mut() {
428 if v.buffer() == buffer && v.id() != except {
429 v.selections = v.selections.map(|s| Selection {
430 anchor: changes.map_position(s.anchor, Bias::Before),
431 head: changes.map_position(s.head, Bias::Before),
432 goal: s.goal,
433 });
434 }
435 }
436 }
437}
438
439fn apply_changes(buffer: &mut Buffer, changes: &ChangeSet) {
440 for e in changes.edits().iter().rev() {
443 let start = buffer.doc.line_of(e.start);
444 let edit = LineEdit {
445 start,
446 old_end: buffer.doc.line_of(e.end),
447 new_end: start + e.text.bytes().filter(|&b| b == b'\n').count(),
448 };
449 buffer.record_line_edit(edit);
450 }
451 changes.apply(&mut buffer.doc);
452}