Add WORD textobject (#991)

* Add WORD textobject

* Document WORD textobject
pull/959/head
Omnikar 3 years ago committed by GitHub
parent e0e227d172
commit a252ecd8c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -62,6 +62,7 @@ Currently supported: `word`, `surround`, `function`, `class`, `parameter`.
| Key after `mi` or `ma` | Textobject selected | | Key after `mi` or `ma` | Textobject selected |
| --- | --- | | --- | --- |
| `w` | Word | | `w` | Word |
| `W` | WORD |
| `(`, `[`, `'`, etc | Specified surround pairs | | `(`, `[`, `'`, etc | Specified surround pairs |
| `f` | Function | | `f` | Function |
| `c` | Class | | `c` | Class |

@ -10,7 +10,7 @@ use crate::surround;
use crate::syntax::LanguageConfiguration; use crate::syntax::LanguageConfiguration;
use crate::Range; use crate::Range;
fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction) -> usize { fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction, long: bool) -> usize {
use CharCategory::{Eol, Whitespace}; use CharCategory::{Eol, Whitespace};
let iter = match direction { let iter = match direction {
@ -33,7 +33,7 @@ fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction) ->
match categorize_char(ch) { match categorize_char(ch) {
Eol | Whitespace => return pos, Eol | Whitespace => return pos,
category => { category => {
if category != prev_category && pos != 0 && pos != slice.len_chars() { if !long && category != prev_category && pos != 0 && pos != slice.len_chars() {
return pos; return pos;
} else { } else {
match direction { match direction {
@ -70,13 +70,14 @@ pub fn textobject_word(
range: Range, range: Range,
textobject: TextObject, textobject: TextObject,
_count: usize, _count: usize,
long: bool,
) -> Range { ) -> Range {
let pos = range.cursor(slice); let pos = range.cursor(slice);
let word_start = find_word_boundary(slice, pos, Direction::Backward); let word_start = find_word_boundary(slice, pos, Direction::Backward, long);
let word_end = match slice.get_char(pos).map(categorize_char) { let word_end = match slice.get_char(pos).map(categorize_char) {
None | Some(CharCategory::Whitespace | CharCategory::Eol) => pos, None | Some(CharCategory::Whitespace | CharCategory::Eol) => pos,
_ => find_word_boundary(slice, pos + 1, Direction::Forward), _ => find_word_boundary(slice, pos + 1, Direction::Forward, long),
}; };
// Special case. // Special case.
@ -268,7 +269,7 @@ mod test {
let slice = doc.slice(..); let slice = doc.slice(..);
for &case in scenario { for &case in scenario {
let (pos, objtype, expected_range) = case; let (pos, objtype, expected_range) = case;
let result = textobject_word(slice, Range::point(pos), objtype, 1); let result = textobject_word(slice, Range::point(pos), objtype, 1, false);
assert_eq!( assert_eq!(
result, result,
expected_range.into(), expected_range.into(),

@ -4672,7 +4672,8 @@ fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) {
let selection = doc.selection(view.id).clone().transform(|range| { let selection = doc.selection(view.id).clone().transform(|range| {
match ch { match ch {
'w' => textobject::textobject_word(text, range, objtype, count), 'w' => textobject::textobject_word(text, range, objtype, count, false),
'W' => textobject::textobject_word(text, range, objtype, count, true),
'c' => textobject_treesitter("class", range), 'c' => textobject_treesitter("class", range),
'f' => textobject_treesitter("function", range), 'f' => textobject_treesitter("function", range),
'p' => textobject_treesitter("parameter", range), 'p' => textobject_treesitter("parameter", range),

@ -491,6 +491,7 @@ impl Component for Prompt {
doc.selection(view.id).primary(), doc.selection(view.id).primary(),
textobject::TextObject::Inside, textobject::TextObject::Inside,
1, 1,
false,
); );
let line = text.slice(range.from()..range.to()).to_string(); let line = text.slice(range.from()..range.to()).to_string();
if !line.is_empty() { if !line.is_empty() {

Loading…
Cancel
Save