Skip to content

Commit

Permalink
#2894 final enter not working because it changes outside the smart range
Browse files Browse the repository at this point in the history
  • Loading branch information
hurricup committed Sep 15, 2024
1 parent 4762ed9 commit e67e3ad
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,12 @@ public boolean isOneLine() {
@Override
public boolean decode(@NotNull TextRange rangeInsideHost, @NotNull StringBuilder outChars) {
var hostTextLength = myHost.getTextLength();
var effectiveRange = rangeInsideHost.getEndOffset() < hostTextLength ?
rangeInsideHost :
TextRange.create(rangeInsideHost.getStartOffset(), rangeInsideHost.getEndOffset() - 1);
if (!effectiveRange.isEmpty()) {
outChars.append(rangeInsideHost.subSequence(myHost.getNode().getChars()));
return true;
}
else {
return false;
var endOffset = rangeInsideHost.getEndOffset();
if (endOffset == hostTextLength) {
endOffset--;
}
outChars.append(myHost.getNode().getChars().subSequence(rangeInsideHost.getStartOffset(), endOffset));
return true;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,34 +32,50 @@
public class PerlHeredocElementManipulator extends AbstractElementManipulator<PerlHeredocElementImpl> {

@Override
public PerlHeredocElementImpl handleContentChange(@NotNull PerlHeredocElementImpl element, @NotNull TextRange range, String newContent)
public PerlHeredocElementImpl handleContentChange(final @NotNull PerlHeredocElementImpl element,
final @NotNull TextRange range,
final String newContent)
throws IncorrectOperationException {
var contentRemoval = newContent.isEmpty();
if (element.getTextLength() == range.getEndOffset() && !contentRemoval && !StringUtil.endsWith(newContent, "\n")) {
newContent += "\n";
var replacementContent = newContent;
var effectiveRange = range;
if (range.isEmpty()) {
// this handles empty heredoc update. We have a single empty shred pointing to the offset of closing \n
effectiveRange = TextRange.create(range.getStartOffset(), element.getTextLength() - 1);
}

var elementText = element.getText();
if (range.getStartOffset() > 0) {
var lineStart = StringUtil.skipWhitespaceBackward(elementText, range.getStartOffset() - 1);
if (lineStart < range.getStartOffset()) {
if (effectiveRange.getStartOffset() > 0) {
var lineStart = getLineStartOffset(elementText, effectiveRange);
if (lineStart < effectiveRange.getStartOffset()) {
if (!contentRemoval) {
var indent = elementText.substring(lineStart, range.getStartOffset());
newContent = prependLines(newContent, indent);
var indent = elementText.substring(lineStart, effectiveRange.getStartOffset());
replacementContent = prependLines(replacementContent, indent);
}
range = TextRange.create(lineStart, range.getEndOffset());
effectiveRange = TextRange.create(lineStart, effectiveRange.getEndOffset());
}
}
else if (range.getStartOffset() == 0) {
newContent = prependLines(newContent, getIndenter(element.getProject(), element.getRealIndentSize()));
else if (effectiveRange.getStartOffset() == 0) {
replacementContent = prependLines(newContent, getIndenter(element.getProject(), element.getRealIndentSize()));
}

String newElementText = range.replace(elementText, newContent);
String newElementText = effectiveRange.replace(elementText, replacementContent);
PerlHeredocElementImpl replacement = PerlElementFactory.createHeredocBodyReplacement(element, newElementText);

return (PerlHeredocElementImpl)element.replace(replacement);
}

private static int getLineStartOffset(@NotNull String elementText, @NotNull TextRange effectiveRange) {
var startOffset = effectiveRange.getStartOffset();
if (startOffset == 0) {
return startOffset;
}
if (elementText.charAt(startOffset - 1) == '\n') {
return startOffset;
}
return StringUtil.skipWhitespaceBackward(elementText, startOffset - 1);
}

private static @NotNull String getIndenter(@NotNull Project project, int indentSize) {
CommonCodeStyleSettings.IndentOptions indentOptions =
CodeStyle.getSettings(project).getCommonSettings(PerlLanguage.INSTANCE).getIndentOptions();
Expand All @@ -68,6 +84,12 @@ else if (range.getStartOffset() == 0) {
}

private static @NotNull String prependLines(@NotNull String newContent, @NotNull String prefix) {
return prefix + String.join(prefix, StringUtil.split(newContent, "\n", false, true));
var result = new StringBuilder();
StringUtil.split(newContent, "\n", false, true)
.forEach(line -> {
result.append(prefix);
result.append(line);
});
return result.toString();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2022 Alexandr Evstigneev
* Copyright 2015-2024 Alexandr Evstigneev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -107,7 +107,8 @@ private void addPlace(@NotNull PerlHeredocElementImpl heredocElement, @NotNull M
while (sourceOffset < sourceLength) {
char currentChar = sourceText.charAt(sourceOffset);
if (currentChar == '\n') {
registrar.addPlace(null, null, heredocElement, TextRange.from(sourceOffset, 1));
var suffix = sourceOffset + 1 < sourceLength ? null : "\n";
registrar.addPlace(null, suffix, heredocElement, TextRange.from(sourceOffset, 1));
currentLineIndent = 0;
}
else if (Character.isWhitespace(currentChar) && currentLineIndent < indentSize) {
Expand All @@ -124,7 +125,9 @@ else if (Character.isWhitespace(currentChar) && currentLineIndent < indentSize)
}
}

registrar.addPlace(null, null, heredocElement, TextRange.create(sourceOffset, sourceEnd));
var suffix = sourceEnd < sourceLength ? null : "\n";

registrar.addPlace(null, suffix, heredocElement, TextRange.create(sourceOffset, sourceEnd));
sourceOffset = sourceEnd;
currentLineIndent = 0;
continue;
Expand Down
24 changes: 13 additions & 11 deletions plugin/src/test/java/intellilang/PerlQuickEditTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class PerlQuickEditTest : PerlLightTestCase() {
hello
there
</html>
</div>""".trimIndent(), myFixture.editor.document.text.trim().replace(Regex("[ \t]+\n"), "\n")
</div>""".trimIndent(), myFixture.editor.document.text.trim().trimLines()
)

assertEquals(
Expand Down Expand Up @@ -79,7 +79,7 @@ class PerlQuickEditTest : PerlLightTestCase() {
hello
there
""".trimIndent(), myFixture.editor.document.text.trim().replace(Regex("[ \t]+\n"), "\n")
""".trimIndent(), myFixture.editor.document.text.trim().trimLines()
)

assertEquals(
Expand Down Expand Up @@ -117,7 +117,7 @@ class PerlQuickEditTest : PerlLightTestCase() {
<div>
<html>
</html>
</div>""".trimIndent(), myFixture.editor.document.text.trim().replace(Regex("[ \t]+\n"), "\n")
</div>""".trimIndent(), myFixture.editor.document.text.trim().trimLines()
)

assertEquals(
Expand Down Expand Up @@ -155,15 +155,13 @@ class PerlQuickEditTest : PerlLightTestCase() {
""
)

myFixture.type("\n hello\n there\n")
myFixture.type("\nhello\n there\n")
assertFalse(myFixture.editor.isDisposed)
assertEquals(
"""
hello
hello
there
""".trimIndent(), myFixture.editor.document.text.trim().replace(Regex("[ \t]+\n"), "\n")
""".trimIndent(), myFixture.editor.document.text.trim().trimLines()
)

assertEquals(
Expand All @@ -173,11 +171,11 @@ class PerlQuickEditTest : PerlLightTestCase() {
sub foo{
say <<~HTML;
hello
hello
there
HTML
}""".trimIndent(), originalEditor.document.text
}""".trimIndent().trimLines(), originalEditor.document.text.trimLines()
)
}

Expand All @@ -192,7 +190,7 @@ class PerlQuickEditTest : PerlLightTestCase() {
"""
hello
there
""".trimIndent(), myFixture.editor.document.text.trim().replace(Regex("[ \t]+\n"), "\n")
""".trimIndent(), myFixture.editor.document.text.trim().trimLines()
)

assertEquals(
Expand Down Expand Up @@ -244,4 +242,8 @@ class PerlQuickEditTest : PerlLightTestCase() {
return if (r == -1) -1 else r + string.length
}

private fun String.trimLines(): String {
return replace(Regex("[ \t]+\n"), "\n")
}

}

0 comments on commit e67e3ad

Please sign in to comment.