Replace documents SlotMap with BTreeMap

pull/950/head
Blaž Hrastnik 3 years ago
parent 39584cbccd
commit e2560f427e

@ -1818,7 +1818,7 @@ mod cmd {
let mut errors = String::new(); let mut errors = String::new();
// save all documents // save all documents
for (_, doc) in &mut cx.editor.documents { for doc in &mut cx.editor.documents.values_mut() {
if doc.path().is_none() { if doc.path().is_none() {
errors.push_str("cannot write a buffer without a filename\n"); errors.push_str("cannot write a buffer without a filename\n");
continue; continue;
@ -2512,7 +2512,7 @@ fn buffer_picker(cx: &mut Context) {
cx.editor cx.editor
.documents .documents
.iter() .iter()
.map(|(id, doc)| (id, doc.path().cloned())) .map(|(id, doc)| (*id, doc.path().cloned()))
.collect(), .collect(),
move |(id, path): &(DocumentId, Option<PathBuf>)| { move |(id, path): &(DocumentId, Option<PathBuf>)| {
let path = path.as_deref().map(helix_core::path::get_relative_path); let path = path.as_deref().map(helix_core::path::get_relative_path);
@ -2531,7 +2531,7 @@ fn buffer_picker(cx: &mut Context) {
editor.switch(*id, Action::Replace); editor.switch(*id, Action::Replace);
}, },
|editor, (id, path)| { |editor, (id, path)| {
let doc = &editor.documents.get(*id)?; let doc = &editor.documents.get(id)?;
let &view_id = doc.selections().keys().next()?; let &view_id = doc.selections().keys().next()?;
let line = doc let line = doc
.selection(view_id) .selection(view_id)

@ -813,12 +813,12 @@ impl EditorView {
let editor = &mut cxt.editor; let editor = &mut cxt.editor;
let result = editor.tree.views().find_map(|(view, _focus)| { let result = editor.tree.views().find_map(|(view, _focus)| {
view.pos_at_screen_coords(&editor.documents[view.doc], row, column) view.pos_at_screen_coords(&editor.documents[&view.doc], row, column)
.map(|pos| (pos, view.id)) .map(|pos| (pos, view.id))
}); });
if let Some((pos, view_id)) = result { if let Some((pos, view_id)) = result {
let doc = &mut editor.documents[editor.tree.get(view_id).doc]; let doc = editor.document_mut(editor.tree.get(view_id).doc).unwrap();
if modifiers == crossterm::event::KeyModifiers::ALT { if modifiers == crossterm::event::KeyModifiers::ALT {
let selection = doc.selection(view_id).clone(); let selection = doc.selection(view_id).clone();
@ -870,7 +870,7 @@ impl EditorView {
}; };
let result = cxt.editor.tree.views().find_map(|(view, _focus)| { let result = cxt.editor.tree.views().find_map(|(view, _focus)| {
view.pos_at_screen_coords(&cxt.editor.documents[view.doc], row, column) view.pos_at_screen_coords(&cxt.editor.documents[&view.doc], row, column)
.map(|_| view.id) .map(|_| view.id)
}); });
@ -926,12 +926,12 @@ impl EditorView {
} }
let result = editor.tree.views().find_map(|(view, _focus)| { let result = editor.tree.views().find_map(|(view, _focus)| {
view.pos_at_screen_coords(&editor.documents[view.doc], row, column) view.pos_at_screen_coords(&editor.documents[&view.doc], row, column)
.map(|pos| (pos, view.id)) .map(|pos| (pos, view.id))
}); });
if let Some((pos, view_id)) = result { if let Some((pos, view_id)) = result {
let doc = &mut editor.documents[editor.tree.get(view_id).doc]; let doc = editor.document_mut(editor.tree.get(view_id).doc).unwrap();
doc.set_selection(view_id, Selection::point(pos)); doc.set_selection(view_id, Selection::point(pos));
editor.tree.focus = view_id; editor.tree.focus = view_id;
commands::Command::paste_primary_clipboard_before.execute(cxt); commands::Command::paste_primary_clipboard_before.execute(cxt);

@ -8,6 +8,7 @@ use crate::{
use futures_util::future; use futures_util::future;
use std::{ use std::{
collections::BTreeMap,
path::{Path, PathBuf}, path::{Path, PathBuf},
pin::Pin, pin::Pin,
sync::Arc, sync::Arc,
@ -15,8 +16,6 @@ use std::{
use tokio::time::{sleep, Duration, Instant, Sleep}; use tokio::time::{sleep, Duration, Instant, Sleep};
use slotmap::SlotMap;
use anyhow::Error; use anyhow::Error;
pub use helix_core::diagnostic::Severity; pub use helix_core::diagnostic::Severity;
@ -108,7 +107,8 @@ impl std::fmt::Debug for Motion {
#[derive(Debug)] #[derive(Debug)]
pub struct Editor { pub struct Editor {
pub tree: Tree, pub tree: Tree,
pub documents: SlotMap<DocumentId, Document>, pub next_document_id: usize,
pub documents: BTreeMap<DocumentId, Document>,
pub count: Option<std::num::NonZeroUsize>, pub count: Option<std::num::NonZeroUsize>,
pub selected_register: Option<char>, pub selected_register: Option<char>,
pub registers: Registers, pub registers: Registers,
@ -149,7 +149,8 @@ impl Editor {
Self { Self {
tree: Tree::new(area), tree: Tree::new(area),
documents: SlotMap::with_key(), next_document_id: 0,
documents: BTreeMap::new(),
count: None, count: None,
selected_register: None, selected_register: None,
theme: themes.default(), theme: themes.default(),
@ -216,7 +217,7 @@ impl Editor {
fn _refresh(&mut self) { fn _refresh(&mut self) {
for (view, _) in self.tree.views_mut() { for (view, _) in self.tree.views_mut() {
let doc = &self.documents[view.doc]; let doc = &self.documents[&view.doc];
view.ensure_cursor_in_view(doc, self.config.scrolloff) view.ensure_cursor_in_view(doc, self.config.scrolloff)
} }
} }
@ -225,7 +226,7 @@ impl Editor {
use crate::tree::Layout; use crate::tree::Layout;
use helix_core::Selection; use helix_core::Selection;
if !self.documents.contains_key(id) { if !self.documents.contains_key(&id) {
log::error!("cannot switch to document that does not exist (anymore)"); log::error!("cannot switch to document that does not exist (anymore)");
return; return;
} }
@ -249,7 +250,7 @@ impl Editor {
// Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable // Copy `doc.id` into a variable before calling `self.documents.remove`, which requires a mutable
// borrow, invalidating direct access to `doc.id`. // borrow, invalidating direct access to `doc.id`.
let id = doc.id; let id = doc.id;
self.documents.remove(id); self.documents.remove(&id);
} else { } else {
let jump = (view.doc, doc.selection(view.id).clone()); let jump = (view.doc, doc.selection(view.id).clone());
view.jumps.push(jump); view.jumps.push(jump);
@ -281,14 +282,14 @@ impl Editor {
let view = View::new(id); let view = View::new(id);
let view_id = self.tree.split(view, Layout::Horizontal); let view_id = self.tree.split(view, Layout::Horizontal);
// initialize selection for view // initialize selection for view
let doc = &mut self.documents[id]; let doc = self.documents.get_mut(&id).unwrap();
doc.selections.insert(view_id, Selection::point(0)); doc.selections.insert(view_id, Selection::point(0));
} }
Action::VerticalSplit => { Action::VerticalSplit => {
let view = View::new(id); let view = View::new(id);
let view_id = self.tree.split(view, Layout::Vertical); let view_id = self.tree.split(view, Layout::Vertical);
// initialize selection for view // initialize selection for view
let doc = &mut self.documents[id]; let doc = self.documents.get_mut(&id).unwrap();
doc.selections.insert(view_id, Selection::point(0)); doc.selections.insert(view_id, Selection::point(0));
} }
} }
@ -297,9 +298,11 @@ impl Editor {
} }
pub fn new_file(&mut self, action: Action) -> DocumentId { pub fn new_file(&mut self, action: Action) -> DocumentId {
let doc = Document::default(); let id = DocumentId(self.next_document_id);
let id = self.documents.insert(doc); self.next_document_id += 1;
self.documents[id].id = id; let mut doc = Document::default();
doc.id = id;
self.documents.insert(id, doc);
self.switch(id, action); self.switch(id, action);
id id
} }
@ -349,8 +352,10 @@ impl Editor {
doc.set_language_server(Some(language_server)); doc.set_language_server(Some(language_server));
} }
let id = self.documents.insert(doc); let id = DocumentId(self.next_document_id);
self.documents[id].id = id; self.next_document_id += 1;
doc.id = id;
self.documents.insert(id, doc);
id id
}; };
@ -361,16 +366,20 @@ impl Editor {
pub fn close(&mut self, id: ViewId, close_buffer: bool) { pub fn close(&mut self, id: ViewId, close_buffer: bool) {
let view = self.tree.get(self.tree.focus); let view = self.tree.get(self.tree.focus);
// remove selection // remove selection
self.documents[view.doc].selections.remove(&id); self.documents
.get_mut(&view.doc)
.unwrap()
.selections
.remove(&id);
if close_buffer { if close_buffer {
// get around borrowck issues // get around borrowck issues
let doc = &self.documents[view.doc]; let doc = &self.documents[&view.doc];
if let Some(language_server) = doc.language_server() { if let Some(language_server) = doc.language_server() {
tokio::spawn(language_server.text_document_did_close(doc.identifier())); tokio::spawn(language_server.text_document_did_close(doc.identifier()));
} }
self.documents.remove(view.doc); self.documents.remove(&view.doc);
} }
self.tree.remove(id); self.tree.remove(id);
@ -409,18 +418,18 @@ impl Editor {
pub fn ensure_cursor_in_view(&mut self, id: ViewId) { pub fn ensure_cursor_in_view(&mut self, id: ViewId) {
let view = self.tree.get_mut(id); let view = self.tree.get_mut(id);
let doc = &self.documents[view.doc]; let doc = &self.documents[&view.doc];
view.ensure_cursor_in_view(doc, self.config.scrolloff) view.ensure_cursor_in_view(doc, self.config.scrolloff)
} }
#[inline] #[inline]
pub fn document(&self, id: DocumentId) -> Option<&Document> { pub fn document(&self, id: DocumentId) -> Option<&Document> {
self.documents.get(id) self.documents.get(&id)
} }
#[inline] #[inline]
pub fn document_mut(&mut self, id: DocumentId) -> Option<&mut Document> { pub fn document_mut(&mut self, id: DocumentId) -> Option<&mut Document> {
self.documents.get_mut(id) self.documents.get_mut(&id)
} }
#[inline] #[inline]
@ -445,7 +454,7 @@ impl Editor {
pub fn cursor(&self) -> (Option<Position>, CursorKind) { pub fn cursor(&self) -> (Option<Position>, CursorKind) {
let view = view!(self); let view = view!(self);
let doc = &self.documents[view.doc]; let doc = &self.documents[&view.doc];
let cursor = doc let cursor = doc
.selection(view.id) .selection(view.id)
.primary() .primary()

@ -12,8 +12,10 @@ pub mod theme;
pub mod tree; pub mod tree;
pub mod view; pub mod view;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)]
pub struct DocumentId(usize);
slotmap::new_key_type! { slotmap::new_key_type! {
pub struct DocumentId;
pub struct ViewId; pub struct ViewId;
} }

@ -13,7 +13,8 @@
macro_rules! current { macro_rules! current {
( $( $editor:ident ).+ ) => {{ ( $( $editor:ident ).+ ) => {{
let view = $crate::view_mut!( $( $editor ).+ ); let view = $crate::view_mut!( $( $editor ).+ );
let doc = &mut $( $editor ).+ .documents[view.doc]; let id = view.doc;
let doc = $( $editor ).+ .documents.get_mut(&id).unwrap();
(view, doc) (view, doc)
}}; }};
} }
@ -56,7 +57,7 @@ macro_rules! doc {
macro_rules! current_ref { macro_rules! current_ref {
( $( $editor:ident ).+ ) => {{ ( $( $editor:ident ).+ ) => {{
let view = $( $editor ).+ .tree.get($( $editor ).+ .tree.focus); let view = $( $editor ).+ .tree.get($( $editor ).+ .tree.focus);
let doc = &$( $editor ).+ .documents[view.doc]; let doc = &$( $editor ).+ .documents[&view.doc];
(view, doc) (view, doc)
}}; }};
} }

Loading…
Cancel
Save