feat: String conversion intentions
This commit is contained in:
parent
824f797eaa
commit
bac9a8f8d1
4 changed files with 147 additions and 0 deletions
|
@ -21,6 +21,7 @@ Changelog structure reference:
|
||||||
|
|
||||||
- Zig
|
- Zig
|
||||||
- Enter key handling in strings and multi line strings
|
- Enter key handling in strings and multi line strings
|
||||||
|
- Intentions for converting between multi line and quoted strings
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,17 @@
|
||||||
id="ZigEnterInQuotedStringHandler"
|
id="ZigEnterInQuotedStringHandler"
|
||||||
implementation="com.falsepattern.zigbrains.zig.editing.ZigEnterInQuotedStringHandler" />
|
implementation="com.falsepattern.zigbrains.zig.editing.ZigEnterInQuotedStringHandler" />
|
||||||
|
|
||||||
|
<intentionAction>
|
||||||
|
<language>Zig</language>
|
||||||
|
<className>com.falsepattern.zigbrains.zig.intentions.MakeStringMultiline</className>
|
||||||
|
<category>Zig intentions</category>
|
||||||
|
</intentionAction>
|
||||||
|
<intentionAction>
|
||||||
|
<language>Zig</language>
|
||||||
|
<className>com.falsepattern.zigbrains.zig.intentions.MakeStringQuoted</className>
|
||||||
|
<category>Zig intentions</category>
|
||||||
|
</intentionAction>
|
||||||
|
|
||||||
<postStartupActivity implementation="com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity"/>
|
<postStartupActivity implementation="com.falsepattern.zigbrains.zig.lsp.ZLSStartupActivity"/>
|
||||||
|
|
||||||
<!-- LSP textDocument/signatureHelp -->
|
<!-- LSP textDocument/signatureHelp -->
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package com.falsepattern.zigbrains.zig.intentions;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigStringLiteral;
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigTypes;
|
||||||
|
import com.falsepattern.zigbrains.zig.util.PsiTextUtil;
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
|
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||||
|
import com.intellij.codeInspection.util.IntentionFamilyName;
|
||||||
|
import com.intellij.codeInspection.util.IntentionName;
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.util.IncorrectOperationException;
|
||||||
|
import lombok.val;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class MakeStringMultiline extends PsiElementBaseIntentionAction implements IntentionAction {
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||||
|
val str = PsiTreeUtil.getParentOfType(element, ZigStringLiteral.class);
|
||||||
|
return str != null && !str.isMultiLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element)
|
||||||
|
throws IncorrectOperationException {
|
||||||
|
val str = PsiTreeUtil.getParentOfType(element, ZigStringLiteral.class);
|
||||||
|
if (str == null)
|
||||||
|
return;
|
||||||
|
PsiTextUtil.splitString(editor, str, editor.getCaretModel().getOffset(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @IntentionName String getText() {
|
||||||
|
return getFamilyName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @IntentionFamilyName String getFamilyName() {
|
||||||
|
return "Convert to multiline";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
package com.falsepattern.zigbrains.zig.intentions;
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigStringLiteral;
|
||||||
|
import com.falsepattern.zigbrains.zig.util.PsiTextUtil;
|
||||||
|
import com.falsepattern.zigbrains.zig.util.ZigStringUtil;
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
|
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||||
|
import com.intellij.codeInspection.util.IntentionFamilyName;
|
||||||
|
import com.intellij.codeInspection.util.IntentionName;
|
||||||
|
import com.intellij.formatting.CoreFormatterUtil;
|
||||||
|
import com.intellij.formatting.FormatterEx;
|
||||||
|
import com.intellij.formatting.FormattingModel;
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.TextRange;
|
||||||
|
import com.intellij.psi.PsiDocumentManager;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.util.IncorrectOperationException;
|
||||||
|
import com.intellij.util.MathUtil;
|
||||||
|
import lombok.val;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class MakeStringQuoted extends PsiElementBaseIntentionAction implements IntentionAction {
|
||||||
|
@Override
|
||||||
|
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||||
|
val str = PsiTreeUtil.getParentOfType(element, ZigStringLiteral.class);
|
||||||
|
return str != null && str.isMultiLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element)
|
||||||
|
throws IncorrectOperationException {
|
||||||
|
val document = editor.getDocument();
|
||||||
|
val file = element.getContainingFile();
|
||||||
|
val str = PsiTreeUtil.getParentOfType(element, ZigStringLiteral.class);
|
||||||
|
if (str == null)
|
||||||
|
return;
|
||||||
|
val escaper = str.createLiteralTextEscaper();
|
||||||
|
val contentRange = escaper.getRelevantTextRange();
|
||||||
|
val contentStart = contentRange.getStartOffset();
|
||||||
|
val contentEnd = contentRange.getEndOffset();
|
||||||
|
val fullRange = str.getTextRange();
|
||||||
|
var caretOffset = editor.getCaretModel().getOffset();
|
||||||
|
val prefix = new TextRange(contentStart, Math.max(contentStart, caretOffset - fullRange.getStartOffset()));
|
||||||
|
val suffix = new TextRange(Math.min(contentEnd, caretOffset - fullRange.getStartOffset()), contentEnd);
|
||||||
|
val sb = new StringBuilder();
|
||||||
|
escaper.decode(prefix, sb);
|
||||||
|
val prefixStr = ZigStringUtil.escape(sb.toString());
|
||||||
|
sb.setLength(0);
|
||||||
|
escaper.decode(suffix, sb);
|
||||||
|
val suffixStr = ZigStringUtil.escape(sb.toString());
|
||||||
|
val stringRange = document.createRangeMarker(fullRange.getStartOffset(), fullRange.getEndOffset());
|
||||||
|
stringRange.setGreedyToRight(true);
|
||||||
|
document.deleteString(stringRange.getStartOffset(), stringRange.getEndOffset());
|
||||||
|
document.insertString(stringRange.getEndOffset(), "\"");
|
||||||
|
document.insertString(stringRange.getEndOffset(), prefixStr);
|
||||||
|
caretOffset = stringRange.getEndOffset();
|
||||||
|
document.insertString(stringRange.getEndOffset(), suffixStr);
|
||||||
|
document.insertString(stringRange.getEndOffset(), "\"");
|
||||||
|
val documentText = document.getCharsSequence();
|
||||||
|
int scanStart = stringRange.getEndOffset();
|
||||||
|
stringRange.dispose();
|
||||||
|
int scanEnd = scanStart;
|
||||||
|
loop:
|
||||||
|
while (scanEnd < documentText.length()) {
|
||||||
|
switch (documentText.charAt(scanEnd)) {
|
||||||
|
case ' ', '\t':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
scanEnd++;
|
||||||
|
}
|
||||||
|
if (scanEnd > scanStart) {
|
||||||
|
document.deleteString(scanStart, scanEnd);
|
||||||
|
}
|
||||||
|
editor.getCaretModel().moveToOffset(caretOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @IntentionName String getText() {
|
||||||
|
return getFamilyName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull @IntentionFamilyName String getFamilyName() {
|
||||||
|
return "Convert to quoted";
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue