documents: TableEdit::Delete removes the table at the caret
Typora's Paragraph > Table > Delete Table. It removes the table as the block command does and refuses outside a table as TableRefusal::Outside. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
6d90351423
commit
24ffc45c6b
4 files changed
+50
-7
No files matched your search
@@ -50,8 +50,9 @@ impl MarkdownDocument {
|
||||
) -> Result<(), EditRefusal> {
|
||||
self.apart(
|
||||
format!("table edit {edit:?}"),
|
||||
move |full, selection| {
|
||||
tables::edit_table(full, selection.start, edit).map_err(EditRefusal::Cells)
|
||||
move |full, selection| match edit {
|
||||
TableEdit::Delete => tables::delete(full, selection.start),
|
||||
_ => tables::edit_table(full, selection.start, edit).map_err(EditRefusal::Cells),
|
||||
},
|
||||
cx,
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use super::{
|
||||
MarkdownDocument,
|
||||
block::{eol, line_end, line_start, next_line, prev_line, settled},
|
||||
block::{self, BlockCommand, eol, line_end, line_start, next_line, prev_line, settled},
|
||||
format::{Change, EditRefusal},
|
||||
};
|
||||
use crate::documents::{
|
||||
@@ -29,6 +29,8 @@ pub enum TableEdit {
|
||||
MoveColumnRight,
|
||||
/// Every cell padded to its column, as Typora tidies.
|
||||
Tidy,
|
||||
/// The whole table.
|
||||
Delete,
|
||||
}
|
||||
|
||||
/// Why a table edit did not happen.
|
||||
@@ -54,9 +56,7 @@ pub(super) fn edit_table(text: &str, at: usize, edit: TableEdit) -> Result<Chang
|
||||
let (range, table) = nodes
|
||||
.into_iter()
|
||||
.find_map(|node| match node {
|
||||
mdast::Node::Table(table) if (span(node).start..=span(node).end).contains(&at) => {
|
||||
Some((span(node), table))
|
||||
}
|
||||
mdast::Node::Table(table) if around(node, at) => Some((span(node), table)),
|
||||
_ => None,
|
||||
})
|
||||
.ok_or(TableRefusal::Outside)?;
|
||||
@@ -164,6 +164,22 @@ pub(super) fn edit_table(text: &str, at: usize, edit: TableEdit) -> Result<Chang
|
||||
Ok((vec![(range, out)], caret..caret))
|
||||
}
|
||||
|
||||
/// The table at the caret gone, as the block command removes it.
|
||||
pub(super) fn delete(text: &str, at: usize) -> Result<Change, EditRefusal> {
|
||||
let root = file_tree(text);
|
||||
let mut nodes = Vec::new();
|
||||
walk(&root, &mut nodes);
|
||||
if !nodes.iter().any(|node| around(node, at)) {
|
||||
return Err(EditRefusal::Cells(TableRefusal::Outside));
|
||||
}
|
||||
block::run(text, at..at, BlockCommand::Delete)
|
||||
}
|
||||
|
||||
/// Whether `node` is a table holding `at`.
|
||||
fn around(node: &mdast::Node, at: usize) -> bool {
|
||||
matches!(node, mdast::Node::Table(_)) && (span(node).start..=span(node).end).contains(&at)
|
||||
}
|
||||
|
||||
/// A cell's source between its pipes.
|
||||
fn written(text: &str, cell: &mdast::Node) -> String {
|
||||
let inside = cell.children().expect("a cell holds inlines");
|
||||
|
||||
@@ -385,3 +385,29 @@ fn a_block_after_end_in_crlf_text_reads_the_line(cx: &mut TestAppContext) {
|
||||
fn a_selection_from_inside_a_crlf_reads_the_line(cx: &mut TestAppContext) {
|
||||
assert_eq!(code_block_after("end shift-right", cx), FENCE_AFTER_INTRO);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn delete_table_takes_the_table_or_refuses_outside(cx: &mut TestAppContext) {
|
||||
let source = "before\n\n| A | B |\n| - | - |\n| 1 | 2 |\n\nafter\n";
|
||||
let (document, cx) = open(source, MarkdownMode::Source, cx);
|
||||
let heard = super::format::refusals(&document, cx);
|
||||
let delete = |cx: &mut gpui::VisualTestContext| {
|
||||
document.update(cx, |document, cx| {
|
||||
document
|
||||
.edit_table(crate::documents::TableEdit::Delete, cx)
|
||||
.expect("taken")
|
||||
});
|
||||
cx.run_until_parked();
|
||||
};
|
||||
document.update(cx, |document, cx| document.set_caret(4, 2, cx));
|
||||
delete(cx);
|
||||
assert_eq!(text(&document, cx), "before\n\nafter\n");
|
||||
let editor = document.read_with(cx, |document, _| document.editor().clone());
|
||||
editor.update(cx, |editor, cx| editor.undo(cx));
|
||||
assert_eq!(text(&document, cx), source);
|
||||
document.update(cx, |document, cx| document.set_caret(0, 2, cx));
|
||||
delete(cx);
|
||||
let outside = crate::documents::EditRefusal::Cells(crate::documents::TableRefusal::Outside);
|
||||
assert_eq!(*heard.borrow(), [outside]);
|
||||
assert_eq!(text(&document, cx), source);
|
||||
}
|
||||
Reference in new issue
Block a user