editor: add select previous command (#2556)

Added a `select previous` command to complement `select next`.
Release Notes:

- Added "Select previous" editor command, mirroring `Select next`.
Ticket number: Z-366
This commit is contained in:
Piotr Osiewicz 2023-06-02 17:32:34 +02:00 committed by GitHub
parent 571d2f4966
commit 345fad3e9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 316 additions and 10 deletions

View file

@ -179,7 +179,11 @@ impl Rope {
}
pub fn bytes_in_range(&self, range: Range<usize>) -> Bytes {
Bytes::new(self, range)
Bytes::new(self, range, false)
}
pub fn reversed_bytes_in_range(&self, range: Range<usize>) -> Bytes {
Bytes::new(self, range, true)
}
pub fn chunks(&self) -> Chunks {
@ -579,22 +583,33 @@ impl<'a> Iterator for Chunks<'a> {
pub struct Bytes<'a> {
chunks: sum_tree::Cursor<'a, Chunk, usize>,
range: Range<usize>,
reversed: bool,
}
impl<'a> Bytes<'a> {
pub fn new(rope: &'a Rope, range: Range<usize>) -> Self {
pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self {
let mut chunks = rope.chunks.cursor();
chunks.seek(&range.start, Bias::Right, &());
Self { chunks, range }
if reversed {
chunks.seek(&range.end, Bias::Left, &());
} else {
chunks.seek(&range.start, Bias::Right, &());
}
Self {
chunks,
range,
reversed,
}
}
pub fn peek(&self) -> Option<&'a [u8]> {
let chunk = self.chunks.item()?;
if self.reversed && self.range.start >= self.chunks.end(&()) {
return None;
}
let chunk_start = *self.chunks.start();
if self.range.end <= chunk_start {
return None;
}
let start = self.range.start.saturating_sub(chunk_start);
let end = self.range.end - chunk_start;
Some(&chunk.0.as_bytes()[start..chunk.0.len().min(end)])
@ -607,7 +622,11 @@ impl<'a> Iterator for Bytes<'a> {
fn next(&mut self) -> Option<Self::Item> {
let result = self.peek();
if result.is_some() {
self.chunks.next(&());
if self.reversed {
self.chunks.prev(&());
} else {
self.chunks.next(&());
}
}
result
}
@ -617,10 +636,21 @@ impl<'a> io::Read for Bytes<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
if let Some(chunk) = self.peek() {
let len = cmp::min(buf.len(), chunk.len());
buf[..len].copy_from_slice(&chunk[..len]);
self.range.start += len;
if self.reversed {
buf[..len].copy_from_slice(&chunk[chunk.len() - len..]);
buf[..len].reverse();
self.range.end -= len;
} else {
buf[..len].copy_from_slice(&chunk[..len]);
self.range.start += len;
}
if len == chunk.len() {
self.chunks.next(&());
if self.reversed {
self.chunks.prev(&());
} else {
self.chunks.next(&());
}
}
Ok(len)
} else {