use crate::bib::ast::{cite_key, fields};
use crate::bib::syntax::{SyntaxKind, SyntaxNode};
use crate::linter::Fix;
pub fn field_deletion_fix(field: &SyntaxNode, description: String) -> Option<Fix> {
let entry = field.parent()?;
if entry.kind() != SyntaxKind::ENTRY {
return None;
}
let siblings: Vec<SyntaxNode> = fields(&entry).collect();
let index = siblings.iter().position(|f| f == field)?;
let (start, end) = if siblings.len() == 1 {
let (_, key_range) = cite_key(&entry)?;
let close = entry
.children_with_tokens()
.filter_map(|e| e.into_token())
.filter(|t| matches!(t.kind(), SyntaxKind::R_BRACE | SyntaxKind::R_PAREN))
.last()?;
(
usize::from(key_range.end()),
usize::from(close.text_range().start()),
)
} else if index + 1 == siblings.len() {
let prev = &siblings[index - 1];
(usize::from(prev.text_range().end()), content_end(field))
} else {
let next = &siblings[index + 1];
(
usize::from(field.text_range().start()),
usize::from(next.text_range().start()),
)
};
Some(Fix::safe(start, end, "", description))
}
fn content_end(field: &SyntaxNode) -> usize {
field
.descendants_with_tokens()
.filter_map(|e| e.into_token())
.filter(|t| !matches!(t.kind(), SyntaxKind::WHITESPACE | SyntaxKind::NEWLINE))
.map(|t| usize::from(t.text_range().end()))
.max()
.unwrap_or_else(|| usize::from(field.text_range().end()))
}