on master help sign in
Allow closing individual views.
commit7877647cf0812380623b0087fbd7bea0ee9fae20 authorBlaž Hrastnik <blaz@mxxn.io> dateFri 19 Feb 2021, 17:46 (6 years ago) parent1e1dae1
5 files changed+123−29
helix-term/src/application.rs+2−3 helix-term/src/commands.rs+4−1 helix-view/src/editor.rs+12−3 helix-view/src/tree.rs+102−22 helix-view/src/view.rs+3
helix-term/src/application.rs+2−3
@@ -82,7 +82,7 @@ impl Application {
8282 self.render();
8383
8484 loop {
85− if self.editor.should_close {
85+ if self.editor.should_close() {
8686 break;
8787 }
8888
@@ -116,9 +116,8 @@ impl Application {
116116 None => panic!(),
117117 };
118118
119− if should_redraw {
119+ if should_redraw && !self.editor.should_close() {
120120 self.render();
121− // calling render twice here fixes it for some reason
122121 }
123122 }
124123
helix-term/src/commands.rs+4−1
@@ -558,7 +558,10 @@ pub fn command_mode(cx: &mut Context) {
558558 let parts = input.split_ascii_whitespace().collect::<Vec<&str>>();
559559
560560 match *parts.as_slice() {
561− ["q"] => editor.should_close = true,
561+ ["q"] => {
562+ editor.tree.remove(editor.view().id);
563+ // editor.should_close = true,
564+ }
562565 ["o", path] => {
563566 editor.open(path.into(), executor);
564567 }
helix-view/src/editor.rs+12−3
@@ -4,12 +4,13 @@ use crate::{Document, View};
44
55use std::path::PathBuf;
66
7+use slotmap::DefaultKey as Key;
8+
79use anyhow::Error;
810
911pub struct Editor {
1012 pub tree: Tree,
1113 // pub documents: Vec<Document>,
12− pub should_close: bool,
1314 pub count: Option<usize>,
1415 pub theme: Theme, // TODO: share one instance
1516 pub language_servers: helix_lsp::Registry,
@@ -25,7 +26,6 @@ impl Editor {
2526
2627 Self {
2728 tree: Tree::new(area),
28− should_close: false,
2929 count: None,
3030 theme,
3131 language_servers,
@@ -54,10 +54,19 @@ impl Editor {
5454 }
5555
5656 let view = View::new(doc)?;
57− self.tree.insert(view);
57+ let id = self.tree.insert(view);
58+ self.tree.get_mut(id).id = id;
5859 Ok(())
5960 }
6061
62+ pub fn close(&mut self, id: Key) {
63+ self.tree.remove(id)
64+ }
65+
66+ pub fn should_close(&mut self) -> bool {
67+ self.tree.is_empty()
68+ }
69+
6170 pub fn view(&self) -> &View {
6271 self.tree.get(self.tree.focus)
6372 }
helix-view/src/tree.rs+102−22
@@ -7,7 +7,6 @@ use tui::layout::Rect;
77pub struct Tree {
88 root: Key,
99 // (container, index inside the container)
10− current: (Key, usize),
1110 pub focus: Key,
1211 // fullscreen: bool,
1312 area: Rect,
@@ -18,18 +17,29 @@ pub struct Tree {
1817 stack: Vec<(Key, Rect)>,
1918}
2019
21−pub enum Node {
20+pub struct Node {
21+ parent: Key,
22+ content: Content,
23+}
24+
25+pub enum Content {
2226 View(Box<View>),
2327 Container(Box<Container>),
2428}
2529
2630impl Node {
2731 pub fn container() -> Self {
28− Self::Container(Box::new(Container::new()))
32+ Node {
33+ parent: Key::default(),
34+ content: Content::Container(Box::new(Container::new())),
35+ }
2936 }
3037
3138 pub fn view(view: View) -> Self {
32− Self::View(Box::new(view))
39+ Node {
40+ parent: Key::default(),
41+ content: Content::View(Box::new(view)),
42+ }
3343 }
3444}
3545
@@ -66,13 +76,16 @@ impl Default for Container {
6676impl Tree {
6777 pub fn new(area: Rect) -> Self {
6878 let root = Node::container();
79+
6980 let mut nodes = HopSlotMap::new();
7081 let root = nodes.insert(root);
7182
83+ // root is it's own parent
84+ nodes[root].parent = root;
85+
7286 Self {
7387 root,
74− current: (root, 0),
75− focus: Key::default(),
88+ focus: root,
7689 // fullscreen: false,
7790 area,
7891 nodes,
@@ -81,23 +94,34 @@ impl Tree {
8194 }
8295
8396 pub fn insert(&mut self, view: View) -> Key {
84− let node = self.nodes.insert(Node::view(view));
85− let (id, pos) = self.current;
86− let container = match &mut self.nodes[id] {
87− Node::Container(container) => container,
97+ let focus = self.focus;
98+ let parent = self.nodes[focus].parent;
99+ let mut node = Node::view(view);
100+ node.parent = parent;
101+ let node = self.nodes.insert(node);
102+
103+ let container = match &mut self.nodes[parent] {
104+ Node {
105+ content: Content::Container(container),
106+ ..
107+ } => container,
88108 _ => unreachable!(),
89109 };
90110
91111 // insert node after the current item if there is children already
92112 let pos = if container.children.is_empty() {
93− pos
113+ 0
94114 } else {
115+ let pos = container
116+ .children
117+ .iter()
118+ .position(|&child| child == focus)
119+ .unwrap();
95120 pos + 1
96121 };
97122
98123 container.children.insert(pos, node);
99124 // focus the new node
100− self.current = (id, pos);
101125 self.focus = node;
102126
103127 // recalculate all the sizes
@@ -106,26 +130,78 @@ impl Tree {
106130 node
107131 }
108132
133+ pub fn remove(&mut self, index: Key) {
134+ let mut stack = Vec::new();
135+
136+ if self.focus == index {
137+ // focus on something else
138+ self.focus_next();
139+ }
140+
141+ stack.push(index);
142+
143+ while let Some(index) = stack.pop() {
144+ let parent_id = self.nodes[index].parent;
145+ if let Node {
146+ content: Content::Container(container),
147+ ..
148+ } = &mut self.nodes[parent_id]
149+ {
150+ if let Some(pos) = container.children.iter().position(|&child| child == index) {
151+ container.children.remove(pos);
152+
153+ // TODO: if container now only has one child, remove it and place child in parent
154+ if container.children.is_empty() && parent_id != self.root {
155+ // if container now empty, remove it
156+ stack.push(parent_id);
157+ }
158+ }
159+ }
160+ self.nodes.remove(index);
161+ }
162+
163+ self.recalculate()
164+ }
165+
109166 pub fn views(&mut self) -> impl Iterator<Item = (&mut View, bool)> {
110167 let focus = self.focus;
111168 self.nodes
112169 .iter_mut()
113170 .filter_map(move |(key, node)| match node {
114− Node::View(view) => Some((view.as_mut(), focus == key)),
115− Node::Container(..) => None,
171+ Node {
172+ content: Content::View(view),
173+ ..
174+ } => Some((view.as_mut(), focus == key)),
175+ _ => None,
116176 })
117177 }
118178
119179 pub fn get(&self, index: Key) -> &View {
120180 match &self.nodes[index] {
121− Node::View(view) => view,
181+ Node {
182+ content: Content::View(view),
183+ ..
184+ } => view,
122185 _ => unreachable!(),
123186 }
124187 }
125188
126189 pub fn get_mut(&mut self, index: Key) -> &mut View {
127190 match &mut self.nodes[index] {
128− Node::View(view) => view,
191+ Node {
192+ content: Content::View(view),
193+ ..
194+ } => view,
195+ _ => unreachable!(),
196+ }
197+ }
198+
199+ pub fn is_empty(&self) -> bool {
200+ match &self.nodes[self.root] {
201+ Node {
202+ content: Content::Container(container),
203+ ..
204+ } => container.children.is_empty(),
129205 _ => unreachable!(),
130206 }
131207 }
@@ -136,6 +212,10 @@ impl Tree {
136212 }
137213
138214 pub fn recalculate(&mut self) {
215+ if self.is_empty() {
216+ return;
217+ }
218+
139219 self.stack.push((self.root, self.area));
140220
141221 // take the area
@@ -146,12 +226,12 @@ impl Tree {
146226 while let Some((key, area)) = self.stack.pop() {
147227 let node = &mut self.nodes[key];
148228
149− match node {
150− Node::View(view) => {
229+ match &mut node.content {
230+ Content::View(view) => {
151231 // debug!!("setting view area {:?}", area);
152232 view.area = area;
153233 } // TODO: call f()
154− Node::Container(container) => {
234+ Content::Container(container) => {
155235 // debug!!("setting container area {:?}", area);
156236 container.area = area;
157237
@@ -263,9 +343,9 @@ impl<'a> Iterator for Traverse<'a> {
263343
264344 let node = &self.tree.nodes[key];
265345
266− match node {
267− Node::View(view) => return Some((key, view)),
268− Node::Container(container) => {
346+ match &node.content {
347+ Content::View(view) => return Some((key, view)),
348+ Content::Container(container) => {
269349 self.stack.extend(container.children.iter().rev());
270350 }
271351 }
helix-view/src/view.rs+3
@@ -8,6 +8,7 @@ use helix_core::{
88 indent::TAB_WIDTH,
99 Position, RopeSlice,
1010};
11+use slotmap::DefaultKey as Key;
1112use tui::layout::Rect;
1213
1314pub const PADDING: usize = 5;
@@ -15,6 +16,7 @@ pub const PADDING: usize = 5;
1516// TODO: view should be View { doc: Document(state, history,..) }
1617// since we can have multiple views into the same file
1718pub struct View {
19+ pub id: Key,
1820 pub doc: Document,
1921 pub first_line: usize,
2022 pub area: Rect,
@@ -24,6 +26,7 @@ pub struct View {
2426impl View {
2527 pub fn new(doc: Document) -> Result<Self, Error> {
2628 let view = Self {
29+ id: Key::default(),
2730 doc,
2831 first_line: 0,
2932 area: Rect::default(), // will get calculated upon inserting into tree