Merge pull request #1469 from zed-industries/distinctive-marked-text
Tweak "marked ranges" test helper so that it can be used in documents with braces and brackets
This commit is contained in:
commit
134803745a
17 changed files with 1362 additions and 1479 deletions
|
@ -1170,7 +1170,7 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
language.set_theme(&theme);
|
language.set_theme(&theme);
|
||||||
|
|
||||||
let (text, highlighted_ranges) = marked_text_ranges(r#"const[] [a]: B = "c [d]""#);
|
let (text, highlighted_ranges) = marked_text_ranges(r#"constˇ «a»: B = "c «d»""#, false);
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
let buffer = cx.add_model(|cx| Buffer::new(0, text, cx).with_language(language, cx));
|
||||||
buffer.condition(&cx, |buf, _| !buf.is_parsing()).await;
|
buffer.condition(&cx, |buf, _| !buf.is_parsing()).await;
|
||||||
|
@ -1246,28 +1246,28 @@ pub mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
use Bias::{Left, Right};
|
use Bias::{Left, Right};
|
||||||
assert("||α", false, Left, cx);
|
assert("ˇˇα", false, Left, cx);
|
||||||
assert("||α", true, Left, cx);
|
assert("ˇˇα", true, Left, cx);
|
||||||
assert("||α", false, Right, cx);
|
assert("ˇˇα", false, Right, cx);
|
||||||
assert("|α|", true, Right, cx);
|
assert("ˇαˇ", true, Right, cx);
|
||||||
assert("||✋", false, Left, cx);
|
assert("ˇˇ✋", false, Left, cx);
|
||||||
assert("||✋", true, Left, cx);
|
assert("ˇˇ✋", true, Left, cx);
|
||||||
assert("||✋", false, Right, cx);
|
assert("ˇˇ✋", false, Right, cx);
|
||||||
assert("|✋|", true, Right, cx);
|
assert("ˇ✋ˇ", true, Right, cx);
|
||||||
assert("||🍐", false, Left, cx);
|
assert("ˇˇ🍐", false, Left, cx);
|
||||||
assert("||🍐", true, Left, cx);
|
assert("ˇˇ🍐", true, Left, cx);
|
||||||
assert("||🍐", false, Right, cx);
|
assert("ˇˇ🍐", false, Right, cx);
|
||||||
assert("|🍐|", true, Right, cx);
|
assert("ˇ🍐ˇ", true, Right, cx);
|
||||||
assert("||\t", false, Left, cx);
|
assert("ˇˇ\t", false, Left, cx);
|
||||||
assert("||\t", true, Left, cx);
|
assert("ˇˇ\t", true, Left, cx);
|
||||||
assert("||\t", false, Right, cx);
|
assert("ˇˇ\t", false, Right, cx);
|
||||||
assert("|\t|", true, Right, cx);
|
assert("ˇ\tˇ", true, Right, cx);
|
||||||
assert(" ||\t", false, Left, cx);
|
assert(" ˇˇ\t", false, Left, cx);
|
||||||
assert(" ||\t", true, Left, cx);
|
assert(" ˇˇ\t", true, Left, cx);
|
||||||
assert(" ||\t", false, Right, cx);
|
assert(" ˇˇ\t", false, Right, cx);
|
||||||
assert(" |\t|", true, Right, cx);
|
assert(" ˇ\tˇ", true, Right, cx);
|
||||||
assert(" ||\t", false, Left, cx);
|
assert(" ˇˇ\t", false, Left, cx);
|
||||||
assert(" ||\t", false, Right, cx);
|
assert(" ˇˇ\t", false, Right, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -1283,10 +1283,10 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert("||", cx);
|
assert("ˇˇ", cx);
|
||||||
assert("|a|", cx);
|
assert("ˇaˇ", cx);
|
||||||
assert("a|b|", cx);
|
assert("aˇbˇ", cx);
|
||||||
assert("a|α|", cx);
|
assert("aˇαˇ", cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,13 +32,10 @@ pub fn refresh_matching_bracket_highlights(editor: &mut Editor, cx: &mut ViewCon
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use indoc::indoc;
|
|
||||||
|
|
||||||
use language::{BracketPair, Language, LanguageConfig};
|
|
||||||
|
|
||||||
use crate::test::EditorLspTestContext;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::test::EditorLspTestContext;
|
||||||
|
use indoc::indoc;
|
||||||
|
use language::{BracketPair, Language, LanguageConfig};
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_matching_bracket_highlights(cx: &mut gpui::TestAppContext) {
|
async fn test_matching_bracket_highlights(cx: &mut gpui::TestAppContext) {
|
||||||
|
@ -76,67 +73,61 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// positioning cursor inside bracket highlights both
|
// positioning cursor inside bracket highlights both
|
||||||
cx.set_state_by(
|
cx.set_state(indoc! {r#"
|
||||||
vec!['|'.into()],
|
pub fn test("Test ˇargument") {
|
||||||
indoc! {r#"
|
another_test(1, 2, 3);
|
||||||
pub fn test("Test |argument") {
|
}
|
||||||
another_test(1, 2, 3);
|
"#});
|
||||||
}"#},
|
|
||||||
);
|
|
||||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||||
pub fn test[(]"Test argument"[)] {
|
pub fn test«(»"Test argument"«)» {
|
||||||
another_test(1, 2, 3);
|
another_test(1, 2, 3);
|
||||||
}"#});
|
}
|
||||||
|
"#});
|
||||||
|
|
||||||
cx.set_state_by(
|
cx.set_state(indoc! {r#"
|
||||||
vec!['|'.into()],
|
pub fn test("Test argument") {
|
||||||
indoc! {r#"
|
another_test(1, ˇ2, 3);
|
||||||
pub fn test("Test argument") {
|
}
|
||||||
another_test(1, |2, 3);
|
"#});
|
||||||
}"#},
|
|
||||||
);
|
|
||||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||||
pub fn test("Test argument") {
|
pub fn test("Test argument") {
|
||||||
another_test[(]1, 2, 3[)];
|
another_test«(»1, 2, 3«)»;
|
||||||
}"#});
|
}
|
||||||
|
"#});
|
||||||
|
|
||||||
cx.set_state_by(
|
cx.set_state(indoc! {r#"
|
||||||
vec!['|'.into()],
|
pub fn test("Test argument") {
|
||||||
indoc! {r#"
|
anotherˇ_test(1, 2, 3);
|
||||||
pub fn test("Test argument") {
|
}
|
||||||
another|_test(1, 2, 3);
|
"#});
|
||||||
}"#},
|
|
||||||
);
|
|
||||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||||
pub fn test("Test argument") [{]
|
pub fn test("Test argument") «{»
|
||||||
another_test(1, 2, 3);
|
another_test(1, 2, 3);
|
||||||
[}]"#});
|
«}»
|
||||||
|
"#});
|
||||||
|
|
||||||
// positioning outside of brackets removes highlight
|
// positioning outside of brackets removes highlight
|
||||||
cx.set_state_by(
|
cx.set_state(indoc! {r#"
|
||||||
vec!['|'.into()],
|
pub fˇn test("Test argument") {
|
||||||
indoc! {r#"
|
another_test(1, 2, 3);
|
||||||
pub f|n test("Test argument") {
|
}
|
||||||
another_test(1, 2, 3);
|
"#});
|
||||||
}"#},
|
|
||||||
);
|
|
||||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||||
pub fn test("Test argument") {
|
pub fn test("Test argument") {
|
||||||
another_test(1, 2, 3);
|
another_test(1, 2, 3);
|
||||||
}"#});
|
}
|
||||||
|
"#});
|
||||||
|
|
||||||
// non empty selection dismisses highlight
|
// non empty selection dismisses highlight
|
||||||
// positioning outside of brackets removes highlight
|
cx.set_state(indoc! {r#"
|
||||||
cx.set_state_by(
|
pub fn test("Te«st argˇ»ument") {
|
||||||
vec![('<', '>').into()],
|
another_test(1, 2, 3);
|
||||||
indoc! {r#"
|
}
|
||||||
pub fn test("Te<st arg>ument") {
|
"#});
|
||||||
another_test(1, 2, 3);
|
|
||||||
}"#},
|
|
||||||
);
|
|
||||||
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
cx.assert_editor_background_highlights::<MatchingBracketHighlight>(indoc! {r#"
|
||||||
pub fn test("Test argument") {
|
pub fn test("Test argument") {
|
||||||
another_test(1, 2, 3);
|
another_test(1, 2, 3);
|
||||||
}"#});
|
}
|
||||||
|
"#});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -439,11 +439,11 @@ mod tests {
|
||||||
|
|
||||||
// Basic hover delays and then pops without moving the mouse
|
// Basic hover delays and then pops without moving the mouse
|
||||||
cx.set_state(indoc! {"
|
cx.set_state(indoc! {"
|
||||||
fn |test()
|
fn ˇtest() { println!(); }
|
||||||
println!();"});
|
"});
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
fn test()
|
fn test() { printˇln!(); }
|
||||||
print|ln!();"});
|
"});
|
||||||
|
|
||||||
cx.update_editor(|editor, cx| {
|
cx.update_editor(|editor, cx| {
|
||||||
hover_at(
|
hover_at(
|
||||||
|
@ -458,16 +458,16 @@ mod tests {
|
||||||
|
|
||||||
// After delay, hover should be visible.
|
// After delay, hover should be visible.
|
||||||
let symbol_range = cx.lsp_range(indoc! {"
|
let symbol_range = cx.lsp_range(indoc! {"
|
||||||
fn test()
|
fn test() { «println!»(); }
|
||||||
[println!]();"});
|
"});
|
||||||
let mut requests =
|
let mut requests =
|
||||||
cx.handle_request::<lsp::request::HoverRequest, _, _>(move |_, _, _| async move {
|
cx.handle_request::<lsp::request::HoverRequest, _, _>(move |_, _, _| async move {
|
||||||
Ok(Some(lsp::Hover {
|
Ok(Some(lsp::Hover {
|
||||||
contents: lsp::HoverContents::Markup(lsp::MarkupContent {
|
contents: lsp::HoverContents::Markup(lsp::MarkupContent {
|
||||||
kind: lsp::MarkupKind::Markdown,
|
kind: lsp::MarkupKind::Markdown,
|
||||||
value: indoc! {"
|
value: indoc! {"
|
||||||
# Some basic docs
|
# Some basic docs
|
||||||
Some test documentation"}
|
Some test documentation"}
|
||||||
.to_string(),
|
.to_string(),
|
||||||
}),
|
}),
|
||||||
range: Some(symbol_range),
|
range: Some(symbol_range),
|
||||||
|
@ -496,8 +496,8 @@ mod tests {
|
||||||
|
|
||||||
// Mouse moved with no hover response dismisses
|
// Mouse moved with no hover response dismisses
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
fn te|st()
|
fn teˇst() { println!(); }
|
||||||
println!();"});
|
"});
|
||||||
let mut request = cx
|
let mut request = cx
|
||||||
.lsp
|
.lsp
|
||||||
.handle_request::<lsp::request::HoverRequest, _, _>(|_, _| async move { Ok(None) });
|
.handle_request::<lsp::request::HoverRequest, _, _>(|_, _| async move { Ok(None) });
|
||||||
|
@ -531,12 +531,12 @@ mod tests {
|
||||||
|
|
||||||
// Hover with keyboard has no delay
|
// Hover with keyboard has no delay
|
||||||
cx.set_state(indoc! {"
|
cx.set_state(indoc! {"
|
||||||
f|n test()
|
fˇn test() { println!(); }
|
||||||
println!();"});
|
"});
|
||||||
cx.update_editor(|editor, cx| hover(editor, &Hover, cx));
|
cx.update_editor(|editor, cx| hover(editor, &Hover, cx));
|
||||||
let symbol_range = cx.lsp_range(indoc! {"
|
let symbol_range = cx.lsp_range(indoc! {"
|
||||||
[fn] test()
|
«fn» test() { println!(); }
|
||||||
println!();"});
|
"});
|
||||||
cx.handle_request::<lsp::request::HoverRequest, _, _>(move |_, _, _| async move {
|
cx.handle_request::<lsp::request::HoverRequest, _, _>(move |_, _, _| async move {
|
||||||
Ok(Some(lsp::Hover {
|
Ok(Some(lsp::Hover {
|
||||||
contents: lsp::HoverContents::Markup(lsp::MarkupContent {
|
contents: lsp::HoverContents::Markup(lsp::MarkupContent {
|
||||||
|
@ -584,13 +584,13 @@ mod tests {
|
||||||
// Hover with just diagnostic, pops DiagnosticPopover immediately and then
|
// Hover with just diagnostic, pops DiagnosticPopover immediately and then
|
||||||
// info popover once request completes
|
// info popover once request completes
|
||||||
cx.set_state(indoc! {"
|
cx.set_state(indoc! {"
|
||||||
fn te|st()
|
fn teˇst() { println!(); }
|
||||||
println!();"});
|
"});
|
||||||
|
|
||||||
// Send diagnostic to client
|
// Send diagnostic to client
|
||||||
let range = cx.text_anchor_range(indoc! {"
|
let range = cx.text_anchor_range(indoc! {"
|
||||||
fn [test]()
|
fn «test»() { println!(); }
|
||||||
println!();"});
|
"});
|
||||||
cx.update_buffer(|buffer, cx| {
|
cx.update_buffer(|buffer, cx| {
|
||||||
let snapshot = buffer.text_snapshot();
|
let snapshot = buffer.text_snapshot();
|
||||||
let set = DiagnosticSet::from_sorted_entries(
|
let set = DiagnosticSet::from_sorted_entries(
|
||||||
|
@ -616,15 +616,15 @@ mod tests {
|
||||||
|
|
||||||
// Info Popover shows after request responded to
|
// Info Popover shows after request responded to
|
||||||
let range = cx.lsp_range(indoc! {"
|
let range = cx.lsp_range(indoc! {"
|
||||||
fn [test]()
|
fn «test»() { println!(); }
|
||||||
println!();"});
|
"});
|
||||||
cx.handle_request::<lsp::request::HoverRequest, _, _>(move |_, _, _| async move {
|
cx.handle_request::<lsp::request::HoverRequest, _, _>(move |_, _, _| async move {
|
||||||
Ok(Some(lsp::Hover {
|
Ok(Some(lsp::Hover {
|
||||||
contents: lsp::HoverContents::Markup(lsp::MarkupContent {
|
contents: lsp::HoverContents::Markup(lsp::MarkupContent {
|
||||||
kind: lsp::MarkupKind::Markdown,
|
kind: lsp::MarkupKind::Markdown,
|
||||||
value: indoc! {"
|
value: indoc! {"
|
||||||
# Some other basic docs
|
# Some other basic docs
|
||||||
Some other test documentation"}
|
Some other test documentation"}
|
||||||
.to_string(),
|
.to_string(),
|
||||||
}),
|
}),
|
||||||
range: Some(range),
|
range: Some(range),
|
||||||
|
|
|
@ -405,20 +405,20 @@ mod tests {
|
||||||
|
|
||||||
cx.set_state(indoc! {"
|
cx.set_state(indoc! {"
|
||||||
struct A;
|
struct A;
|
||||||
let v|ariable = A;
|
let vˇariable = A;
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Basic hold cmd+shift, expect highlight in region if response contains type definition
|
// Basic hold cmd+shift, expect highlight in region if response contains type definition
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
struct A;
|
struct A;
|
||||||
let v|ariable = A;
|
let vˇariable = A;
|
||||||
"});
|
"});
|
||||||
let symbol_range = cx.lsp_range(indoc! {"
|
let symbol_range = cx.lsp_range(indoc! {"
|
||||||
struct A;
|
struct A;
|
||||||
let [variable] = A;
|
let «variable» = A;
|
||||||
"});
|
"});
|
||||||
let target_range = cx.lsp_range(indoc! {"
|
let target_range = cx.lsp_range(indoc! {"
|
||||||
struct [A];
|
struct «A»;
|
||||||
let variable = A;
|
let variable = A;
|
||||||
"});
|
"});
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ mod tests {
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
struct A;
|
struct A;
|
||||||
let [variable] = A;
|
let «variable» = A;
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Unpress shift causes highlight to go away (normal goto-definition is not valid here)
|
// Unpress shift causes highlight to go away (normal goto-definition is not valid here)
|
||||||
|
@ -473,10 +473,10 @@ mod tests {
|
||||||
// Cmd+shift click without existing definition requests and jumps
|
// Cmd+shift click without existing definition requests and jumps
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
struct A;
|
struct A;
|
||||||
let v|ariable = A;
|
let vˇariable = A;
|
||||||
"});
|
"});
|
||||||
let target_range = cx.lsp_range(indoc! {"
|
let target_range = cx.lsp_range(indoc! {"
|
||||||
struct [A];
|
struct «A»;
|
||||||
let variable = A;
|
let variable = A;
|
||||||
"});
|
"});
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ mod tests {
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
|
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
struct [A};
|
struct «Aˇ»;
|
||||||
let variable = A;
|
let variable = A;
|
||||||
"});
|
"});
|
||||||
}
|
}
|
||||||
|
@ -520,34 +520,22 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
cx.set_state(indoc! {"
|
cx.set_state(indoc! {"
|
||||||
fn |test()
|
fn ˇtest() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Basic hold cmd, expect highlight in region if response contains definition
|
// Basic hold cmd, expect highlight in region if response contains definition
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
fn test()
|
fn test() { do_wˇork(); }
|
||||||
do_w|ork();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
let symbol_range = cx.lsp_range(indoc! {"
|
let symbol_range = cx.lsp_range(indoc! {"
|
||||||
fn test()
|
fn test() { «do_work»(); }
|
||||||
[do_work]();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
let target_range = cx.lsp_range(indoc! {"
|
let target_range = cx.lsp_range(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn «do_work»() { test(); }
|
||||||
|
|
||||||
fn [do_work]()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
let mut requests = cx.handle_request::<GotoDefinition, _, _>(move |url, _, _| async move {
|
let mut requests = cx.handle_request::<GotoDefinition, _, _>(move |url, _, _| async move {
|
||||||
|
@ -575,11 +563,8 @@ mod tests {
|
||||||
requests.next().await;
|
requests.next().await;
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { «do_work»(); }
|
||||||
[do_work]();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Unpress cmd causes highlight to go away
|
// Unpress cmd causes highlight to go away
|
||||||
|
@ -593,13 +578,11 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert no link highlights
|
// Assert no link highlights
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Response without source range still highlights word
|
// Response without source range still highlights word
|
||||||
|
@ -630,20 +613,14 @@ mod tests {
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
|
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { «do_work»(); }
|
||||||
[do_work]();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Moving mouse to location with no response dismisses highlight
|
// Moving mouse to location with no response dismisses highlight
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
f|n test()
|
fˇn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
let mut requests = cx
|
let mut requests = cx
|
||||||
.lsp
|
.lsp
|
||||||
|
@ -667,20 +644,14 @@ mod tests {
|
||||||
|
|
||||||
// Assert no link highlights
|
// Assert no link highlights
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Move mouse without cmd and then pressing cmd triggers highlight
|
// Move mouse without cmd and then pressing cmd triggers highlight
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { teˇst(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
te|st();
|
|
||||||
"});
|
"});
|
||||||
cx.update_editor(|editor, cx| {
|
cx.update_editor(|editor, cx| {
|
||||||
update_go_to_definition_link(
|
update_go_to_definition_link(
|
||||||
|
@ -697,26 +668,17 @@ mod tests {
|
||||||
|
|
||||||
// Assert no link highlights
|
// Assert no link highlights
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
let symbol_range = cx.lsp_range(indoc! {"
|
let symbol_range = cx.lsp_range(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { «test»(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
[test]();
|
|
||||||
"});
|
"});
|
||||||
let target_range = cx.lsp_range(indoc! {"
|
let target_range = cx.lsp_range(indoc! {"
|
||||||
fn [test]()
|
fn «test»() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
let mut requests = cx.handle_request::<GotoDefinition, _, _>(move |url, _, _| async move {
|
let mut requests = cx.handle_request::<GotoDefinition, _, _>(move |url, _, _| async move {
|
||||||
|
@ -743,20 +705,14 @@ mod tests {
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
|
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { «test»(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
[test]();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Moving within symbol range doesn't re-request
|
// Moving within symbol range doesn't re-request
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { tesˇt(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
tes|t();
|
|
||||||
"});
|
"});
|
||||||
cx.update_editor(|editor, cx| {
|
cx.update_editor(|editor, cx| {
|
||||||
update_go_to_definition_link(
|
update_go_to_definition_link(
|
||||||
|
@ -771,11 +727,8 @@ mod tests {
|
||||||
});
|
});
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { «test»(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
[test]();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Cmd click with existing definition doesn't re-request and dismisses highlight
|
// Cmd click with existing definition doesn't re-request and dismisses highlight
|
||||||
|
@ -790,35 +743,24 @@ mod tests {
|
||||||
Ok(Some(lsp::GotoDefinitionResponse::Link(vec![])))
|
Ok(Some(lsp::GotoDefinitionResponse::Link(vec![])))
|
||||||
});
|
});
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
fn [test}()
|
fn «testˇ»() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Assert no link highlights after jump
|
// Assert no link highlights after jump
|
||||||
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
cx.assert_editor_text_highlights::<LinkGoToDefinitionState>(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
// Cmd click without existing definition requests and jumps
|
// Cmd click without existing definition requests and jumps
|
||||||
let hover_point = cx.display_point(indoc! {"
|
let hover_point = cx.display_point(indoc! {"
|
||||||
fn test()
|
fn test() { do_wˇork(); }
|
||||||
do_w|ork();
|
fn do_work() { test(); }
|
||||||
|
|
||||||
fn do_work()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
let target_range = cx.lsp_range(indoc! {"
|
let target_range = cx.lsp_range(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn «do_work»() { test(); }
|
||||||
|
|
||||||
fn [do_work]()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
|
|
||||||
let mut requests = cx.handle_request::<GotoDefinition, _, _>(move |url, _, _| async move {
|
let mut requests = cx.handle_request::<GotoDefinition, _, _>(move |url, _, _| async move {
|
||||||
|
@ -836,13 +778,9 @@ mod tests {
|
||||||
});
|
});
|
||||||
requests.next().await;
|
requests.next().await;
|
||||||
cx.foreground().run_until_parked();
|
cx.foreground().run_until_parked();
|
||||||
|
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
fn test()
|
fn test() { do_work(); }
|
||||||
do_work();
|
fn «do_workˇ»() { test(); }
|
||||||
|
|
||||||
fn [do_work}()
|
|
||||||
test();
|
|
||||||
"});
|
"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,11 +67,9 @@ pub fn deploy_context_menu(
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use indoc::indoc;
|
|
||||||
|
|
||||||
use crate::test::EditorLspTestContext;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::test::EditorLspTestContext;
|
||||||
|
use indoc::indoc;
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_mouse_context_menu(cx: &mut gpui::TestAppContext) {
|
async fn test_mouse_context_menu(cx: &mut gpui::TestAppContext) {
|
||||||
|
@ -85,11 +83,15 @@ mod tests {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
cx.set_state(indoc! {"
|
cx.set_state(indoc! {"
|
||||||
fn te|st()
|
fn teˇst() {
|
||||||
do_work();"});
|
do_work();
|
||||||
|
}
|
||||||
|
"});
|
||||||
let point = cx.display_point(indoc! {"
|
let point = cx.display_point(indoc! {"
|
||||||
fn test()
|
fn test() {
|
||||||
do_w|ork();"});
|
do_wˇork();
|
||||||
|
}
|
||||||
|
"});
|
||||||
cx.update_editor(|editor, cx| {
|
cx.update_editor(|editor, cx| {
|
||||||
deploy_context_menu(
|
deploy_context_menu(
|
||||||
editor,
|
editor,
|
||||||
|
@ -102,8 +104,10 @@ mod tests {
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
fn test()
|
fn test() {
|
||||||
do_w|ork();"});
|
do_wˇork();
|
||||||
|
}
|
||||||
|
"});
|
||||||
cx.editor(|editor, app| assert!(editor.mouse_context_menu.read(app).visible()));
|
cx.editor(|editor, app| assert!(editor.mouse_context_menu.read(app).visible()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -287,20 +287,20 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert("\n| |lorem", cx);
|
assert("\nˇ ˇlorem", cx);
|
||||||
assert("|\n| lorem", cx);
|
assert("ˇ\nˇ lorem", cx);
|
||||||
assert(" |lorem|", cx);
|
assert(" ˇloremˇ", cx);
|
||||||
assert("| |lorem", cx);
|
assert("ˇ ˇlorem", cx);
|
||||||
assert(" |lor|em", cx);
|
assert(" ˇlorˇem", cx);
|
||||||
assert("\nlorem\n| |ipsum", cx);
|
assert("\nlorem\nˇ ˇipsum", cx);
|
||||||
assert("\n\n|\n|", cx);
|
assert("\n\nˇ\nˇ", cx);
|
||||||
assert(" |lorem |ipsum", cx);
|
assert(" ˇlorem ˇipsum", cx);
|
||||||
assert("lorem|-|ipsum", cx);
|
assert("loremˇ-ˇipsum", cx);
|
||||||
assert("lorem|-#$@|ipsum", cx);
|
assert("loremˇ-#$@ˇipsum", cx);
|
||||||
assert("|lorem_|ipsum", cx);
|
assert("ˇlorem_ˇipsum", cx);
|
||||||
assert(" |defγ|", cx);
|
assert(" ˇdefγˇ", cx);
|
||||||
assert(" |bcΔ|", cx);
|
assert(" ˇbcΔˇ", cx);
|
||||||
assert(" ab|——|cd", cx);
|
assert(" abˇ——ˇcd", cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -315,26 +315,26 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subword boundaries are respected
|
// Subword boundaries are respected
|
||||||
assert("lorem_|ip|sum", cx);
|
assert("lorem_ˇipˇsum", cx);
|
||||||
assert("lorem_|ipsum|", cx);
|
assert("lorem_ˇipsumˇ", cx);
|
||||||
assert("|lorem_|ipsum", cx);
|
assert("ˇlorem_ˇipsum", cx);
|
||||||
assert("lorem_|ipsum_|dolor", cx);
|
assert("lorem_ˇipsum_ˇdolor", cx);
|
||||||
assert("lorem|Ip|sum", cx);
|
assert("loremˇIpˇsum", cx);
|
||||||
assert("lorem|Ipsum|", cx);
|
assert("loremˇIpsumˇ", cx);
|
||||||
|
|
||||||
// Word boundaries are still respected
|
// Word boundaries are still respected
|
||||||
assert("\n| |lorem", cx);
|
assert("\nˇ ˇlorem", cx);
|
||||||
assert(" |lorem|", cx);
|
assert(" ˇloremˇ", cx);
|
||||||
assert(" |lor|em", cx);
|
assert(" ˇlorˇem", cx);
|
||||||
assert("\nlorem\n| |ipsum", cx);
|
assert("\nlorem\nˇ ˇipsum", cx);
|
||||||
assert("\n\n|\n|", cx);
|
assert("\n\nˇ\nˇ", cx);
|
||||||
assert(" |lorem |ipsum", cx);
|
assert(" ˇlorem ˇipsum", cx);
|
||||||
assert("lorem|-|ipsum", cx);
|
assert("loremˇ-ˇipsum", cx);
|
||||||
assert("lorem|-#$@|ipsum", cx);
|
assert("loremˇ-#$@ˇipsum", cx);
|
||||||
assert(" |defγ|", cx);
|
assert(" ˇdefγˇ", cx);
|
||||||
assert(" bc|Δ|", cx);
|
assert(" bcˇΔˇ", cx);
|
||||||
assert(" |bcδ|", cx);
|
assert(" ˇbcδˇ", cx);
|
||||||
assert(" ab|——|cd", cx);
|
assert(" abˇ——ˇcd", cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -352,14 +352,14 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert("abc|def\ngh\nij|k", cx, |left, right| {
|
assert("abcˇdef\ngh\nijˇk", cx, |left, right| {
|
||||||
left == 'c' && right == 'd'
|
left == 'c' && right == 'd'
|
||||||
});
|
});
|
||||||
assert("abcdef\n|gh\nij|k", cx, |left, right| {
|
assert("abcdef\nˇgh\nijˇk", cx, |left, right| {
|
||||||
left == '\n' && right == 'g'
|
left == '\n' && right == 'g'
|
||||||
});
|
});
|
||||||
let mut line_count = 0;
|
let mut line_count = 0;
|
||||||
assert("abcdef\n|gh\nij|k", cx, |left, _| {
|
assert("abcdef\nˇgh\nijˇk", cx, |left, _| {
|
||||||
if left == '\n' {
|
if left == '\n' {
|
||||||
line_count += 1;
|
line_count += 1;
|
||||||
line_count == 2
|
line_count == 2
|
||||||
|
@ -380,17 +380,17 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert("\n| lorem|", cx);
|
assert("\nˇ loremˇ", cx);
|
||||||
assert(" |lorem|", cx);
|
assert(" ˇloremˇ", cx);
|
||||||
assert(" lor|em|", cx);
|
assert(" lorˇemˇ", cx);
|
||||||
assert(" lorem| |\nipsum\n", cx);
|
assert(" loremˇ ˇ\nipsum\n", cx);
|
||||||
assert("\n|\n|\n\n", cx);
|
assert("\nˇ\nˇ\n\n", cx);
|
||||||
assert("lorem| ipsum| ", cx);
|
assert("loremˇ ipsumˇ ", cx);
|
||||||
assert("lorem|-|ipsum", cx);
|
assert("loremˇ-ˇipsum", cx);
|
||||||
assert("lorem|#$@-|ipsum", cx);
|
assert("loremˇ#$@-ˇipsum", cx);
|
||||||
assert("lorem|_ipsum|", cx);
|
assert("loremˇ_ipsumˇ", cx);
|
||||||
assert(" |bcΔ|", cx);
|
assert(" ˇbcΔˇ", cx);
|
||||||
assert(" ab|——|cd", cx);
|
assert(" abˇ——ˇcd", cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -405,25 +405,25 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subword boundaries are respected
|
// Subword boundaries are respected
|
||||||
assert("lo|rem|_ipsum", cx);
|
assert("loˇremˇ_ipsum", cx);
|
||||||
assert("|lorem|_ipsum", cx);
|
assert("ˇloremˇ_ipsum", cx);
|
||||||
assert("lorem|_ipsum|", cx);
|
assert("loremˇ_ipsumˇ", cx);
|
||||||
assert("lorem|_ipsum|_dolor", cx);
|
assert("loremˇ_ipsumˇ_dolor", cx);
|
||||||
assert("lo|rem|Ipsum", cx);
|
assert("loˇremˇIpsum", cx);
|
||||||
assert("lorem|Ipsum|Dolor", cx);
|
assert("loremˇIpsumˇDolor", cx);
|
||||||
|
|
||||||
// Word boundaries are still respected
|
// Word boundaries are still respected
|
||||||
assert("\n| lorem|", cx);
|
assert("\nˇ loremˇ", cx);
|
||||||
assert(" |lorem|", cx);
|
assert(" ˇloremˇ", cx);
|
||||||
assert(" lor|em|", cx);
|
assert(" lorˇemˇ", cx);
|
||||||
assert(" lorem| |\nipsum\n", cx);
|
assert(" loremˇ ˇ\nipsum\n", cx);
|
||||||
assert("\n|\n|\n\n", cx);
|
assert("\nˇ\nˇ\n\n", cx);
|
||||||
assert("lorem| ipsum| ", cx);
|
assert("loremˇ ipsumˇ ", cx);
|
||||||
assert("lorem|-|ipsum", cx);
|
assert("loremˇ-ˇipsum", cx);
|
||||||
assert("lorem|#$@-|ipsum", cx);
|
assert("loremˇ#$@-ˇipsum", cx);
|
||||||
assert("lorem|_ipsum|", cx);
|
assert("loremˇ_ipsumˇ", cx);
|
||||||
assert(" |bc|Δ", cx);
|
assert(" ˇbcˇΔ", cx);
|
||||||
assert(" ab|——|cd", cx);
|
assert(" abˇ——ˇcd", cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -441,14 +441,14 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert("abc|def\ngh\nij|k", cx, |left, right| {
|
assert("abcˇdef\ngh\nijˇk", cx, |left, right| {
|
||||||
left == 'j' && right == 'k'
|
left == 'j' && right == 'k'
|
||||||
});
|
});
|
||||||
assert("ab|cdef\ngh\n|ijk", cx, |left, right| {
|
assert("abˇcdef\ngh\nˇijk", cx, |left, right| {
|
||||||
left == '\n' && right == 'i'
|
left == '\n' && right == 'i'
|
||||||
});
|
});
|
||||||
let mut line_count = 0;
|
let mut line_count = 0;
|
||||||
assert("abc|def\ngh\n|ijk", cx, |left, _| {
|
assert("abcˇdef\ngh\nˇijk", cx, |left, _| {
|
||||||
if left == '\n' {
|
if left == '\n' {
|
||||||
line_count += 1;
|
line_count += 1;
|
||||||
line_count == 2
|
line_count == 2
|
||||||
|
@ -469,14 +469,14 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert("||lorem| ipsum", cx);
|
assert("ˇˇloremˇ ipsum", cx);
|
||||||
assert("|lo|rem| ipsum", cx);
|
assert("ˇloˇremˇ ipsum", cx);
|
||||||
assert("|lorem|| ipsum", cx);
|
assert("ˇloremˇˇ ipsum", cx);
|
||||||
assert("lorem| | |ipsum", cx);
|
assert("loremˇ ˇ ˇipsum", cx);
|
||||||
assert("lorem\n|||\nipsum", cx);
|
assert("lorem\nˇˇˇ\nipsum", cx);
|
||||||
assert("lorem\n||ipsum|", cx);
|
assert("lorem\nˇˇipsumˇ", cx);
|
||||||
assert("lorem,|| |ipsum", cx);
|
assert("lorem,ˇˇ ˇipsum", cx);
|
||||||
assert("|lorem||, ipsum", cx);
|
assert("ˇloremˇˇ, ipsum", cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
|
|
@ -1,34 +1,28 @@
|
||||||
use std::{
|
|
||||||
any::TypeId,
|
|
||||||
ops::{Deref, DerefMut, Range},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use anyhow::Result;
|
|
||||||
use futures::{Future, StreamExt};
|
|
||||||
use indoc::indoc;
|
|
||||||
|
|
||||||
use collections::BTreeMap;
|
|
||||||
use gpui::{
|
|
||||||
json, keymap::Keystroke, AppContext, ModelContext, ModelHandle, ViewContext, ViewHandle,
|
|
||||||
};
|
|
||||||
use language::{
|
|
||||||
point_to_lsp, Buffer, BufferSnapshot, FakeLspAdapter, Language, LanguageConfig, Selection,
|
|
||||||
};
|
|
||||||
use lsp::{notification, request};
|
|
||||||
use project::Project;
|
|
||||||
use settings::Settings;
|
|
||||||
use util::{
|
|
||||||
assert_set_eq, set_eq,
|
|
||||||
test::{marked_text, marked_text_ranges, marked_text_ranges_by, SetEqError, TextRangeMarker},
|
|
||||||
};
|
|
||||||
use workspace::{pane, AppState, Workspace, WorkspaceHandle};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
|
display_map::{DisplayMap, DisplaySnapshot, ToDisplayPoint},
|
||||||
multi_buffer::ToPointUtf16,
|
multi_buffer::ToPointUtf16,
|
||||||
AnchorRangeExt, Autoscroll, DisplayPoint, Editor, EditorMode, MultiBuffer, ToPoint,
|
AnchorRangeExt, Autoscroll, DisplayPoint, Editor, EditorMode, MultiBuffer, ToPoint,
|
||||||
};
|
};
|
||||||
|
use anyhow::Result;
|
||||||
|
use futures::{Future, StreamExt};
|
||||||
|
use gpui::{
|
||||||
|
json, keymap::Keystroke, AppContext, ModelContext, ModelHandle, ViewContext, ViewHandle,
|
||||||
|
};
|
||||||
|
use indoc::indoc;
|
||||||
|
use language::{point_to_lsp, Buffer, BufferSnapshot, FakeLspAdapter, Language, LanguageConfig};
|
||||||
|
use lsp::{notification, request};
|
||||||
|
use project::Project;
|
||||||
|
use settings::Settings;
|
||||||
|
use std::{
|
||||||
|
any::TypeId,
|
||||||
|
ops::{Deref, DerefMut, Range},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
use util::{
|
||||||
|
assert_set_eq, set_eq,
|
||||||
|
test::{generate_marked_text, marked_text_offsets, marked_text_ranges},
|
||||||
|
};
|
||||||
|
use workspace::{pane, AppState, Workspace, WorkspaceHandle};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[ctor::ctor]
|
#[ctor::ctor]
|
||||||
|
@ -43,7 +37,7 @@ pub fn marked_display_snapshot(
|
||||||
text: &str,
|
text: &str,
|
||||||
cx: &mut gpui::MutableAppContext,
|
cx: &mut gpui::MutableAppContext,
|
||||||
) -> (DisplaySnapshot, Vec<DisplayPoint>) {
|
) -> (DisplaySnapshot, Vec<DisplayPoint>) {
|
||||||
let (unmarked_text, markers) = marked_text(text);
|
let (unmarked_text, markers) = marked_text_offsets(text);
|
||||||
|
|
||||||
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
let family_id = cx.font_cache().load_family(&["Helvetica"]).unwrap();
|
||||||
let font_id = cx
|
let font_id = cx
|
||||||
|
@ -65,7 +59,7 @@ pub fn marked_display_snapshot(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_ranges(editor: &mut Editor, marked_text: &str, cx: &mut ViewContext<Editor>) {
|
pub fn select_ranges(editor: &mut Editor, marked_text: &str, cx: &mut ViewContext<Editor>) {
|
||||||
let (umarked_text, text_ranges) = marked_text_ranges(marked_text);
|
let (umarked_text, text_ranges) = marked_text_ranges(marked_text, true);
|
||||||
assert_eq!(editor.text(cx), umarked_text);
|
assert_eq!(editor.text(cx), umarked_text);
|
||||||
editor.change_selections(None, cx, |s| s.select_ranges(text_ranges));
|
editor.change_selections(None, cx, |s| s.select_ranges(text_ranges));
|
||||||
}
|
}
|
||||||
|
@ -75,8 +69,7 @@ pub fn assert_text_with_selections(
|
||||||
marked_text: &str,
|
marked_text: &str,
|
||||||
cx: &mut ViewContext<Editor>,
|
cx: &mut ViewContext<Editor>,
|
||||||
) {
|
) {
|
||||||
let (unmarked_text, text_ranges) = marked_text_ranges(marked_text);
|
let (unmarked_text, text_ranges) = marked_text_ranges(marked_text, true);
|
||||||
|
|
||||||
assert_eq!(editor.text(cx), unmarked_text);
|
assert_eq!(editor.text(cx), unmarked_text);
|
||||||
assert_eq!(editor.selections.ranges(cx), text_ranges);
|
assert_eq!(editor.selections.ranges(cx), text_ranges);
|
||||||
}
|
}
|
||||||
|
@ -190,94 +183,58 @@ impl<'a> EditorTestContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display_point(&mut self, cursor_location: &str) -> DisplayPoint {
|
fn ranges(&self, marked_text: &str) -> Vec<Range<usize>> {
|
||||||
let (_, locations) = marked_text(cursor_location);
|
let (unmarked_text, ranges) = marked_text_ranges(marked_text, false);
|
||||||
|
assert_eq!(self.buffer_text(), unmarked_text);
|
||||||
|
ranges
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn display_point(&mut self, marked_text: &str) -> DisplayPoint {
|
||||||
|
let ranges = self.ranges(marked_text);
|
||||||
let snapshot = self
|
let snapshot = self
|
||||||
.editor
|
.editor
|
||||||
.update(self.cx, |editor, cx| editor.snapshot(cx));
|
.update(self.cx, |editor, cx| editor.snapshot(cx));
|
||||||
locations[0].to_display_point(&snapshot.display_snapshot)
|
ranges[0].start.to_display_point(&snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns anchors for the current buffer using `[`..`]`
|
// Returns anchors for the current buffer using `«` and `»`
|
||||||
pub fn text_anchor_range(&self, marked_text: &str) -> Range<language::Anchor> {
|
pub fn text_anchor_range(&self, marked_text: &str) -> Range<language::Anchor> {
|
||||||
let range_marker: TextRangeMarker = ('[', ']').into();
|
let ranges = self.ranges(marked_text);
|
||||||
let (unmarked_text, mut ranges) =
|
|
||||||
marked_text_ranges_by(&marked_text, vec![range_marker.clone()]);
|
|
||||||
assert_eq!(self.buffer_text(), unmarked_text);
|
|
||||||
let offset_range = ranges.remove(&range_marker).unwrap()[0].clone();
|
|
||||||
let snapshot = self.buffer_snapshot();
|
let snapshot = self.buffer_snapshot();
|
||||||
|
snapshot.anchor_before(ranges[0].start)..snapshot.anchor_after(ranges[0].end)
|
||||||
snapshot.anchor_before(offset_range.start)..snapshot.anchor_after(offset_range.end)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the editor state via a marked string.
|
/// Change the editor's text and selections using a string containing
|
||||||
// `|` characters represent empty selections
|
/// embedded range markers that represent the ranges and directions of
|
||||||
// `[` to `}` represents a non empty selection with the head at `}`
|
/// each selection.
|
||||||
// `{` to `]` represents a non empty selection with the head at `{`
|
///
|
||||||
pub fn set_state(&mut self, text: &str) {
|
/// See the `util::test::marked_text_ranges` function for more information.
|
||||||
self.set_state_by(
|
pub fn set_state(&mut self, marked_text: &str) {
|
||||||
vec![
|
let (unmarked_text, selection_ranges) = marked_text_ranges(marked_text, true);
|
||||||
'|'.into(),
|
|
||||||
('[', '}').into(),
|
|
||||||
TextRangeMarker::ReverseRange('{', ']'),
|
|
||||||
],
|
|
||||||
text,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_state_by(&mut self, range_markers: Vec<TextRangeMarker>, text: &str) {
|
|
||||||
self.editor.update(self.cx, |editor, cx| {
|
self.editor.update(self.cx, |editor, cx| {
|
||||||
let (unmarked_text, selection_ranges) = marked_text_ranges_by(&text, range_markers);
|
|
||||||
editor.set_text(unmarked_text, cx);
|
editor.set_text(unmarked_text, cx);
|
||||||
|
|
||||||
let selection_ranges: Vec<Range<usize>> = selection_ranges
|
|
||||||
.values()
|
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
|
editor.change_selections(Some(Autoscroll::Fit), cx, |s| {
|
||||||
s.select_ranges(selection_ranges)
|
s.select_ranges(selection_ranges)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asserts the editor state via a marked string.
|
/// Make an assertion about the editor's text and the ranges and directions
|
||||||
// `|` characters represent empty selections
|
/// of its selections using a string containing embedded range markers.
|
||||||
// `[` to `}` represents a non empty selection with the head at `}`
|
///
|
||||||
// `{` to `]` represents a non empty selection with the head at `{`
|
/// See the `util::test::marked_text_ranges` function for more information.
|
||||||
pub fn assert_editor_state(&mut self, text: &str) {
|
pub fn assert_editor_state(&mut self, marked_text: &str) {
|
||||||
let (unmarked_text, mut selection_ranges) = marked_text_ranges_by(
|
let (unmarked_text, expected_selections) = marked_text_ranges(marked_text, true);
|
||||||
&text,
|
|
||||||
vec!['|'.into(), ('[', '}').into(), ('{', ']').into()],
|
|
||||||
);
|
|
||||||
let buffer_text = self.buffer_text();
|
let buffer_text = self.buffer_text();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
buffer_text, unmarked_text,
|
buffer_text, unmarked_text,
|
||||||
"Unmarked text doesn't match buffer text"
|
"Unmarked text doesn't match buffer text"
|
||||||
);
|
);
|
||||||
|
self.assert_selections(expected_selections, marked_text.to_string())
|
||||||
let expected_empty_selections = selection_ranges.remove(&'|'.into()).unwrap_or_default();
|
|
||||||
let expected_reverse_selections = selection_ranges
|
|
||||||
.remove(&('{', ']').into())
|
|
||||||
.unwrap_or_default();
|
|
||||||
let expected_forward_selections = selection_ranges
|
|
||||||
.remove(&('[', '}').into())
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
self.assert_selections(
|
|
||||||
expected_empty_selections,
|
|
||||||
expected_reverse_selections,
|
|
||||||
expected_forward_selections,
|
|
||||||
Some(text.to_string()),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_editor_background_highlights<Tag: 'static>(&mut self, marked_text: &str) {
|
pub fn assert_editor_background_highlights<Tag: 'static>(&mut self, marked_text: &str) {
|
||||||
let (unmarked, mut ranges) = marked_text_ranges_by(marked_text, vec![('[', ']').into()]);
|
let expected_ranges = self.ranges(marked_text);
|
||||||
assert_eq!(unmarked, self.buffer_text());
|
|
||||||
|
|
||||||
let asserted_ranges = ranges.remove(&('[', ']').into()).unwrap();
|
|
||||||
let actual_ranges: Vec<Range<usize>> = self.update_editor(|editor, cx| {
|
let actual_ranges: Vec<Range<usize>> = self.update_editor(|editor, cx| {
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
editor
|
editor
|
||||||
|
@ -289,176 +246,62 @@ impl<'a> EditorTestContext<'a> {
|
||||||
.map(|range| range.to_offset(&snapshot.buffer_snapshot))
|
.map(|range| range.to_offset(&snapshot.buffer_snapshot))
|
||||||
.collect()
|
.collect()
|
||||||
});
|
});
|
||||||
|
assert_set_eq!(actual_ranges, expected_ranges);
|
||||||
assert_set_eq!(asserted_ranges, actual_ranges);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_editor_text_highlights<Tag: ?Sized + 'static>(&mut self, marked_text: &str) {
|
pub fn assert_editor_text_highlights<Tag: ?Sized + 'static>(&mut self, marked_text: &str) {
|
||||||
let (unmarked, mut ranges) = marked_text_ranges_by(marked_text, vec![('[', ']').into()]);
|
let expected_ranges = self.ranges(marked_text);
|
||||||
assert_eq!(unmarked, self.buffer_text());
|
|
||||||
|
|
||||||
let asserted_ranges = ranges.remove(&('[', ']').into()).unwrap();
|
|
||||||
let snapshot = self.update_editor(|editor, cx| editor.snapshot(cx));
|
let snapshot = self.update_editor(|editor, cx| editor.snapshot(cx));
|
||||||
let actual_ranges: Vec<Range<usize>> = snapshot
|
let actual_ranges: Vec<Range<usize>> = snapshot
|
||||||
.display_snapshot
|
|
||||||
.highlight_ranges::<Tag>()
|
.highlight_ranges::<Tag>()
|
||||||
.map(|ranges| ranges.as_ref().clone().1)
|
.map(|ranges| ranges.as_ref().clone().1)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|range| range.to_offset(&snapshot.buffer_snapshot))
|
.map(|range| range.to_offset(&snapshot.buffer_snapshot))
|
||||||
.collect();
|
.collect();
|
||||||
|
assert_set_eq!(actual_ranges, expected_ranges);
|
||||||
assert_set_eq!(asserted_ranges, actual_ranges);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_editor_selections(&mut self, expected_selections: Vec<Selection<usize>>) {
|
pub fn assert_editor_selections(&mut self, expected_selections: Vec<Range<usize>>) {
|
||||||
let mut empty_selections = Vec::new();
|
let expected_marked_text =
|
||||||
let mut reverse_selections = Vec::new();
|
generate_marked_text(&self.buffer_text(), &expected_selections, true);
|
||||||
let mut forward_selections = Vec::new();
|
self.assert_selections(expected_selections, expected_marked_text)
|
||||||
|
|
||||||
for selection in expected_selections {
|
|
||||||
let range = selection.range();
|
|
||||||
if selection.is_empty() {
|
|
||||||
empty_selections.push(range);
|
|
||||||
} else if selection.reversed {
|
|
||||||
reverse_selections.push(range);
|
|
||||||
} else {
|
|
||||||
forward_selections.push(range)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.assert_selections(
|
|
||||||
empty_selections,
|
|
||||||
reverse_selections,
|
|
||||||
forward_selections,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_selections(
|
fn assert_selections(
|
||||||
&mut self,
|
&mut self,
|
||||||
expected_empty_selections: Vec<Range<usize>>,
|
expected_selections: Vec<Range<usize>>,
|
||||||
expected_reverse_selections: Vec<Range<usize>>,
|
expected_marked_text: String,
|
||||||
expected_forward_selections: Vec<Range<usize>>,
|
|
||||||
asserted_text: Option<String>,
|
|
||||||
) {
|
) {
|
||||||
let (empty_selections, reverse_selections, forward_selections) =
|
let actual_selections = self
|
||||||
self.editor.read_with(self.cx, |editor, cx| {
|
.editor
|
||||||
let mut empty_selections = Vec::new();
|
.read_with(self.cx, |editor, cx| editor.selections.all::<usize>(cx))
|
||||||
let mut reverse_selections = Vec::new();
|
.into_iter()
|
||||||
let mut forward_selections = Vec::new();
|
.map(|s| {
|
||||||
|
if s.reversed {
|
||||||
for selection in editor.selections.all::<usize>(cx) {
|
s.end..s.start
|
||||||
let range = selection.range();
|
} else {
|
||||||
if selection.is_empty() {
|
s.start..s.end
|
||||||
empty_selections.push(range);
|
|
||||||
} else if selection.reversed {
|
|
||||||
reverse_selections.push(range);
|
|
||||||
} else {
|
|
||||||
forward_selections.push(range)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let actual_marked_text =
|
||||||
|
generate_marked_text(&self.buffer_text(), &actual_selections, true);
|
||||||
|
if expected_selections != actual_selections {
|
||||||
|
panic!(
|
||||||
|
indoc! {"
|
||||||
|
Editor has unexpected selections.
|
||||||
|
|
||||||
(empty_selections, reverse_selections, forward_selections)
|
Expected selections:
|
||||||
});
|
{}
|
||||||
|
|
||||||
let asserted_selections = asserted_text.unwrap_or_else(|| {
|
Actual selections:
|
||||||
self.insert_markers(
|
{}
|
||||||
&expected_empty_selections,
|
"},
|
||||||
&expected_reverse_selections,
|
expected_marked_text, actual_marked_text,
|
||||||
&expected_forward_selections,
|
);
|
||||||
)
|
|
||||||
});
|
|
||||||
let actual_selections =
|
|
||||||
self.insert_markers(&empty_selections, &reverse_selections, &forward_selections);
|
|
||||||
|
|
||||||
let unmarked_text = self.buffer_text();
|
|
||||||
let all_eq: Result<(), SetEqError<String>> =
|
|
||||||
set_eq!(expected_empty_selections, empty_selections)
|
|
||||||
.map_err(|err| {
|
|
||||||
err.map(|missing| {
|
|
||||||
let mut error_text = unmarked_text.clone();
|
|
||||||
error_text.insert(missing.start, '|');
|
|
||||||
error_text
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.and_then(|_| {
|
|
||||||
set_eq!(expected_reverse_selections, reverse_selections).map_err(|err| {
|
|
||||||
err.map(|missing| {
|
|
||||||
let mut error_text = unmarked_text.clone();
|
|
||||||
error_text.insert(missing.start, '{');
|
|
||||||
error_text.insert(missing.end, ']');
|
|
||||||
error_text
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.and_then(|_| {
|
|
||||||
set_eq!(expected_forward_selections, forward_selections).map_err(|err| {
|
|
||||||
err.map(|missing| {
|
|
||||||
let mut error_text = unmarked_text.clone();
|
|
||||||
error_text.insert(missing.start, '[');
|
|
||||||
error_text.insert(missing.end, '}');
|
|
||||||
error_text
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
match all_eq {
|
|
||||||
Err(SetEqError::LeftMissing(location_text)) => {
|
|
||||||
panic!(
|
|
||||||
indoc! {"
|
|
||||||
Editor has extra selection
|
|
||||||
Extra Selection Location:
|
|
||||||
{}
|
|
||||||
Asserted selections:
|
|
||||||
{}
|
|
||||||
Actual selections:
|
|
||||||
{}"},
|
|
||||||
location_text, asserted_selections, actual_selections,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(SetEqError::RightMissing(location_text)) => {
|
|
||||||
panic!(
|
|
||||||
indoc! {"
|
|
||||||
Editor is missing empty selection
|
|
||||||
Missing Selection Location:
|
|
||||||
{}
|
|
||||||
Asserted selections:
|
|
||||||
{}
|
|
||||||
Actual selections:
|
|
||||||
{}"},
|
|
||||||
location_text, asserted_selections, actual_selections,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_markers(
|
|
||||||
&mut self,
|
|
||||||
empty_selections: &Vec<Range<usize>>,
|
|
||||||
reverse_selections: &Vec<Range<usize>>,
|
|
||||||
forward_selections: &Vec<Range<usize>>,
|
|
||||||
) -> String {
|
|
||||||
let mut editor_text_with_selections = self.buffer_text();
|
|
||||||
let mut selection_marks = BTreeMap::new();
|
|
||||||
for range in empty_selections {
|
|
||||||
selection_marks.insert(&range.start, '|');
|
|
||||||
}
|
|
||||||
for range in reverse_selections {
|
|
||||||
selection_marks.insert(&range.start, '{');
|
|
||||||
selection_marks.insert(&range.end, ']');
|
|
||||||
}
|
|
||||||
for range in forward_selections {
|
|
||||||
selection_marks.insert(&range.start, '[');
|
|
||||||
selection_marks.insert(&range.end, '}');
|
|
||||||
}
|
|
||||||
for (offset, mark) in selection_marks.into_iter().rev() {
|
|
||||||
editor_text_with_selections.insert(*offset, mark);
|
|
||||||
}
|
|
||||||
|
|
||||||
editor_text_with_selections
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Deref for EditorTestContext<'a> {
|
impl<'a> Deref for EditorTestContext<'a> {
|
||||||
|
@ -575,10 +418,8 @@ impl<'a> EditorLspTestContext<'a> {
|
||||||
|
|
||||||
// Constructs lsp range using a marked string with '[', ']' range delimiters
|
// Constructs lsp range using a marked string with '[', ']' range delimiters
|
||||||
pub fn lsp_range(&mut self, marked_text: &str) -> lsp::Range {
|
pub fn lsp_range(&mut self, marked_text: &str) -> lsp::Range {
|
||||||
let (unmarked, mut ranges) = marked_text_ranges_by(marked_text, vec![('[', ']').into()]);
|
let ranges = self.ranges(marked_text);
|
||||||
assert_eq!(unmarked, self.buffer_text());
|
self.to_lsp_range(ranges[0].clone())
|
||||||
let offset_range = ranges.remove(&('[', ']').into()).unwrap()[0].clone();
|
|
||||||
self.to_lsp_range(offset_range)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_lsp_range(&mut self, range: Range<usize>) -> lsp::Range {
|
pub fn to_lsp_range(&mut self, range: Range<usize>) -> lsp::Range {
|
||||||
|
|
|
@ -15,6 +15,9 @@ futures = "0.3"
|
||||||
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
|
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
|
||||||
rand = { version = "0.8", optional = true }
|
rand = { version = "0.8", optional = true }
|
||||||
tempdir = { version = "0.3.7", optional = true }
|
tempdir = { version = "0.3.7", optional = true }
|
||||||
serde_json = { version = "1.0", features = [
|
serde_json = { version = "1.0", features = ["preserve_order"], optional = true }
|
||||||
"preserve_order",
|
|
||||||
], optional = true }
|
[dev-dependencies]
|
||||||
|
rand = { version = "0.8" }
|
||||||
|
tempdir = { version = "0.3.7" }
|
||||||
|
serde_json = { version = "1.0", features = ["preserve_order"] }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#[cfg(feature = "test-support")]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub mod test;
|
pub mod test;
|
||||||
|
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use std::{collections::HashMap, ops::Range};
|
use std::{cmp::Ordering, collections::HashMap, ops::Range};
|
||||||
|
|
||||||
pub fn marked_text_by(
|
/// Construct a string and a list of offsets within that string using a single
|
||||||
|
/// string containing embedded position markers.
|
||||||
|
pub fn marked_text_offsets_by(
|
||||||
marked_text: &str,
|
marked_text: &str,
|
||||||
markers: Vec<char>,
|
markers: Vec<char>,
|
||||||
) -> (String, HashMap<char, Vec<usize>>) {
|
) -> (String, HashMap<char, Vec<usize>>) {
|
||||||
|
@ -19,9 +21,196 @@ pub fn marked_text_by(
|
||||||
(unmarked_text, extracted_markers)
|
(unmarked_text, extracted_markers)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn marked_text(marked_text: &str) -> (String, Vec<usize>) {
|
/// Construct a string and a list of ranges within that string using a single
|
||||||
let (unmarked_text, mut markers) = marked_text_by(marked_text, vec!['|']);
|
/// string containing embedded range markers, using arbitrary characters as
|
||||||
(unmarked_text, markers.remove(&'|').unwrap_or_default())
|
/// range markers. By using multiple different range markers, you can construct
|
||||||
|
/// ranges that overlap each other.
|
||||||
|
///
|
||||||
|
/// The returned ranges will be grouped by their range marking characters.
|
||||||
|
pub fn marked_text_ranges_by(
|
||||||
|
marked_text: &str,
|
||||||
|
markers: Vec<TextRangeMarker>,
|
||||||
|
) -> (String, HashMap<TextRangeMarker, Vec<Range<usize>>>) {
|
||||||
|
let all_markers = markers.iter().flat_map(|m| m.markers()).collect();
|
||||||
|
|
||||||
|
let (unmarked_text, mut marker_offsets) = marked_text_offsets_by(marked_text, all_markers);
|
||||||
|
let range_lookup = markers
|
||||||
|
.into_iter()
|
||||||
|
.map(|marker| {
|
||||||
|
(
|
||||||
|
marker.clone(),
|
||||||
|
match marker {
|
||||||
|
TextRangeMarker::Empty(empty_marker_char) => marker_offsets
|
||||||
|
.remove(&empty_marker_char)
|
||||||
|
.unwrap_or_default()
|
||||||
|
.into_iter()
|
||||||
|
.map(|empty_index| empty_index..empty_index)
|
||||||
|
.collect::<Vec<Range<usize>>>(),
|
||||||
|
TextRangeMarker::Range(start_marker, end_marker) => {
|
||||||
|
let starts = marker_offsets.remove(&start_marker).unwrap_or_default();
|
||||||
|
let ends = marker_offsets.remove(&end_marker).unwrap_or_default();
|
||||||
|
assert_eq!(starts.len(), ends.len(), "marked ranges are unbalanced");
|
||||||
|
starts
|
||||||
|
.into_iter()
|
||||||
|
.zip(ends)
|
||||||
|
.map(|(start, end)| {
|
||||||
|
assert!(end >= start, "marked ranges must be disjoint");
|
||||||
|
start..end
|
||||||
|
})
|
||||||
|
.collect::<Vec<Range<usize>>>()
|
||||||
|
}
|
||||||
|
TextRangeMarker::ReverseRange(start_marker, end_marker) => {
|
||||||
|
let starts = marker_offsets.remove(&start_marker).unwrap_or_default();
|
||||||
|
let ends = marker_offsets.remove(&end_marker).unwrap_or_default();
|
||||||
|
assert_eq!(starts.len(), ends.len(), "marked ranges are unbalanced");
|
||||||
|
starts
|
||||||
|
.into_iter()
|
||||||
|
.zip(ends)
|
||||||
|
.map(|(start, end)| {
|
||||||
|
assert!(end >= start, "marked ranges must be disjoint");
|
||||||
|
end..start
|
||||||
|
})
|
||||||
|
.collect::<Vec<Range<usize>>>()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
(unmarked_text, range_lookup)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a string and a list of ranges within that string using a single
|
||||||
|
/// string containing embedded range markers. The characters used to mark the
|
||||||
|
/// ranges are as follows:
|
||||||
|
///
|
||||||
|
/// 1. To mark a range of text, surround it with the `«` and `»` angle brackets,
|
||||||
|
/// which can be typed on a US keyboard with the `alt-|` and `alt-shift-|` keys.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// foo «selected text» bar
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 2. To mark a single position in the text, use the `ˇ` caron,
|
||||||
|
/// which can be typed on a US keyboard with the `alt-shift-t` key.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// the cursors are hereˇ and hereˇ.
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// 3. To mark a range whose direction is meaningful (like a selection),
|
||||||
|
/// put a caron character beside one of its bounds, on the inside:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// one «ˇreversed» selection and one «forwardˇ» selection
|
||||||
|
/// ```
|
||||||
|
pub fn marked_text_ranges(
|
||||||
|
marked_text: &str,
|
||||||
|
ranges_are_directed: bool,
|
||||||
|
) -> (String, Vec<Range<usize>>) {
|
||||||
|
let mut unmarked_text = String::with_capacity(marked_text.len());
|
||||||
|
let mut ranges = Vec::new();
|
||||||
|
let mut prev_marked_ix = 0;
|
||||||
|
let mut current_range_start = None;
|
||||||
|
let mut current_range_cursor = None;
|
||||||
|
|
||||||
|
for (marked_ix, marker) in marked_text.match_indices(&['«', '»', 'ˇ']) {
|
||||||
|
unmarked_text.push_str(&marked_text[prev_marked_ix..marked_ix]);
|
||||||
|
let unmarked_len = unmarked_text.len();
|
||||||
|
let len = marker.len();
|
||||||
|
prev_marked_ix = marked_ix + len;
|
||||||
|
|
||||||
|
match marker {
|
||||||
|
"ˇ" => {
|
||||||
|
if current_range_start.is_some() {
|
||||||
|
if current_range_cursor.is_some() {
|
||||||
|
panic!("duplicate point marker 'ˇ' at index {marked_ix}");
|
||||||
|
} else {
|
||||||
|
current_range_cursor = Some(unmarked_len);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ranges.push(unmarked_len..unmarked_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"«" => {
|
||||||
|
if current_range_start.is_some() {
|
||||||
|
panic!("unexpected range start marker '«' at index {marked_ix}");
|
||||||
|
}
|
||||||
|
current_range_start = Some(unmarked_len);
|
||||||
|
}
|
||||||
|
"»" => {
|
||||||
|
let current_range_start = if let Some(start) = current_range_start.take() {
|
||||||
|
start
|
||||||
|
} else {
|
||||||
|
panic!("unexpected range end marker '»' at index {marked_ix}");
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut reversed = false;
|
||||||
|
if let Some(current_range_cursor) = current_range_cursor.take() {
|
||||||
|
if current_range_cursor == current_range_start {
|
||||||
|
reversed = true;
|
||||||
|
} else if current_range_cursor != unmarked_len {
|
||||||
|
panic!("unexpected 'ˇ' marker in the middle of a range");
|
||||||
|
}
|
||||||
|
} else if ranges_are_directed {
|
||||||
|
panic!("missing 'ˇ' marker to indicate range direction");
|
||||||
|
}
|
||||||
|
|
||||||
|
ranges.push(if reversed {
|
||||||
|
unmarked_len..current_range_start
|
||||||
|
} else {
|
||||||
|
current_range_start..unmarked_len
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unmarked_text.push_str(&marked_text[prev_marked_ix..]);
|
||||||
|
(unmarked_text, ranges)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn marked_text_offsets(marked_text: &str) -> (String, Vec<usize>) {
|
||||||
|
let (text, ranges) = marked_text_ranges(marked_text, false);
|
||||||
|
(
|
||||||
|
text,
|
||||||
|
ranges
|
||||||
|
.into_iter()
|
||||||
|
.map(|range| {
|
||||||
|
assert_eq!(range.start, range.end);
|
||||||
|
range.start
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_marked_text(
|
||||||
|
unmarked_text: &str,
|
||||||
|
ranges: &[Range<usize>],
|
||||||
|
indicate_cursors: bool,
|
||||||
|
) -> String {
|
||||||
|
let mut marked_text = unmarked_text.to_string();
|
||||||
|
for range in ranges.iter().rev() {
|
||||||
|
if indicate_cursors {
|
||||||
|
match range.start.cmp(&range.end) {
|
||||||
|
Ordering::Less => {
|
||||||
|
marked_text.insert_str(range.end, "ˇ»");
|
||||||
|
marked_text.insert_str(range.start, "«");
|
||||||
|
}
|
||||||
|
Ordering::Equal => {
|
||||||
|
marked_text.insert_str(range.start, "ˇ");
|
||||||
|
}
|
||||||
|
Ordering::Greater => {
|
||||||
|
marked_text.insert_str(range.start, "»");
|
||||||
|
marked_text.insert_str(range.end, "«ˇ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
marked_text.insert_str(range.end, "»");
|
||||||
|
marked_text.insert_str(range.start, "«");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
marked_text
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||||
|
@ -53,75 +242,24 @@ impl From<(char, char)> for TextRangeMarker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn marked_text_ranges_by(
|
#[cfg(test)]
|
||||||
marked_text: &str,
|
mod tests {
|
||||||
markers: Vec<TextRangeMarker>,
|
use super::{generate_marked_text, marked_text_ranges};
|
||||||
) -> (String, HashMap<TextRangeMarker, Vec<Range<usize>>>) {
|
|
||||||
let all_markers = markers.iter().flat_map(|m| m.markers()).collect();
|
|
||||||
|
|
||||||
let (unmarked_text, mut marker_offsets) = marked_text_by(marked_text, all_markers);
|
#[test]
|
||||||
let range_lookup = markers
|
fn test_marked_text() {
|
||||||
.into_iter()
|
let (text, ranges) = marked_text_ranges("one «ˇtwo» «threeˇ» «ˇfour» fiveˇ six", true);
|
||||||
.map(|marker| match marker {
|
|
||||||
TextRangeMarker::Empty(empty_marker_char) => {
|
|
||||||
let ranges = marker_offsets
|
|
||||||
.remove(&empty_marker_char)
|
|
||||||
.unwrap_or_default()
|
|
||||||
.into_iter()
|
|
||||||
.map(|empty_index| empty_index..empty_index)
|
|
||||||
.collect::<Vec<Range<usize>>>();
|
|
||||||
(marker, ranges)
|
|
||||||
}
|
|
||||||
TextRangeMarker::Range(start_marker, end_marker) => {
|
|
||||||
let starts = marker_offsets.remove(&start_marker).unwrap_or_default();
|
|
||||||
let ends = marker_offsets.remove(&end_marker).unwrap_or_default();
|
|
||||||
assert_eq!(starts.len(), ends.len(), "marked ranges are unbalanced");
|
|
||||||
|
|
||||||
let ranges = starts
|
assert_eq!(text, "one two three four five six");
|
||||||
.into_iter()
|
assert_eq!(ranges.len(), 4);
|
||||||
.zip(ends)
|
assert_eq!(ranges[0], 7..4);
|
||||||
.map(|(start, end)| {
|
assert_eq!(ranges[1], 8..13);
|
||||||
assert!(end >= start, "marked ranges must be disjoint");
|
assert_eq!(ranges[2], 18..14);
|
||||||
start..end
|
assert_eq!(ranges[3], 23..23);
|
||||||
})
|
|
||||||
.collect::<Vec<Range<usize>>>();
|
|
||||||
(marker, ranges)
|
|
||||||
}
|
|
||||||
TextRangeMarker::ReverseRange(start_marker, end_marker) => {
|
|
||||||
let starts = marker_offsets.remove(&start_marker).unwrap_or_default();
|
|
||||||
let ends = marker_offsets.remove(&end_marker).unwrap_or_default();
|
|
||||||
assert_eq!(starts.len(), ends.len(), "marked ranges are unbalanced");
|
|
||||||
|
|
||||||
let ranges = starts
|
assert_eq!(
|
||||||
.into_iter()
|
generate_marked_text(&text, &ranges, true),
|
||||||
.zip(ends)
|
"one «ˇtwo» «threeˇ» «ˇfour» fiveˇ six"
|
||||||
.map(|(start, end)| {
|
);
|
||||||
assert!(end >= start, "marked ranges must be disjoint");
|
}
|
||||||
end..start
|
|
||||||
})
|
|
||||||
.collect::<Vec<Range<usize>>>();
|
|
||||||
(marker, ranges)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
(unmarked_text, range_lookup)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns ranges delimited by (), [], and <> ranges. Ranges using the same markers
|
|
||||||
// must not be overlapping. May also include | for empty ranges
|
|
||||||
pub fn marked_text_ranges(full_marked_text: &str) -> (String, Vec<Range<usize>>) {
|
|
||||||
let (unmarked, range_lookup) = marked_text_ranges_by(
|
|
||||||
&full_marked_text,
|
|
||||||
vec![
|
|
||||||
'|'.into(),
|
|
||||||
('[', ']').into(),
|
|
||||||
('(', ')').into(),
|
|
||||||
('<', '>').into(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
let mut combined_ranges: Vec<_> = range_lookup.into_values().flatten().collect();
|
|
||||||
|
|
||||||
combined_ranges.sort_by_key(|range| range.start);
|
|
||||||
(unmarked, combined_ranges)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,9 +34,9 @@ mod test {
|
||||||
cx.simulate_keystroke("i");
|
cx.simulate_keystroke("i");
|
||||||
assert_eq!(cx.mode(), Mode::Insert);
|
assert_eq!(cx.mode(), Mode::Insert);
|
||||||
cx.simulate_keystrokes(["T", "e", "s", "t"]);
|
cx.simulate_keystrokes(["T", "e", "s", "t"]);
|
||||||
cx.assert_editor_state("Test|");
|
cx.assert_editor_state("Testˇ");
|
||||||
cx.simulate_keystroke("escape");
|
cx.simulate_keystroke("escape");
|
||||||
assert_eq!(cx.mode(), Mode::Normal);
|
assert_eq!(cx.mode(), Mode::Normal);
|
||||||
cx.assert_editor_state("Tes|t");
|
cx.assert_editor_state("Tesˇt");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,8 +297,7 @@ fn paste(_: &mut Workspace, _: &Paste, cx: &mut ViewContext<Workspace>) {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use indoc::indoc;
|
use indoc::indoc;
|
||||||
use language::Selection;
|
use util::test::marked_text_offsets;
|
||||||
use util::test::marked_text;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
state::{
|
state::{
|
||||||
|
@ -312,15 +311,15 @@ mod test {
|
||||||
async fn test_h(cx: &mut gpui::TestAppContext) {
|
async fn test_h(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["h"]);
|
let mut cx = cx.binding(["h"]);
|
||||||
cx.assert("The q|uick", "The |quick");
|
cx.assert("The qˇuick", "The ˇquick");
|
||||||
cx.assert("|The quick", "|The quick");
|
cx.assert("ˇThe quick", "ˇThe quick");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown"},
|
ˇbrown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown"},
|
ˇbrown"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,15 +327,15 @@ mod test {
|
||||||
async fn test_backspace(cx: &mut gpui::TestAppContext) {
|
async fn test_backspace(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["backspace"]);
|
let mut cx = cx.binding(["backspace"]);
|
||||||
cx.assert("The q|uick", "The |quick");
|
cx.assert("The qˇuick", "The ˇquick");
|
||||||
cx.assert("|The quick", "|The quick");
|
cx.assert("ˇThe quick", "ˇThe quick");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown"},
|
ˇbrown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown"},
|
ˇbrown"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,35 +345,35 @@ mod test {
|
||||||
let mut cx = cx.binding(["j"]);
|
let mut cx = cx.binding(["j"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick
|
The ˇquick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brow|n fox"},
|
browˇn fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brow|n fox"},
|
browˇn fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brow|n fox"},
|
browˇn fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quic|k
|
The quicˇk
|
||||||
brown"},
|
brown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brow|n"},
|
browˇn"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown"},
|
ˇbrown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown"},
|
ˇbrown"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,26 +383,26 @@ mod test {
|
||||||
let mut cx = cx.binding(["k"]);
|
let mut cx = cx.binding(["k"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick
|
The ˇquick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick
|
The ˇquick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brow|n fox"},
|
browˇn fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick
|
The ˇquick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The
|
The
|
||||||
quic|k"},
|
quicˇk"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Th|e
|
Thˇe
|
||||||
quick"},
|
quick"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -412,14 +411,14 @@ mod test {
|
||||||
async fn test_l(cx: &mut gpui::TestAppContext) {
|
async fn test_l(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["l"]);
|
let mut cx = cx.binding(["l"]);
|
||||||
cx.assert("The q|uick", "The qu|ick");
|
cx.assert("The qˇuick", "The quˇick");
|
||||||
cx.assert("The quic|k", "The quic|k");
|
cx.assert("The quicˇk", "The quicˇk");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quic|k
|
The quicˇk
|
||||||
brown"},
|
brown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quic|k
|
The quicˇk
|
||||||
brown"},
|
brown"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -428,42 +427,42 @@ mod test {
|
||||||
async fn test_jump_to_line_boundaries(cx: &mut gpui::TestAppContext) {
|
async fn test_jump_to_line_boundaries(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["$"]);
|
let mut cx = cx.binding(["$"]);
|
||||||
cx.assert("T|est test", "Test tes|t");
|
cx.assert("Tˇest test", "Test tesˇt");
|
||||||
cx.assert("Test tes|t", "Test tes|t");
|
cx.assert("Test tesˇt", "Test tesˇt");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick
|
The ˇquick
|
||||||
brown"},
|
brown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quic|k
|
The quicˇk
|
||||||
brown"},
|
brown"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quic|k
|
The quicˇk
|
||||||
brown"},
|
brown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quic|k
|
The quicˇk
|
||||||
brown"},
|
brown"},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cx = cx.binding(["0"]);
|
let mut cx = cx.binding(["0"]);
|
||||||
cx.assert("Test |test", "|Test test");
|
cx.assert("Test ˇtest", "ˇTest test");
|
||||||
cx.assert("|Test test", "|Test test");
|
cx.assert("ˇTest test", "ˇTest test");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick
|
The ˇquick
|
||||||
brown"},
|
brown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick
|
ˇThe quick
|
||||||
brown"},
|
brown"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick
|
ˇThe quick
|
||||||
brown"},
|
brown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick
|
ˇThe quick
|
||||||
brown"},
|
brown"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -475,7 +474,7 @@ mod test {
|
||||||
|
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick
|
The ˇquick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the lazy dog"},
|
over the lazy dog"},
|
||||||
|
@ -483,54 +482,54 @@ mod test {
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over| the lazy dog"},
|
overˇ the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over| the lazy dog"},
|
overˇ the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over| the lazy dog"},
|
overˇ the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The qui|ck
|
The quiˇck
|
||||||
|
|
||||||
brown"},
|
brown"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
brow|n"},
|
browˇn"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The qui|ck
|
The quiˇck
|
||||||
|
|
||||||
"},
|
"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_w(cx: &mut gpui::TestAppContext) {
|
async fn test_w(cx: &mut gpui::TestAppContext) {
|
||||||
let mut cx = VimTestContext::new(cx, true).await;
|
let mut cx = VimTestContext::new(cx, true).await;
|
||||||
let (_, cursor_offsets) = marked_text(indoc! {"
|
let (_, cursor_offsets) = marked_text_offsets(indoc! {"
|
||||||
The |quick|-|brown
|
The ˇquickˇ-ˇbrown
|
||||||
|
|
ˇ
|
||||||
|
|
ˇ
|
||||||
|fox_jumps |over
|
ˇfox_jumps ˇover
|
||||||
|th||e"});
|
ˇthˇˇe"});
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick-brown
|
ˇThe quick-brown
|
||||||
|
|
||||||
|
|
||||||
fox_jumps over
|
fox_jumps over
|
||||||
|
@ -540,19 +539,19 @@ mod test {
|
||||||
|
|
||||||
for cursor_offset in cursor_offsets {
|
for cursor_offset in cursor_offsets {
|
||||||
cx.simulate_keystroke("w");
|
cx.simulate_keystroke("w");
|
||||||
cx.assert_editor_selections(vec![Selection::from_offset(cursor_offset)]);
|
cx.assert_editor_selections(vec![cursor_offset..cursor_offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset and test ignoring punctuation
|
// Reset and test ignoring punctuation
|
||||||
let (_, cursor_offsets) = marked_text(indoc! {"
|
let (_, cursor_offsets) = marked_text_offsets(indoc! {"
|
||||||
The |quick-brown
|
The ˇquick-brown
|
||||||
|
|
ˇ
|
||||||
|
|
ˇ
|
||||||
|fox_jumps |over
|
ˇfox_jumps ˇover
|
||||||
|th||e"});
|
ˇthˇˇe"});
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick-brown
|
ˇThe quick-brown
|
||||||
|
|
||||||
|
|
||||||
fox_jumps over
|
fox_jumps over
|
||||||
|
@ -562,22 +561,22 @@ mod test {
|
||||||
|
|
||||||
for cursor_offset in cursor_offsets {
|
for cursor_offset in cursor_offsets {
|
||||||
cx.simulate_keystroke("shift-w");
|
cx.simulate_keystroke("shift-w");
|
||||||
cx.assert_editor_selections(vec![Selection::from_offset(cursor_offset)]);
|
cx.assert_editor_selections(vec![cursor_offset..cursor_offset]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_e(cx: &mut gpui::TestAppContext) {
|
async fn test_e(cx: &mut gpui::TestAppContext) {
|
||||||
let mut cx = VimTestContext::new(cx, true).await;
|
let mut cx = VimTestContext::new(cx, true).await;
|
||||||
let (_, cursor_offsets) = marked_text(indoc! {"
|
let (_, cursor_offsets) = marked_text_offsets(indoc! {"
|
||||||
Th|e quic|k|-brow|n
|
Thˇe quicˇkˇ-browˇn
|
||||||
|
|
||||||
|
|
||||||
fox_jump|s ove|r
|
fox_jumpˇs oveˇr
|
||||||
th|e"});
|
thˇe"});
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick-brown
|
ˇThe quick-brown
|
||||||
|
|
||||||
|
|
||||||
fox_jumps over
|
fox_jumps over
|
||||||
|
@ -587,19 +586,19 @@ mod test {
|
||||||
|
|
||||||
for cursor_offset in cursor_offsets {
|
for cursor_offset in cursor_offsets {
|
||||||
cx.simulate_keystroke("e");
|
cx.simulate_keystroke("e");
|
||||||
cx.assert_editor_selections(vec![Selection::from_offset(cursor_offset)]);
|
cx.assert_editor_selections(vec![cursor_offset..cursor_offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset and test ignoring punctuation
|
// Reset and test ignoring punctuation
|
||||||
let (_, cursor_offsets) = marked_text(indoc! {"
|
let (_, cursor_offsets) = marked_text_offsets(indoc! {"
|
||||||
Th|e quick-brow|n
|
Thˇe quick-browˇn
|
||||||
|
|
||||||
|
|
||||||
fox_jump|s ove|r
|
fox_jumpˇs oveˇr
|
||||||
th||e"});
|
thˇˇe"});
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick-brown
|
ˇThe quick-brown
|
||||||
|
|
||||||
|
|
||||||
fox_jumps over
|
fox_jumps over
|
||||||
|
@ -608,53 +607,53 @@ mod test {
|
||||||
);
|
);
|
||||||
for cursor_offset in cursor_offsets {
|
for cursor_offset in cursor_offsets {
|
||||||
cx.simulate_keystroke("shift-e");
|
cx.simulate_keystroke("shift-e");
|
||||||
cx.assert_editor_selections(vec![Selection::from_offset(cursor_offset)]);
|
cx.assert_editor_selections(vec![cursor_offset..cursor_offset]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_b(cx: &mut gpui::TestAppContext) {
|
async fn test_b(cx: &mut gpui::TestAppContext) {
|
||||||
let mut cx = VimTestContext::new(cx, true).await;
|
let mut cx = VimTestContext::new(cx, true).await;
|
||||||
let (_, cursor_offsets) = marked_text(indoc! {"
|
let (_, cursor_offsets) = marked_text_offsets(indoc! {"
|
||||||
||The |quick|-|brown
|
ˇˇThe ˇquickˇ-ˇbrown
|
||||||
|
|
ˇ
|
||||||
|
|
ˇ
|
||||||
|fox_jumps |over
|
ˇfox_jumps ˇover
|
||||||
|the"});
|
ˇthe"});
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick-brown
|
The quick-brown
|
||||||
|
|
||||||
|
|
||||||
fox_jumps over
|
fox_jumps over
|
||||||
th|e"},
|
thˇe"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
|
||||||
for cursor_offset in cursor_offsets.into_iter().rev() {
|
for cursor_offset in cursor_offsets.into_iter().rev() {
|
||||||
cx.simulate_keystroke("b");
|
cx.simulate_keystroke("b");
|
||||||
cx.assert_editor_selections(vec![Selection::from_offset(cursor_offset)]);
|
cx.assert_editor_selections(vec![cursor_offset..cursor_offset]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset and test ignoring punctuation
|
// Reset and test ignoring punctuation
|
||||||
let (_, cursor_offsets) = marked_text(indoc! {"
|
let (_, cursor_offsets) = marked_text_offsets(indoc! {"
|
||||||
||The |quick-brown
|
ˇˇThe ˇquick-brown
|
||||||
|
|
ˇ
|
||||||
|
|
ˇ
|
||||||
|fox_jumps |over
|
ˇfox_jumps ˇover
|
||||||
|the"});
|
ˇthe"});
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick-brown
|
The quick-brown
|
||||||
|
|
||||||
|
|
||||||
fox_jumps over
|
fox_jumps over
|
||||||
th|e"},
|
thˇe"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
for cursor_offset in cursor_offsets.into_iter().rev() {
|
for cursor_offset in cursor_offsets.into_iter().rev() {
|
||||||
cx.simulate_keystroke("shift-b");
|
cx.simulate_keystroke("shift-b");
|
||||||
cx.assert_editor_selections(vec![Selection::from_offset(cursor_offset)]);
|
cx.assert_editor_selections(vec![cursor_offset..cursor_offset]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,21 +682,21 @@ mod test {
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over |the lazy dog"},
|
over ˇthe lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the lazy dog"},
|
over the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the lazy dog"},
|
over the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the lazy dog"},
|
over the lazy dog"},
|
||||||
|
@ -707,9 +706,9 @@ mod test {
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the la|zy dog"},
|
over the laˇzy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quic|k
|
The quicˇk
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the lazy dog"},
|
over the lazy dog"},
|
||||||
|
@ -719,9 +718,9 @@ mod test {
|
||||||
|
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the la|zy dog"},
|
over the laˇzy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
|
|
||||||
brown fox jumps
|
brown fox jumps
|
||||||
over the lazy dog"},
|
over the lazy dog"},
|
||||||
|
@ -733,31 +732,31 @@ mod test {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["a"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["a"]).mode_after(Mode::Insert);
|
||||||
|
|
||||||
cx.assert("The q|uick", "The qu|ick");
|
cx.assert("The qˇuick", "The quˇick");
|
||||||
cx.assert("The quic|k", "The quick|");
|
cx.assert("The quicˇk", "The quickˇ");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_insert_end_of_line(cx: &mut gpui::TestAppContext) {
|
async fn test_insert_end_of_line(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["shift-a"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["shift-a"]).mode_after(Mode::Insert);
|
||||||
cx.assert("The q|uick", "The quick|");
|
cx.assert("The qˇuick", "The quickˇ");
|
||||||
cx.assert("The q|uick ", "The quick |");
|
cx.assert("The qˇuick ", "The quick ˇ");
|
||||||
cx.assert("|", "|");
|
cx.assert("ˇ", "ˇ");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick|
|
The quickˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick"},
|
The quick"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick"},
|
The quick"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -766,50 +765,50 @@ mod test {
|
||||||
async fn test_jump_to_first_non_whitespace(cx: &mut gpui::TestAppContext) {
|
async fn test_jump_to_first_non_whitespace(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["^"]);
|
let mut cx = cx.binding(["^"]);
|
||||||
cx.assert("The q|uick", "|The quick");
|
cx.assert("The qˇuick", "ˇThe quick");
|
||||||
cx.assert(" The q|uick", " |The quick");
|
cx.assert(" The qˇuick", " ˇThe quick");
|
||||||
cx.assert("|", "|");
|
cx.assert("ˇ", "ˇ");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick
|
ˇThe quick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick"},
|
The quick"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick"},
|
The quick"},
|
||||||
);
|
);
|
||||||
// Indoc disallows trailing whitspace.
|
// Indoc disallows trailing whitspace.
|
||||||
cx.assert(" | \nThe quick", " | \nThe quick");
|
cx.assert(" ˇ \nThe quick", " ˇ \nThe quick");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_insert_first_non_whitespace(cx: &mut gpui::TestAppContext) {
|
async fn test_insert_first_non_whitespace(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["shift-i"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["shift-i"]).mode_after(Mode::Insert);
|
||||||
cx.assert("The q|uick", "|The quick");
|
cx.assert("The qˇuick", "ˇThe quick");
|
||||||
cx.assert(" The q|uick", " |The quick");
|
cx.assert(" The qˇuick", " ˇThe quick");
|
||||||
cx.assert("|", "|");
|
cx.assert("ˇ", "ˇ");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick
|
ˇThe quick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick"},
|
The quick"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick"},
|
The quick"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -820,20 +819,20 @@ mod test {
|
||||||
let mut cx = cx.binding(["shift-d"]);
|
let mut cx = cx.binding(["shift-d"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |q
|
The ˇq
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -842,15 +841,15 @@ mod test {
|
||||||
async fn test_x(cx: &mut gpui::TestAppContext) {
|
async fn test_x(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["x"]);
|
let mut cx = cx.binding(["x"]);
|
||||||
cx.assert("|Test", "|est");
|
cx.assert("ˇTest", "ˇest");
|
||||||
cx.assert("Te|st", "Te|t");
|
cx.assert("Teˇst", "Teˇt");
|
||||||
cx.assert("Tes|t", "Te|s");
|
cx.assert("Tesˇt", "Teˇs");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Tes|t
|
Tesˇt
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Te|s
|
Teˇs
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -859,16 +858,16 @@ mod test {
|
||||||
async fn test_delete_left(cx: &mut gpui::TestAppContext) {
|
async fn test_delete_left(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["shift-x"]);
|
let mut cx = cx.binding(["shift-x"]);
|
||||||
cx.assert("Te|st", "T|st");
|
cx.assert("Teˇst", "Tˇst");
|
||||||
cx.assert("T|est", "|est");
|
cx.assert("Tˇest", "ˇest");
|
||||||
cx.assert("|Test", "|Test");
|
cx.assert("ˇTest", "ˇTest");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test
|
Test
|
||||||
|test"},
|
ˇtest"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test
|
Test
|
||||||
|test"},
|
ˇtest"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -878,78 +877,84 @@ mod test {
|
||||||
let mut cx = cx.binding(["o"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["o"]).mode_after(Mode::Insert);
|
||||||
|
|
||||||
cx.assert(
|
cx.assert(
|
||||||
"|",
|
"ˇ",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
"The |quick",
|
"The ˇquick",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|
|
ˇ
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fn test()
|
fn test() {
|
||||||
println!(|);"},
|
println!(ˇ);
|
||||||
|
}
|
||||||
|
"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fn test()
|
fn test() {
|
||||||
println!();
|
println!();
|
||||||
|"},
|
ˇ
|
||||||
|
}
|
||||||
|
"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fn test(|)
|
fn test(ˇ) {
|
||||||
println!();"},
|
println!();
|
||||||
|
}"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fn test()
|
fn test() {
|
||||||
|
|
ˇ
|
||||||
println!();"},
|
println!();
|
||||||
|
}"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,25 +964,25 @@ mod test {
|
||||||
let mut cx = cx.binding(["shift-o"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["shift-o"]).mode_after(Mode::Insert);
|
||||||
|
|
||||||
cx.assert(
|
cx.assert(
|
||||||
"|",
|
"ˇ",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
"},
|
"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
"The |quick",
|
"The ˇquick",
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick"},
|
The quick"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
|
@ -985,20 +990,20 @@ mod test {
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|
|
ˇ
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
|
@ -1006,31 +1011,33 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
|
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fn test()
|
fn test()
|
||||||
println!(|);"},
|
println!(ˇ);"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fn test()
|
fn test()
|
||||||
|
|
ˇ
|
||||||
println!();"},
|
println!();"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fn test(|)
|
fn test(ˇ) {
|
||||||
println!();"},
|
println!();
|
||||||
|
}"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
fn test()
|
fn test() {
|
||||||
println!();"},
|
println!();
|
||||||
|
}"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1039,43 +1046,43 @@ mod test {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["d", "d"]);
|
let mut cx = cx.binding(["d", "d"]);
|
||||||
|
|
||||||
cx.assert("|", "|");
|
cx.assert("ˇ", "ˇ");
|
||||||
cx.assert("The |quick", "|");
|
cx.assert("The ˇquick", "ˇ");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox"},
|
brown ˇfox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown fox"},
|
ˇbrown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1084,46 +1091,46 @@ mod test {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["c", "c"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "c"]).mode_after(Mode::Insert);
|
||||||
|
|
||||||
cx.assert("|", "|");
|
cx.assert("ˇ", "ˇ");
|
||||||
cx.assert("The |quick", "|");
|
cx.assert("The ˇquick", "ˇ");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1134,7 +1141,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
@ -1142,21 +1149,21 @@ mod test {
|
||||||
cx.simulate_keystrokes(["d", "d"]);
|
cx.simulate_keystrokes(["d", "d"]);
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
the la|zy dog"});
|
the laˇzy dog"});
|
||||||
|
|
||||||
cx.simulate_keystroke("p");
|
cx.simulate_keystroke("p");
|
||||||
cx.assert_state(
|
cx.assert_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
the lazy dog
|
the lazy dog
|
||||||
|fox jumps over"},
|
ˇfox jumps over"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox [jump}s over
|
fox «jumpˇ»s over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Visual { line: false },
|
Mode::Visual { line: false },
|
||||||
);
|
);
|
||||||
|
@ -1164,7 +1171,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps ove|r
|
fox jumps oveˇr
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
@ -1172,7 +1179,7 @@ mod test {
|
||||||
cx.assert_state(
|
cx.assert_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over|jumps
|
fox jumps overˇjumps
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
|
|
@ -84,16 +84,16 @@ mod test {
|
||||||
async fn test_change_h(cx: &mut gpui::TestAppContext) {
|
async fn test_change_h(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["c", "h"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "h"]).mode_after(Mode::Insert);
|
||||||
cx.assert("Te|st", "T|st");
|
cx.assert("Teˇst", "Tˇst");
|
||||||
cx.assert("T|est", "|est");
|
cx.assert("Tˇest", "ˇest");
|
||||||
cx.assert("|Test", "|Test");
|
cx.assert("ˇTest", "ˇTest");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test
|
Test
|
||||||
|test"},
|
ˇtest"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test
|
Test
|
||||||
|test"},
|
ˇtest"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,111 +101,111 @@ mod test {
|
||||||
async fn test_change_l(cx: &mut gpui::TestAppContext) {
|
async fn test_change_l(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["c", "l"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "l"]).mode_after(Mode::Insert);
|
||||||
cx.assert("Te|st", "Te|t");
|
cx.assert("Teˇst", "Teˇt");
|
||||||
cx.assert("Tes|t", "Tes|");
|
cx.assert("Tesˇt", "Tesˇ");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_change_w(cx: &mut gpui::TestAppContext) {
|
async fn test_change_w(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["c", "w"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "w"]).mode_after(Mode::Insert);
|
||||||
cx.assert("Te|st", "Te|");
|
cx.assert("Teˇst", "Teˇ");
|
||||||
cx.assert("T|est test", "T| test");
|
cx.assert("Tˇest test", "Tˇ test");
|
||||||
cx.assert("Test| test", "Test|test");
|
cx.assert("Testˇ test", "Testˇtest");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test te|st
|
Test teˇst
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test te|
|
Test teˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test tes|t
|
Test tesˇt
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test tes|
|
Test tesˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cx = cx.binding(["c", "shift-w"]);
|
let mut cx = cx.binding(["c", "shift-w"]);
|
||||||
cx.assert("Test te|st-test test", "Test te| test");
|
cx.assert("Test teˇst-test test", "Test teˇ test");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_change_e(cx: &mut gpui::TestAppContext) {
|
async fn test_change_e(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["c", "e"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "e"]).mode_after(Mode::Insert);
|
||||||
cx.assert("Te|st Test", "Te| Test");
|
cx.assert("Teˇst Test", "Teˇ Test");
|
||||||
cx.assert("T|est test", "T| test");
|
cx.assert("Tˇest test", "Tˇ test");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test te|st
|
Test teˇst
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test te|
|
Test teˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test tes|t
|
Test tesˇt
|
||||||
test"},
|
test"},
|
||||||
"Test tes|",
|
"Test tesˇ",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cx = cx.binding(["c", "shift-e"]);
|
let mut cx = cx.binding(["c", "shift-e"]);
|
||||||
cx.assert("Test te|st-test test", "Test te| test");
|
cx.assert("Test teˇst-test test", "Test teˇ test");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_change_b(cx: &mut gpui::TestAppContext) {
|
async fn test_change_b(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["c", "b"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "b"]).mode_after(Mode::Insert);
|
||||||
cx.assert("Te|st Test", "|st Test");
|
cx.assert("Teˇst Test", "ˇst Test");
|
||||||
cx.assert("Test |test", "|test");
|
cx.assert("Test ˇtest", "ˇtest");
|
||||||
cx.assert("Test1 test2 |test3", "Test1 |test3");
|
cx.assert("Test1 test2 ˇtest3", "Test1 ˇtest3");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|test"},
|
ˇtest"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test |
|
Test ˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test |
|
Test ˇ
|
||||||
|
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cx = cx.binding(["c", "shift-b"]);
|
let mut cx = cx.binding(["c", "shift-b"]);
|
||||||
cx.assert("Test test-test |test", "Test |test");
|
cx.assert("Test test-test ˇtest", "Test ˇtest");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -214,20 +214,20 @@ mod test {
|
||||||
let mut cx = cx.binding(["c", "$"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "$"]).mode_after(Mode::Insert);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|
|
The qˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -238,20 +238,20 @@ mod test {
|
||||||
let mut cx = cx.binding(["c", "0"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["c", "0"]).mode_after(Mode::Insert);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|uick
|
ˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -263,38 +263,38 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
|
@ -307,40 +307,40 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|"},
|
ˇ"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,46 +351,46 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the l|azy"},
|
the lˇazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
|"},
|
ˇ"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,11 +401,11 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
);
|
);
|
||||||
|
@ -414,29 +414,29 @@ mod test {
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the l|azy"},
|
the lˇazy"},
|
||||||
"|",
|
"ˇ",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
|
|
|
@ -46,16 +46,16 @@ mod test {
|
||||||
async fn test_delete_h(cx: &mut gpui::TestAppContext) {
|
async fn test_delete_h(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["d", "h"]);
|
let mut cx = cx.binding(["d", "h"]);
|
||||||
cx.assert("Te|st", "T|st");
|
cx.assert("Teˇst", "Tˇst");
|
||||||
cx.assert("T|est", "|est");
|
cx.assert("Tˇest", "ˇest");
|
||||||
cx.assert("|Test", "|Test");
|
cx.assert("ˇTest", "ˇTest");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test
|
Test
|
||||||
|test"},
|
ˇtest"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test
|
Test
|
||||||
|test"},
|
ˇtest"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,15 +63,15 @@ mod test {
|
||||||
async fn test_delete_l(cx: &mut gpui::TestAppContext) {
|
async fn test_delete_l(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["d", "l"]);
|
let mut cx = cx.binding(["d", "l"]);
|
||||||
cx.assert("|Test", "|est");
|
cx.assert("ˇTest", "ˇest");
|
||||||
cx.assert("Te|st", "Te|t");
|
cx.assert("Teˇst", "Teˇt");
|
||||||
cx.assert("Tes|t", "Te|s");
|
cx.assert("Tesˇt", "Teˇs");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Tes|t
|
Tesˇt
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Te|s
|
Teˇs
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -80,104 +80,104 @@ mod test {
|
||||||
async fn test_delete_w(cx: &mut gpui::TestAppContext) {
|
async fn test_delete_w(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["d", "w"]);
|
let mut cx = cx.binding(["d", "w"]);
|
||||||
cx.assert("Te|st", "T|e");
|
cx.assert("Teˇst", "Tˇe");
|
||||||
cx.assert("T|est test", "T|test");
|
cx.assert("Tˇest test", "Tˇtest");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test te|st
|
Test teˇst
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test t|e
|
Test tˇe
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test tes|t
|
Test tesˇt
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test te|s
|
Test teˇs
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cx = cx.binding(["d", "shift-w"]);
|
let mut cx = cx.binding(["d", "shift-w"]);
|
||||||
cx.assert("Test te|st-test test", "Test te|test");
|
cx.assert("Test teˇst-test test", "Test teˇtest");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_delete_e(cx: &mut gpui::TestAppContext) {
|
async fn test_delete_e(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["d", "e"]);
|
let mut cx = cx.binding(["d", "e"]);
|
||||||
cx.assert("Te|st Test", "Te| Test");
|
cx.assert("Teˇst Test", "Teˇ Test");
|
||||||
cx.assert("T|est test", "T| test");
|
cx.assert("Tˇest test", "Tˇ test");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test te|st
|
Test teˇst
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test t|e
|
Test tˇe
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test tes|t
|
Test tesˇt
|
||||||
test"},
|
test"},
|
||||||
"Test te|s",
|
"Test teˇs",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cx = cx.binding(["d", "shift-e"]);
|
let mut cx = cx.binding(["d", "shift-e"]);
|
||||||
cx.assert("Test te|st-test test", "Test te| test");
|
cx.assert("Test teˇst-test test", "Test teˇ test");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_delete_b(cx: &mut gpui::TestAppContext) {
|
async fn test_delete_b(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["d", "b"]);
|
let mut cx = cx.binding(["d", "b"]);
|
||||||
cx.assert("Te|st Test", "|st Test");
|
cx.assert("Teˇst Test", "ˇst Test");
|
||||||
cx.assert("Test |test", "|test");
|
cx.assert("Test ˇtest", "ˇtest");
|
||||||
cx.assert("Test1 test2 |test3", "Test1 |test3");
|
cx.assert("Test1 test2 ˇtest3", "Test1 ˇtest3");
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|test"},
|
ˇtest"},
|
||||||
// Trailing whitespace after cursor
|
// Trailing whitespace after cursor
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test|
|
Testˇ
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test test
|
Test test
|
||||||
|
|
ˇ
|
||||||
test"},
|
test"},
|
||||||
// Trailing whitespace after cursor
|
// Trailing whitespace after cursor
|
||||||
indoc! {"
|
indoc! {"
|
||||||
Test|
|
Testˇ
|
||||||
|
|
||||||
test"},
|
test"},
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut cx = cx.binding(["d", "shift-b"]);
|
let mut cx = cx.binding(["d", "shift-b"]);
|
||||||
cx.assert("Test test-test |test", "Test |test");
|
cx.assert("Test test-test ˇtest", "Test ˇtest");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -186,20 +186,20 @@ mod test {
|
||||||
let mut cx = cx.binding(["d", "$"]);
|
let mut cx = cx.binding(["d", "$"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |q
|
The ˇq
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -210,20 +210,20 @@ mod test {
|
||||||
let mut cx = cx.binding(["d", "0"]);
|
let mut cx = cx.binding(["d", "0"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|uick
|
ˇuick
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|
|
ˇ
|
||||||
brown fox"},
|
brown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -235,31 +235,31 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
"jumps |over",
|
"jumps ˇover",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
"The qu|ick",
|
"The quˇick",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|brown fox
|
ˇbrown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
"|jumps over",
|
"ˇjumps over",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,34 +270,34 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox
|
brown ˇfox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
"The qu|ick",
|
"The quˇick",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps |over"},
|
jumps ˇover"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown |fox"},
|
brown ˇfox"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over"},
|
jumps over"},
|
||||||
"jumps| over",
|
"jumpsˇ over",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|"},
|
ˇ"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
|brown fox"},
|
ˇbrown fox"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,40 +308,40 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
"The q|uick",
|
"The qˇuick",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
"The q|uick",
|
"The qˇuick",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the l|azy"},
|
the lˇazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps| over"},
|
jumpsˇ over"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
|"},
|
ˇ"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
|jumps over"},
|
ˇjumps over"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,11 +352,11 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick
|
The quick
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
jumps| over
|
jumpsˇ over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
|
@ -364,28 +364,28 @@ mod test {
|
||||||
The quick
|
The quick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the l|azy"},
|
the lˇazy"},
|
||||||
"|",
|
"ˇ",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The q|uick
|
The qˇuick
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
brown| fox
|
brownˇ fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
brown fox
|
brown fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|brown fox
|
ˇbrown fox
|
||||||
jumps over
|
jumps over
|
||||||
the lazy"},
|
the lazy"},
|
||||||
);
|
);
|
||||||
|
@ -397,7 +397,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
@ -407,7 +407,7 @@ mod test {
|
||||||
assert_eq!(cx.active_operator(), None);
|
assert_eq!(cx.active_operator(), None);
|
||||||
assert_eq!(cx.mode(), Mode::Normal);
|
assert_eq!(cx.mode(), Mode::Normal);
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
The qu|ick brown
|
The quˇick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"});
|
the lazy dog"});
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
|
|
@ -216,7 +216,7 @@ mod test {
|
||||||
async fn test_initially_disabled(cx: &mut gpui::TestAppContext) {
|
async fn test_initially_disabled(cx: &mut gpui::TestAppContext) {
|
||||||
let mut cx = VimTestContext::new(cx, false).await;
|
let mut cx = VimTestContext::new(cx, false).await;
|
||||||
cx.simulate_keystrokes(["h", "j", "k", "l"]);
|
cx.simulate_keystrokes(["h", "j", "k", "l"]);
|
||||||
cx.assert_editor_state("hjkl|");
|
cx.assert_editor_state("hjklˇ");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
|
@ -229,24 +229,24 @@ mod test {
|
||||||
// Editor acts as though vim is disabled
|
// Editor acts as though vim is disabled
|
||||||
cx.disable_vim();
|
cx.disable_vim();
|
||||||
cx.simulate_keystrokes(["h", "j", "k", "l"]);
|
cx.simulate_keystrokes(["h", "j", "k", "l"]);
|
||||||
cx.assert_editor_state("hjkl|");
|
cx.assert_editor_state("hjklˇ");
|
||||||
|
|
||||||
// Selections aren't changed if editor is blurred but vim-mode is still disabled.
|
// Selections aren't changed if editor is blurred but vim-mode is still disabled.
|
||||||
cx.set_state("[hjkl}", Mode::Normal);
|
cx.set_state("«hjklˇ»", Mode::Normal);
|
||||||
cx.assert_editor_state("[hjkl}");
|
cx.assert_editor_state("«hjklˇ»");
|
||||||
cx.update_editor(|_, cx| cx.blur());
|
cx.update_editor(|_, cx| cx.blur());
|
||||||
cx.assert_editor_state("[hjkl}");
|
cx.assert_editor_state("«hjklˇ»");
|
||||||
cx.update_editor(|_, cx| cx.focus_self());
|
cx.update_editor(|_, cx| cx.focus_self());
|
||||||
cx.assert_editor_state("[hjkl}");
|
cx.assert_editor_state("«hjklˇ»");
|
||||||
|
|
||||||
// Enabling dynamically sets vim mode again and restores normal mode
|
// Enabling dynamically sets vim mode again and restores normal mode
|
||||||
cx.enable_vim();
|
cx.enable_vim();
|
||||||
assert_eq!(cx.mode(), Mode::Normal);
|
assert_eq!(cx.mode(), Mode::Normal);
|
||||||
cx.simulate_keystrokes(["h", "h", "h", "l"]);
|
cx.simulate_keystrokes(["h", "h", "h", "l"]);
|
||||||
assert_eq!(cx.buffer_text(), "hjkl".to_owned());
|
assert_eq!(cx.buffer_text(), "hjkl".to_owned());
|
||||||
cx.assert_editor_state("h|jkl");
|
cx.assert_editor_state("hˇjkl");
|
||||||
cx.simulate_keystrokes(["i", "T", "e", "s", "t"]);
|
cx.simulate_keystrokes(["i", "T", "e", "s", "t"]);
|
||||||
cx.assert_editor_state("hTest|jkl");
|
cx.assert_editor_state("hTestˇjkl");
|
||||||
|
|
||||||
// Disabling and enabling resets to normal mode
|
// Disabling and enabling resets to normal mode
|
||||||
assert_eq!(cx.mode(), Mode::Insert);
|
assert_eq!(cx.mode(), Mode::Insert);
|
||||||
|
@ -262,7 +262,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
|
|
@ -284,44 +284,44 @@ mod test {
|
||||||
.mode_after(Mode::Visual { line: false });
|
.mode_after(Mode::Visual { line: false });
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The [quick brown
|
The «quick brown
|
||||||
fox jumps }over
|
fox jumps ˇ»over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the [lazy }dog"},
|
the «lazy ˇ»dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps [over
|
fox jumps «over
|
||||||
}the lazy dog"},
|
ˇ»the lazy dog"},
|
||||||
);
|
);
|
||||||
let mut cx = cx
|
let mut cx = cx
|
||||||
.binding(["v", "b", "k"])
|
.binding(["v", "b", "k"])
|
||||||
.mode_after(Mode::Visual { line: false });
|
.mode_after(Mode::Visual { line: false });
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
{The q]uick brown
|
«ˇThe q»uick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
|
@ -329,20 +329,20 @@ mod test {
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
{fox jumps over
|
«ˇfox jumps over
|
||||||
the l]azy dog"},
|
the l»azy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The {quick brown
|
The «ˇquick brown
|
||||||
fox jumps o]ver
|
fox jumps o»ver
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -351,51 +351,51 @@ mod test {
|
||||||
async fn test_visual_delete(cx: &mut gpui::TestAppContext) {
|
async fn test_visual_delete(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["v", "w", "x"]);
|
let mut cx = cx.binding(["v", "w", "x"]);
|
||||||
cx.assert("The quick |brown", "The quick| ");
|
cx.assert("The quick ˇbrown", "The quickˇ ");
|
||||||
let mut cx = cx.binding(["v", "w", "j", "x"]);
|
let mut cx = cx.binding(["v", "w", "j", "x"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |ver
|
The ˇver
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
// Test pasting code copied on delete
|
// Test pasting code copied on delete
|
||||||
cx.simulate_keystrokes(["j", "p"]);
|
cx.simulate_keystrokes(["j", "p"]);
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
The ver
|
The ver
|
||||||
the l|quick brown
|
the lˇquick brown
|
||||||
fox jumps oazy dog"});
|
fox jumps oazy dog"});
|
||||||
|
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |og"},
|
the ˇog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |he lazy dog"},
|
fox jumps ˇhe lazy dog"},
|
||||||
);
|
);
|
||||||
let mut cx = cx.binding(["v", "b", "k", "x"]);
|
let mut cx = cx.binding(["v", "b", "k", "x"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|uick brown
|
ˇuick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
|
@ -403,18 +403,18 @@ mod test {
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
|azy dog"},
|
ˇazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |ver
|
The ˇver
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -425,68 +425,68 @@ mod test {
|
||||||
let mut cx = cx.binding(["shift-v", "x"]);
|
let mut cx = cx.binding(["shift-v", "x"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The qu|ick brown
|
The quˇick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
// Test pasting code copied on delete
|
// Test pasting code copied on delete
|
||||||
cx.simulate_keystroke("p");
|
cx.simulate_keystroke("p");
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
fox jumps over
|
fox jumps over
|
||||||
|The quick brown
|
ˇThe quick brown
|
||||||
the lazy dog"});
|
the lazy dog"});
|
||||||
|
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
the la|zy dog"},
|
the laˇzy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the la|zy dog"},
|
the laˇzy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over"},
|
fox juˇmps over"},
|
||||||
);
|
);
|
||||||
let mut cx = cx.binding(["shift-v", "j", "x"]);
|
let mut cx = cx.binding(["shift-v", "j", "x"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The qu|ick brown
|
The quˇick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
"the la|zy dog",
|
"the laˇzy dog",
|
||||||
);
|
);
|
||||||
// Test pasting code copied on delete
|
// Test pasting code copied on delete
|
||||||
cx.simulate_keystroke("p");
|
cx.simulate_keystroke("p");
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
the lazy dog
|
the lazy dog
|
||||||
|The quick brown
|
ˇThe quick brown
|
||||||
fox jumps over"});
|
fox jumps over"});
|
||||||
|
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
"The qu|ick brown",
|
"The quˇick brown",
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the la|zy dog"},
|
the laˇzy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over"},
|
fox juˇmps over"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,44 +494,44 @@ mod test {
|
||||||
async fn test_visual_change(cx: &mut gpui::TestAppContext) {
|
async fn test_visual_change(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["v", "w", "c"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["v", "w", "c"]).mode_after(Mode::Insert);
|
||||||
cx.assert("The quick |brown", "The quick |");
|
cx.assert("The quick ˇbrown", "The quick ˇ");
|
||||||
let mut cx = cx.binding(["v", "w", "j", "c"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["v", "w", "j", "c"]).mode_after(Mode::Insert);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |ver
|
The ˇver
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |og"},
|
the ˇog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |he lazy dog"},
|
fox jumps ˇhe lazy dog"},
|
||||||
);
|
);
|
||||||
let mut cx = cx.binding(["v", "b", "k", "c"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["v", "b", "k", "c"]).mode_after(Mode::Insert);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|uick brown
|
ˇuick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
|
@ -539,18 +539,18 @@ mod test {
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
|azy dog"},
|
ˇazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |ver
|
The ˇver
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -561,11 +561,11 @@ mod test {
|
||||||
let mut cx = cx.binding(["shift-v", "c"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["shift-v", "c"]).mode_after(Mode::Insert);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The qu|ick brown
|
The quˇick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
|
@ -574,37 +574,37 @@ mod test {
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
|
|
||||||
fox jumps over
|
fox jumps over
|
||||||
|The quick brown
|
ˇThe quick brown
|
||||||
the lazy dog"});
|
the lazy dog"});
|
||||||
|
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
|
|
ˇ
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the la|zy dog"},
|
the laˇzy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
let mut cx = cx.binding(["shift-v", "j", "c"]).mode_after(Mode::Insert);
|
let mut cx = cx.binding(["shift-v", "j", "c"]).mode_after(Mode::Insert);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The qu|ick brown
|
The quˇick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|
|
ˇ
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
// Test pasting code copied on delete
|
// Test pasting code copied on delete
|
||||||
|
@ -612,26 +612,26 @@ mod test {
|
||||||
cx.assert_editor_state(indoc! {"
|
cx.assert_editor_state(indoc! {"
|
||||||
|
|
||||||
the lazy dog
|
the lazy dog
|
||||||
|The quick brown
|
ˇThe quick brown
|
||||||
fox jumps over"});
|
fox jumps over"});
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the la|zy dog"},
|
the laˇzy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
|"},
|
ˇ"},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,16 +639,16 @@ mod test {
|
||||||
async fn test_visual_yank(cx: &mut gpui::TestAppContext) {
|
async fn test_visual_yank(cx: &mut gpui::TestAppContext) {
|
||||||
let cx = VimTestContext::new(cx, true).await;
|
let cx = VimTestContext::new(cx, true).await;
|
||||||
let mut cx = cx.binding(["v", "w", "y"]);
|
let mut cx = cx.binding(["v", "w", "y"]);
|
||||||
cx.assert("The quick |brown", "The quick |brown");
|
cx.assert("The quick ˇbrown", "The quick ˇbrown");
|
||||||
cx.assert_clipboard_content(Some("brown"));
|
cx.assert_clipboard_content(Some("brown"));
|
||||||
let mut cx = cx.binding(["v", "w", "j", "y"]);
|
let mut cx = cx.binding(["v", "w", "j", "y"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
|
@ -659,21 +659,21 @@ mod test {
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert_clipboard_content(Some("lazy d"));
|
cx.assert_clipboard_content(Some("lazy d"));
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert_clipboard_content(Some(indoc! {"
|
cx.assert_clipboard_content(Some(indoc! {"
|
||||||
|
@ -682,11 +682,11 @@ mod test {
|
||||||
let mut cx = cx.binding(["v", "b", "k", "y"]);
|
let mut cx = cx.binding(["v", "b", "k", "y"]);
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
|The quick brown
|
ˇThe quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
|
@ -695,10 +695,10 @@ mod test {
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the |lazy dog"},
|
the ˇlazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
|fox jumps over
|
ˇfox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
cx.assert_clipboard_content(Some(indoc! {"
|
cx.assert_clipboard_content(Some(indoc! {"
|
||||||
|
@ -707,10 +707,10 @@ mod test {
|
||||||
cx.assert(
|
cx.assert(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps |over
|
fox jumps ˇover
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The |quick brown
|
The ˇquick brown
|
||||||
fox jumps over
|
fox jumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
);
|
);
|
||||||
|
@ -725,7 +725,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox [jump}s over
|
fox «jumpˇ»s over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Visual { line: false },
|
Mode::Visual { line: false },
|
||||||
);
|
);
|
||||||
|
@ -733,7 +733,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jump|s over
|
fox jumpˇs over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
@ -741,7 +741,7 @@ mod test {
|
||||||
cx.assert_state(
|
cx.assert_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox jumps|jumps over
|
fox jumpsˇjumps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
@ -749,7 +749,7 @@ mod test {
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
fox ju|mps over
|
fox juˇmps over
|
||||||
the lazy dog"},
|
the lazy dog"},
|
||||||
Mode::Visual { line: true },
|
Mode::Visual { line: true },
|
||||||
);
|
);
|
||||||
|
@ -757,13 +757,13 @@ mod test {
|
||||||
cx.assert_state(
|
cx.assert_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
the la|zy dog"},
|
the laˇzy dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
cx.set_state(
|
cx.set_state(
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
the [laz}y dog"},
|
the «lazˇ»y dog"},
|
||||||
Mode::Visual { line: false },
|
Mode::Visual { line: false },
|
||||||
);
|
);
|
||||||
cx.simulate_keystroke("p");
|
cx.simulate_keystroke("p");
|
||||||
|
@ -771,7 +771,7 @@ mod test {
|
||||||
indoc! {"
|
indoc! {"
|
||||||
The quick brown
|
The quick brown
|
||||||
the
|
the
|
||||||
|fox jumps over
|
ˇfox jumps over
|
||||||
dog"},
|
dog"},
|
||||||
Mode::Normal,
|
Mode::Normal,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue