on master help sign in
Extract a method for view alignment.
1be8b20Blaž Hrastnik
helix-term/src/commands.rs+32−27
@@ -98,6 +98,25 @@ impl<'a> Context<'a> {
98 }
98 }
99}
99}
100
100
101+enum Align {
102+ Top,
103+ Center,
104+ Bottom,
105+}
106+
107+fn align_view(doc: &Document, view: &mut View, align: Align) {
108+ let pos = doc.selection(view.id).cursor();
109+ let line = doc.text().char_to_line(pos);
110+
111+ let relative = match align {
112+ Align::Center => view.area.height as usize / 2,
113+ Align::Top => 0,
114+ Align::Bottom => view.area.height as usize,
115+ };
116+
117+ view.first_line = line.saturating_sub(relative);
118+}
119+
101/// A command is a function that takes the current state and a count, and does a side-effect on the
120/// A command is a function that takes the current state and a count, and does a side-effect on the
102/// state (usually by creating and applying a transaction).
121/// state (usually by creating and applying a transaction).
103pub type Command = fn(cx: &mut Context);
122pub type Command = fn(cx: &mut Context);
@@ -616,6 +635,7 @@ fn _search(doc: &mut Document, view: &mut View, contents: &str, regex: &Regex, e
616 let mat = regex
635 let mat = regex
617 .find_at(contents, start)
636 .find_at(contents, start)
618 .or_else(|| regex.find(contents));
637 .or_else(|| regex.find(contents));
638+ // TODO: message on wraparound
619 if let Some(mat) = mat {
639 if let Some(mat) = mat {
620 let start = text.byte_to_char(mat.start());
640 let start = text.byte_to_char(mat.start());
621 let end = text.byte_to_char(mat.end());
641 let end = text.byte_to_char(mat.end());
@@ -630,9 +650,7 @@ fn _search(doc: &mut Document, view: &mut View, contents: &str, regex: &Regex, e
630
650
631 // TODO: (first_match, regex) stuff in register?
651 // TODO: (first_match, regex) stuff in register?
632 doc.set_selection(view.id, selection);
652 doc.set_selection(view.id, selection);
633− // TODO: extract this centering into a function to share with _goto?
653+ align_view(doc, view, Align::Center);
634− let line = doc.text().char_to_line(head);
635− view.first_line = line.saturating_sub(view.area.height as usize / 2);
636 };
654 };
637}
655}
638
656
@@ -1243,8 +1261,7 @@ fn _goto(
1243 // TODO: convert inside server
1261 // TODO: convert inside server
1244 let new_pos = lsp_pos_to_pos(doc.text(), definition_pos, offset_encoding);
1262 let new_pos = lsp_pos_to_pos(doc.text(), definition_pos, offset_encoding);
1245 doc.set_selection(view.id, Selection::point(new_pos));
1263 doc.set_selection(view.id, Selection::point(new_pos));
1246− let line = doc.text().char_to_line(new_pos);
1264+ align_view(doc, view, Align::Center);
1247− view.first_line = line.saturating_sub(view.area.height as usize / 2);
1248 }
1265 }
1249
1266
1250 match locations.as_slice() {
1267 match locations.as_slice() {
@@ -1946,7 +1963,6 @@ pub fn save(cx: &mut Context) {
1946 // Spawns an async task to actually do the saving. This way we prevent blocking.
1963 // Spawns an async task to actually do the saving. This way we prevent blocking.
1947
1964
1948 // TODO: handle save errors somehow?
1965 // TODO: handle save errors somehow?
1949− // TODO: don't block
1950 tokio::spawn(cx.doc().save());
1966 tokio::spawn(cx.doc().save());
1951}
1967}
1952
1968
@@ -2051,8 +2067,6 @@ pub fn hover(cx: &mut Context) {
2051
2067
2052 // TODO: factor out a doc.position_identifier() that returns lsp::TextDocumentPositionIdentifier
2068 // TODO: factor out a doc.position_identifier() that returns lsp::TextDocumentPositionIdentifier
2053
2069
2054− // TODO: blocking here is not ideal, make commands async fn?
2055− // not like we can process additional input meanwhile though
2056 let pos = pos_to_lsp_pos(
2070 let pos = pos_to_lsp_pos(
2057 doc.text(),
2071 doc.text(),
2058 doc.selection(view.id).cursor(),
2072 doc.selection(view.id).cursor(),
@@ -2137,11 +2151,9 @@ pub fn jump_forward(cx: &mut Context) {
2137 if let Some((id, selection)) = view.jumps.forward(count) {
2151 if let Some((id, selection)) = view.jumps.forward(count) {
2138 view.doc = *id;
2152 view.doc = *id;
2139 let selection = selection.clone();
2153 let selection = selection.clone();
2140− let cursor = selection.cursor();
2141 doc.set_selection(view.id, selection);
2154 doc.set_selection(view.id, selection);
2142− // TODO: extract this centering into a function to share with _goto?
2155+
2143− let line = doc.text().char_to_line(cursor);
2156+ align_view(doc, view, Align::Center);
2144− view.first_line = line.saturating_sub(view.area.height as usize / 2);
2145 };
2157 };
2146}
2158}
2147
2159
@@ -2151,12 +2163,9 @@ pub fn jump_backward(cx: &mut Context) {
2151
2163
2152 if let Some((id, selection)) = view.jumps.backward(count) {
2164 if let Some((id, selection)) = view.jumps.backward(count) {
2153 view.doc = *id;
2165 view.doc = *id;
2154− let selection = selection.clone();
2155− let cursor = selection.cursor();
2156− doc.set_selection(view.id, selection);
2166+ doc.set_selection(view.id, selection.clone());
2157− // TODO: extract this centering into a function to share with _goto?
2167+
2158− let line = doc.text().char_to_line(cursor);
2168+ align_view(doc, view, Align::Center);
2159− view.first_line = line.saturating_sub(view.area.height as usize / 2);
2160 };
2169 };
2161}
2170}
2162
2171
@@ -2216,17 +2225,13 @@ pub fn view_mode(cx: &mut Context) {
2216 // bottom
2225 // bottom
2217 | 'b' => {
2226 | 'b' => {
2218 let (view, doc) = cx.current();
2227 let (view, doc) = cx.current();
2219− let pos = doc.selection(view.id).cursor();
2220− // TODO: extract this centering into a function to share with _goto?
2221− let line = doc.text().char_to_line(pos);
2222
2228
2223− let relative = match ch {
2229+ align_view(doc, view, match ch {
2224− 'z' | 'c' => view.area.height as usize / 2,
2230+ 'z' | 'c' => Align::Center,
2225− 't' => 0,
2231+ 't' => Align::Top,
2226− 'b' => view.area.height as usize,
2232+ 'b' => Align::Bottom,
2227 _ => unreachable!()
2233 _ => unreachable!()
2228− };
2234+ });
2229− view.first_line = line.saturating_sub(relative);
2230 }
2235 }
2231 'm' => {
2236 'm' => {
2232 let (view, doc) = cx.current();
2237 let (view, doc) = cx.current();