on master help sign in
Merge branch 'master' into great_line_ending_and_cursor_range_cleanup
a873e71Nathan Vegdahl
Cargo.lock+12−12
@@ -238,15 +238,15 @@ dependencies = [
238
238
239[[package]]
239[[package]]
240name = "futures-core"
240name = "futures-core"
241−version = "0.3.15"
241+version = "0.3.16"
242source = "registry+https://github.com/rust-lang/crates.io-index"
242source = "registry+https://github.com/rust-lang/crates.io-index"
243−checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1"
243+checksum = "af51b1b4a7fdff033703db39de8802c673eb91855f2e0d47dcf3bf2c0ef01f99"
244
244
245[[package]]
245[[package]]
246name = "futures-executor"
246name = "futures-executor"
247−version = "0.3.15"
247+version = "0.3.16"
248source = "registry+https://github.com/rust-lang/crates.io-index"
248source = "registry+https://github.com/rust-lang/crates.io-index"
249−checksum = "badaa6a909fac9e7236d0620a2f57f7664640c56575b71a7552fbd68deafab79"
249+checksum = "4d0d535a57b87e1ae31437b892713aee90cd2d7b0ee48727cd11fc72ef54761c"
250dependencies = [
250dependencies = [
251 "futures-core",
251 "futures-core",
252 "futures-task",
252 "futures-task",
@@ -255,15 +255,15 @@ dependencies = [
255
255
256[[package]]
256[[package]]
257name = "futures-task"
257name = "futures-task"
258−version = "0.3.15"
258+version = "0.3.16"
259source = "registry+https://github.com/rust-lang/crates.io-index"
259source = "registry+https://github.com/rust-lang/crates.io-index"
260−checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae"
260+checksum = "bbe54a98670017f3be909561f6ad13e810d9a51f3f061b902062ca3da80799f2"
261
261
262[[package]]
262[[package]]
263name = "futures-util"
263name = "futures-util"
264−version = "0.3.15"
264+version = "0.3.16"
265source = "registry+https://github.com/rust-lang/crates.io-index"
265source = "registry+https://github.com/rust-lang/crates.io-index"
266−checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967"
266+checksum = "67eb846bfd58e44a8481a00049e82c43e0ccb5d61f8dc071057cb19249dd4d78"
267dependencies = [
267dependencies = [
268 "autocfg",
268 "autocfg",
269 "futures-core",
269 "futures-core",
@@ -475,9 +475,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
475
475
476[[package]]
476[[package]]
477name = "jsonrpc-core"
477name = "jsonrpc-core"
478−version = "17.1.0"
478+version = "18.0.0"
479source = "registry+https://github.com/rust-lang/crates.io-index"
479source = "registry+https://github.com/rust-lang/crates.io-index"
480−checksum = "d4467ab6dfa369b69e52bd0692e480c4d117410538526a57a304a0f2250fd95e"
480+checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb"
481dependencies = [
481dependencies = [
482 "futures-util",
482 "futures-util",
483 "log",
483 "log",
@@ -1009,9 +1009,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
1009
1009
1010[[package]]
1010[[package]]
1011name = "tokio"
1011name = "tokio"
1012−version = "1.8.2"
1012+version = "1.9.0"
1013source = "registry+https://github.com/rust-lang/crates.io-index"
1013source = "registry+https://github.com/rust-lang/crates.io-index"
1014−checksum = "c2602b8af3767c285202012822834005f596c811042315fa7e9f5b12b2a43207"
1014+checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c"
1015dependencies = [
1015dependencies = [
1016 "autocfg",
1016 "autocfg",
1017 "bytes",
1017 "bytes",
book/book.toml+1
@@ -4,6 +4,7 @@ language = "en"
4multilingual = false
4multilingual = false
5src = "src"
5src = "src"
6theme = "colibri"
6theme = "colibri"
7+edit-url-template = "https://github.com/helix-editor/helix/tree/master/book/{path}?mode=edit"
7
8
8[output.html]
9[output.html]
9cname = "docs.helix-editor.com"
10cname = "docs.helix-editor.com"
helix-lsp/Cargo.toml+2−2
@@ -17,11 +17,11 @@ helix-core = { version = "0.3", path = "../helix-core" }
17anyhow = "1.0"
17anyhow = "1.0"
18futures-executor = "0.3"
18futures-executor = "0.3"
19futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false }
19futures-util = { version = "0.3", features = ["std", "async-await"], default-features = false }
20−jsonrpc-core = { version = "17.1", default-features = false } # don't pull in all of futures
20+jsonrpc-core = { version = "18.0", default-features = false } # don't pull in all of futures
21log = "0.4"
21log = "0.4"
22lsp-types = { version = "0.89", features = ["proposed"] }
22lsp-types = { version = "0.89", features = ["proposed"] }
23serde = { version = "1.0", features = ["derive"] }
23serde = { version = "1.0", features = ["derive"] }
24serde_json = "1.0"
24serde_json = "1.0"
25thiserror = "1.0"
25thiserror = "1.0"
26−tokio = { version = "1.8", features = ["full"] }
26+tokio = { version = "1.9", features = ["full"] }
27tokio-stream = "0.1.7"
27tokio-stream = "0.1.7"
helix-term/src/commands.rs+20−4
@@ -228,13 +228,14 @@ impl Command {
228 goto_definition, "Goto definition",
228 goto_definition, "Goto definition",
229 goto_type_definition, "Goto type definition",
229 goto_type_definition, "Goto type definition",
230 goto_implementation, "Goto implementation",
230 goto_implementation, "Goto implementation",
231− goto_file_start, "Goto file start",
231+ goto_file_start, "Goto file start/line",
232 goto_file_end, "Goto file end",
232 goto_file_end, "Goto file end",
233 goto_reference, "Goto references",
233 goto_reference, "Goto references",
234 goto_window_top, "Goto window top",
234 goto_window_top, "Goto window top",
235 goto_window_middle, "Goto window middle",
235 goto_window_middle, "Goto window middle",
236 goto_window_bottom, "Goto window bottom",
236 goto_window_bottom, "Goto window bottom",
237 goto_last_accessed_file, "Goto last accessed file",
237 goto_last_accessed_file, "Goto last accessed file",
238+ goto_line, "Goto line",
238 goto_first_diag, "Goto first diagnostic",
239 goto_first_diag, "Goto first diagnostic",
239 goto_last_diag, "Goto last diagnostic",
240 goto_last_diag, "Goto last diagnostic",
240 goto_next_diag, "Goto next diagnostic",
241 goto_next_diag, "Goto next diagnostic",
@@ -553,9 +554,13 @@ fn move_next_long_word_end(cx: &mut Context) {
553}
554}
554
555
555fn goto_file_start(cx: &mut Context) {
556fn goto_file_start(cx: &mut Context) {
557+ if cx.count.is_some() {
558+ goto_line(cx);
559+ } else {
556− push_jump(cx.editor);
560+ push_jump(cx.editor);
557− let (view, doc) = current!(cx.editor);
561+ let (view, doc) = current!(cx.editor);
558− doc.set_selection(view.id, Selection::point(0));
562+ doc.set_selection(view.id, Selection::point(0));
563+ }
559}
564}
560
565
561fn goto_file_end(cx: &mut Context) {
566fn goto_file_end(cx: &mut Context) {
@@ -2442,6 +2447,17 @@ fn push_jump(editor: &mut Editor) {
2442 view.jumps.push(jump);
2447 view.jumps.push(jump);
2443}
2448}
2444
2449
2450+fn goto_line(cx: &mut Context) {
2451+ if let Some(count) = cx.count {
2452+ push_jump(cx.editor);
2453+
2454+ let (view, doc) = current!(cx.editor);
2455+ let line_idx = std::cmp::min(count.get() - 1, doc.text().len_lines().saturating_sub(2));
2456+ let pos = doc.text().line_to_char(line_idx);
2457+ doc.set_selection(view.id, Selection::point(pos));
2458+ }
2459+}
2460+
2445fn goto_last_accessed_file(cx: &mut Context) {
2461fn goto_last_accessed_file(cx: &mut Context) {
2446 let alternate_file = view!(cx.editor).last_accessed_doc;
2462 let alternate_file = view!(cx.editor).last_accessed_doc;
2447 if let Some(alt) = alternate_file {
2463 if let Some(alt) = alternate_file {
helix-term/src/keymap.rs+20
@@ -234,6 +234,7 @@ pub struct Keymap {
234 /// Always a Node
234 /// Always a Node
235 #[serde(flatten)]
235 #[serde(flatten)]
236 root: KeyTrie,
236 root: KeyTrie,
237+ /// Stores pending keys waiting for the next key
237 #[serde(skip)]
238 #[serde(skip)]
238 state: Vec<KeyEvent>,
239 state: Vec<KeyEvent>,
239}
240}
@@ -250,6 +251,11 @@ impl Keymap {
250 &self.root
251 &self.root
251 }
252 }
252
253
254+ /// Returns list of keys waiting to be disambiguated.
255+ pub fn pending(&self) -> &[KeyEvent] {
256+ &self.state
257+ }
258+
253 /// Lookup `key` in the keymap to try and find a command to execute
259 /// Lookup `key` in the keymap to try and find a command to execute
254 pub fn get(&mut self, key: KeyEvent) -> KeymapResult {
260 pub fn get(&mut self, key: KeyEvent) -> KeymapResult {
255 let &first = self.state.get(0).unwrap_or(&key);
261 let &first = self.state.get(0).unwrap_or(&key);
@@ -292,6 +298,19 @@ impl Default for Keymap {
292#[serde(transparent)]
298#[serde(transparent)]
293pub struct Keymaps(pub HashMap<Mode, Keymap>);
299pub struct Keymaps(pub HashMap<Mode, Keymap>);
294
300
301+impl Keymaps {
302+ /// Returns list of keys waiting to be disambiguated in current mode.
303+ pub fn pending(&self) -> &[KeyEvent] {
304+ self.0
305+ .values()
306+ .find_map(|keymap| match keymap.pending().is_empty() {
307+ true => None,
308+ false => Some(keymap.pending()),
309+ })
310+ .unwrap_or_default()
311+ }
312+}
313+
295impl Deref for Keymaps {
314impl Deref for Keymaps {
296 type Target = HashMap<Mode, Keymap>;
315 type Target = HashMap<Mode, Keymap>;
297
316
@@ -337,6 +356,7 @@ impl Default for Keymaps {
337 "E" => move_next_long_word_end,
356 "E" => move_next_long_word_end,
338
357
339 "v" => select_mode,
358 "v" => select_mode,
359+ "G" => goto_line,
340 "g" => { "Goto"
360 "g" => { "Goto"
341 "g" => goto_file_start,
361 "g" => goto_file_start,
342 "e" => goto_file_end,
362 "e" => goto_file_end,
helix-term/src/ui/editor.rs+32−1
@@ -10,6 +10,8 @@ use helix_core::{
10 coords_at_pos,
10 coords_at_pos,
11 graphemes::{ensure_grapheme_boundary_next, next_grapheme_boundary, prev_grapheme_boundary},
11 graphemes::{ensure_grapheme_boundary_next, next_grapheme_boundary, prev_grapheme_boundary},
12 syntax::{self, HighlightEvent},
12 syntax::{self, HighlightEvent},
13+ unicode::segmentation::UnicodeSegmentation,
14+ unicode::width::UnicodeWidthStr,
13 LineEnding, Position, Range,
15 LineEnding, Position, Range,
14};
16};
15use helix_view::{
17use helix_view::{
@@ -662,7 +664,7 @@ impl EditorView {
662 }
664 }
663 _ => {
665 _ => {
664 // set the count
666 // set the count
665− cxt.count = cxt.editor.count.take();
667+ cxt.count = cxt.editor.count;
666 // TODO: edge case: 0j -> reset to 1
668 // TODO: edge case: 0j -> reset to 1
667 // if this fails, count was Some(0)
669 // if this fails, count was Some(0)
668 // debug_assert!(cxt.count != 0);
670 // debug_assert!(cxt.count != 0);
@@ -671,6 +673,9 @@ impl EditorView {
671 cxt.selected_register = cxt.editor.selected_register.take();
673 cxt.selected_register = cxt.editor.selected_register.take();
672
674
673 self.handle_keymap_event(mode, cxt, event);
675 self.handle_keymap_event(mode, cxt, event);
676+ if self.keymaps.pending().is_empty() {
677+ cxt.editor.count = None
678+ }
674 }
679 }
675 }
680 }
676 }
681 }
@@ -830,8 +835,12 @@ impl Component for EditorView {
830 info.render(area, surface, cx);
835 info.render(area, surface, cx);
831 }
836 }
832
837
838+ let key_width = 15u16; // for showing pending keys
839+ let mut status_msg_width = 0;
840+
833 // render status msg
841 // render status msg
834 if let Some((status_msg, severity)) = &cx.editor.status_msg {
842 if let Some((status_msg, severity)) = &cx.editor.status_msg {
843+ status_msg_width = status_msg.width();
835 use helix_view::editor::Severity;
844 use helix_view::editor::Severity;
836 let style = if *severity == Severity::Error {
845 let style = if *severity == Severity::Error {
837 cx.editor.theme.get("error")
846 cx.editor.theme.get("error")
@@ -847,6 +856,28 @@ impl Component for EditorView {
847 );
856 );
848 }
857 }
849
858
859+ if area.width.saturating_sub(status_msg_width as u16) > key_width {
860+ let mut disp = String::new();
861+ if let Some(count) = cx.editor.count {
862+ disp.push_str(&count.to_string())
863+ }
864+ for key in self.keymaps.pending() {
865+ let s = key.to_string();
866+ if s.graphemes(true).count() > 1 {
867+ disp.push_str(&format!("<{}>", s));
868+ } else {
869+ disp.push_str(&s);
870+ }
871+ }
872+ surface.set_string(
873+ area.x + area.width.saturating_sub(key_width),
874+ area.y + area.height.saturating_sub(1),
875+ disp.get(disp.len().saturating_sub(key_width as usize)..)
876+ .unwrap_or(&disp),
877+ cx.editor.theme.get("ui.text"),
878+ );
879+ }
880+
850 if let Some(completion) = &self.completion {
881 if let Some(completion) = &self.completion {
851 completion.render(area, surface, cx);
882 completion.render(area, surface, cx);
852 }
883 }
helix-view/src/keyboard.rs+1−1
@@ -75,7 +75,7 @@ pub enum KeyCode {
75 End,
75 End,
76 /// Page up key.
76 /// Page up key.
77 PageUp,
77 PageUp,
78− /// Page dow key.
78+ /// Page down key.
79 PageDown,
79 PageDown,
80 /// Tab key.
80 /// Tab key.
81 Tab,
81 Tab,