|
|
@ -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()
|
|
|
|