Closes #49957 Also adds `start_of_input` context, and modifies both `{start,end}_of_input` to work for both single line and auto height editor modes. https://github.com/user-attachments/assets/e30f2b20-a96c-49d5-9eb6-3c95a485d14a Before you mark this PR as ready for review, make sure that you have: - [x] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [x] Aligned any UI changes with the [UI checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) Release Notes: - Added support for multi-line search and replace input in Buffer Search and Project Search --------- Co-authored-by: Nathan Sobo <nathan@zed.dev>
152 lines
5.5 KiB
Rust
152 lines
5.5 KiB
Rust
use project::search_history::{QueryInsertionBehavior, SearchHistory, SearchHistoryCursor};
|
|
|
|
#[test]
|
|
fn test_add() {
|
|
const MAX_HISTORY_LEN: usize = 20;
|
|
let mut search_history = SearchHistory::new(
|
|
Some(MAX_HISTORY_LEN),
|
|
QueryInsertionBehavior::ReplacePreviousIfContains,
|
|
);
|
|
let mut cursor = SearchHistoryCursor::default();
|
|
|
|
assert_eq!(
|
|
search_history.current(&cursor),
|
|
None,
|
|
"No current selection should be set for the default search history"
|
|
);
|
|
|
|
search_history.add(&mut cursor, "rust".to_string());
|
|
assert_eq!(
|
|
search_history.current(&cursor),
|
|
Some("rust"),
|
|
"Newly added item should be selected"
|
|
);
|
|
|
|
// check if duplicates are not added
|
|
search_history.add(&mut cursor, "rust".to_string());
|
|
assert_eq!(search_history.len(), 1, "Should not add a duplicate");
|
|
assert_eq!(search_history.current(&cursor), Some("rust"));
|
|
|
|
// check if new string containing the previous string replaces it
|
|
search_history.add(&mut cursor, "rustlang".to_string());
|
|
assert_eq!(
|
|
search_history.len(),
|
|
1,
|
|
"Should replace previous item if it's a substring"
|
|
);
|
|
assert_eq!(search_history.current(&cursor), Some("rustlang"));
|
|
|
|
// add item when it equals to current item if it's not the last one
|
|
search_history.add(&mut cursor, "php".to_string());
|
|
search_history.previous(&mut cursor, "");
|
|
assert_eq!(search_history.current(&cursor), Some("rustlang"));
|
|
search_history.add(&mut cursor, "rustlang".to_string());
|
|
assert_eq!(search_history.len(), 3, "Should add item");
|
|
assert_eq!(search_history.current(&cursor), Some("rustlang"));
|
|
|
|
// push enough items to test SEARCH_HISTORY_LIMIT
|
|
for i in 0..MAX_HISTORY_LEN * 2 {
|
|
search_history.add(&mut cursor, format!("item{i}"));
|
|
}
|
|
assert!(search_history.len() <= MAX_HISTORY_LEN);
|
|
}
|
|
|
|
#[test]
|
|
fn test_next_and_previous() {
|
|
let mut search_history = SearchHistory::new(None, QueryInsertionBehavior::AlwaysInsert);
|
|
let mut cursor = SearchHistoryCursor::default();
|
|
|
|
assert_eq!(
|
|
search_history.next(&mut cursor),
|
|
None,
|
|
"Default search history should not have a next item"
|
|
);
|
|
|
|
search_history.add(&mut cursor, "Rust".to_string());
|
|
assert_eq!(search_history.next(&mut cursor), None);
|
|
search_history.add(&mut cursor, "JavaScript".to_string());
|
|
assert_eq!(search_history.next(&mut cursor), None);
|
|
search_history.add(&mut cursor, "TypeScript".to_string());
|
|
assert_eq!(search_history.next(&mut cursor), None);
|
|
|
|
assert_eq!(search_history.current(&cursor), Some("TypeScript"));
|
|
|
|
assert_eq!(search_history.previous(&mut cursor, ""), Some("JavaScript"));
|
|
assert_eq!(search_history.current(&cursor), Some("JavaScript"));
|
|
|
|
assert_eq!(search_history.previous(&mut cursor, ""), Some("Rust"));
|
|
assert_eq!(search_history.current(&cursor), Some("Rust"));
|
|
|
|
assert_eq!(search_history.previous(&mut cursor, ""), None);
|
|
assert_eq!(search_history.current(&cursor), Some("Rust"));
|
|
|
|
assert_eq!(search_history.next(&mut cursor), Some("JavaScript"));
|
|
assert_eq!(search_history.current(&cursor), Some("JavaScript"));
|
|
|
|
assert_eq!(search_history.next(&mut cursor), Some("TypeScript"));
|
|
assert_eq!(search_history.current(&cursor), Some("TypeScript"));
|
|
|
|
assert_eq!(search_history.next(&mut cursor), None);
|
|
assert_eq!(search_history.current(&cursor), Some("TypeScript"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_reset_selection() {
|
|
let mut search_history = SearchHistory::new(None, QueryInsertionBehavior::AlwaysInsert);
|
|
let mut cursor = SearchHistoryCursor::default();
|
|
|
|
search_history.add(&mut cursor, "Rust".to_string());
|
|
search_history.add(&mut cursor, "JavaScript".to_string());
|
|
search_history.add(&mut cursor, "TypeScript".to_string());
|
|
|
|
assert_eq!(search_history.current(&cursor), Some("TypeScript"));
|
|
cursor.reset();
|
|
assert_eq!(search_history.current(&cursor), None);
|
|
assert_eq!(
|
|
search_history.previous(&mut cursor, ""),
|
|
Some("TypeScript"),
|
|
"Should start from the end after reset on previous item query"
|
|
);
|
|
|
|
search_history.previous(&mut cursor, "");
|
|
assert_eq!(search_history.current(&cursor), Some("JavaScript"));
|
|
search_history.previous(&mut cursor, "");
|
|
assert_eq!(search_history.current(&cursor), Some("Rust"));
|
|
|
|
cursor.reset();
|
|
assert_eq!(search_history.current(&cursor), None);
|
|
}
|
|
|
|
#[test]
|
|
fn test_multiple_cursors() {
|
|
let mut search_history = SearchHistory::new(None, QueryInsertionBehavior::AlwaysInsert);
|
|
let mut cursor1 = SearchHistoryCursor::default();
|
|
let mut cursor2 = SearchHistoryCursor::default();
|
|
|
|
search_history.add(&mut cursor1, "Rust".to_string());
|
|
search_history.add(&mut cursor1, "JavaScript".to_string());
|
|
search_history.add(&mut cursor1, "TypeScript".to_string());
|
|
|
|
search_history.add(&mut cursor2, "Python".to_string());
|
|
search_history.add(&mut cursor2, "Java".to_string());
|
|
search_history.add(&mut cursor2, "C++".to_string());
|
|
|
|
assert_eq!(search_history.current(&cursor1), Some("TypeScript"));
|
|
assert_eq!(search_history.current(&cursor2), Some("C++"));
|
|
|
|
assert_eq!(
|
|
search_history.previous(&mut cursor1, ""),
|
|
Some("JavaScript")
|
|
);
|
|
assert_eq!(search_history.previous(&mut cursor2, ""), Some("Java"));
|
|
|
|
assert_eq!(search_history.next(&mut cursor1), Some("TypeScript"));
|
|
assert_eq!(search_history.next(&mut cursor1), Some("Python"));
|
|
|
|
cursor1.reset();
|
|
cursor2.reset();
|
|
|
|
assert_eq!(search_history.current(&cursor1), None);
|
|
assert_eq!(search_history.current(&cursor2), None);
|
|
}
|