mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
text blocks: add text block escaping (only escape """ and \) when pasting (IDEA-217353)
GitOrigin-RevId: 03db759d2b770edc191aa0614251bdbaaa1742ed
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1094935f12
commit
507c853824
+6
-20
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.application.options.CodeStyle;
|
||||
@@ -135,7 +121,9 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
return escapeCharCharacters(text, token);
|
||||
}
|
||||
else if (isTextBlock(token)) {
|
||||
return escapeTextBlock(text);
|
||||
final String before = document.getText(new TextRange(selectionStart - 1, selectionStart));
|
||||
final String after = document.getText(new TextRange(selectionEnd, selectionEnd + 1));
|
||||
return escapeTextBlock(text, "\"".equals(before), "\"".equals(after));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
@@ -241,13 +229,11 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String escapeTextBlock(@NotNull String text) {
|
||||
protected String escapeTextBlock(@NotNull String text, boolean escapeStartQuote, boolean escapeEndQuote) {
|
||||
StringBuilder buffer = new StringBuilder(text.length());
|
||||
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
String line = lines[i];
|
||||
//todo don't escape single quote; prefer \""" if the next char is not a quote
|
||||
StringUtil.escapeStringCharacters(line.length(), line, buffer);
|
||||
buffer.append(StringUtil.escapeTextBlockCharacters(lines[i], i == 0 && escapeStartQuote, i == lines.length - 1 && escapeEndQuote));
|
||||
if (i < lines.length - 1) {
|
||||
buffer.append("\n");
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
class C {
|
||||
String empty = """
|
||||
\"\"\"
|
||||
target\"\"\"<caret>""";
|
||||
\"""
|
||||
target\""\"<caret>""";
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
class C {
|
||||
String x = """
|
||||
"\"
|
||||
target\""
|
||||
""";
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class C {
|
||||
String x = """
|
||||
"<caret>"
|
||||
""";
|
||||
}
|
||||
+5
-1
@@ -23,7 +23,11 @@ class JavaTextBlocksHighlightingTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
}
|
||||
|
||||
fun testEscapeQuotes() {
|
||||
doTestPaste("\"\"\"\ntarget\"\"\"".trimIndent())
|
||||
doTestPaste("\"\"\"\ntarget\"\"\"")
|
||||
}
|
||||
|
||||
fun testEscapeQuotes2() {
|
||||
doTestPaste("\"\ntarget\"")
|
||||
}
|
||||
|
||||
fun testNoEscapeWhenNotInTextBlockContent() {
|
||||
|
||||
@@ -641,6 +641,51 @@ public class StringUtil extends StringUtilRt {
|
||||
t != Character.CONTROL && t != Character.FORMAT && t != Character.PRIVATE_USE && t != Character.SURROGATE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
public static String escapeTextBlockCharacters(@NotNull String s) {
|
||||
return escapeTextBlockCharacters(s, false, true);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
public static String escapeTextBlockCharacters(@NotNull String s, boolean escapeStartQuote, boolean escapeEndQuote) {
|
||||
int length = s.length();
|
||||
StringBuilder result = new StringBuilder(length);
|
||||
int q = 0;
|
||||
for (int i = 0; i < length; i++) {
|
||||
char c = s.charAt(i);
|
||||
if (c == '"') {
|
||||
if (escapeStartQuote && i == 0) result.append('\\');
|
||||
q++;
|
||||
}
|
||||
else {
|
||||
appendQuotes(q, result);
|
||||
if (c == '\\') result.append('\\');
|
||||
result.append(c);
|
||||
q = 0;
|
||||
}
|
||||
}
|
||||
appendQuotes(q, result);
|
||||
if (escapeEndQuote && result.charAt(result.length() - 1) == '"') {
|
||||
result.insert(result.length() - 1, '\\');
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static void appendQuotes(int quotes, StringBuilder result) {
|
||||
int q = quotes;
|
||||
while (q > 0) {
|
||||
if (quotes >= 3) result.append('\\');
|
||||
switch (q) {
|
||||
default: result.append('"');
|
||||
case 2: result.append('"');
|
||||
case 1: result.append('"');
|
||||
}
|
||||
q -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
public static String escapeStringCharacters(@NotNull String s) {
|
||||
|
||||
@@ -268,6 +268,12 @@ public class StringUtilTest {
|
||||
assertEquals("AspectJ (Syntax Highlighting Only)", StringUtil.capitalizeWords("AspectJ (syntax highlighting only)", true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEscapeTextBlockCharacters() {
|
||||
assertEquals("\\\"\"\"\\\"\"\"\\\"\\\"", StringUtil.escapeTextBlockCharacters("\"\"\"\"\"\"\"\"", false, true));
|
||||
assertEquals("\\\\", StringUtil.escapeTextBlockCharacters("\\", false, true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEscapeStringCharacters() {
|
||||
assertEquals("\\\"\\n", StringUtil.escapeStringCharacters(3, "\\\"\n", "\"", false, new StringBuilder()).toString());
|
||||
|
||||
Reference in New Issue
Block a user