mirror of
https://github.com/openai/codex.git
synced 2026-10-20 17:38:45 +00:00
## What changed - Add draft-local forward and backward literal search with `/` and `?`, plus wrapped repeat navigation with `n` and `N`. - Support search motions after delete, change, and yank operators, while keeping queries separate from the draft and skipping atomic elements and partial grapheme matches. - Render and edit the query in the composer footer, highlight matches, and add configurable `tui.keymap.vim_search` bindings to the keymap picker and schema. ## Testing - Cover navigation, wrapping, operator composition, repeat behavior, Unicode graphemes, atomic elements, query editing, paste handling, and rendering. GitOrigin-RevId: 087b080ff8fd74e48456c6b899c07ea5eed38e0c
45 lines
1.3 KiB
Rust
45 lines
1.3 KiB
Rust
//! Surface-independent literal Vim search queries. Matches span complete graphemes;
|
|
//! callers own navigation, operator ranges, and the lifetime of accepted versus pending input.
|
|
|
|
use std::ops::Range;
|
|
use unicode_segmentation::UnicodeSegmentation;
|
|
|
|
#[derive(Clone, Copy, Debug, Default)]
|
|
pub(crate) enum SearchDirection {
|
|
#[default]
|
|
Forward,
|
|
Backward,
|
|
}
|
|
|
|
impl SearchDirection {
|
|
pub(crate) fn reversed(self) -> Self {
|
|
match self {
|
|
Self::Forward => Self::Backward,
|
|
Self::Backward => Self::Forward,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, Default)]
|
|
pub(crate) struct SearchQuery {
|
|
pub(crate) text: String,
|
|
pub(crate) direction: SearchDirection,
|
|
}
|
|
|
|
pub(crate) fn matching_ranges<'a>(
|
|
text: &'a str,
|
|
query: &'a str,
|
|
) -> impl Iterator<Item = Range<usize>> + 'a {
|
|
let text = if query.is_empty() { "" } else { text };
|
|
text.grapheme_indices(/*is_extended*/ true)
|
|
.filter(move |&(start, _)| text[start..].starts_with(query))
|
|
.map(move |(start, _)| {
|
|
let end = text[start..]
|
|
.grapheme_indices(/*is_extended*/ true)
|
|
.map(|(offset, grapheme)| start + offset + grapheme.len())
|
|
.find(|&end| end >= start + query.len())
|
|
.unwrap_or(text.len());
|
|
start..end
|
|
})
|
|
}
|