@@ -22,7 +22,7 @@ use anyhow::Error;
22pub use helix_core::diagnostic::Severity;
22pub use helix_core::diagnostic::Severity;
23pub use helix_core::register::Registers;
23pub use helix_core::register::Registers;
24use helix_core::syntax;
24use helix_core::syntax;
25−use helix_core::Position;
25+use helix_core::{Position, Selection};
27use serde::Deserialize;
27use serde::Deserialize;
@@ -235,9 +235,28 @@ impl Editor {
238+ fn replace_document_in_view(&mut self, current_view: ViewId, doc_id: DocumentId) {
239+ let view = self.tree.get_mut(current_view);
241+ view.offset = Position::default();
243+ let doc = self.documents.get_mut(&doc_id).unwrap();
245+ // initialize selection for view
248+ .or_insert_with(|| Selection::point(0));
249+ // TODO: reuse align_view
253+ .cursor(doc.text().slice(..));
254+ let line = doc.text().char_to_line(pos);
255+ view.offset.row = line.saturating_sub(view.inner_area().height as usize / 2);
238 pub fn switch(&mut self, id: DocumentId, action: Action) {
258 pub fn switch(&mut self, id: DocumentId, action: Action) {
239 use crate::tree::Layout;
259 use crate::tree::Layout;
240− use helix_core::Selection;
242 if !self.documents.contains_key(&id) {
261 if !self.documents.contains_key(&id) {
243 log::error!("cannot switch to document that does not exist (anymore)");
262 log::error!("cannot switch to document that does not exist (anymore)");
@@ -271,22 +290,9 @@ impl Editor {
271 view.jumps.push(jump);
290 view.jumps.push(jump);
272 view.last_accessed_doc = Some(view.doc);
291 view.last_accessed_doc = Some(view.doc);
275− view.offset = Position::default();
277− let (view, doc) = current!(self);
279− // initialize selection for view
294+ let view_id = view.id;
280− doc.selections
295+ self.replace_document_in_view(view_id, id);
282− .or_insert_with(|| Selection::point(0));
283− // TODO: reuse align_view
287− .cursor(doc.text().slice(..));
288− let line = doc.text().char_to_line(pos);
289− view.offset.row = line.saturating_sub(view.inner_area().height as usize / 2);
@@ -318,11 +324,16 @@ impl Editor {
318 self._refresh();
324 self._refresh();
321− fn new_file_from_document(&mut self, action: Action, mut document: Document) -> DocumentId {
327+ fn new_document(&mut self, mut document: Document) -> DocumentId {
322 let id = DocumentId(self.next_document_id);
328 let id = DocumentId(self.next_document_id);
323 self.next_document_id += 1;
329 self.next_document_id += 1;
324 document.id = id;
330 document.id = id;
325 self.documents.insert(id, document);
331 self.documents.insert(id, document);
335+ fn new_file_from_document(&mut self, action: Action, document: Document) -> DocumentId {
336+ let id = self.new_document(document);
326 self.switch(id, action);
337 self.switch(id, action);
@@ -392,7 +403,7 @@ impl Editor {
395− pub fn close(&mut self, id: ViewId, close_buffer: bool) {
406+ pub fn close(&mut self, id: ViewId) {
396 let view = self.tree.get(self.tree.focus);
407 let view = self.tree.get(self.tree.focus);
397 // remove selection
408 // remove selection
398 self.documents
409 self.documents
@@ -401,18 +412,66 @@ impl Editor {
401 .selections
412 .selections
402 .remove(&id);
413 .remove(&id);
404− if close_buffer {
415+ self.tree.remove(id);
405− // get around borrowck issues
416+ self._refresh();
406− let doc = &self.documents[&view.doc];
417+ }
419+ pub fn close_document(&mut self, doc_id: DocumentId, force: bool) -> anyhow::Result<()> {
420+ let doc = match self.documents.get(&doc_id) {
422+ None => anyhow::bail!("document does not exist"),
425+ if !force && doc.is_modified() {
427+ "buffer {:?} is modified",
429+ .map(|path| path.to_string_lossy().to_string())
430+ .unwrap_or_else(|| "[scratch]".into())
408− if let Some(language_server) = doc.language_server() {
434+ if let Some(language_server) = doc.language_server() {
409− tokio::spawn(language_server.text_document_did_close(doc.identifier()));
435+ tokio::spawn(language_server.text_document_did_close(doc.identifier()));
438+ let views_to_close = self
441+ .filter_map(|(view, _focus)| {
442+ if view.doc == doc_id {
448+ .collect::<Vec<_>>();
450+ for view_id in views_to_close {
451+ self.close(view_id);
411− self.documents.remove(&view.doc);
454+ self.documents.remove(&doc_id);
456+ // If the document we removed was visible in all views, we will have no more views. We don't
457+ // want to close the editor just for a simple buffer close, so we need to create a new view
458+ // containing either an existing document, or a brand new document.
459+ if self.tree.views().peekable().peek().is_none() {
463+ .map(|(&doc_id, _)| doc_id)
465+ .unwrap_or_else(|| self.new_document(Document::default()));
466+ let view = View::new(doc_id);
467+ let view_id = self.tree.insert(view);
468+ let doc = self.documents.get_mut(&doc_id).unwrap();
469+ doc.selections.insert(view_id, Selection::point(0));
414− self.tree.remove(id);
415 self._refresh();
472 self._refresh();
418 pub fn resize(&mut self, area: Rect) {
477 pub fn resize(&mut self, area: Rect) {