Make textobject select last paragraph (#1992)
* Make textobject select last paragraph Last paragraph shoud be selected if the cursor was placed on the whitespace paragraph part and `map` is done, otherwise it would do nothing useful, but now we select backwards for the last paragraph which behaves similarly to kakoune, making `map` useful for the last paragraph with whitespace. Example usecase is to copy and paste last ledger cli paragraph quickly by `mapyp` to duplicate last entry. * Fix typo in core textobject Co-authored-by: Michael Davis <mcarsondavis@gmail.com> Co-authored-by: Michael Davis <mcarsondavis@gmail.com>
This commit is contained in:
parent
a0c6c45c1b
commit
62283fdadb
1 changed files with 30 additions and 9 deletions
|
@ -132,9 +132,9 @@ pub fn textobject_paragraph(
|
|||
if prev_empty_to_line || curr_empty_to_line {
|
||||
line_back += 1;
|
||||
}
|
||||
let mut lines = slice.lines_at(line_back);
|
||||
// do not include current paragraph on paragraph end (include next)
|
||||
if !(curr_empty_to_line && last_char) {
|
||||
let mut lines = slice.lines_at(line_back);
|
||||
lines.reverse();
|
||||
let mut lines = lines.map(rope_is_line_ending).peekable();
|
||||
while lines.next_if(|&e| e).is_some() {
|
||||
|
@ -150,25 +150,46 @@ pub fn textobject_paragraph(
|
|||
line += 1;
|
||||
}
|
||||
let mut lines = slice.lines_at(line).map(rope_is_line_ending).peekable();
|
||||
for _ in 0..count - 1 {
|
||||
let mut count_done = 0; // count how many non-whitespace paragraphs done
|
||||
for _ in 0..count {
|
||||
let mut done = false;
|
||||
while lines.next_if(|&e| !e).is_some() {
|
||||
line += 1;
|
||||
done = true;
|
||||
}
|
||||
while lines.next_if(|&e| e).is_some() {
|
||||
line += 1;
|
||||
}
|
||||
count_done += done as usize;
|
||||
}
|
||||
while lines.next_if(|&e| !e).is_some() {
|
||||
line += 1;
|
||||
|
||||
// search one paragraph backwards for last paragraph
|
||||
// makes `map` at the end of the paragraph with trailing newlines useful
|
||||
let last_paragraph = count_done != count && lines.peek().is_none();
|
||||
if last_paragraph {
|
||||
let mut lines = slice.lines_at(line_back);
|
||||
lines.reverse();
|
||||
let mut lines = lines.map(rope_is_line_ending).peekable();
|
||||
while lines.next_if(|&e| e).is_some() {
|
||||
line_back -= 1;
|
||||
}
|
||||
while lines.next_if(|&e| !e).is_some() {
|
||||
line_back -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// handle last whitespaces part separately depending on textobject
|
||||
match textobject {
|
||||
TextObject::Around => {
|
||||
TextObject::Around => {}
|
||||
TextObject::Inside => {
|
||||
// remove last whitespace paragraph
|
||||
let mut lines = slice.lines_at(line);
|
||||
lines.reverse();
|
||||
let mut lines = lines.map(rope_is_line_ending).peekable();
|
||||
while lines.next_if(|&e| e).is_some() {
|
||||
line += 1;
|
||||
line -= 1;
|
||||
}
|
||||
}
|
||||
TextObject::Inside => {}
|
||||
TextObject::Movement => unreachable!(),
|
||||
}
|
||||
|
||||
|
@ -364,7 +385,7 @@ mod test {
|
|||
"second\n\n#[paragraph\n|]#\n",
|
||||
),
|
||||
("#[f|]#irst char\n\n", "#[first char\n|]#\n"),
|
||||
("last char\n#[\n|]#", "last char\n\n#[|]#"),
|
||||
("last char\n#[\n|]#", "#[last char\n|]#\n"),
|
||||
(
|
||||
"empty to line\n#[\n|]#paragraph boundary\n\n",
|
||||
"empty to line\n\n#[paragraph boundary\n|]#\n",
|
||||
|
@ -418,7 +439,7 @@ mod test {
|
|||
"second\n\n#[paragraph\n\n|]#",
|
||||
),
|
||||
("#[f|]#irst char\n\n", "#[first char\n\n|]#"),
|
||||
("last char\n#[\n|]#", "last char\n\n#[|]#"),
|
||||
("last char\n#[\n|]#", "#[last char\n\n|]#"),
|
||||
(
|
||||
"empty to line\n#[\n|]#paragraph boundary\n\n",
|
||||
"empty to line\n\n#[paragraph boundary\n\n|]#",
|
||||
|
|
Loading…
Reference in a new issue