mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-17 02:08:30 +00:00
Merge #5285
5285: Don't mess with cursor position when adding hashes r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
5fc84f071d
4 changed files with 34 additions and 16 deletions
|
@ -1,5 +1,7 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use ra_syntax::{
|
||||
ast::{self, HasStringValue},
|
||||
ast::{self, HasQuotes, HasStringValue},
|
||||
AstToken,
|
||||
SyntaxKind::{RAW_STRING, STRING},
|
||||
TextSize,
|
||||
|
@ -32,14 +34,17 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext) -> Option<
|
|||
target,
|
||||
|edit| {
|
||||
let max_hash_streak = count_hashes(&value);
|
||||
let mut hashes = String::with_capacity(max_hash_streak + 1);
|
||||
for _ in 0..hashes.capacity() {
|
||||
hashes.push('#');
|
||||
let hashes = "#".repeat(max_hash_streak + 1);
|
||||
if matches!(value, Cow::Borrowed(_)) {
|
||||
// Avoid replacing the whole string to better position the cursor.
|
||||
edit.insert(token.syntax().text_range().start(), format!("r{}", hashes));
|
||||
edit.insert(token.syntax().text_range().end(), format!("{}", hashes));
|
||||
} else {
|
||||
edit.replace(
|
||||
token.syntax().text_range(),
|
||||
format!("r{}\"{}\"{}", hashes, value, hashes),
|
||||
);
|
||||
}
|
||||
edit.replace(
|
||||
token.syntax().text_range(),
|
||||
format!("r{}\"{}\"{}", hashes, value, hashes),
|
||||
);
|
||||
},
|
||||
)
|
||||
}
|
||||
|
@ -70,6 +75,14 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext) -> Optio
|
|||
|edit| {
|
||||
// parse inside string to escape `"`
|
||||
let escaped = value.escape_default().to_string();
|
||||
if let Some(offsets) = token.quote_offsets() {
|
||||
if token.text()[offsets.contents - token.syntax().text_range().start()] == escaped {
|
||||
edit.replace(offsets.quotes.0, "\"");
|
||||
edit.replace(offsets.quotes.1, "\"");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
edit.replace(token.syntax().text_range(), format!("\"{}\"", escaped));
|
||||
},
|
||||
)
|
||||
|
|
|
@ -272,7 +272,7 @@ fn format_args_expand(
|
|||
fn unquote_str(lit: &tt::Literal) -> Option<String> {
|
||||
let lit = ast::make::tokens::literal(&lit.to_string());
|
||||
let token = ast::String::cast(lit)?;
|
||||
token.value()
|
||||
token.value().map(|it| it.into_owned())
|
||||
}
|
||||
|
||||
fn concat_expand(
|
||||
|
|
|
@ -25,7 +25,7 @@ pub(super) fn highlight_injection(
|
|||
return None;
|
||||
}
|
||||
let value = literal.value()?;
|
||||
let (analysis, tmp_file_id) = Analysis::from_single_file(value);
|
||||
let (analysis, tmp_file_id) = Analysis::from_single_file(value.into_owned());
|
||||
|
||||
if let Some(range) = literal.open_quote_text_range() {
|
||||
acc.add(HighlightedRange {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
//! There are many AstNodes, but only a few tokens, so we hand-write them here.
|
||||
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
convert::{TryFrom, TryInto},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ast::{AstToken, Comment, RawString, String, Whitespace},
|
||||
|
@ -138,11 +141,11 @@ impl HasQuotes for String {}
|
|||
impl HasQuotes for RawString {}
|
||||
|
||||
pub trait HasStringValue: HasQuotes {
|
||||
fn value(&self) -> Option<std::string::String>;
|
||||
fn value(&self) -> Option<Cow<'_, str>>;
|
||||
}
|
||||
|
||||
impl HasStringValue for String {
|
||||
fn value(&self) -> Option<std::string::String> {
|
||||
fn value(&self) -> Option<Cow<'_, str>> {
|
||||
let text = self.text().as_str();
|
||||
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
|
||||
|
||||
|
@ -156,15 +159,17 @@ impl HasStringValue for String {
|
|||
if has_error {
|
||||
return None;
|
||||
}
|
||||
Some(buf)
|
||||
// FIXME: don't actually allocate for borrowed case
|
||||
let res = if buf == text { Cow::Borrowed(text) } else { Cow::Owned(buf) };
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasStringValue for RawString {
|
||||
fn value(&self) -> Option<std::string::String> {
|
||||
fn value(&self) -> Option<Cow<'_, str>> {
|
||||
let text = self.text().as_str();
|
||||
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
|
||||
Some(text.to_string())
|
||||
Some(Cow::Borrowed(text))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue