Implement whole word mode

This commit is contained in:
Antonio Scandurra 2022-01-28 11:23:14 +01:00
parent df1810a3b0
commit b980b11053
3 changed files with 43 additions and 24 deletions

View file

@ -438,6 +438,14 @@ pub struct NavigationData {
offset: usize,
}
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub enum CharKind {
Newline,
Punctuation,
Whitespace,
Word,
}
impl Editor {
pub fn single_line(build_settings: BuildSettings, cx: &mut ViewContext<Self>) -> Self {
let buffer = cx.add_model(|cx| Buffer::new(0, String::new(), cx));
@ -4215,6 +4223,18 @@ pub fn settings_builder(
})
}
pub fn char_kind(c: char) -> CharKind {
if c == '\n' {
CharKind::Newline
} else if c.is_whitespace() {
CharKind::Whitespace
} else if c.is_alphanumeric() || c == '_' {
CharKind::Word
} else {
CharKind::Punctuation
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1,5 +1,5 @@
use super::{Bias, DisplayPoint, DisplaySnapshot, SelectionGoal, ToDisplayPoint};
use crate::ToPoint;
use crate::{char_kind, CharKind, ToPoint};
use anyhow::Result;
use std::{cmp, ops::Range};
@ -215,26 +215,6 @@ pub fn surrounding_word(map: &DisplaySnapshot, point: DisplayPoint) -> Range<Dis
..end.to_point(&map.buffer_snapshot).to_display_point(map)
}
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
enum CharKind {
Newline,
Punctuation,
Whitespace,
Word,
}
fn char_kind(c: char) -> CharKind {
if c == '\n' {
CharKind::Newline
} else if c.is_whitespace() {
CharKind::Whitespace
} else if c.is_alphanumeric() || c == '_' {
CharKind::Word
} else {
CharKind::Punctuation
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -1,5 +1,5 @@
use aho_corasick::AhoCorasickBuilder;
use editor::{Editor, EditorSettings};
use editor::{char_kind, Editor, EditorSettings};
use gpui::{
action, elements::*, keymap::Binding, Entity, MutableAppContext, RenderContext, View,
ViewContext, ViewHandle,
@ -200,9 +200,28 @@ impl FindBar {
let buffer = editor.buffer().read(cx).snapshot(cx);
let ranges = search
.stream_find_iter(buffer.bytes_in_range(0..buffer.len()))
.map(|mat| {
.filter_map(|mat| {
let mat = mat.unwrap();
buffer.anchor_after(mat.start())..buffer.anchor_before(mat.end())
if self.whole_word_mode {
let prev_kind =
buffer.reversed_chars_at(mat.start()).next().map(char_kind);
let start_kind =
char_kind(buffer.chars_at(mat.start()).next().unwrap());
let end_kind =
char_kind(buffer.reversed_chars_at(mat.end()).next().unwrap());
let next_kind = buffer.chars_at(mat.end()).next().map(char_kind);
if Some(start_kind) != prev_kind && Some(end_kind) != next_kind {
Some(
buffer.anchor_after(mat.start())
..buffer.anchor_before(mat.end()),
)
} else {
None
}
} else {
Some(buffer.anchor_after(mat.start())..buffer.anchor_before(mat.end()))
}
})
.collect();
editor.highlight_ranges::<Self>(ranges, theme.match_background, cx);