mirror of https://github.com/helix-editor/helix
Implement keep_selections (filter selections on regex).
parent
872d770753
commit
dd91090a1a
|
@ -273,14 +273,33 @@ impl Selection {
|
||||||
|
|
||||||
// TODO: checkSelection -> check if valid for doc length
|
// TODO: checkSelection -> check if valid for doc length
|
||||||
|
|
||||||
pub fn select_on_matches(
|
pub fn keep_matches(
|
||||||
text: RopeSlice,
|
text: RopeSlice,
|
||||||
selections: &Selection,
|
selection: &Selection,
|
||||||
regex: &crate::regex::Regex,
|
regex: &crate::regex::Regex,
|
||||||
) -> Option<Selection> {
|
) -> Option<Selection> {
|
||||||
let mut result = SmallVec::with_capacity(selections.ranges().len());
|
let result: SmallVec<_> = selection
|
||||||
|
.ranges()
|
||||||
|
.iter()
|
||||||
|
.filter(|range| regex.is_match(&range.fragment(text)))
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
|
||||||
for sel in selections.ranges() {
|
// TODO: figure out a new primary index
|
||||||
|
if !result.is_empty() {
|
||||||
|
return Some(Selection::new(result, 0));
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_on_matches(
|
||||||
|
text: RopeSlice,
|
||||||
|
selection: &Selection,
|
||||||
|
regex: &crate::regex::Regex,
|
||||||
|
) -> Option<Selection> {
|
||||||
|
let mut result = SmallVec::with_capacity(selection.ranges().len());
|
||||||
|
|
||||||
|
for sel in selection.ranges() {
|
||||||
// TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
|
// TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
|
||||||
let fragment = sel.fragment(text);
|
let fragment = sel.fragment(text);
|
||||||
|
|
||||||
|
@ -309,12 +328,12 @@ pub fn select_on_matches(
|
||||||
// TODO: support to split on capture #N instead of whole match
|
// TODO: support to split on capture #N instead of whole match
|
||||||
pub fn split_on_matches(
|
pub fn split_on_matches(
|
||||||
text: RopeSlice,
|
text: RopeSlice,
|
||||||
selections: &Selection,
|
selection: &Selection,
|
||||||
regex: &crate::regex::Regex,
|
regex: &crate::regex::Regex,
|
||||||
) -> Selection {
|
) -> Selection {
|
||||||
let mut result = SmallVec::with_capacity(selections.ranges().len());
|
let mut result = SmallVec::with_capacity(selection.ranges().len());
|
||||||
|
|
||||||
for sel in selections.ranges() {
|
for sel in selection.ranges() {
|
||||||
// TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
|
// TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
|
||||||
let fragment = sel.fragment(text);
|
let fragment = sel.fragment(text);
|
||||||
|
|
||||||
|
@ -417,9 +436,9 @@ mod test {
|
||||||
|
|
||||||
let text = Rope::from("abcd efg wrs xyz 123 456");
|
let text = Rope::from("abcd efg wrs xyz 123 456");
|
||||||
|
|
||||||
let selections = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0);
|
let selection = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0);
|
||||||
|
|
||||||
let result = split_on_matches(text.slice(..), &selections, &Regex::new(r"\s+").unwrap());
|
let result = split_on_matches(text.slice(..), &selection, &Regex::new(r"\s+").unwrap());
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result.ranges(),
|
result.ranges(),
|
||||||
|
|
|
@ -1156,7 +1156,15 @@ pub fn join_selections(cx: &mut Context) {
|
||||||
pub fn keep_selections(cx: &mut Context) {
|
pub fn keep_selections(cx: &mut Context) {
|
||||||
let doc = cx.doc();
|
let doc = cx.doc();
|
||||||
// keep selections matching regex
|
// keep selections matching regex
|
||||||
// and another method for inverse
|
let prompt = ui::regex_prompt(cx, "keep:".to_string(), |doc, regex| {
|
||||||
|
let text = doc.text().slice(..);
|
||||||
|
|
||||||
|
if let Some(selection) = selection::keep_matches(text, doc.selection(), ®ex) {
|
||||||
|
doc.set_selection(selection);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.push_layer(Box::new(prompt));
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -207,6 +207,7 @@ pub fn default() -> Keymaps {
|
||||||
key!('<') => commands::unindent,
|
key!('<') => commands::unindent,
|
||||||
key!('=') => commands::format_selections,
|
key!('=') => commands::format_selections,
|
||||||
shift!('J') => commands::join_selections,
|
shift!('J') => commands::join_selections,
|
||||||
|
// TODO: conflicts hover/doc
|
||||||
shift!('K') => commands::keep_selections,
|
shift!('K') => commands::keep_selections,
|
||||||
|
|
||||||
// key!('q') => commands::record_macro,
|
// key!('q') => commands::record_macro,
|
||||||
|
|
|
@ -44,7 +44,6 @@ impl Editor {
|
||||||
.and_then(|language| self.language_servers.get(language, &executor));
|
.and_then(|language| self.language_servers.get(language, &executor));
|
||||||
|
|
||||||
if let Some(language_server) = language_server {
|
if let Some(language_server) = language_server {
|
||||||
// TODO: do this everywhere
|
|
||||||
doc.set_language_server(Some(language_server.clone()));
|
doc.set_language_server(Some(language_server.clone()));
|
||||||
|
|
||||||
smol::block_on(language_server.text_document_did_open(
|
smol::block_on(language_server.text_document_did_open(
|
||||||
|
|
Loading…
Reference in New Issue