use crate::app::App;
use crate::editor::Cursor;
impl App {
pub fn line_comment_token(&self) -> Option<String> {
let path = self.buffer.path.as_deref()?;
let lang = self.config.languages.by_path(path)?;
lang.comment_token.clone()
}
pub fn block_comment_tokens(&self) -> Option<(String, String)> {
let path = self.buffer.path.as_deref()?;
let lang = self.config.languages.by_path(path)?;
lang.block_comment_token.clone()
}
pub fn apply_line_comment(&mut self, rows: &[usize]) -> bool {
let Some(tok) = self.line_comment_token() else {
return false;
};
self.buffer.toggle_block_comment(&tok, rows);
true
}
pub fn apply_block_comment(
&mut self,
rows: &[usize],
range: Option<(Cursor, Cursor)>,
) -> bool {
match self.block_comment_tokens() {
Some((open, close)) => {
let (lo, hi) = range.unwrap_or_else(|| {
let lo_row = rows.iter().min().copied().unwrap_or(0);
let hi_row = rows.iter().max().copied().unwrap_or(0);
let hi_col = self.buffer.lines[hi_row].chars().count();
(
Cursor {
row: lo_row,
col: 0,
},
Cursor {
row: hi_row,
col: hi_col,
},
)
});
let (lo, hi) = trim_blank_edges(&self.buffer.lines, lo, hi);
self.buffer.toggle_block_wrap(&open, &close, lo, hi);
true
}
None => self.apply_line_comment(rows),
}
}
}
fn trim_blank_edges(lines: &[String], lo: Cursor, hi: Cursor) -> (Cursor, Cursor) {
if lo.col != 0 {
return (lo, hi);
}
let hi_at_boundary = hi.col == 0 || hi.col == lines[hi.row].chars().count();
if !hi_at_boundary {
return (lo, hi);
}
let last_content_row = if hi.col == 0 && hi.row > 0 {
hi.row - 1
} else {
hi.row
};
let is_blank = |r: usize| lines[r].chars().all(|c| c.is_whitespace());
let mut first = lo.row;
while first <= last_content_row && is_blank(first) {
first += 1;
}
if first > last_content_row {
return (lo, hi);
}
let mut last = last_content_row;
while last > first && is_blank(last) {
last -= 1;
}
let new_lo = Cursor {
row: first,
col: 0,
};
let new_hi = if hi.col == 0 {
Cursor {
row: last + 1,
col: 0,
}
} else {
Cursor {
row: last,
col: lines[last].chars().count(),
}
};
(new_lo, new_hi)
}