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
|
||||
- Enter key handling in strings and multi line strings
|
||||
- Intentions for converting between multi line and quoted strings
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -39,6 +39,17 @@
|
|||
id="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"/>
|
||||
|
||||
<!-- 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