aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO.md13
-rw-r--r--helix-core/src/state.rs102
-rw-r--r--helix-term/src/commands.rs27
-rw-r--r--helix-view/src/editor.rs2
4 files changed, 80 insertions, 64 deletions
diff --git a/TODO.md b/TODO.md
index e378d457..9f20ebb2 100644
--- a/TODO.md
+++ b/TODO.md
@@ -12,16 +12,16 @@
- [x] % for whole doc selection
- [x] vertical splits
- [x] input counts (30j)
- - [ ] input counts for b, w, e
+ - [x] input counts for b, w, e
- [ ] respect view fullscreen flag
- [x] retain horiz when moving vertically
+- [w] retain horiz when moving via ctrl-u/d
- [x] deindent
- [ ] ensure_cursor_in_view always before rendering? or always in app after event process?
- [x] update lsp on redo/undo
- [ ] Implement marks (superset of Selection/Range)
- [ ] ctrl-v/ctrl-x on file picker
- [ ] linewise selection work
-- [ ] goto definition
- [ ] nixos packaging
- [ ] CI binary builds
@@ -33,6 +33,13 @@
- [ ] buffers should sit on editor.buffers, view simply refs them
+- [ ] lsp: signature help
+- [ ] lsp: hover
+- [ ] lsp: document symbols (nested/vec)
+- [ ] lsp: code actions
+- [ ] lsp: formatting
+- [ ] lsp: goto
+
2
- [ ] tab completion for paths on the prompt
- [ ] extend selection (treesitter select parent node) (replaces viw, vi(, va( etc )
@@ -41,7 +48,7 @@
- [ ] completion signature popups/docs
- [ ] multiple views into the same file
- [ ] selection align
-- [ ] store some state: file positions, prompt history
+- [ ] store some state between restarts: file positions, prompt history
3
- [ ] diagnostics popups
diff --git a/helix-core/src/state.rs b/helix-core/src/state.rs
index 78c9deb0..90e75eb4 100644
--- a/helix-core/src/state.rs
+++ b/helix-core/src/state.rs
@@ -120,76 +120,84 @@ impl State {
}
}
- pub fn move_next_word_start(slice: RopeSlice, mut pos: usize) -> usize {
+ pub fn move_next_word_start(slice: RopeSlice, mut pos: usize, count: usize) -> usize {
// TODO: confirm it's fine without using graphemes, I think it should be
- let ch = slice.char(pos);
- let next = slice.char(pos.saturating_add(1));
- if categorize(ch) != categorize(next) {
- pos += 1;
- }
+ for _ in 0..count {
+ let ch = slice.char(pos);
+ let next = slice.char(pos.saturating_add(1));
+ if categorize(ch) != categorize(next) {
+ pos += 1;
+ }
- // refetch
- let ch = slice.char(pos);
+ // refetch
+ let ch = slice.char(pos);
- if is_word(ch) {
- skip_over_next(slice, &mut pos, is_word);
- } else if ch.is_ascii_punctuation() {
- skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
- }
+ if is_word(ch) {
+ skip_over_next(slice, &mut pos, is_word);
+ } else if ch.is_ascii_punctuation() {
+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
+ }
- // TODO: don't include newline?
- skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
+ // TODO: don't include newline?
+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
+ }
pos
}
- pub fn move_prev_word_start(slice: RopeSlice, mut pos: usize) -> usize {
+ pub fn move_prev_word_start(slice: RopeSlice, mut pos: usize, count: usize) -> usize {
// TODO: confirm it's fine without using graphemes, I think it should be
- let ch = slice.char(pos);
- let prev = slice.char(pos.saturating_sub(1)); // TODO: just return original pos if at start
+ for _ in 0..count {
+ let ch = slice.char(pos);
+ let prev = slice.char(pos.saturating_sub(1)); // TODO: just return original pos if at start
- if categorize(ch) != categorize(prev) {
- pos -= 1;
- }
+ if categorize(ch) != categorize(prev) {
+ pos -= 1;
+ }
- // TODO: skip while eol
+ // TODO: skip while eol
- // TODO: don't include newline?
- skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_whitespace());
+ // TODO: don't include newline?
+ skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_whitespace());
- // refetch
- let ch = slice.char(pos);
+ // refetch
+ let ch = slice.char(pos);
- if is_word(ch) {
- skip_over_prev(slice, &mut pos, is_word);
- } else if ch.is_ascii_punctuation() {
- skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_punctuation());
+ if is_word(ch) {
+ skip_over_prev(slice, &mut pos, is_word);
+ } else if ch.is_ascii_punctuation() {
+ skip_over_prev(slice, &mut pos, |ch| ch.is_ascii_punctuation());
+ }
+ pos = pos.saturating_add(1)
}
- pos.saturating_add(1)
+ pos
}
- pub fn move_next_word_end(slice: RopeSlice, mut pos: usize, _count: usize) -> usize {
- // TODO: confirm it's fine without using graphemes, I think it should be
- let ch = slice.char(pos);
- let next = slice.char(pos.saturating_add(1));
- if categorize(ch) != categorize(next) {
- pos += 1;
- }
+ pub fn move_next_word_end(slice: RopeSlice, mut pos: usize, count: usize) -> usize {
+ for _ in 0..count {
+ // TODO: confirm it's fine without using graphemes, I think it should be
+ let ch = slice.char(pos);
+ let next = slice.char(pos.saturating_add(1));
+ if categorize(ch) != categorize(next) {
+ pos += 1;
+ }
- // TODO: don't include newline?
- skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
+ // TODO: don't include newline?
+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_whitespace());
- // refetch
- let ch = slice.char(pos);
+ // refetch
+ let ch = slice.char(pos);
- if is_word(ch) {
- skip_over_next(slice, &mut pos, is_word);
- } else if ch.is_ascii_punctuation() {
- skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
+ if is_word(ch) {
+ skip_over_next(slice, &mut pos, is_word);
+ } else if ch.is_ascii_punctuation() {
+ skip_over_next(slice, &mut pos, |ch| ch.is_ascii_punctuation());
+ }
+ pos = pos.saturating_sub(1)
}
- pos.saturating_sub(1)
+ pos
}
pub fn move_selection(
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 2b8fe405..7d7ad0c9 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -128,8 +128,7 @@ pub fn move_line_start(cx: &mut Context) {
pub fn move_next_word_start(cx: &mut Context) {
let count = cx.count;
let doc = cx.doc();
- // TODO: count
- let pos = State::move_next_word_start(doc.text().slice(..), doc.selection().cursor());
+ let pos = State::move_next_word_start(doc.text().slice(..), doc.selection().cursor(), count);
doc.set_selection(Selection::point(pos));
}
@@ -137,7 +136,7 @@ pub fn move_next_word_start(cx: &mut Context) {
pub fn move_prev_word_start(cx: &mut Context) {
let count = cx.count;
let doc = cx.doc();
- let pos = State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor());
+ let pos = State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor(), count);
doc.set_selection(Selection::point(pos));
}
@@ -169,11 +168,12 @@ pub fn move_file_end(cx: &mut Context) {
pub fn extend_next_word_start(cx: &mut Context) {
let count = cx.count;
let doc = cx.doc();
- let mut selection = doc.selection().transform(|mut range| {
- let pos = State::move_next_word_start(doc.text().slice(..), doc.selection().cursor());
+ let selection = doc.selection().transform(|mut range| {
+ let pos =
+ State::move_next_word_start(doc.text().slice(..), doc.selection().cursor(), count);
range.head = pos;
range
- }); // TODO: count
+ });
doc.set_selection(selection);
}
@@ -181,22 +181,23 @@ pub fn extend_next_word_start(cx: &mut Context) {
pub fn extend_prev_word_start(cx: &mut Context) {
let count = cx.count;
let doc = cx.doc();
- let mut selection = doc.selection().transform(|mut range| {
- let pos = State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor());
+ let selection = doc.selection().transform(|mut range| {
+ let pos =
+ State::move_prev_word_start(doc.text().slice(..), doc.selection().cursor(), count);
range.head = pos;
range
- }); // TODO: count
+ });
doc.set_selection(selection);
}
pub fn extend_next_word_end(cx: &mut Context) {
let count = cx.count;
let doc = cx.doc();
- let mut selection = doc.selection().transform(|mut range| {
+ let selection = doc.selection().transform(|mut range| {
let pos = State::move_next_word_end(doc.text().slice(..), doc.selection().cursor(), count);
range.head = pos;
range
- }); // TODO: count
+ });
doc.set_selection(selection);
}
@@ -417,13 +418,13 @@ pub fn search_selection(cx: &mut Context) {
//
pub fn select_line(cx: &mut Context) {
- // TODO: count
+ let count = cx.count;
let doc = cx.doc();
let pos = doc.selection().primary();
let text = doc.text();
let line = text.char_to_line(pos.head);
let start = text.line_to_char(line);
- let end = text.line_to_char(line + 1).saturating_sub(1);
+ let end = text.line_to_char(line + count).saturating_sub(1);
doc.set_selection(Selection::single(start, end));
}
diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs
index b70a6abd..1c737b3e 100644
--- a/helix-view/src/editor.rs
+++ b/helix-view/src/editor.rs
@@ -12,7 +12,7 @@ pub struct Editor {
pub tree: Tree,
// pub documents: Vec<Document>,
pub count: Option<usize>,
- pub theme: Theme, // TODO: share one instance
+ pub theme: Theme,
pub language_servers: helix_lsp::Registry,
}