on master help sign in
commands: Implement count for a few more commands.
commit01907b349771106865853dc2ea90aaa0913a7297 authorBlaž Hrastnik <blaz@mxxn.io> dateWed 24 Feb 2021, 17:29 (6 years ago) parent5fa1ba6
4 files changed+80−64
TODO.md+10−3 helix-core/src/state.rs+55−47 helix-term/src/commands.rs+14−13 helix-view/src/editor.rs+1−1
TODO.md+10−3
@@ -12,16 +12,16 @@
1212- [x] % for whole doc selection
1313- [x] vertical splits
1414- [x] input counts (30j)
15− - [ ] input counts for b, w, e
15+ - [x] input counts for b, w, e
1616- [ ] respect view fullscreen flag
1717- [x] retain horiz when moving vertically
18+- [w] retain horiz when moving via ctrl-u/d
1819- [x] deindent
1920- [ ] ensure_cursor_in_view always before rendering? or always in app after event process?
2021- [x] update lsp on redo/undo
2122- [ ] Implement marks (superset of Selection/Range)
2223- [ ] ctrl-v/ctrl-x on file picker
2324- [ ] linewise selection work
24−- [ ] goto definition
2525- [ ] nixos packaging
2626- [ ] CI binary builds
2727
@@ -33,6 +33,13 @@
3333- [ ] buffers should sit on editor.buffers, view simply refs them
3434
3535
36+- [ ] lsp: signature help
37+- [ ] lsp: hover
38+- [ ] lsp: document symbols (nested/vec)
39+- [ ] lsp: code actions
40+- [ ] lsp: formatting
41+- [ ] lsp: goto
42+
36432
3744- [ ] tab completion for paths on the prompt
3845- [ ] extend selection (treesitter select parent node) (replaces viw, vi(, va( etc )
@@ -41,7 +48,7 @@
4148- [ ] completion signature popups/docs
4249- [ ] multiple views into the same file
4350- [ ] selection align
44−- [ ] store some state: file positions, prompt history
51+- [ ] store some state between restarts: file positions, prompt history
4552
46533
4754- [ ] diagnostics popups
helix-core/src/state.rs+55−47
@@ -120,76 +120,84 @@ impl State {
120120 }
121121 }
122122
123− pub fn move_next_word_start(slice: RopeSlice, mut pos: usize) -> usize {
123+ pub fn move_next_word_start(slice: RopeSlice, mut pos: usize, count: usize) -> usize {
124124 // TODO: confirm it's fine without using graphemes, I think it should be
125− let ch = slice.char(pos);
126− let next = slice.char(pos.saturating_add(1));
127− if categorize(ch) != categorize(next) {
128− pos += 1;
129− }
125+ for _ in 0..count {
126+ let ch = slice.char(pos);
127+ let next = slice.char(pos.saturating_add(1));
128+ if categorize(ch) != categorize(next) {
129+ pos += 1;
130+ }
130131
131− // refetch
132− let ch = slice.char(pos);
132+ // refetch
133+ let ch = slice.char(pos);
133134
134− if is_word(ch) {
135− skip_over_next(slice, &mut pos, is_word);
136− } else if ch.is_ascii_punctuation() {
137− skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
138− }
135+ if is_word(ch) {
136+ skip_over_next(slice, &mut pos, is_word);
137+ } else if ch.is_ascii_punctuation() {
138+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
139+ }
139140
140− // TODO: don't include newline?
141− skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
141+ // TODO: don't include newline?
142+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
143+ }
142144
143145 pos
144146 }
145147
146− pub fn move_prev_word_start(slice: RopeSlice, mut pos: usize) -> usize {
148+ pub fn move_prev_word_start(slice: RopeSlice, mut pos: usize, count: usize) -> usize {
147149 // TODO: confirm it's fine without using graphemes, I think it should be
148− let ch = slice.char(pos);
149− let prev = slice.char(pos.saturating_sub(1)); // TODO: just return original pos if at start
150+ for _ in 0..count {
151+ let ch = slice.char(pos);
152+ let prev = slice.char(pos.saturating_sub(1)); // TODO: just return original pos if at start
150153
151− if categorize(ch) != categorize(prev) {
152− pos -= 1;
153− }
154+ if categorize(ch) != categorize(prev) {
155+ pos -= 1;
156+ }
154157
155− // TODO: skip while eol
158+ // TODO: skip while eol
156159
157− // TODO: don't include newline?
158− skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_whitespace());
160+ // TODO: don't include newline?
161+ skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_whitespace());
159162
160− // refetch
161− let ch = slice.char(pos);
163+ // refetch
164+ let ch = slice.char(pos);
162165
163− if is_word(ch) {
164− skip_over_prev(slice, &mut pos, is_word);
165− } else if ch.is_ascii_punctuation() {
166− skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_punctuation());
166+ if is_word(ch) {
167+ skip_over_prev(slice, &mut pos, is_word);
168+ } else if ch.is_ascii_punctuation() {
169+ skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_punctuation());
170+ }
171+ pos = pos.saturating_add(1)
167172 }
168173
169− pos.saturating_add(1)
174+ pos
170175 }
171176
172− pub fn move_next_word_end(slice: RopeSlice, mut pos: usize, _count: usize) -> usize {
173− // TODO: confirm it's fine without using graphemes, I think it should be
174− let ch = slice.char(pos);
175− let next = slice.char(pos.saturating_add(1));
176− if categorize(ch) != categorize(next) {
177− pos += 1;
178− }
177+ pub fn move_next_word_end(slice: RopeSlice, mut pos: usize, count: usize) -> usize {
178+ for _ in 0..count {
179+ // TODO: confirm it's fine without using graphemes, I think it should be
180+ let ch = slice.char(pos);
181+ let next = slice.char(pos.saturating_add(1));
182+ if categorize(ch) != categorize(next) {
183+ pos += 1;
184+ }
179185
180− // TODO: don't include newline?
181− skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
186+ // TODO: don't include newline?
187+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
182188
183− // refetch
184− let ch = slice.char(pos);
189+ // refetch
190+ let ch = slice.char(pos);
185191
186− if is_word(ch) {
187− skip_over_next(slice, &mut pos, is_word);
188− } else if ch.is_ascii_punctuation() {
189− skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
192+ if is_word(ch) {
193+ skip_over_next(slice, &mut pos, is_word);
194+ } else if ch.is_ascii_punctuation() {
195+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
196+ }
197+ pos = pos.saturating_sub(1)
190198 }
191199
192− pos.saturating_sub(1)
200+ pos
193201 }
194202
195203 pub fn move_selection(
helix-term/src/commands.rs+14−13
@@ -128,8 +128,7 @@ pub fn move_line_start(cx: &mut Context) {
128128pub fn move_next_word_start(cx: &mut Context) {
129129 let count = cx.count;
130130 let doc = cx.doc();
131− // TODO: count
132− let pos = State::move_next_word_start(doc.text().slice(..), doc.selection().cursor());
131+ let pos = State::move_next_word_start(doc.text().slice(..), doc.selection().cursor(), count);
133132
134133 doc.set_selection(Selection::point(pos));
135134}
@@ -137,7 +136,7 @@ pub fn move_next_word_start(cx: &mut Context) {
137136pub fn move_prev_word_start(cx: &mut Context) {
138137 let count = cx.count;
139138 let doc = cx.doc();
140− let pos = State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor());
139+ let pos = State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor(), count);
141140
142141 doc.set_selection(Selection::point(pos));
143142}
@@ -169,11 +168,12 @@ pub fn move_file_end(cx: &mut Context) {
169168pub fn extend_next_word_start(cx: &mut Context) {
170169 let count = cx.count;
171170 let doc = cx.doc();
172− let mut selection = doc.selection().transform(|mut range| {
173− let pos = State::move_next_word_start(doc.text().slice(..), doc.selection().cursor());
171+ let selection = doc.selection().transform(|mut range| {
172+ let pos =
173+ State::move_next_word_start(doc.text().slice(..), doc.selection().cursor(), count);
174174 range.head = pos;
175175 range
176− }); // TODO: count
176+ });
177177
178178 doc.set_selection(selection);
179179}
@@ -181,22 +181,23 @@ pub fn extend_next_word_start(cx: &mut Context) {
181181pub fn extend_prev_word_start(cx: &mut Context) {
182182 let count = cx.count;
183183 let doc = cx.doc();
184− let mut selection = doc.selection().transform(|mut range| {
185− let pos = State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor());
184+ let selection = doc.selection().transform(|mut range| {
185+ let pos =
186+ State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor(), count);
186187 range.head = pos;
187188 range
188− }); // TODO: count
189+ });
189190 doc.set_selection(selection);
190191}
191192
192193pub fn extend_next_word_end(cx: &mut Context) {
193194 let count = cx.count;
194195 let doc = cx.doc();
195− let mut selection = doc.selection().transform(|mut range| {
196+ let selection = doc.selection().transform(|mut range| {
196197 let pos = State::move_next_word_end(doc.text().slice(..), doc.selection().cursor(), count);
197198 range.head = pos;
198199 range
199− }); // TODO: count
200+ });
200201
201202 doc.set_selection(selection);
202203}
@@ -417,13 +418,13 @@ pub fn search_selection(cx: &mut Context) {
417418//
418419
419420pub fn select_line(cx: &mut Context) {
420− // TODO: count
421+ let count = cx.count;
421422 let doc = cx.doc();
422423 let pos = doc.selection().primary();
423424 let text = doc.text();
424425 let line = text.char_to_line(pos.head);
425426 let start = text.line_to_char(line);
426− let end = text.line_to_char(line + 1).saturating_sub(1);
427+ let end = text.line_to_char(line + count).saturating_sub(1);
427428
428429 doc.set_selection(Selection::single(start, end));
429430}
helix-view/src/editor.rs+1−1
@@ -12,7 +12,7 @@ pub struct Editor {
1212 pub tree: Tree,
1313 // pub documents: Vec<Document>,
1414 pub count: Option<usize>,
15− pub theme: Theme, // TODO: share one instance
15+ pub theme: Theme,
1616 pub language_servers: helix_lsp::Registry,
1717}
1818