on master help sign in
Support go to line 1
ae51065Zheming Li
helix-term/src/commands.rs+33−32
@@ -37,7 +37,7 @@ use once_cell::sync::Lazy;
37
37
38pub struct Context<'a> {
38pub struct Context<'a> {
39 pub register: helix_view::RegisterSelection,
39 pub register: helix_view::RegisterSelection,
40− pub count: usize,
40+ pub _count: Option<std::num::NonZeroUsize>,
41 pub editor: &'a mut Editor,
41 pub editor: &'a mut Editor,
42
42
43 pub callback: Option<crate::compositor::Callback>,
43 pub callback: Option<crate::compositor::Callback>,
@@ -97,6 +97,11 @@ impl<'a> Context<'a> {
97 });
97 });
98 self.callbacks.push(callback);
98 self.callbacks.push(callback);
99 }
99 }
100+
101+ #[inline]
102+ pub fn count(&self) -> usize {
103+ self._count.map_or(1, |v| v.get())
104+ }
100}
105}
101
106
102enum Align {
107enum Align {
@@ -123,7 +128,7 @@ fn align_view(doc: &Document, view: &mut View, align: Align) {
123pub type Command = fn(cx: &mut Context);
128pub type Command = fn(cx: &mut Context);
124
129
125pub fn move_char_left(cx: &mut Context) {
130pub fn move_char_left(cx: &mut Context) {
126− let count = cx.count;
131+ let count = cx.count();
127 let (view, doc) = cx.current();
132 let (view, doc) = cx.current();
128 let text = doc.text().slice(..);
133 let text = doc.text().slice(..);
129 let selection = doc.selection(view.id).transform(|range| {
134 let selection = doc.selection(view.id).transform(|range| {
@@ -139,7 +144,7 @@ pub fn move_char_left(cx: &mut Context) {
139}
144}
140
145
141pub fn move_char_right(cx: &mut Context) {
146pub fn move_char_right(cx: &mut Context) {
142− let count = cx.count;
147+ let count = cx.count();
143 let (view, doc) = cx.current();
148 let (view, doc) = cx.current();
144 let text = doc.text().slice(..);
149 let text = doc.text().slice(..);
145 let selection = doc.selection(view.id).transform(|range| {
150 let selection = doc.selection(view.id).transform(|range| {
@@ -155,7 +160,7 @@ pub fn move_char_right(cx: &mut Context) {
155}
160}
156
161
157pub fn move_line_up(cx: &mut Context) {
162pub fn move_line_up(cx: &mut Context) {
158− let count = cx.count;
163+ let count = cx.count();
159 let (view, doc) = cx.current();
164 let (view, doc) = cx.current();
160 let text = doc.text().slice(..);
165 let text = doc.text().slice(..);
161 let selection = doc.selection(view.id).transform(|range| {
166 let selection = doc.selection(view.id).transform(|range| {
@@ -171,7 +176,7 @@ pub fn move_line_up(cx: &mut Context) {
171}
176}
172
177
173pub fn move_line_down(cx: &mut Context) {
178pub fn move_line_down(cx: &mut Context) {
174− let count = cx.count;
179+ let count = cx.count();
175 let (view, doc) = cx.current();
180 let (view, doc) = cx.current();
176 let text = doc.text().slice(..);
181 let text = doc.text().slice(..);
177 let selection = doc.selection(view.id).transform(|range| {
182 let selection = doc.selection(view.id).transform(|range| {
@@ -240,7 +245,7 @@ pub fn move_first_nonwhitespace(cx: &mut Context) {
240// since these all really do the same thing
245// since these all really do the same thing
241
246
242pub fn move_next_word_start(cx: &mut Context) {
247pub fn move_next_word_start(cx: &mut Context) {
243− let count = cx.count;
248+ let count = cx.count();
244 let (view, doc) = cx.current();
249 let (view, doc) = cx.current();
245 let text = doc.text().slice(..);
250 let text = doc.text().slice(..);
246
251
@@ -252,7 +257,7 @@ pub fn move_next_word_start(cx: &mut Context) {
252}
257}
253
258
254pub fn move_prev_word_start(cx: &mut Context) {
259pub fn move_prev_word_start(cx: &mut Context) {
255− let count = cx.count;
260+ let count = cx.count();
256 let (view, doc) = cx.current();
261 let (view, doc) = cx.current();
257 let text = doc.text().slice(..);
262 let text = doc.text().slice(..);
258
263
@@ -264,7 +269,7 @@ pub fn move_prev_word_start(cx: &mut Context) {
264}
269}
265
270
266pub fn move_next_word_end(cx: &mut Context) {
271pub fn move_next_word_end(cx: &mut Context) {
267− let count = cx.count;
272+ let count = cx.count();
268 let (view, doc) = cx.current();
273 let (view, doc) = cx.current();
269 let text = doc.text().slice(..);
274 let text = doc.text().slice(..);
270
275
@@ -290,7 +295,7 @@ pub fn move_file_end(cx: &mut Context) {
290}
295}
291
296
292pub fn extend_next_word_start(cx: &mut Context) {
297pub fn extend_next_word_start(cx: &mut Context) {
293− let count = cx.count;
298+ let count = cx.count();
294 let (view, doc) = cx.current();
299 let (view, doc) = cx.current();
295 let text = doc.text().slice(..);
300 let text = doc.text().slice(..);
296
301
@@ -304,7 +309,7 @@ pub fn extend_next_word_start(cx: &mut Context) {
304}
309}
305
310
306pub fn extend_prev_word_start(cx: &mut Context) {
311pub fn extend_prev_word_start(cx: &mut Context) {
307− let count = cx.count;
312+ let count = cx.count();
308 let (view, doc) = cx.current();
313 let (view, doc) = cx.current();
309 let text = doc.text().slice(..);
314 let text = doc.text().slice(..);
310
315
@@ -317,7 +322,7 @@ pub fn extend_prev_word_start(cx: &mut Context) {
317}
322}
318
323
319pub fn extend_next_word_end(cx: &mut Context) {
324pub fn extend_next_word_end(cx: &mut Context) {
320− let count = cx.count;
325+ let count = cx.count();
321 let (view, doc) = cx.current();
326 let (view, doc) = cx.current();
322 let text = doc.text().slice(..);
327 let text = doc.text().slice(..);
323
328
@@ -339,7 +344,7 @@ where
339{
344{
340 // TODO: count is reset to 1 before next key so we move it into the closure here.
345 // TODO: count is reset to 1 before next key so we move it into the closure here.
341 // Would be nice to carry over.
346 // Would be nice to carry over.
342− let count = cx.count;
347+ let count = cx.count();
343
348
344 // need to wait for next key
349 // need to wait for next key
345 cx.on_next_key(move |cx, event| {
350 cx.on_next_key(move |cx, event| {
@@ -563,7 +568,7 @@ pub fn half_page_down(cx: &mut Context) {
563}
568}
564
569
565pub fn extend_char_left(cx: &mut Context) {
570pub fn extend_char_left(cx: &mut Context) {
566− let count = cx.count;
571+ let count = cx.count();
567 let (view, doc) = cx.current();
572 let (view, doc) = cx.current();
568 let text = doc.text().slice(..);
573 let text = doc.text().slice(..);
569 let selection = doc.selection(view.id).transform(|range| {
574 let selection = doc.selection(view.id).transform(|range| {
@@ -579,7 +584,7 @@ pub fn extend_char_left(cx: &mut Context) {
579}
584}
580
585
581pub fn extend_char_right(cx: &mut Context) {
586pub fn extend_char_right(cx: &mut Context) {
582− let count = cx.count;
587+ let count = cx.count();
583 let (view, doc) = cx.current();
588 let (view, doc) = cx.current();
584 let text = doc.text().slice(..);
589 let text = doc.text().slice(..);
585 let selection = doc.selection(view.id).transform(|range| {
590 let selection = doc.selection(view.id).transform(|range| {
@@ -595,7 +600,7 @@ pub fn extend_char_right(cx: &mut Context) {
595}
600}
596
601
597pub fn extend_line_up(cx: &mut Context) {
602pub fn extend_line_up(cx: &mut Context) {
598− let count = cx.count;
603+ let count = cx.count();
599 let (view, doc) = cx.current();
604 let (view, doc) = cx.current();
600 let text = doc.text().slice(..);
605 let text = doc.text().slice(..);
601 let selection = doc.selection(view.id).transform(|range| {
606 let selection = doc.selection(view.id).transform(|range| {
@@ -611,7 +616,7 @@ pub fn extend_line_up(cx: &mut Context) {
611}
616}
612
617
613pub fn extend_line_down(cx: &mut Context) {
618pub fn extend_line_down(cx: &mut Context) {
614− let count = cx.count;
619+ let count = cx.count();
615 let (view, doc) = cx.current();
620 let (view, doc) = cx.current();
616 let text = doc.text().slice(..);
621 let text = doc.text().slice(..);
617 let selection = doc.selection(view.id).transform(|range| {
622 let selection = doc.selection(view.id).transform(|range| {
@@ -795,7 +800,7 @@ pub fn search_selection(cx: &mut Context) {
795//
800//
796
801
797pub fn select_line(cx: &mut Context) {
802pub fn select_line(cx: &mut Context) {
798− let count = cx.count;
803+ let count = cx.count();
799 let (view, doc) = cx.current();
804 let (view, doc) = cx.current();
800
805
801 let pos = doc.selection(view.id).primary();
806 let pos = doc.selection(view.id).primary();
@@ -810,7 +815,7 @@ pub fn select_line(cx: &mut Context) {
810 doc.set_selection(view.id, Selection::single(start, end));
815 doc.set_selection(view.id, Selection::single(start, end));
811}
816}
812pub fn extend_line(cx: &mut Context) {
817pub fn extend_line(cx: &mut Context) {
813− let count = cx.count;
818+ let count = cx.count();
814 let (view, doc) = cx.current();
819 let (view, doc) = cx.current();
815
820
816 let pos = doc.selection(view.id).primary();
821 let pos = doc.selection(view.id).primary();
@@ -1212,7 +1217,7 @@ enum Open {
1212}
1217}
1213
1218
1214fn open(cx: &mut Context, open: Open) {
1219fn open(cx: &mut Context, open: Open) {
1215− let count = cx.count;
1220+ let count = cx.count();
1216 let (view, doc) = cx.current();
1221 let (view, doc) = cx.current();
1217 enter_insert_mode(doc);
1222 enter_insert_mode(doc);
1218
1223
@@ -1308,15 +1313,11 @@ fn push_jump(editor: &mut Editor) {
1308}
1313}
1309
1314
1310pub fn goto_mode(cx: &mut Context) {
1315pub fn goto_mode(cx: &mut Context) {
1311− let count = cx.count;
1316+ if let Some(count) = cx._count {
1312−
1313− if count > 1 {
1314 push_jump(cx.editor);
1317 push_jump(cx.editor);
1315
1318
1316− // TODO: can't go to line 1 since we can't distinguish between g and 1g, g gets converted
1317− // to 1g
1318 let (view, doc) = cx.current();
1319 let (view, doc) = cx.current();
1319− let line_idx = std::cmp::min(count - 1, doc.text().len_lines().saturating_sub(2));
1320+ let line_idx = std::cmp::min(count.get() - 1, doc.text().len_lines().saturating_sub(2));
1320 let pos = doc.text().line_to_char(line_idx);
1321 let pos = doc.text().line_to_char(line_idx);
1321 doc.set_selection(view.id, Selection::point(pos));
1322 doc.set_selection(view.id, Selection::point(pos));
1322 return;
1323 return;
@@ -1880,7 +1881,7 @@ pub mod insert {
1880
1881
1881 // TODO: handle indent-aware delete
1882 // TODO: handle indent-aware delete
1882 pub fn delete_char_backward(cx: &mut Context) {
1883 pub fn delete_char_backward(cx: &mut Context) {
1883− let count = cx.count;
1884+ let count = cx.count();
1884 let (view, doc) = cx.current();
1885 let (view, doc) = cx.current();
1885 let text = doc.text().slice(..);
1886 let text = doc.text().slice(..);
1886 let transaction =
1887 let transaction =
@@ -1895,7 +1896,7 @@ pub mod insert {
1895 }
1896 }
1896
1897
1897 pub fn delete_char_forward(cx: &mut Context) {
1898 pub fn delete_char_forward(cx: &mut Context) {
1898− let count = cx.count;
1899+ let count = cx.count();
1899 let (view, doc) = cx.current();
1900 let (view, doc) = cx.current();
1900 let text = doc.text().slice(..);
1901 let text = doc.text().slice(..);
1901 let transaction =
1902 let transaction =
@@ -1910,7 +1911,7 @@ pub mod insert {
1910 }
1911 }
1911
1912
1912 pub fn delete_word_backward(cx: &mut Context) {
1913 pub fn delete_word_backward(cx: &mut Context) {
1913− let count = cx.count;
1914+ let count = cx.count();
1914 let (view, doc) = cx.current();
1915 let (view, doc) = cx.current();
1915 let text = doc.text().slice(..);
1916 let text = doc.text().slice(..);
1916 let transaction =
1917 let transaction =
@@ -2071,7 +2072,7 @@ fn get_lines(doc: &Document, view_id: ViewId) -> Vec<usize> {
2071}
2072}
2072
2073
2073pub fn indent(cx: &mut Context) {
2074pub fn indent(cx: &mut Context) {
2074− let count = cx.count;
2075+ let count = cx.count();
2075 let (view, doc) = cx.current();
2076 let (view, doc) = cx.current();
2076 let lines = get_lines(doc, view.id);
2077 let lines = get_lines(doc, view.id);
2077
2078
@@ -2090,7 +2091,7 @@ pub fn indent(cx: &mut Context) {
2090}
2091}
2091
2092
2092pub fn unindent(cx: &mut Context) {
2093pub fn unindent(cx: &mut Context) {
2093− let count = cx.count;
2094+ let count = cx.count();
2094 let (view, doc) = cx.current();
2095 let (view, doc) = cx.current();
2095 let lines = get_lines(doc, view.id);
2096 let lines = get_lines(doc, view.id);
2096 let mut changes = Vec::with_capacity(lines.len());
2097 let mut changes = Vec::with_capacity(lines.len());
@@ -2428,7 +2429,7 @@ pub fn match_brackets(cx: &mut Context) {
2428//
2429//
2429
2430
2430pub fn jump_forward(cx: &mut Context) {
2431pub fn jump_forward(cx: &mut Context) {
2431− let count = cx.count;
2432+ let count = cx.count();
2432 let (view, doc) = cx.current();
2433 let (view, doc) = cx.current();
2433
2434
2434 if let Some((id, selection)) = view.jumps.forward(count) {
2435 if let Some((id, selection)) = view.jumps.forward(count) {
@@ -2442,7 +2443,7 @@ pub fn jump_forward(cx: &mut Context) {
2442}
2443}
2443
2444
2444pub fn jump_backward(cx: &mut Context) {
2445pub fn jump_backward(cx: &mut Context) {
2445− let count = cx.count;
2446+ let count = cx.count();
2446 let (view, doc) = cx.current();
2447 let (view, doc) = cx.current();
2447
2448
2448 if let Some((id, selection)) = view.jumps.backward(count) {
2449 if let Some((id, selection)) = view.jumps.backward(count) {
helix-term/src/ui/editor.rs+4−3
@@ -527,7 +527,8 @@ impl EditorView {
527 // count handling
527 // count handling
528 key!(i @ '0'..='9') => {
528 key!(i @ '0'..='9') => {
529 let i = i.to_digit(10).unwrap() as usize;
529 let i = i.to_digit(10).unwrap() as usize;
530+ cxt.editor.count =
530− cxt.editor.count = Some(cxt.editor.count.map_or(i, |c| c * 10 + i));
531+ std::num::NonZeroUsize::new(cxt.editor.count.map_or(i, |c| c.get() * 10 + i));
531 }
532 }
532 // special handling for repeat operator
533 // special handling for repeat operator
533 key!('.') => {
534 key!('.') => {
@@ -540,7 +541,7 @@ impl EditorView {
540 }
541 }
541 _ => {
542 _ => {
542 // set the count
543 // set the count
543− cxt.count = cxt.editor.count.take().unwrap_or(1);
544+ cxt._count = cxt.editor.count.take();
544 // TODO: edge case: 0j -> reset to 1
545 // TODO: edge case: 0j -> reset to 1
545 // if this fails, count was Some(0)
546 // if this fails, count was Some(0)
546 // debug_assert!(cxt.count != 0);
547 // debug_assert!(cxt.count != 0);
@@ -587,8 +588,8 @@ impl Component for EditorView {
587
588
588 let mut cxt = commands::Context {
589 let mut cxt = commands::Context {
589 register: helix_view::RegisterSelection::default(),
590 register: helix_view::RegisterSelection::default(),
590− count: 1,
591 editor: &mut cx.editor,
591 editor: &mut cx.editor,
592+ _count: None,
592 callback: None,
593 callback: None,
593 on_next_key_callback: None,
594 on_next_key_callback: None,
594 callbacks: cx.callbacks,
595 callbacks: cx.callbacks,
helix-view/src/editor.rs+1−1
@@ -12,7 +12,7 @@ pub use helix_core::diagnostic::Severity;
12pub struct Editor {
12pub struct Editor {
13 pub tree: Tree,
13 pub tree: Tree,
14 pub documents: SlotMap<DocumentId, Document>,
14 pub documents: SlotMap<DocumentId, Document>,
15− pub count: Option<usize>,
15+ pub count: Option<std::num::NonZeroUsize>,
16 pub register: RegisterSelection,
16 pub register: RegisterSelection,
17 pub theme: Theme,
17 pub theme: Theme,
18 pub language_servers: helix_lsp::Registry,
18 pub language_servers: helix_lsp::Registry,