aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-07-09 18:21:41 +0100
committerAleksey Kladov <[email protected]>2020-07-09 18:21:41 +0100
commit68706b59c9177db2a6dd276e1ce599d8fe5942c1 (patch)
tree9cc123ba4b246b2c6f150bee3e39d8d6fd35505c /crates
parent1fb92d791e44d3b225f73d9160de173f255ab881 (diff)
Don't mess with cursor position when adding hashes
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_assists/src/handlers/raw_string.rs31
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs2
-rw-r--r--crates/ra_ide/src/syntax_highlighting/injection.rs2
-rw-r--r--crates/ra_syntax/src/ast/tokens.rs17
4 files changed, 35 insertions, 17 deletions
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs
index 96679e160..6d77dff13 100644
--- a/crates/ra_assists/src/handlers/raw_string.rs
+++ b/crates/ra_assists/src/handlers/raw_string.rs
@@ -1,5 +1,7 @@
1use std::borrow::Cow;
2
1use ra_syntax::{ 3use ra_syntax::{
2 ast::{self, HasStringValue}, 4 ast::{self, HasQuotes, HasStringValue},
3 AstToken, 5 AstToken,
4 SyntaxKind::{RAW_STRING, STRING}, 6 SyntaxKind::{RAW_STRING, STRING},
5 TextSize, 7 TextSize,
@@ -32,14 +34,17 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext) -> Option<
32 target, 34 target,
33 |edit| { 35 |edit| {
34 let max_hash_streak = count_hashes(&value); 36 let max_hash_streak = count_hashes(&value);
35 let mut hashes = String::with_capacity(max_hash_streak + 1); 37 let hashes = "#".repeat(max_hash_streak + 1);
36 for _ in 0..hashes.capacity() { 38 if matches!(value, Cow::Borrowed(_)) {
37 hashes.push('#'); 39 // Avoid replacing the whole string to better position the cursor.
38 } 40 edit.insert(token.syntax().text_range().start(), format!("r{}", hashes));
39 edit.replace( 41 edit.insert(token.syntax().text_range().end(), format!("{}", hashes));
40 token.syntax().text_range(), 42 } else {
41 format!("r{}\"{}\"{}", hashes, value, hashes), 43 edit.replace(
42 ); 44 token.syntax().text_range(),
45 format!("r{}\"{}\"{}", hashes, value, hashes),
46 );
47 }
43 }, 48 },
44 ) 49 )
45} 50}
@@ -70,6 +75,14 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext) -> Optio
70 |edit| { 75 |edit| {
71 // parse inside string to escape `"` 76 // parse inside string to escape `"`
72 let escaped = value.escape_default().to_string(); 77 let escaped = value.escape_default().to_string();
78 if let Some(offsets) = token.quote_offsets() {
79 if token.text()[offsets.contents - token.syntax().text_range().start()] == escaped {
80 edit.replace(offsets.quotes.0, "\"");
81 edit.replace(offsets.quotes.1, "\"");
82 return;
83 }
84 }
85
73 edit.replace(token.syntax().text_range(), format!("\"{}\"", escaped)); 86 edit.replace(token.syntax().text_range(), format!("\"{}\"", escaped));
74 }, 87 },
75 ) 88 )
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index 626f9efd0..9f50569dc 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -272,7 +272,7 @@ fn format_args_expand(
272fn unquote_str(lit: &tt::Literal) -> Option<String> { 272fn unquote_str(lit: &tt::Literal) -> Option<String> {
273 let lit = ast::make::tokens::literal(&lit.to_string()); 273 let lit = ast::make::tokens::literal(&lit.to_string());
274 let token = ast::String::cast(lit)?; 274 let token = ast::String::cast(lit)?;
275 token.value() 275 token.value().map(|it| it.into_owned())
276} 276}
277 277
278fn concat_expand( 278fn concat_expand(
diff --git a/crates/ra_ide/src/syntax_highlighting/injection.rs b/crates/ra_ide/src/syntax_highlighting/injection.rs
index 181c21256..8665b480f 100644
--- a/crates/ra_ide/src/syntax_highlighting/injection.rs
+++ b/crates/ra_ide/src/syntax_highlighting/injection.rs
@@ -25,7 +25,7 @@ pub(super) fn highlight_injection(
25 return None; 25 return None;
26 } 26 }
27 let value = literal.value()?; 27 let value = literal.value()?;
28 let (analysis, tmp_file_id) = Analysis::from_single_file(value); 28 let (analysis, tmp_file_id) = Analysis::from_single_file(value.into_owned());
29 29
30 if let Some(range) = literal.open_quote_text_range() { 30 if let Some(range) = literal.open_quote_text_range() {
31 acc.add(HighlightedRange { 31 acc.add(HighlightedRange {
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs
index 2e72d4927..045f69133 100644
--- a/crates/ra_syntax/src/ast/tokens.rs
+++ b/crates/ra_syntax/src/ast/tokens.rs
@@ -1,6 +1,9 @@
1//! There are many AstNodes, but only a few tokens, so we hand-write them here. 1//! There are many AstNodes, but only a few tokens, so we hand-write them here.
2 2
3use std::convert::{TryFrom, TryInto}; 3use std::{
4 borrow::Cow,
5 convert::{TryFrom, TryInto},
6};
4 7
5use crate::{ 8use crate::{
6 ast::{AstToken, Comment, RawString, String, Whitespace}, 9 ast::{AstToken, Comment, RawString, String, Whitespace},
@@ -138,11 +141,11 @@ impl HasQuotes for String {}
138impl HasQuotes for RawString {} 141impl HasQuotes for RawString {}
139 142
140pub trait HasStringValue: HasQuotes { 143pub trait HasStringValue: HasQuotes {
141 fn value(&self) -> Option<std::string::String>; 144 fn value(&self) -> Option<Cow<'_, str>>;
142} 145}
143 146
144impl HasStringValue for String { 147impl HasStringValue for String {
145 fn value(&self) -> Option<std::string::String> { 148 fn value(&self) -> Option<Cow<'_, str>> {
146 let text = self.text().as_str(); 149 let text = self.text().as_str();
147 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; 150 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
148 151
@@ -156,15 +159,17 @@ impl HasStringValue for String {
156 if has_error { 159 if has_error {
157 return None; 160 return None;
158 } 161 }
159 Some(buf) 162 // FIXME: don't actually allocate for borrowed case
163 let res = if buf == text { Cow::Borrowed(text) } else { Cow::Owned(buf) };
164 Some(res)
160 } 165 }
161} 166}
162 167
163impl HasStringValue for RawString { 168impl HasStringValue for RawString {
164 fn value(&self) -> Option<std::string::String> { 169 fn value(&self) -> Option<Cow<'_, str>> {
165 let text = self.text().as_str(); 170 let text = self.text().as_str();
166 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()]; 171 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
167 Some(text.to_string()) 172 Some(Cow::Borrowed(text))
168 } 173 }
169} 174}
170 175