on master help sign in
Replace documents SlotMap with BTreeMap
e2560f4Blaž Hrastnik
helix-term/src/commands.rs+3−3
@@ -1818,7 +1818,7 @@ mod cmd {
1818 let mut errors = String::new();
1818 let mut errors = String::new();
1819
1819
1820 // save all documents
1820 // save all documents
1821− for (_, doc) in &mut cx.editor.documents {
1821+ for doc in &mut cx.editor.documents.values_mut() {
1822 if doc.path().is_none() {
1822 if doc.path().is_none() {
1823 errors.push_str("cannot write a buffer without a filename\n");
1823 errors.push_str("cannot write a buffer without a filename\n");
1824 continue;
1824 continue;
@@ -2512,7 +2512,7 @@ fn buffer_picker(cx: &mut Context) {
2512 cx.editor
2512 cx.editor
2513 .documents
2513 .documents
2514 .iter()
2514 .iter()
2515− .map(|(id, doc)| (id, doc.path().cloned()))
2515+ .map(|(id, doc)| (*id, doc.path().cloned()))
2516 .collect(),
2516 .collect(),
2517 move |(id, path): &(DocumentId, Option<PathBuf>)| {
2517 move |(id, path): &(DocumentId, Option<PathBuf>)| {
2518 let path = path.as_deref().map(helix_core::path::get_relative_path);
2518 let path = path.as_deref().map(helix_core::path::get_relative_path);
@@ -2531,7 +2531,7 @@ fn buffer_picker(cx: &mut Context) {
2531 editor.switch(*id, Action::Replace);
2531 editor.switch(*id, Action::Replace);
2532 },
2532 },
2533 |editor, (id, path)| {
2533 |editor, (id, path)| {
2534− let doc = &editor.documents.get(*id)?;
2534+ let doc = &editor.documents.get(id)?;
2535 let &view_id = doc.selections().keys().next()?;
2535 let &view_id = doc.selections().keys().next()?;
2536 let line = doc
2536 let line = doc
2537 .selection(view_id)
2537 .selection(view_id)
helix-term/src/ui/editor.rs+5−5
@@ -813,12 +813,12 @@ impl EditorView {
813 let editor = &mut cxt.editor;
813 let editor = &mut cxt.editor;
814
814
815 let result = editor.tree.views().find_map(|(view, _focus)| {
815 let result = editor.tree.views().find_map(|(view, _focus)| {
816− view.pos_at_screen_coords(&editor.documents[view.doc], row, column)
816+ view.pos_at_screen_coords(&editor.documents[&view.doc], row, column)
817 .map(|pos| (pos, view.id))
817 .map(|pos| (pos, view.id))
818 });
818 });
819
819
820 if let Some((pos, view_id)) = result {
820 if let Some((pos, view_id)) = result {
821− let doc = &mut editor.documents[editor.tree.get(view_id).doc];
821+ let doc = editor.document_mut(editor.tree.get(view_id).doc).unwrap();
822
822
823 if modifiers == crossterm::event::KeyModifiers::ALT {
823 if modifiers == crossterm::event::KeyModifiers::ALT {
824 let selection = doc.selection(view_id).clone();
824 let selection = doc.selection(view_id).clone();
@@ -870,7 +870,7 @@ impl EditorView {
870 };
870 };
871
871
872 let result = cxt.editor.tree.views().find_map(|(view, _focus)| {
872 let result = cxt.editor.tree.views().find_map(|(view, _focus)| {
873− view.pos_at_screen_coords(&cxt.editor.documents[view.doc], row, column)
873+ view.pos_at_screen_coords(&cxt.editor.documents[&view.doc], row, column)
874 .map(|_| view.id)
874 .map(|_| view.id)
875 });
875 });
876
876
@@ -926,12 +926,12 @@ impl EditorView {
926 }
926 }
927
927
928 let result = editor.tree.views().find_map(|(view, _focus)| {
928 let result = editor.tree.views().find_map(|(view, _focus)| {
929− view.pos_at_screen_coords(&editor.documents[view.doc], row, column)
929+ view.pos_at_screen_coords(&editor.documents[&view.doc], row, column)
930 .map(|pos| (pos, view.id))
930 .map(|pos| (pos, view.id))
931 });
931 });
932
932
933 if let Some((pos, view_id)) = result {
933 if let Some((pos, view_id)) = result {
934− let doc = &mut editor.documents[editor.tree.get(view_id).doc];
934+ let doc = editor.document_mut(editor.tree.get(view_id).doc).unwrap();
935 doc.set_selection(view_id, Selection::point(pos));
935 doc.set_selection(view_id, Selection::point(pos));
936 editor.tree.focus = view_id;
936 editor.tree.focus = view_id;
937 commands::Command::paste_primary_clipboard_before.execute(cxt);
937 commands::Command::paste_primary_clipboard_before.execute(cxt);
helix-view/src/editor.rs+30−21
@@ -8,6 +8,7 @@ use crate::{
8
8
9use futures_util::future;
9use futures_util::future;
10use std::{
10use std::{
11+ collections::BTreeMap,
11 path::{Path, PathBuf},
12 path::{Path, PathBuf},
12 pin::Pin,
13 pin::Pin,
13 sync::Arc,
14 sync::Arc,
@@ -15,8 +16,6 @@ use std::{
15
16
16use tokio::time::{sleep, Duration, Instant, Sleep};
17use tokio::time::{sleep, Duration, Instant, Sleep};
17
18
18−use slotmap::SlotMap;
19−
20use anyhow::Error;
19use anyhow::Error;
21
20
22pub use helix_core::diagnostic::Severity;
21pub use helix_core::diagnostic::Severity;
@@ -108,7 +107,8 @@ impl std::fmt::Debug for Motion {
108#[derive(Debug)]
107#[derive(Debug)]
109pub struct Editor {
108pub struct Editor {
110 pub tree: Tree,
109 pub tree: Tree,
110+ pub next_document_id: usize,
111− pub documents: SlotMap<DocumentId, Document>,
111+ pub documents: BTreeMap<DocumentId, Document>,
112 pub count: Option<std::num::NonZeroUsize>,
112 pub count: Option<std::num::NonZeroUsize>,
113 pub selected_register: Option<char>,
113 pub selected_register: Option<char>,
114 pub registers: Registers,
114 pub registers: Registers,
@@ -149,7 +149,8 @@ impl Editor {
149
149
150 Self {
150 Self {
151 tree: Tree::new(area),
151 tree: Tree::new(area),
152+ next_document_id: 0,
152− documents: SlotMap::with_key(),
153+ documents: BTreeMap::new(),
153 count: None,
154 count: None,
154 selected_register: None,
155 selected_register: None,
155 theme: themes.default(),
156 theme: themes.default(),
@@ -216,7 +217,7 @@ impl Editor {
216
217
217 fn _refresh(&mut self) {
218 fn _refresh(&mut self) {
218 for (view, _) in self.tree.views_mut() {
219 for (view, _) in self.tree.views_mut() {
219− let doc = &self.documents[view.doc];
220+ let doc = &self.documents[&view.doc];
220 view.ensure_cursor_in_view(doc, self.config.scrolloff)
221 view.ensure_cursor_in_view(doc, self.config.scrolloff)
221 }
222 }
222 }
223 }
@@ -225,7 +226,7 @@ impl Editor {
225 use crate::tree::Layout;
226 use crate::tree::Layout;
226 use helix_core::Selection;
227 use helix_core::Selection;
227
228
228− if !self.documents.contains_key(id) {
229+ if !self.documents.contains_key(&id) {
229 log::error!("cannot switch to document that does not exist (anymore)");
230 log::error!("cannot switch to document that does not exist (anymore)");
230 return;
231 return;
231 }
232 }
@@ -249,7 +250,7 @@ impl Editor {
249 // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable
250 // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable
250 // borrow, invalidating direct access to `doc.id`.
251 // borrow, invalidating direct access to `doc.id`.
251 let id = doc.id;
252 let id = doc.id;
252− self.documents.remove(id);
253+ self.documents.remove(&id);
253 } else {
254 } else {
254 let jump = (view.doc, doc.selection(view.id).clone());
255 let jump = (view.doc, doc.selection(view.id).clone());
255 view.jumps.push(jump);
256 view.jumps.push(jump);
@@ -281,14 +282,14 @@ impl Editor {
281 let view = View::new(id);
282 let view = View::new(id);
282 let view_id = self.tree.split(view, Layout::Horizontal);
283 let view_id = self.tree.split(view, Layout::Horizontal);
283 // initialize selection for view
284 // initialize selection for view
284− let doc = &mut self.documents[id];
285+ let doc = self.documents.get_mut(&id).unwrap();
285 doc.selections.insert(view_id, Selection::point(0));
286 doc.selections.insert(view_id, Selection::point(0));
286 }
287 }
287 Action::VerticalSplit => {
288 Action::VerticalSplit => {
288 let view = View::new(id);
289 let view = View::new(id);
289 let view_id = self.tree.split(view, Layout::Vertical);
290 let view_id = self.tree.split(view, Layout::Vertical);
290 // initialize selection for view
291 // initialize selection for view
291− let doc = &mut self.documents[id];
292+ let doc = self.documents.get_mut(&id).unwrap();
292 doc.selections.insert(view_id, Selection::point(0));
293 doc.selections.insert(view_id, Selection::point(0));
293 }
294 }
294 }
295 }
@@ -297,9 +298,11 @@ impl Editor {
297 }
298 }
298
299
299 pub fn new_file(&mut self, action: Action) -> DocumentId {
300 pub fn new_file(&mut self, action: Action) -> DocumentId {
301+ let id = DocumentId(self.next_document_id);
302+ self.next_document_id += 1;
300− let doc = Document::default();
303+ let mut doc = Document::default();
304+ doc.id = id;
301− let id = self.documents.insert(doc);
305+ self.documents.insert(id, doc);
302− self.documents[id].id = id;
303 self.switch(id, action);
306 self.switch(id, action);
304 id
307 id
305 }
308 }
@@ -349,8 +352,10 @@ impl Editor {
349 doc.set_language_server(Some(language_server));
352 doc.set_language_server(Some(language_server));
350 }
353 }
351
354
355+ let id = DocumentId(self.next_document_id);
356+ self.next_document_id += 1;
357+ doc.id = id;
352− let id = self.documents.insert(doc);
358+ self.documents.insert(id, doc);
353− self.documents[id].id = id;
354 id
359 id
355 };
360 };
356
361
@@ -361,16 +366,20 @@ impl Editor {
361 pub fn close(&mut self, id: ViewId, close_buffer: bool) {
366 pub fn close(&mut self, id: ViewId, close_buffer: bool) {
362 let view = self.tree.get(self.tree.focus);
367 let view = self.tree.get(self.tree.focus);
363 // remove selection
368 // remove selection
364− self.documents[view.doc].selections.remove(&id);
369+ self.documents
370+ .get_mut(&view.doc)
371+ .unwrap()
372+ .selections
373+ .remove(&id);
365
374
366 if close_buffer {
375 if close_buffer {
367 // get around borrowck issues
376 // get around borrowck issues
368− let doc = &self.documents[view.doc];
377+ let doc = &self.documents[&view.doc];
369
378
370 if let Some(language_server) = doc.language_server() {
379 if let Some(language_server) = doc.language_server() {
371 tokio::spawn(language_server.text_document_did_close(doc.identifier()));
380 tokio::spawn(language_server.text_document_did_close(doc.identifier()));
372 }
381 }
373− self.documents.remove(view.doc);
382+ self.documents.remove(&view.doc);
374 }
383 }
375
384
376 self.tree.remove(id);
385 self.tree.remove(id);
@@ -409,18 +418,18 @@ impl Editor {
409
418
410 pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
419 pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
411 let view = self.tree.get_mut(id);
420 let view = self.tree.get_mut(id);
412− let doc = &self.documents[view.doc];
421+ let doc = &self.documents[&view.doc];
413 view.ensure_cursor_in_view(doc, self.config.scrolloff)
422 view.ensure_cursor_in_view(doc, self.config.scrolloff)
414 }
423 }
415
424
416 #[inline]
425 #[inline]
417 pub fn document(&self, id: DocumentId) -> Option<&Document> {
426 pub fn document(&self, id: DocumentId) -> Option<&Document> {
418− self.documents.get(id)
427+ self.documents.get(&id)
419 }
428 }
420
429
421 #[inline]
430 #[inline]
422 pub fn document_mut(&mut self, id: DocumentId) -> Option<&mut Document> {
431 pub fn document_mut(&mut self, id: DocumentId) -> Option<&mut Document> {
423− self.documents.get_mut(id)
432+ self.documents.get_mut(&id)
424 }
433 }
425
434
426 #[inline]
435 #[inline]
@@ -445,7 +454,7 @@ impl Editor {
445
454
446 pub fn cursor(&self) -> (Option<Position>, CursorKind) {
455 pub fn cursor(&self) -> (Option<Position>, CursorKind) {
447 let view = view!(self);
456 let view = view!(self);
448− let doc = &self.documents[view.doc];
457+ let doc = &self.documents[&view.doc];
449 let cursor = doc
458 let cursor = doc
450 .selection(view.id)
459 .selection(view.id)
451 .primary()
460 .primary()
helix-view/src/lib.rs+3−1
@@ -12,8 +12,10 @@ pub mod theme;
12pub mod tree;
12pub mod tree;
13pub mod view;
13pub mod view;
14
14
15+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)]
16+pub struct DocumentId(usize);
17+
15slotmap::new_key_type! {
18slotmap::new_key_type! {
16− pub struct DocumentId;
17 pub struct ViewId;
19 pub struct ViewId;
18}
20}
19
21
helix-view/src/macros.rs+3−2
@@ -13,7 +13,8 @@
13macro_rules! current {
13macro_rules! current {
14 ( $( $editor:ident ).+ ) => {{
14 ( $( $editor:ident ).+ ) => {{
15 let view = $crate::view_mut!( $( $editor ).+ );
15 let view = $crate::view_mut!( $( $editor ).+ );
16+ let id = view.doc;
16− let doc = &mut $( $editor ).+ .documents[view.doc];
17+ let doc = $( $editor ).+ .documents.get_mut(&id).unwrap();
17 (view, doc)
18 (view, doc)
18 }};
19 }};
19}
20}
@@ -56,7 +57,7 @@ macro_rules! doc {
56macro_rules! current_ref {
57macro_rules! current_ref {
57 ( $( $editor:ident ).+ ) => {{
58 ( $( $editor:ident ).+ ) => {{
58 let view = $( $editor ).+ .tree.get($( $editor ).+ .tree.focus);
59 let view = $( $editor ).+ .tree.get($( $editor ).+ .tree.focus);
59− let doc = &$( $editor ).+ .documents[view.doc];
60+ let doc = &$( $editor ).+ .documents[&view.doc];
60 (view, doc)
61 (view, doc)
61 }};
62 }};
62}
63}