mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-22 01:16:18 +04:00
Join single-line comments with J. (#11742)
Fixes #8565. Co-authored-by: Rose Hogenson <rosehogenson@posteo.net>
This commit is contained in:
parent
d6eb10d9f9
commit
8b1764d164
@ -4626,6 +4626,14 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
|
||||
let text = doc.text();
|
||||
let slice = text.slice(..);
|
||||
|
||||
let comment_tokens = doc
|
||||
.language_config()
|
||||
.and_then(|config| config.comment_tokens.as_deref())
|
||||
.unwrap_or(&[]);
|
||||
// Sort by length to handle Rust's /// vs //
|
||||
let mut comment_tokens: Vec<&str> = comment_tokens.iter().map(|x| x.as_str()).collect();
|
||||
comment_tokens.sort_unstable_by_key(|x| std::cmp::Reverse(x.len()));
|
||||
|
||||
let mut changes = Vec::new();
|
||||
|
||||
for selection in doc.selection(view.id) {
|
||||
@ -4637,10 +4645,31 @@ fn join_selections_impl(cx: &mut Context, select_space: bool) {
|
||||
|
||||
changes.reserve(lines.len());
|
||||
|
||||
let first_line_idx = slice.line_to_char(start);
|
||||
let first_line_idx = skip_while(slice, first_line_idx, |ch| matches!(ch, ' ' | 't'))
|
||||
.unwrap_or(first_line_idx);
|
||||
let first_line = slice.slice(first_line_idx..);
|
||||
let mut current_comment_token = comment_tokens
|
||||
.iter()
|
||||
.find(|token| first_line.starts_with(token));
|
||||
|
||||
for line in lines {
|
||||
let start = line_end_char_index(&slice, line);
|
||||
let mut end = text.line_to_char(line + 1);
|
||||
end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\t')).unwrap_or(end);
|
||||
let slice_from_end = slice.slice(end..);
|
||||
if let Some(token) = comment_tokens
|
||||
.iter()
|
||||
.find(|token| slice_from_end.starts_with(token))
|
||||
{
|
||||
if Some(token) == current_comment_token {
|
||||
end += token.chars().count();
|
||||
end = skip_while(slice, end, |ch| matches!(ch, ' ' | '\t')).unwrap_or(end);
|
||||
} else {
|
||||
// update current token, but don't delete this one.
|
||||
current_comment_token = Some(token);
|
||||
}
|
||||
}
|
||||
|
||||
let separator = if end == line_end_char_index(&slice, line + 1) {
|
||||
// the joining line contains only space-characters => don't include a whitespace when joining
|
||||
|
@ -632,6 +632,41 @@ async fn test_join_selections_space() -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_join_selections_comment() -> anyhow::Result<()> {
|
||||
test((
|
||||
indoc! {"\
|
||||
/// #[a|]#bc
|
||||
/// def
|
||||
"},
|
||||
":lang rust<ret>J",
|
||||
indoc! {"\
|
||||
/// #[a|]#bc def
|
||||
"},
|
||||
))
|
||||
.await?;
|
||||
|
||||
// Only join if the comment token matches the previous line.
|
||||
test((
|
||||
indoc! {"\
|
||||
#[| // a
|
||||
// b
|
||||
/// c
|
||||
/// d
|
||||
e
|
||||
/// f
|
||||
// g]#
|
||||
"},
|
||||
":lang rust<ret>J",
|
||||
indoc! {"\
|
||||
#[| // a b /// c d e f // g]#
|
||||
"},
|
||||
))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_read_file() -> anyhow::Result<()> {
|
||||
let mut file = tempfile::NamedTempFile::new()?;
|
||||
|
Loading…
Reference in New Issue
Block a user