mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-04 00:57:06 +03:00
WIP
This commit is contained in:
parent
bdd0b9f387
commit
1a84382881
@ -74,6 +74,8 @@ pub use multi_buffer::{
|
|||||||
};
|
};
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
use project::{FormatTrigger, Location, LocationLink, Project, ProjectPath, ProjectTransaction};
|
use project::{FormatTrigger, Location, LocationLink, Project, ProjectPath, ProjectTransaction};
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
use rand::thread_rng;
|
||||||
use scroll::{
|
use scroll::{
|
||||||
autoscroll::Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide,
|
autoscroll::Autoscroll, OngoingScroll, ScrollAnchor, ScrollManager, ScrollbarAutoHide,
|
||||||
};
|
};
|
||||||
@ -226,6 +228,10 @@ actions!(
|
|||||||
MoveLineUp,
|
MoveLineUp,
|
||||||
MoveLineDown,
|
MoveLineDown,
|
||||||
JoinLines,
|
JoinLines,
|
||||||
|
SortLinesCaseSensitive,
|
||||||
|
SortLinesCaseInsensitive,
|
||||||
|
ReverseLines,
|
||||||
|
ShuffleLines,
|
||||||
Transpose,
|
Transpose,
|
||||||
Cut,
|
Cut,
|
||||||
Copy,
|
Copy,
|
||||||
@ -344,6 +350,10 @@ pub fn init(cx: &mut AppContext) {
|
|||||||
cx.add_action(Editor::outdent);
|
cx.add_action(Editor::outdent);
|
||||||
cx.add_action(Editor::delete_line);
|
cx.add_action(Editor::delete_line);
|
||||||
cx.add_action(Editor::join_lines);
|
cx.add_action(Editor::join_lines);
|
||||||
|
cx.add_action(Editor::sort_lines_case_sensitive);
|
||||||
|
cx.add_action(Editor::sort_lines_case_insensitive);
|
||||||
|
cx.add_action(Editor::reverse_lines);
|
||||||
|
// cx.add_action(Editor::shuffle_lines);
|
||||||
cx.add_action(Editor::delete_to_previous_word_start);
|
cx.add_action(Editor::delete_to_previous_word_start);
|
||||||
cx.add_action(Editor::delete_to_previous_subword_start);
|
cx.add_action(Editor::delete_to_previous_subword_start);
|
||||||
cx.add_action(Editor::delete_to_next_word_end);
|
cx.add_action(Editor::delete_to_next_word_end);
|
||||||
@ -4205,6 +4215,99 @@ impl Editor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sort_lines_case_sensitive(
|
||||||
|
&mut self,
|
||||||
|
_: &SortLinesCaseSensitive,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
self.manipulate_lines(cx, {
|
||||||
|
|mut lines| {
|
||||||
|
lines.sort();
|
||||||
|
lines
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sort_lines_case_insensitive(
|
||||||
|
&mut self,
|
||||||
|
_: &SortLinesCaseInsensitive,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
self.manipulate_lines(cx, {
|
||||||
|
|mut lines| {
|
||||||
|
lines.sort_by_key(|line| line.to_lowercase());
|
||||||
|
lines
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reverse_lines(&mut self, _: &ReverseLines, cx: &mut ViewContext<Self>) {
|
||||||
|
self.manipulate_lines(cx, {
|
||||||
|
|mut lines| {
|
||||||
|
lines.reverse();
|
||||||
|
lines
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn shuffle_lines(&mut self, _: &ShuffleLines, cx: &mut ViewContext<Self>) {
|
||||||
|
// self.manipulate_lines(cx, {
|
||||||
|
// |mut lines| {
|
||||||
|
// lines.shuffle(&mut thread_rng());
|
||||||
|
// lines
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
fn manipulate_lines<Fn>(&mut self, cx: &mut ViewContext<Self>, mut callback: Fn)
|
||||||
|
where
|
||||||
|
Fn: FnMut(Vec<&str>) -> Vec<&str>,
|
||||||
|
{
|
||||||
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
|
let buffer = self.buffer.read(cx).snapshot(cx);
|
||||||
|
|
||||||
|
let mut edits = Vec::new();
|
||||||
|
|
||||||
|
let selections = self.selections.all::<Point>(cx);
|
||||||
|
let mut selections = selections.iter().peekable();
|
||||||
|
let mut contiguous_row_selections = Vec::new();
|
||||||
|
|
||||||
|
while let Some(selection) = selections.next() {
|
||||||
|
// Find all the selections that span a contiguous row range
|
||||||
|
let (start_row, end_row) = consume_contiguous_rows(
|
||||||
|
&mut contiguous_row_selections,
|
||||||
|
selection,
|
||||||
|
&display_map,
|
||||||
|
&mut selections,
|
||||||
|
);
|
||||||
|
let start = Point::new(start_row, 0);
|
||||||
|
let end = Point::new(end_row - 1, buffer.line_len(end_row - 1));
|
||||||
|
let text = buffer.text_for_range(start..end).collect::<String>();
|
||||||
|
// TODO SORT LINES: Is there a smarter / more effificent way to obtain lines?
|
||||||
|
let lines = text.split("\n").collect::<Vec<_>>();
|
||||||
|
let lines = callback(lines);
|
||||||
|
edits.push((start..end, lines.join("\n")));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.transact(cx, |this, cx| {
|
||||||
|
this.buffer.update(cx, |buffer, cx| {
|
||||||
|
buffer.edit(edits, None, cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.change_selections(Some(Autoscroll::fit()), cx, |s| {
|
||||||
|
s.select(contiguous_row_selections);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.request_autoscroll(Autoscroll::fit(), cx);
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// Write tests
|
||||||
|
// - Use cx.set_state("«one✅ ˇ»two «three ˇ»four «five ˇ»six "); in tests
|
||||||
|
// Mikayla check for perf stuff
|
||||||
|
// Shuffle
|
||||||
|
}
|
||||||
|
|
||||||
pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
|
pub fn duplicate_line(&mut self, _: &DuplicateLine, cx: &mut ViewContext<Self>) {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
let buffer = &display_map.buffer_snapshot;
|
let buffer = &display_map.buffer_snapshot;
|
||||||
|
@ -2500,6 +2500,85 @@ fn test_join_lines_with_multi_selection(cx: &mut TestAppContext) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_sort_lines_with_single_selection(cx: &mut TestAppContext) {
|
||||||
|
init_test(cx, |_| {});
|
||||||
|
|
||||||
|
cx.add_window(|cx| {
|
||||||
|
let buffer = MultiBuffer::build_simple("dddd\nccc\nbb\na\n\n", cx);
|
||||||
|
let mut editor = build_editor(buffer.clone(), cx);
|
||||||
|
let buffer = buffer.read(cx).as_singleton().unwrap();
|
||||||
|
|
||||||
|
editor.change_selections(None, cx, |s| {
|
||||||
|
s.select_ranges([Point::new(0, 2)..Point::new(0, 2)])
|
||||||
|
});
|
||||||
|
editor.sort_lines_case_sensitive(&SortLinesCaseSensitive, cx);
|
||||||
|
assert_eq!(
|
||||||
|
buffer.read(cx).text(),
|
||||||
|
"dddd\nccc\nbb\na\n\n",
|
||||||
|
"no sorting when single cursor parked on single line"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
editor.selections.ranges::<Point>(cx),
|
||||||
|
&[Point::new(0, 2)..Point::new(0, 2)]
|
||||||
|
);
|
||||||
|
|
||||||
|
editor.change_selections(None, cx, |s| {
|
||||||
|
s.select_ranges([Point::new(0, 2)..Point::new(5, 1)])
|
||||||
|
});
|
||||||
|
editor.sort_lines_case_sensitive(&SortLinesCaseSensitive, cx);
|
||||||
|
assert_eq!(
|
||||||
|
buffer.read(cx).text(),
|
||||||
|
"a\nbb\nccc\ndddd\n\n",
|
||||||
|
"single selection is sorted"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
editor.selections.ranges::<Point>(cx),
|
||||||
|
&[Point::new(0, 0)..Point::new(5, 1)]
|
||||||
|
);
|
||||||
|
|
||||||
|
editor
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[gpui::test]
|
||||||
|
fn test_sort_lines_with_multi_selection(cx: &mut TestAppContext) {
|
||||||
|
init_test(cx, |_| {});
|
||||||
|
|
||||||
|
cx.add_window(|cx| {
|
||||||
|
let buffer = MultiBuffer::build_simple("dddd\nccc\nbb\na\n\n3\n2\n1\n\n", cx);
|
||||||
|
let mut editor = build_editor(buffer.clone(), cx);
|
||||||
|
let buffer = buffer.read(cx).as_singleton().unwrap();
|
||||||
|
|
||||||
|
editor.change_selections(None, cx, |s| {
|
||||||
|
s.select_ranges([
|
||||||
|
Point::new(0, 2)..Point::new(3, 2),
|
||||||
|
Point::new(5, 0)..Point::new(7, 1),
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.sort_lines_case_sensitive(&SortLinesCaseSensitive, cx);
|
||||||
|
assert_eq!(buffer.read(cx).text(), "a\nbb\nccc\ndddd\n\n1\n2\n3\n\n");
|
||||||
|
assert_eq!(
|
||||||
|
editor.selections.ranges::<Point>(cx),
|
||||||
|
&[Point::new(0, 5)..Point::new(2, 2)]
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
editor.selections.ranges::<Point>(cx),
|
||||||
|
&[Point::new(0, 5)..Point::new(2, 2)]
|
||||||
|
);
|
||||||
|
|
||||||
|
// assert_eq!(
|
||||||
|
// editor.selections.ranges::<Point>(cx),
|
||||||
|
// [
|
||||||
|
// Point::new(0, 7)..Point::new(0, 7),
|
||||||
|
// Point::new(1, 3)..Point::new(1, 3)
|
||||||
|
// ]
|
||||||
|
// );
|
||||||
|
editor
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
fn test_duplicate_line(cx: &mut TestAppContext) {
|
fn test_duplicate_line(cx: &mut TestAppContext) {
|
||||||
init_test(cx, |_| {});
|
init_test(cx, |_| {});
|
||||||
|
Loading…
Reference in New Issue
Block a user