on master help sign in
Extend selection commands.
3020077Blaž Hrastnik
Cargo.lock+24−22
@@ -52,9 +52,9 @@ checksum = "e1ba68f4276a778591e36a0c348a269888f3a177c8d2054969389e3b59611ff5"
52
52
53[[package]]
53[[package]]
54name = "async-barrier"
54name = "async-barrier"
55−version = "1.0.1"
55+version = "1.1.0"
56source = "registry+https://github.com/rust-lang/crates.io-index"
56source = "registry+https://github.com/rust-lang/crates.io-index"
57−checksum = "c06293698675eb72e1155867e5982f199d6b6c230dca35bc5ffd9852f470c22a"
57+checksum = "04b50fe84d0aea412a4e751cb01b9e26e2be533b2708607c2a2a739b192ee45a"
58dependencies = [
58dependencies = [
59 "async-mutex",
59 "async-mutex",
60 "event-listener",
60 "event-listener",
@@ -97,9 +97,9 @@ dependencies = [
97
97
98[[package]]
98[[package]]
99name = "async-io"
99name = "async-io"
100−version = "1.1.2"
100+version = "1.1.3"
101source = "registry+https://github.com/rust-lang/crates.io-index"
101source = "registry+https://github.com/rust-lang/crates.io-index"
102−checksum = "64c629684e697f58c0e99e5e2d84a840e3b336afbcfdbac7b44c3b1e222c2fd8"
102+checksum = "a9951f92a2b4f7793f8fc06a80bdb89b62c618c993497d4606474fb8c34941b5"
103dependencies = [
103dependencies = [
104 "concurrent-queue",
104 "concurrent-queue",
105 "fastrand",
105 "fastrand",
@@ -115,9 +115,9 @@ dependencies = [
115
115
116[[package]]
116[[package]]
117name = "async-lock"
117name = "async-lock"
118−version = "2.1.3"
118+version = "2.2.0"
119source = "registry+https://github.com/rust-lang/crates.io-index"
119source = "registry+https://github.com/rust-lang/crates.io-index"
120−checksum = "ab3ad7fb4345397e57c19566844b0eba274b92e5d2d2791bb0664cc441697b95"
120+checksum = "76000290eb3c67dfe4e2bdf6b6155847f8e16fc844377a7bd0b5e97622656362"
121dependencies = [
121dependencies = [
122 "async-barrier",
122 "async-barrier",
123 "async-mutex",
123 "async-mutex",
@@ -127,9 +127,9 @@ dependencies = [
127
127
128[[package]]
128[[package]]
129name = "async-mutex"
129name = "async-mutex"
130−version = "1.3.0"
130+version = "1.4.0"
131source = "registry+https://github.com/rust-lang/crates.io-index"
131source = "registry+https://github.com/rust-lang/crates.io-index"
132−checksum = "66941c2577c4fa351e4ce5fdde8f86c69b88d623f3b955be1bc7362a23434632"
132+checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e"
133dependencies = [
133dependencies = [
134 "event-listener",
134 "event-listener",
135]
135]
@@ -164,9 +164,9 @@ dependencies = [
164
164
165[[package]]
165[[package]]
166name = "async-rwlock"
166name = "async-rwlock"
167−version = "1.2.1"
167+version = "1.3.0"
168source = "registry+https://github.com/rust-lang/crates.io-index"
168source = "registry+https://github.com/rust-lang/crates.io-index"
169−checksum = "806b1cc0828c2b1611ccbdd743fc0cc7af09009e62c95a0501c1e5da7b142a22"
169+checksum = "261803dcc39ba9e72760ba6e16d0199b1eef9fc44e81bffabbebb9f5aea3906c"
170dependencies = [
170dependencies = [
171 "async-mutex",
171 "async-mutex",
172 "event-listener",
172 "event-listener",
@@ -174,18 +174,18 @@ dependencies = [
174
174
175[[package]]
175[[package]]
176name = "async-semaphore"
176name = "async-semaphore"
177−version = "1.1.0"
177+version = "1.2.0"
178source = "registry+https://github.com/rust-lang/crates.io-index"
178source = "registry+https://github.com/rust-lang/crates.io-index"
179−checksum = "66d2be5973230861689460806b8db059bbd8bcb507cabaa71646ae89f5b2f2ee"
179+checksum = "538c756e85eb6ffdefaec153804afb6da84b033e2e5ec3e9d459c34b4bf4d3f6"
180dependencies = [
180dependencies = [
181 "event-listener",
181 "event-listener",
182]
182]
183
183
184[[package]]
184[[package]]
185name = "async-task"
185name = "async-task"
186−version = "4.0.1"
186+version = "4.0.2"
187source = "registry+https://github.com/rust-lang/crates.io-index"
187source = "registry+https://github.com/rust-lang/crates.io-index"
188−checksum = "6725e96011a83fae25074a8734932e8d67763522839be7473dcfe8a0d6a378b1"
188+checksum = "8ab27c1aa62945039e44edaeee1dc23c74cc0c303dd5fe0fb462a184f1c3a518"
189
189
190[[package]]
190[[package]]
191name = "atomic-waker"
191name = "atomic-waker"
@@ -306,9 +306,9 @@ dependencies = [
306
306
307[[package]]
307[[package]]
308name = "event-listener"
308name = "event-listener"
309−version = "2.4.0"
309+version = "2.5.1"
310source = "registry+https://github.com/rust-lang/crates.io-index"
310source = "registry+https://github.com/rust-lang/crates.io-index"
311−checksum = "e1cd41440ae7e4734bbd42302f63eaba892afc93a3912dad84006247f0dedb0e"
311+checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
312
312
313[[package]]
313[[package]]
314name = "fastrand"
314name = "fastrand"
@@ -340,9 +340,9 @@ checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
340
340
341[[package]]
341[[package]]
342name = "futures-lite"
342name = "futures-lite"
343−version = "1.7.0"
343+version = "1.8.0"
344source = "registry+https://github.com/rust-lang/crates.io-index"
344source = "registry+https://github.com/rust-lang/crates.io-index"
345−checksum = "5b77e08e656f472d8ea84c472fa8b0a7a917883048e1cf2d4e34a323cd0aaf63"
345+checksum = "0db18c5f58083b54b0c416638ea73066722c2815c1e54dd8ba85ee3def593c3a"
346dependencies = [
346dependencies = [
347 "fastrand",
347 "fastrand",
348 "futures-core",
348 "futures-core",
@@ -387,6 +387,7 @@ dependencies = [
387 "anyhow",
387 "anyhow",
388 "helix-syntax",
388 "helix-syntax",
389 "once_cell",
389 "once_cell",
390+ "regex",
390 "ropey",
391 "ropey",
391 "smallvec",
392 "smallvec",
392 "tendril",
393 "tendril",
@@ -425,6 +426,7 @@ dependencies = [
425 "anyhow",
426 "anyhow",
426 "crossterm",
427 "crossterm",
427 "helix-core",
428 "helix-core",
429+ "once_cell",
428 "tui",
430 "tui",
429]
431]
430
432
@@ -774,9 +776,9 @@ dependencies = [
774
776
775[[package]]
777[[package]]
776name = "tree-sitter"
778name = "tree-sitter"
777−version = "0.16.1"
779+version = "0.17.0"
778source = "registry+https://github.com/rust-lang/crates.io-index"
780source = "registry+https://github.com/rust-lang/crates.io-index"
779−checksum = "1df33680edb07e4fb76edcbdd9c7b849b96709fb878afcf0ada678d6bda167af"
781+checksum = "70ee7370fec3aecde3862a7d64c571048f70a7298daef1815e8fc68b9de54b5c"
780dependencies = [
782dependencies = [
781 "cc",
783 "cc",
782 "regex",
784 "regex",
@@ -784,9 +786,9 @@ dependencies = [
784
786
785[[package]]
787[[package]]
786name = "tui"
788name = "tui"
787−version = "0.10.0"
789+version = "0.11.0"
788source = "registry+https://github.com/rust-lang/crates.io-index"
790source = "registry+https://github.com/rust-lang/crates.io-index"
789−checksum = "a977b0bb2e2033a6fef950f218f13622c3c34e59754b704ce3492dedab1dfe95"
791+checksum = "36626dee5ede9fd34015e9fb4fd7eedf3f3d05bdf1436aaef15b7d0a24233778"
790dependencies = [
792dependencies = [
791 "bitflags",
793 "bitflags",
792 "cassowary",
794 "cassowary",
helix-core/Cargo.toml+8−7
@@ -9,12 +9,13 @@ edition = "2018"
9[dependencies]
9[dependencies]
10helix-syntax = { path = "../helix-syntax" }
10helix-syntax = { path = "../helix-syntax" }
11
11
12−ropey = "1.2.0"
12+ropey = "1.2"
13−anyhow = "1.0.31"
13+anyhow = "1"
14−smallvec = "1.4.0"
14+smallvec = "1.4"
15tendril = { git = "https://github.com/servo/tendril" }
15tendril = { git = "https://github.com/servo/tendril" }
16−unicode-segmentation = "1.6.0"
16+unicode-segmentation = "1.6"
17−unicode-width = "0.1.7"
17+unicode-width = "0.1"
18# slab = "0.4.2"
18# slab = "0.4.2"
19−tree-sitter = "0.16.1"
19+tree-sitter = "0.17"
20−once_cell = "1.4.1"
20+once_cell = "1.4"
21+regex = "1"
helix-core/src/lib.rs+1
@@ -8,6 +8,7 @@ pub mod syntax;
8mod transaction;
8mod transaction;
9
9
10pub use ropey::{Rope, RopeSlice};
10pub use ropey::{Rope, RopeSlice};
11+
11pub use tendril::StrTendril as Tendril;
12pub use tendril::StrTendril as Tendril;
12
13
13pub use position::Position;
14pub use position::Position;
helix-core/src/selection.rs+29
@@ -60,6 +60,18 @@ impl Range {
60 }
60 }
61 }
61 }
62
62
63+ pub fn contains(&self, pos: usize) -> bool {
64+ if self.is_empty() {
65+ return false;
66+ }
67+
68+ if self.anchor < self.head {
69+ self.anchor <= pos && pos < self.head
70+ } else {
71+ self.head < pos && pos <= self.anchor
72+ }
73+ }
74+
63 /// Map a range through a set of changes. Returns a new range representing the same position
75 /// Map a range through a set of changes. Returns a new range representing the same position
64 /// after the changes are applied.
76 /// after the changes are applied.
65 pub fn map(self, changes: &ChangeSet) -> Self {
77 pub fn map(self, changes: &ChangeSet) -> Self {
@@ -283,4 +295,21 @@ mod test {
283
295
284 assert_eq!(res, "8/10,10/12");
296 assert_eq!(res, "8/10,10/12");
285 }
297 }
298+
299+ #[test]
300+ fn test_contains() {
301+ let range = Range::new(10, 12);
302+
303+ assert_eq!(range.contains(9), false);
304+ assert_eq!(range.contains(10), true);
305+ assert_eq!(range.contains(11), true);
306+ assert_eq!(range.contains(12), false);
307+ assert_eq!(range.contains(13), false);
308+
309+ let range = Range::new(9, 6);
310+ assert_eq!(range.contains(9), true);
311+ assert_eq!(range.contains(7), true);
312+ assert_eq!(range.contains(6), false);
313+ }
314+
286}
315}
helix-core/src/syntax.rs+3−3
@@ -48,7 +48,7 @@ impl LanguageConfiguration {
48 if highlights_query.is_empty() {
48 if highlights_query.is_empty() {
49 Ok(None)
49 Ok(None)
50 } else {
50 } else {
51− let language = get_language(&self.language_id);
51+ let language = get_language(self.language_id);
52 let mut config = HighlightConfiguration::new(
52 let mut config = HighlightConfiguration::new(
53 language,
53 language,
54 &highlights_query,
54 &highlights_query,
@@ -1456,7 +1456,7 @@ fn test_parser() {
1456 .map(String::from)
1456 .map(String::from)
1457 .collect();
1457 .collect();
1458
1458
1459− let language = get_language(&LANG::Rust);
1459+ let language = get_language(LANG::Rust);
1460 let mut config = HighlightConfiguration::new(
1460 let mut config = HighlightConfiguration::new(
1461 language,
1461 language,
1462 &std::fs::read_to_string(
1462 &std::fs::read_to_string(
@@ -1478,7 +1478,7 @@ fn test_parser() {
1478 fn main() {}
1478 fn main() {}
1479 ",
1479 ",
1480 );
1480 );
1481− let syntax = Syntax::new(LANG::Rust, &source, config);
1481+ let syntax = Syntax::new(&source, Arc::new(config));
1482 let tree = syntax.root_layer.tree.unwrap();
1482 let tree = syntax.root_layer.tree.unwrap();
1483 let root = tree.root_node();
1483 let root = tree.root_node();
1484 assert_eq!(root.kind(), "source_file");
1484 assert_eq!(root.kind(), "source_file");
helix-core/src/transaction.rs+3−2
@@ -1,4 +1,5 @@
1use crate::{Range, Rope, Selection, State, Tendril};
1use crate::{Range, Rope, Selection, State, Tendril};
2+use std::convert::TryFrom;
2
3
3/// (from, to, replacement)
4/// (from, to, replacement)
4pub type Change = (usize, usize, Option<Tendril>);
5pub type Change = (usize, usize, Option<Tendril>);
@@ -112,7 +113,7 @@ impl ChangeSet {
112 let (pos, _) = s.char_indices().nth(len - j).unwrap();
113 let (pos, _) = s.char_indices().nth(len - j).unwrap();
113 // calculate the difference
114 // calculate the difference
114 let to_drop = s.len() - pos;
115 let to_drop = s.len() - pos;
115− s.pop_back(to_drop as u32);
116+ s.pop_back(u32::try_from(to_drop).unwrap());
116 head_a = Some(Insert(s));
117 head_a = Some(Insert(s));
117 head_b = changes_b.next();
118 head_b = changes_b.next();
118 }
119 }
@@ -136,7 +137,7 @@ impl ChangeSet {
136 let (pos, _) = s.char_indices().nth(j).unwrap();
137 let (pos, _) = s.char_indices().nth(j).unwrap();
137 // calculate the difference
138 // calculate the difference
138 let to_drop = s.len() - pos;
139 let to_drop = s.len() - pos;
139− s.pop_back(to_drop as u32);
140+ s.pop_back(u32::try_from(to_drop).unwrap());
140 head_a = Some(Insert(s));
141 head_a = Some(Insert(s));
141 head_b = changes_b.next();
142 head_b = changes_b.next();
142 }
143 }
helix-syntax/Cargo.toml+1−1
@@ -7,7 +7,7 @@ edition = "2018"
7# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8
8
9[dependencies]
9[dependencies]
10−tree-sitter = "0.16"
10+tree-sitter = "0.17"
11enum-iterator = "0.6"
11enum-iterator = "0.6"
12
12
13[build-dependencies]
13[build-dependencies]
helix-syntax/src/lib.rs+5−3
@@ -13,7 +13,7 @@ macro_rules! mk_extern {
13#[macro_export]
13#[macro_export]
14macro_rules! mk_enum {
14macro_rules! mk_enum {
15 ( $( $camel:ident ),* ) => {
15 ( $( $camel:ident ),* ) => {
16− #[derive(Clone, Debug, IntoEnumIterator, PartialEq)]
16+ #[derive(Clone, Copy, Debug, IntoEnumIterator, PartialEq)]
17 pub enum LANG {
17 pub enum LANG {
18 $(
18 $(
19 $camel,
19 $camel,
@@ -25,7 +25,8 @@ macro_rules! mk_enum {
25#[macro_export]
25#[macro_export]
26macro_rules! mk_get_language {
26macro_rules! mk_get_language {
27 ( $( ($camel:ident, $name:ident) ),* ) => {
27 ( $( ($camel:ident, $name:ident) ),* ) => {
28+ #[must_use]
28− pub fn get_language(lang: &LANG) -> Language {
29+ pub fn get_language(lang: LANG) -> Language {
29 unsafe {
30 unsafe {
30 match lang {
31 match lang {
31 $(
32 $(
@@ -40,7 +41,8 @@ macro_rules! mk_get_language {
40#[macro_export]
41#[macro_export]
41macro_rules! mk_get_language_name {
42macro_rules! mk_get_language_name {
42 ( $( $camel:ident ),* ) => {
43 ( $( $camel:ident ),* ) => {
44+ #[must_use]
43− pub fn get_language_name(lang: &LANG) -> &'static str {
45+ pub const fn get_language_name(lang: LANG) -> &'static str {
44 match lang {
46 match lang {
45 $(
47 $(
46 LANG::$camel => stringify!($camel),
48 LANG::$camel => stringify!($camel),
helix-term/Cargo.toml+3−3
@@ -15,9 +15,9 @@ helix-core = { path = "../helix-core" }
15helix-view = { path = "../helix-view", features = ["term"]}
15helix-view = { path = "../helix-view", features = ["term"]}
16
16
17anyhow = "1"
17anyhow = "1"
18−argh = "0.1.3"
18+argh = "0.1"
19
19
20smol = "1"
20smol = "1"
21−num_cpus = "1.13.0"
21+num_cpus = "1.13"
22−tui = { version = "0.10.0", default-features = false, features = ["crossterm"] }
22+tui = { version = "0.11", default-features = false, features = ["crossterm"] }
23crossterm = { version = "0.17", features = ["event-stream"] }
23crossterm = { version = "0.17", features = ["event-stream"] }
helix-term/src/editor.rs+30−2
@@ -1,8 +1,9 @@
1use crate::Args;
1use crate::Args;
2−use helix_core::{state::coords_at_pos, state::Mode, syntax::HighlightEvent, State};
2+use helix_core::{state::coords_at_pos, state::Mode, syntax::HighlightEvent, Range, State};
3use helix_view::{commands, keymap, View};
3use helix_view::{commands, keymap, View};
4
4
5use std::{
5use std::{
6+ borrow::Cow,
6 io::{self, stdout, Write},
7 io::{self, stdout, Write},
7 path::PathBuf,
8 path::PathBuf,
8 time::Duration,
9 time::Duration,
@@ -120,6 +121,16 @@ impl Editor {
120 let mut visual_x = 0;
121 let mut visual_x = 0;
121 let mut line = 0u16;
122 let mut line = 0u16;
122
123
124+ let visible_selections: Vec<Range> = view
125+ .state
126+ .selection()
127+ .ranges()
128+ .iter()
129+ // TODO: limit selection to one in viewport
130+ .filter(|range| !range.is_empty()) // && range.overlaps(&Range::new(start, end + 1))
131+ .copied()
132+ .collect();
133+
123 'outer: for event in highlights {
134 'outer: for event in highlights {
124 match event.unwrap() {
135 match event.unwrap() {
125 HighlightEvent::HighlightStart(span) => {
136 HighlightEvent::HighlightStart(span) => {
@@ -149,6 +160,8 @@ impl Editor {
149 // way if only the selection/cursor changes we can copy from cache
160 // way if only the selection/cursor changes we can copy from cache
150 // and paint the new cursor.
161 // and paint the new cursor.
151
162
163+ let mut char_index = start;
164+
152 // iterate over range char by char
165 // iterate over range char by char
153 for grapheme in RopeGraphemes::new(&text) {
166 for grapheme in RopeGraphemes::new(&text) {
154 // TODO: track current char_index
167 // TODO: track current char_index
@@ -164,8 +177,21 @@ impl Editor {
164 } else {
177 } else {
165 // Cow will prevent allocations if span contained in a single slice
178 // Cow will prevent allocations if span contained in a single slice
166 // which should really be the majority case
179 // which should really be the majority case
167− let grapheme = std::borrow::Cow::from(grapheme);
180+ let grapheme = Cow::from(grapheme);
168 let width = grapheme_width(&grapheme) as u16;
181 let width = grapheme_width(&grapheme) as u16;
182+
183+ let style = if visible_selections
184+ .iter()
185+ .any(|range| range.contains(char_index))
186+ {
187+ // cedar
188+ style.clone().bg(Color::Rgb(128, 47, 0))
189+ } else {
190+ style
191+ };
192+
193+ // TODO: paint cursor heads except primary
194+
169 self.surface.set_string(
195 self.surface.set_string(
170 offset + visual_x,
196 offset + visual_x,
171 line,
197 line,
@@ -176,6 +202,8 @@ impl Editor {
176 visual_x += width;
202 visual_x += width;
177 }
203 }
178 // if grapheme == "\t"
204 // if grapheme == "\t"
205+
206+ char_index += 1;
179 }
207 }
180 }
208 }
181 }
209 }
helix-view/Cargo.toml+3−2
@@ -10,9 +10,10 @@ edition = "2018"
10term = ["tui", "crossterm"]
10term = ["tui", "crossterm"]
11
11
12[dependencies]
12[dependencies]
13−anyhow = "1.0.32"
13+anyhow = "1"
14helix-core = { path = "../helix-core" }
14helix-core = { path = "../helix-core" }
15
15
16# Conversion traits
16# Conversion traits
17−tui = { version = "0.10.0", default-features = false, features = ["crossterm"], optional = true}
17+tui = { version = "0.11", default-features = false, features = ["crossterm"], optional = true}
18crossterm = { version = "0.17", features = ["event-stream"], optional = true}
18crossterm = { version = "0.17", features = ["event-stream"], optional = true}
19+once_cell = "1.4"
helix-view/src/commands.rs+40
@@ -115,6 +115,46 @@ pub fn move_next_word_end(view: &mut View, count: usize) {
115
115
116// avoid select by default by having a visual mode switch that makes movements into selects
116// avoid select by default by having a visual mode switch that makes movements into selects
117
117
118+pub fn extend_char_left(view: &mut View, count: usize) {
119+ // TODO: use a transaction
120+ let selection = view
121+ .state
122+ .extend_selection(Direction::Backward, Granularity::Character, count);
123+ view.state.selection = selection;
124+}
125+
126+pub fn extend_char_right(view: &mut View, count: usize) {
127+ // TODO: use a transaction
128+ view.state.selection =
129+ view.state
130+ .extend_selection(Direction::Forward, Granularity::Character, count);
131+}
132+
133+pub fn extend_line_up(view: &mut View, count: usize) {
134+ // TODO: use a transaction
135+ view.state.selection =
136+ view.state
137+ .extend_selection(Direction::Backward, Granularity::Line, count);
138+}
139+
140+pub fn extend_line_down(view: &mut View, count: usize) {
141+ // TODO: use a transaction
142+ view.state.selection =
143+ view.state
144+ .extend_selection(Direction::Forward, Granularity::Line, count);
145+}
146+
147+pub fn delete_selection(view: &mut View, _count: usize) {
148+ let transaction =
149+ Transaction::change_by_selection(&view.state, |range| (range.from(), range.to(), None));
150+ transaction.apply(&mut view.state);
151+}
152+
153+pub fn change_selection(view: &mut View, count: usize) {
154+ delete_selection(view, count);
155+ insert_mode(view, count);
156+}
157+
118// insert mode:
158// insert mode:
119// first we calculate the correct cursors/selections
159// first we calculate the correct cursors/selections
120// then we just append at each cursor
160// then we just append at each cursor
helix-view/src/keymap.rs+32
@@ -7,7 +7,9 @@ use std::collections::HashMap;
7// normal = {
7// normal = {
8// q = record_macro
8// q = record_macro
9// w = (next) word
9// w = (next) word
10+// W = next WORD
10// e = end of word
11// e = end of word
12+// E = end of WORD
11// r =
13// r =
12// t = 'till char
14// t = 'till char
13// y = yank
15// y = yank
@@ -55,6 +57,12 @@ use std::collections::HashMap;
55// & = align cursor
57// & = align cursor
56// ? = extend to next given regex match (alt = to prev)
58// ? = extend to next given regex match (alt = to prev)
57//
59//
60+// in kakoune these are alt-h alt-l / gh gl
61+// select from curs to begin end / move curs to begin end
62+// 0 = start of line
63+// ^ = start of line (first non blank char)
64+// $ = end of line
65+//
58// z = save selections
66// z = save selections
59// Z = restore selections
67// Z = restore selections
60// x = select line
68// x = select line
@@ -110,6 +118,22 @@ pub fn default() -> Keymaps {
110 code: KeyCode::Char('l'),
118 code: KeyCode::Char('l'),
111 modifiers: Modifiers::NONE
119 modifiers: Modifiers::NONE
112 }] => commands::move_char_right as Command,
120 }] => commands::move_char_right as Command,
121+ vec![Key {
122+ code: KeyCode::Char('H'),
123+ modifiers: Modifiers::SHIFT
124+ }] => commands::extend_char_left as Command,
125+ vec![Key {
126+ code: KeyCode::Char('J'),
127+ modifiers: Modifiers::SHIFT
128+ }] => commands::extend_line_down as Command,
129+ vec![Key {
130+ code: KeyCode::Char('K'),
131+ modifiers: Modifiers::SHIFT
132+ }] => commands::extend_line_up as Command,
133+ vec![Key {
134+ code: KeyCode::Char('L'),
135+ modifiers: Modifiers::SHIFT
136+ }] => commands::extend_char_right as Command,
113 vec![Key {
137 vec![Key {
114 code: KeyCode::Char('w'),
138 code: KeyCode::Char('w'),
115 modifiers: Modifiers::NONE
139 modifiers: Modifiers::NONE
@@ -142,6 +166,14 @@ pub fn default() -> Keymaps {
142 code: KeyCode::Char('o'),
166 code: KeyCode::Char('o'),
143 modifiers: Modifiers::NONE
167 modifiers: Modifiers::NONE
144 }] => commands::open_below as Command,
168 }] => commands::open_below as Command,
169+ vec![Key {
170+ code: KeyCode::Char('d'),
171+ modifiers: Modifiers::NONE
172+ }] => commands::delete_selection as Command,
173+ vec![Key {
174+ code: KeyCode::Char('c'),
175+ modifiers: Modifiers::NONE
176+ }] => commands::change_selection as Command,
145 vec![Key {
177 vec![Key {
146 code: KeyCode::Esc,
178 code: KeyCode::Esc,
147 modifiers: Modifiers::NONE
179 modifiers: Modifiers::NONE