on master help sign in
Add ctrl-w in insert mode
40744ceIvan Tham
helix-core/src/lib.rs+1
@@ -16,6 +16,7 @@ pub mod selection;
16mod state;
16mod state;
17pub mod syntax;
17pub mod syntax;
18mod transaction;
18mod transaction;
19+pub mod words;
19
20
20pub(crate) fn find_first_non_whitespace_char2(line: RopeSlice) -> Option<usize> {
21pub(crate) fn find_first_non_whitespace_char2(line: RopeSlice) -> Option<usize> {
21 // find first non-whitespace char
22 // find first non-whitespace char
helix-core/src/movement.rs+4−4
@@ -174,22 +174,22 @@ pub fn move_next_word_end(slice: RopeSlice, mut begin: usize, count: usize) -> O
174
174
175// used for by-word movement
175// used for by-word movement
176
176
177−fn is_word(ch: char) -> bool {
177+pub(crate) fn is_word(ch: char) -> bool {
178 ch.is_alphanumeric() || ch == '_'
178 ch.is_alphanumeric() || ch == '_'
179}
179}
180
180
181−fn is_horiz_blank(ch: char) -> bool {
181+pub(crate) fn is_horiz_blank(ch: char) -> bool {
182 matches!(ch, ' ' | '\t')
182 matches!(ch, ' ' | '\t')
183}
183}
184
184
185#[derive(Debug, Eq, PartialEq)]
185#[derive(Debug, Eq, PartialEq)]
186−enum Category {
186+pub(crate) enum Category {
187 Whitespace,
187 Whitespace,
188 Eol,
188 Eol,
189 Word,
189 Word,
190 Punctuation,
190 Punctuation,
191}
191}
192−fn categorize(ch: char) -> Category {
192+pub(crate) fn categorize(ch: char) -> Category {
193 if ch == '\n' {
193 if ch == '\n' {
194 Category::Eol
194 Category::Eol
195 } else if ch.is_ascii_whitespace() {
195 } else if ch.is_ascii_whitespace() {
helix-core/src/words.rsnew file+33
@@ -0,0 +1,33 @@
1+use crate::movement::{categorize, is_horiz_blank, is_word, skip_over_prev};
2+use ropey::RopeSlice;
3+
4+#[must_use]
5+pub fn nth_prev_word_boundary(slice: RopeSlice, mut char_idx: usize, count: usize) -> usize {
6+ let mut with_end = false;
7+
8+ for _ in 0..count {
9+ if char_idx == 0 {
10+ break;
11+ }
12+
13+ // return if not skip while?
14+ skip_over_prev(slice, &mut char_idx, |ch| ch == '\n');
15+
16+ with_end = skip_over_prev(slice, &mut char_idx, is_horiz_blank);
17+
18+ // refetch
19+ let ch = slice.char(char_idx);
20+
21+ if is_word(ch) {
22+ with_end = skip_over_prev(slice, &mut char_idx, is_word);
23+ } else if ch.is_ascii_punctuation() {
24+ with_end = skip_over_prev(slice, &mut char_idx, |ch| ch.is_ascii_punctuation());
25+ }
26+ }
27+
28+ if with_end {
29+ char_idx
30+ } else {
31+ char_idx + 1
32+ }
33+}
helix-term/src/commands.rs+17−3
@@ -3,8 +3,8 @@ use helix_core::{
3 movement::{self, Direction},
3 movement::{self, Direction},
4 object, pos_at_coords,
4 object, pos_at_coords,
5 regex::{self, Regex},
5 regex::{self, Regex},
6− register, search, selection, Change, ChangeSet, Position, Range, Rope, RopeSlice, Selection,
6+ register, search, selection, words, Change, ChangeSet, Position, Range, Rope, RopeSlice,
7− SmallVec, Tendril, Transaction,
7+ Selection, SmallVec, Tendril, Transaction,
8};
8};
9
9
10use helix_view::{
10use helix_view::{
@@ -1782,7 +1782,6 @@ pub mod insert {
1782
1782
1783 pub fn delete_char_forward(cx: &mut Context) {
1783 pub fn delete_char_forward(cx: &mut Context) {
1784 let count = cx.count;
1784 let count = cx.count;
1785− let doc = cx.doc();
1786 let (view, doc) = cx.current();
1785 let (view, doc) = cx.current();
1787 let text = doc.text().slice(..);
1786 let text = doc.text().slice(..);
1788 let transaction =
1787 let transaction =
@@ -1795,6 +1794,21 @@ pub mod insert {
1795 });
1794 });
1796 doc.apply(&transaction, view.id);
1795 doc.apply(&transaction, view.id);
1797 }
1796 }
1797+
1798+ pub fn delete_word_backward(cx: &mut Context) {
1799+ let count = cx.count;
1800+ let (view, doc) = cx.current();
1801+ let text = doc.text().slice(..);
1802+ let transaction =
1803+ Transaction::change_by_selection(doc.text(), doc.selection(view.id), |range| {
1804+ (
1805+ words::nth_prev_word_boundary(text, range.head, count),
1806+ range.head,
1807+ None,
1808+ )
1809+ });
1810+ doc.apply(&transaction, view.id);
1811+ }
1798}
1812}
1799
1813
1800// Undo / Redo
1814// Undo / Redo
helix-term/src/keymap.rs+1
@@ -360,6 +360,7 @@ pub fn default() -> Keymaps {
360 } => commands::insert::insert_tab,
360 } => commands::insert::insert_tab,
361
361
362 ctrl!('x') => commands::completion,
362 ctrl!('x') => commands::completion,
363+ ctrl!('w') => commands::insert::delete_word_backward,
363 ),
364 ),
364 )
365 )
365}
366}