Migrate raw_string assist to use SyntaxEditor
This commit is contained in:
parent
ddf8dd7875
commit
d1ecdca22f
1 changed files with 45 additions and 40 deletions
|
|
@ -1,6 +1,8 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use syntax::{AstToken, TextRange, TextSize, ast, ast::IsString};
|
||||
use ide_db::source_change::SourceChangeBuilder;
|
||||
use syntax::{
|
||||
AstToken,
|
||||
ast::{self, IsString, make::tokens::literal},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
AssistContext, AssistId, Assists,
|
||||
|
|
@ -35,17 +37,10 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opt
|
|||
target,
|
||||
|edit| {
|
||||
let hashes = "#".repeat(required_hashes(&value).max(1));
|
||||
let range = token.syntax().text_range();
|
||||
let raw_prefix = token.raw_prefix();
|
||||
let suffix = string_suffix(token.text()).unwrap_or_default();
|
||||
let range = TextRange::new(range.start(), range.end() - TextSize::of(suffix));
|
||||
if matches!(value, Cow::Borrowed(_)) {
|
||||
// Avoid replacing the whole string to better position the cursor.
|
||||
edit.insert(range.start(), format!("{raw_prefix}{hashes}"));
|
||||
edit.insert(range.end(), hashes);
|
||||
} else {
|
||||
edit.replace(range, format!("{raw_prefix}{hashes}\"{value}\"{hashes}"));
|
||||
}
|
||||
let new_str = format!("{raw_prefix}{hashes}\"{value}\"{hashes}{suffix}");
|
||||
replace_literal(&token, &new_str, edit, ctx);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -81,21 +76,8 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> O
|
|||
let escaped = value.escape_default().to_string();
|
||||
let suffix = string_suffix(token.text()).unwrap_or_default();
|
||||
let prefix = string_prefix(token.text()).map_or("", |s| s.trim_end_matches('r'));
|
||||
if let Some(offsets) = token.quote_offsets()
|
||||
&& token.text()[offsets.contents - token.syntax().text_range().start()] == escaped
|
||||
{
|
||||
let start_quote = offsets.quotes.0;
|
||||
let start_quote =
|
||||
TextRange::new(start_quote.start() + TextSize::of(prefix), start_quote.end());
|
||||
let end_quote = offsets.quotes.1;
|
||||
let end_quote =
|
||||
TextRange::new(end_quote.start(), end_quote.end() - TextSize::of(suffix));
|
||||
edit.replace(end_quote, "\"");
|
||||
edit.replace(start_quote, "\"");
|
||||
return;
|
||||
}
|
||||
|
||||
edit.replace(token.syntax().text_range(), format!("{prefix}\"{escaped}\"{suffix}"));
|
||||
let new_str = format!("{prefix}\"{escaped}\"{suffix}");
|
||||
replace_literal(&token, &new_str, edit, ctx);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -120,12 +102,14 @@ pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()>
|
|||
if !token.is_raw() {
|
||||
return None;
|
||||
}
|
||||
let text_range = token.syntax().text_range();
|
||||
let target = text_range;
|
||||
let target = token.syntax().text_range();
|
||||
acc.add(AssistId::refactor("add_hash"), "Add #", target, |edit| {
|
||||
let suffix = string_suffix(token.text()).unwrap_or_default();
|
||||
edit.insert(text_range.start() + TextSize::of(token.raw_prefix()), "#");
|
||||
edit.insert(text_range.end() - TextSize::of(suffix), "#");
|
||||
let str = token.text();
|
||||
let suffix = string_suffix(str).unwrap_or_default();
|
||||
let raw_prefix = token.raw_prefix();
|
||||
let wrap_range = raw_prefix.len()..str.len() - suffix.len();
|
||||
let new_str = [raw_prefix, "#", &str[wrap_range], "#", suffix].concat();
|
||||
replace_literal(&token, &new_str, edit, ctx);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -165,17 +149,38 @@ pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
|
|||
|
||||
acc.add(AssistId::refactor_rewrite("remove_hash"), "Remove #", text_range, |edit| {
|
||||
let suffix = string_suffix(text).unwrap_or_default();
|
||||
edit.delete(TextRange::at(
|
||||
text_range.start() + TextSize::of(token.raw_prefix()),
|
||||
TextSize::of('#'),
|
||||
));
|
||||
edit.delete(
|
||||
TextRange::new(text_range.end() - TextSize::of('#'), text_range.end())
|
||||
- TextSize::of(suffix),
|
||||
);
|
||||
let prefix = token.raw_prefix();
|
||||
let wrap_range = prefix.len() + 1..text.len() - suffix.len() - 1;
|
||||
let new_str = [prefix, &text[wrap_range], suffix].concat();
|
||||
replace_literal(&token, &new_str, edit, ctx);
|
||||
})
|
||||
}
|
||||
|
||||
fn replace_literal(
|
||||
token: &impl AstToken,
|
||||
new: &str,
|
||||
builder: &mut SourceChangeBuilder,
|
||||
ctx: &AssistContext<'_>,
|
||||
) {
|
||||
let token = token.syntax();
|
||||
let node = token.parent().expect("no parent token");
|
||||
let mut edit = builder.make_editor(&node);
|
||||
let new_literal = literal(new);
|
||||
|
||||
edit.replace(token, mut_token(new_literal));
|
||||
|
||||
builder.add_file_edits(ctx.vfs_file_id(), edit);
|
||||
}
|
||||
|
||||
fn mut_token(token: syntax::SyntaxToken) -> syntax::SyntaxToken {
|
||||
let node = token.parent().expect("no parent token");
|
||||
node.clone_for_update()
|
||||
.children_with_tokens()
|
||||
.filter_map(|it| it.into_token())
|
||||
.find(|it| it.text_range() == token.text_range() && it.text() == token.text())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue