Skip autoclosed pairs
Co-Authored-By: Nathan Sobo <nathan@zed.dev> Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
05d7e9c4e7
commit
724272931a
5 changed files with 174 additions and 58 deletions
|
@ -1,5 +1,5 @@
|
||||||
use super::{
|
use super::{
|
||||||
DisplayPoint, Editor, EditorMode, EditorSettings, EditorStyle, Insert, Scroll, Select,
|
DisplayPoint, Editor, EditorMode, EditorSettings, EditorStyle, Input, Scroll, Select,
|
||||||
SelectPhase, Snapshot, MAX_LINE_LEN,
|
SelectPhase, Snapshot, MAX_LINE_LEN,
|
||||||
};
|
};
|
||||||
use buffer::HighlightId;
|
use buffer::HighlightId;
|
||||||
|
@ -143,7 +143,7 @@ impl EditorElement {
|
||||||
if chars.chars().any(|c| c.is_control()) || keystroke.cmd || keystroke.ctrl {
|
if chars.chars().any(|c| c.is_control()) || keystroke.cmd || keystroke.ctrl {
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
cx.dispatch_action(Insert(chars.to_string()));
|
cx.dispatch_action(Input(chars.to_string()));
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ const MAX_LINE_LEN: usize = 1024;
|
||||||
action!(Cancel);
|
action!(Cancel);
|
||||||
action!(Backspace);
|
action!(Backspace);
|
||||||
action!(Delete);
|
action!(Delete);
|
||||||
action!(Insert, String);
|
action!(Input, String);
|
||||||
action!(DeleteLine);
|
action!(DeleteLine);
|
||||||
action!(DeleteToPreviousWordBoundary);
|
action!(DeleteToPreviousWordBoundary);
|
||||||
action!(DeleteToNextWordBoundary);
|
action!(DeleteToNextWordBoundary);
|
||||||
|
@ -95,13 +95,13 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
Binding::new("ctrl-h", Backspace, Some("Editor")),
|
Binding::new("ctrl-h", Backspace, Some("Editor")),
|
||||||
Binding::new("delete", Delete, Some("Editor")),
|
Binding::new("delete", Delete, Some("Editor")),
|
||||||
Binding::new("ctrl-d", Delete, Some("Editor")),
|
Binding::new("ctrl-d", Delete, Some("Editor")),
|
||||||
Binding::new("enter", Insert("\n".into()), Some("Editor && mode == full")),
|
Binding::new("enter", Input("\n".into()), Some("Editor && mode == full")),
|
||||||
Binding::new(
|
Binding::new(
|
||||||
"alt-enter",
|
"alt-enter",
|
||||||
Insert("\n".into()),
|
Input("\n".into()),
|
||||||
Some("Editor && mode == auto_height"),
|
Some("Editor && mode == auto_height"),
|
||||||
),
|
),
|
||||||
Binding::new("tab", Insert("\t".into()), Some("Editor")),
|
Binding::new("tab", Input("\t".into()), Some("Editor")),
|
||||||
Binding::new("ctrl-shift-K", DeleteLine, Some("Editor")),
|
Binding::new("ctrl-shift-K", DeleteLine, Some("Editor")),
|
||||||
Binding::new(
|
Binding::new(
|
||||||
"alt-backspace",
|
"alt-backspace",
|
||||||
|
@ -192,7 +192,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_action(|this: &mut Editor, action: &Scroll, cx| this.set_scroll_position(action.0, cx));
|
cx.add_action(|this: &mut Editor, action: &Scroll, cx| this.set_scroll_position(action.0, cx));
|
||||||
cx.add_action(Editor::select);
|
cx.add_action(Editor::select);
|
||||||
cx.add_action(Editor::cancel);
|
cx.add_action(Editor::cancel);
|
||||||
cx.add_action(Editor::insert);
|
cx.add_action(Editor::handle_input);
|
||||||
cx.add_action(Editor::backspace);
|
cx.add_action(Editor::backspace);
|
||||||
cx.add_action(Editor::delete);
|
cx.add_action(Editor::delete);
|
||||||
cx.add_action(Editor::delete_line);
|
cx.add_action(Editor::delete_line);
|
||||||
|
@ -292,6 +292,7 @@ pub struct Editor {
|
||||||
pending_selection: Option<Selection>,
|
pending_selection: Option<Selection>,
|
||||||
next_selection_id: usize,
|
next_selection_id: usize,
|
||||||
add_selections_state: Option<AddSelectionsState>,
|
add_selections_state: Option<AddSelectionsState>,
|
||||||
|
autoclose_stack: Vec<AutoclosePairState>,
|
||||||
select_larger_syntax_node_stack: Vec<Arc<[Selection]>>,
|
select_larger_syntax_node_stack: Vec<Arc<[Selection]>>,
|
||||||
scroll_position: Vector2F,
|
scroll_position: Vector2F,
|
||||||
scroll_top_anchor: Anchor,
|
scroll_top_anchor: Anchor,
|
||||||
|
@ -319,6 +320,11 @@ struct AddSelectionsState {
|
||||||
stack: Vec<usize>,
|
stack: Vec<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AutoclosePairState {
|
||||||
|
ranges: SmallVec<[Range<Anchor>; 32]>,
|
||||||
|
pair: AutoclosePair,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct ClipboardSelection {
|
struct ClipboardSelection {
|
||||||
len: usize,
|
len: usize,
|
||||||
|
@ -404,6 +410,7 @@ impl Editor {
|
||||||
pending_selection: None,
|
pending_selection: None,
|
||||||
next_selection_id,
|
next_selection_id,
|
||||||
add_selections_state: None,
|
add_selections_state: None,
|
||||||
|
autoclose_stack: Default::default(),
|
||||||
select_larger_syntax_node_stack: Vec::new(),
|
select_larger_syntax_node_stack: Vec::new(),
|
||||||
build_settings,
|
build_settings,
|
||||||
scroll_position: Vector2F::zero(),
|
scroll_position: Vector2F::zero(),
|
||||||
|
@ -733,7 +740,18 @@ impl Editor {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, action: &Insert, cx: &mut ViewContext<Self>) {
|
pub fn handle_input(&mut self, action: &Input, cx: &mut ViewContext<Self>) {
|
||||||
|
let text = action.0.as_ref();
|
||||||
|
if !self.skip_autoclose_end(text, cx) {
|
||||||
|
self.start_transaction(cx);
|
||||||
|
self.insert(text, cx);
|
||||||
|
self.autoclose_pairs(cx);
|
||||||
|
self.end_transaction(cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn insert(&mut self, text: &str, cx: &mut ViewContext<Self>) {
|
||||||
|
self.start_transaction(cx);
|
||||||
let mut old_selections = SmallVec::<[_; 32]>::new();
|
let mut old_selections = SmallVec::<[_; 32]>::new();
|
||||||
{
|
{
|
||||||
let selections = self.selections(cx);
|
let selections = self.selections(cx);
|
||||||
|
@ -745,12 +763,11 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.start_transaction(cx);
|
|
||||||
let mut new_selections = Vec::new();
|
let mut new_selections = Vec::new();
|
||||||
self.buffer.update(cx, |buffer, cx| {
|
self.buffer.update(cx, |buffer, cx| {
|
||||||
let edit_ranges = old_selections.iter().map(|(_, range)| range.clone());
|
let edit_ranges = old_selections.iter().map(|(_, range)| range.clone());
|
||||||
buffer.edit(edit_ranges, action.0.as_str(), cx);
|
buffer.edit(edit_ranges, text, cx);
|
||||||
let text_len = action.0.len() as isize;
|
let text_len = text.len() as isize;
|
||||||
let mut delta = 0_isize;
|
let mut delta = 0_isize;
|
||||||
new_selections = old_selections
|
new_selections = old_selections
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -772,13 +789,12 @@ impl Editor {
|
||||||
});
|
});
|
||||||
|
|
||||||
self.update_selections(new_selections, true, cx);
|
self.update_selections(new_selections, true, cx);
|
||||||
self.autoclose_pairs(cx);
|
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn autoclose_pairs(&mut self, cx: &mut ViewContext<Self>) {
|
fn autoclose_pairs(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
let selections = self.selections(cx);
|
let selections = self.selections(cx);
|
||||||
self.buffer.update(cx, |buffer, cx| {
|
let new_autoclose_pair_state = self.buffer.update(cx, |buffer, cx| {
|
||||||
let autoclose_pair = buffer.language().and_then(|language| {
|
let autoclose_pair = buffer.language().and_then(|language| {
|
||||||
let first_selection_start = selections.first().unwrap().start.to_offset(&*buffer);
|
let first_selection_start = selections.first().unwrap().start.to_offset(&*buffer);
|
||||||
let pair = language.autoclose_pairs().iter().find(|pair| {
|
let pair = language.autoclose_pairs().iter().find(|pair| {
|
||||||
|
@ -804,23 +820,87 @@ impl Editor {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(pair) = autoclose_pair {
|
autoclose_pair.and_then(|pair| {
|
||||||
let mut selection_ranges = SmallVec::<[_; 32]>::new();
|
let selection_ranges = selections
|
||||||
for selection in selections.as_ref() {
|
.iter()
|
||||||
let start = selection.start.to_offset(&*buffer);
|
.map(|selection| {
|
||||||
let end = selection.end.to_offset(&*buffer);
|
let start = selection.start.to_offset(&*buffer);
|
||||||
selection_ranges.push(start..end);
|
start..start
|
||||||
}
|
})
|
||||||
|
.collect::<SmallVec<[_; 32]>>();
|
||||||
|
|
||||||
buffer.edit(selection_ranges, &pair.end, cx);
|
buffer.edit(selection_ranges, &pair.end, cx);
|
||||||
}
|
|
||||||
|
if pair.end.len() == 1 {
|
||||||
|
Some(AutoclosePairState {
|
||||||
|
ranges: selections
|
||||||
|
.iter()
|
||||||
|
.map(|selection| {
|
||||||
|
selection.start.bias_left(buffer)
|
||||||
|
..selection.start.bias_right(buffer)
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
pair,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
self.autoclose_stack.extend(new_autoclose_pair_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn skip_autoclose_end(&mut self, text: &str, cx: &mut ViewContext<Self>) -> bool {
|
||||||
|
let old_selections = self.selections(cx);
|
||||||
|
let autoclose_pair_state = if let Some(autoclose_pair_state) = self.autoclose_stack.last() {
|
||||||
|
autoclose_pair_state
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if text != autoclose_pair_state.pair.end {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert_eq!(old_selections.len(), autoclose_pair_state.ranges.len());
|
||||||
|
|
||||||
|
let buffer = self.buffer.read(cx);
|
||||||
|
let old_selection_ranges: SmallVec<[_; 32]> = old_selections
|
||||||
|
.iter()
|
||||||
|
.map(|selection| (selection.id, selection.offset_range(buffer)))
|
||||||
|
.collect();
|
||||||
|
if old_selection_ranges
|
||||||
|
.iter()
|
||||||
|
.zip(&autoclose_pair_state.ranges)
|
||||||
|
.all(|((_, selection_range), autoclose_range)| {
|
||||||
|
let autoclose_range_end = autoclose_range.end.to_offset(buffer);
|
||||||
|
selection_range.is_empty() && selection_range.start == autoclose_range_end
|
||||||
|
})
|
||||||
|
{
|
||||||
|
let new_selections = old_selection_ranges
|
||||||
|
.into_iter()
|
||||||
|
.map(|(id, range)| {
|
||||||
|
let new_head = buffer.anchor_before(range.start + 1);
|
||||||
|
Selection {
|
||||||
|
id,
|
||||||
|
start: new_head.clone(),
|
||||||
|
end: new_head,
|
||||||
|
reversed: false,
|
||||||
|
goal: SelectionGoal::None,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
self.autoclose_stack.pop();
|
||||||
|
self.update_selections(new_selections, true, cx);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
|
pub fn clear(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
self.start_transaction(cx);
|
self.start_transaction(cx);
|
||||||
self.select_all(&SelectAll, cx);
|
self.select_all(&SelectAll, cx);
|
||||||
self.insert(&Insert(String::new()), cx);
|
self.insert("", cx);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -843,7 +923,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_selections(selections, true, cx);
|
self.update_selections(selections, true, cx);
|
||||||
self.insert(&Insert(String::new()), cx);
|
self.insert("", cx);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -866,7 +946,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_selections(selections, true, cx);
|
self.update_selections(selections, true, cx);
|
||||||
self.insert(&Insert(String::new()), cx);
|
self.insert(&"", cx);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1214,7 +1294,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.update_selections(selections, true, cx);
|
self.update_selections(selections, true, cx);
|
||||||
self.insert(&Insert(String::new()), cx);
|
self.insert("", cx);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
|
|
||||||
cx.as_mut()
|
cx.as_mut()
|
||||||
|
@ -1261,7 +1341,6 @@ impl Editor {
|
||||||
clipboard_selections.clear();
|
clipboard_selections.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.start_transaction(cx);
|
|
||||||
let mut start_offset = 0;
|
let mut start_offset = 0;
|
||||||
let mut new_selections = Vec::with_capacity(selections.len());
|
let mut new_selections = Vec::with_capacity(selections.len());
|
||||||
for (i, selection) in selections.iter().enumerate() {
|
for (i, selection) in selections.iter().enumerate() {
|
||||||
|
@ -1304,9 +1383,8 @@ impl Editor {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.update_selections(new_selections, true, cx);
|
self.update_selections(new_selections, true, cx);
|
||||||
self.end_transaction(cx);
|
|
||||||
} else {
|
} else {
|
||||||
self.insert(&Insert(clipboard_text.into()), cx);
|
self.insert(clipboard_text, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1548,7 +1626,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_selections(selections, true, cx);
|
self.update_selections(selections, true, cx);
|
||||||
self.insert(&Insert(String::new()), cx);
|
self.insert("", cx);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1618,7 +1696,7 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_selections(selections, true, cx);
|
self.update_selections(selections, true, cx);
|
||||||
self.insert(&Insert(String::new()), cx);
|
self.insert("", cx);
|
||||||
self.end_transaction(cx);
|
self.end_transaction(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2146,20 +2224,41 @@ impl Editor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buffer.update(cx, |buffer, cx| {
|
self.add_selections_state = None;
|
||||||
buffer
|
self.select_larger_syntax_node_stack.clear();
|
||||||
.update_selection_set(self.selection_set_id, selections, cx)
|
while let Some(autoclose_pair_state) = self.autoclose_stack.last() {
|
||||||
.unwrap();
|
let all_selections_inside_autoclose_ranges =
|
||||||
});
|
if selections.len() == autoclose_pair_state.ranges.len() {
|
||||||
self.pause_cursor_blinking(cx);
|
selections.iter().zip(&autoclose_pair_state.ranges).all(
|
||||||
|
|(selection, autoclose_range)| {
|
||||||
|
let head = selection.head();
|
||||||
|
autoclose_range.start.cmp(head, buffer).unwrap() <= Ordering::Equal
|
||||||
|
&& autoclose_range.end.cmp(head, buffer).unwrap() >= Ordering::Equal
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if all_selections_inside_autoclose_ranges {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
self.autoclose_stack.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if autoscroll {
|
if autoscroll {
|
||||||
self.autoscroll_requested = true;
|
self.autoscroll_requested = true;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.add_selections_state = None;
|
self.pause_cursor_blinking(cx);
|
||||||
self.select_larger_syntax_node_stack.clear();
|
|
||||||
|
self.buffer.update(cx, |buffer, cx| {
|
||||||
|
buffer
|
||||||
|
.update_selection_set(self.selection_set_id, selections, cx)
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_transaction(&self, cx: &mut ViewContext<Self>) {
|
fn start_transaction(&self, cx: &mut ViewContext<Self>) {
|
||||||
|
@ -3708,9 +3807,9 @@ mod tests {
|
||||||
// is pasted at each cursor.
|
// is pasted at each cursor.
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.select_ranges(vec![0..0, 31..31], false, cx);
|
view.select_ranges(vec![0..0, 31..31], false, cx);
|
||||||
view.insert(&Insert("( ".into()), cx);
|
view.handle_input(&Input("( ".into()), cx);
|
||||||
view.paste(&Paste, cx);
|
view.paste(&Paste, cx);
|
||||||
view.insert(&Insert(") ".into()), cx);
|
view.handle_input(&Input(") ".into()), cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
view.display_text(cx),
|
view.display_text(cx),
|
||||||
"( one✅ three five ) two one✅ four three six five ( one✅ three five ) "
|
"( one✅ three five ) two one✅ four three six five ( one✅ three five ) "
|
||||||
|
@ -3719,7 +3818,7 @@ mod tests {
|
||||||
|
|
||||||
view.update(cx, |view, cx| {
|
view.update(cx, |view, cx| {
|
||||||
view.select_ranges(vec![0..0], false, cx);
|
view.select_ranges(vec![0..0], false, cx);
|
||||||
view.insert(&Insert("123\n4567\n89\n".into()), cx);
|
view.handle_input(&Input("123\n4567\n89\n".into()), cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
view.display_text(cx),
|
view.display_text(cx),
|
||||||
"123\n4567\n89\n( one✅ three five ) two one✅ four three six five ( one✅ three five ) "
|
"123\n4567\n89\n( one✅ three five ) two one✅ four three six five ( one✅ three five ) "
|
||||||
|
@ -4296,12 +4395,29 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
view.insert(&Insert("{".to_string()), cx);
|
view.handle_input(&Input("{".to_string()), cx);
|
||||||
|
view.handle_input(&Input("{".to_string()), cx);
|
||||||
|
view.handle_input(&Input("{".to_string()), cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
view.text(cx),
|
view.text(cx),
|
||||||
"
|
"
|
||||||
{}
|
{{{}}}
|
||||||
{}
|
{{{}}}
|
||||||
|
/
|
||||||
|
|
||||||
|
"
|
||||||
|
.unindent()
|
||||||
|
);
|
||||||
|
|
||||||
|
view.move_right(&MoveRight, cx);
|
||||||
|
view.handle_input(&Input("}".to_string()), cx);
|
||||||
|
view.handle_input(&Input("}".to_string()), cx);
|
||||||
|
view.handle_input(&Input("}".to_string()), cx);
|
||||||
|
assert_eq!(
|
||||||
|
view.text(cx),
|
||||||
|
"
|
||||||
|
{{{}}}}
|
||||||
|
{{{}}}}
|
||||||
/
|
/
|
||||||
|
|
||||||
"
|
"
|
||||||
|
@ -4309,8 +4425,8 @@ mod tests {
|
||||||
);
|
);
|
||||||
|
|
||||||
view.undo(&Undo, cx);
|
view.undo(&Undo, cx);
|
||||||
view.insert(&Insert("/".to_string()), cx);
|
view.handle_input(&Input("/".to_string()), cx);
|
||||||
view.insert(&Insert("*".to_string()), cx);
|
view.handle_input(&Input("*".to_string()), cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
view.text(cx),
|
view.text(cx),
|
||||||
"
|
"
|
||||||
|
@ -4331,7 +4447,7 @@ mod tests {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
view.insert(&Insert("*".to_string()), cx);
|
view.handle_input(&Input("*".to_string()), cx);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
view.text(cx),
|
view.text(cx),
|
||||||
"
|
"
|
||||||
|
|
|
@ -422,7 +422,7 @@ impl FileFinder {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use editor::Insert;
|
use editor::Input;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use workspace::{Workspace, WorkspaceParams};
|
use workspace::{Workspace, WorkspaceParams};
|
||||||
|
@ -471,9 +471,9 @@ mod tests {
|
||||||
let query_buffer = cx.read(|cx| finder.read(cx).query_editor.clone());
|
let query_buffer = cx.read(|cx| finder.read(cx).query_editor.clone());
|
||||||
|
|
||||||
let chain = vec![finder.id(), query_buffer.id()];
|
let chain = vec![finder.id(), query_buffer.id()];
|
||||||
cx.dispatch_action(window_id, chain.clone(), Insert("b".into()));
|
cx.dispatch_action(window_id, chain.clone(), Input("b".into()));
|
||||||
cx.dispatch_action(window_id, chain.clone(), Insert("n".into()));
|
cx.dispatch_action(window_id, chain.clone(), Input("n".into()));
|
||||||
cx.dispatch_action(window_id, chain.clone(), Insert("a".into()));
|
cx.dispatch_action(window_id, chain.clone(), Input("a".into()));
|
||||||
finder
|
finder
|
||||||
.condition(&cx, |finder, _| finder.matches.len() == 2)
|
.condition(&cx, |finder, _| finder.matches.len() == 2)
|
||||||
.await;
|
.await;
|
||||||
|
|
|
@ -981,7 +981,7 @@ mod tests {
|
||||||
self, test::FakeHttpClient, Channel, ChannelDetails, ChannelList, Client, Credentials,
|
self, test::FakeHttpClient, Channel, ChannelDetails, ChannelList, Client, Credentials,
|
||||||
EstablishConnectionError, UserStore,
|
EstablishConnectionError, UserStore,
|
||||||
},
|
},
|
||||||
editor::{Editor, EditorSettings, Insert},
|
editor::{Editor, EditorSettings, Input},
|
||||||
fs::{FakeFs, Fs as _},
|
fs::{FakeFs, Fs as _},
|
||||||
people_panel::JoinWorktree,
|
people_panel::JoinWorktree,
|
||||||
project::{ProjectPath, Worktree},
|
project::{ProjectPath, Worktree},
|
||||||
|
@ -1068,7 +1068,7 @@ mod tests {
|
||||||
|
|
||||||
// Edit the buffer as client B and see that edit as client A.
|
// Edit the buffer as client B and see that edit as client A.
|
||||||
editor_b.update(&mut cx_b, |editor, cx| {
|
editor_b.update(&mut cx_b, |editor, cx| {
|
||||||
editor.insert(&Insert("ok, ".into()), cx)
|
editor.handle_input(&Input("ok, ".into()), cx)
|
||||||
});
|
});
|
||||||
buffer_a
|
buffer_a
|
||||||
.condition(&cx_a, |buffer, _| buffer.text() == "ok, b-contents")
|
.condition(&cx_a, |buffer, _| buffer.text() == "ok, b-contents")
|
||||||
|
|
|
@ -1070,7 +1070,7 @@ impl WorkspaceHandle for ViewHandle<Workspace> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use editor::{Editor, Insert};
|
use editor::{Editor, Input};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
@ -1282,7 +1282,7 @@ mod tests {
|
||||||
item.to_any().downcast::<Editor>().unwrap()
|
item.to_any().downcast::<Editor>().unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.update(|cx| editor.update(cx, |editor, cx| editor.insert(&Insert("x".into()), cx)));
|
cx.update(|cx| editor.update(cx, |editor, cx| editor.handle_input(&Input("x".into()), cx)));
|
||||||
fs.insert_file("/root/a.txt", "changed".to_string())
|
fs.insert_file("/root/a.txt", "changed".to_string())
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1335,7 +1335,7 @@ mod tests {
|
||||||
assert!(!editor.is_dirty(cx.as_ref()));
|
assert!(!editor.is_dirty(cx.as_ref()));
|
||||||
assert_eq!(editor.title(cx.as_ref()), "untitled");
|
assert_eq!(editor.title(cx.as_ref()), "untitled");
|
||||||
assert!(editor.language(cx).is_none());
|
assert!(editor.language(cx).is_none());
|
||||||
editor.insert(&Insert("hi".into()), cx);
|
editor.handle_input(&Input("hi".into()), cx);
|
||||||
assert!(editor.is_dirty(cx.as_ref()));
|
assert!(editor.is_dirty(cx.as_ref()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1367,7 +1367,7 @@ mod tests {
|
||||||
|
|
||||||
// Edit the file and save it again. This time, there is no filename prompt.
|
// Edit the file and save it again. This time, there is no filename prompt.
|
||||||
editor.update(&mut cx, |editor, cx| {
|
editor.update(&mut cx, |editor, cx| {
|
||||||
editor.insert(&Insert(" there".into()), cx);
|
editor.handle_input(&Input(" there".into()), cx);
|
||||||
assert_eq!(editor.is_dirty(cx.as_ref()), true);
|
assert_eq!(editor.is_dirty(cx.as_ref()), true);
|
||||||
});
|
});
|
||||||
workspace.update(&mut cx, |workspace, cx| {
|
workspace.update(&mut cx, |workspace, cx| {
|
||||||
|
@ -1428,7 +1428,7 @@ mod tests {
|
||||||
|
|
||||||
editor.update(&mut cx, |editor, cx| {
|
editor.update(&mut cx, |editor, cx| {
|
||||||
assert!(editor.language(cx).is_none());
|
assert!(editor.language(cx).is_none());
|
||||||
editor.insert(&Insert("hi".into()), cx);
|
editor.handle_input(&Input("hi".into()), cx);
|
||||||
assert!(editor.is_dirty(cx.as_ref()));
|
assert!(editor.is_dirty(cx.as_ref()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue