Intellij 插件:xml 文件的目的是用具有相同值的不同前缀的两个自定义属性替换一个属性

Intellij plugin: Intention for xml file that replace an attribute with two custom attribute with different prefix with same value

我想在插件上为 XML 文件中的意图执行以下操作。

当您位于 xml 属性(光标在文本上)时出现意图

调用意图时,我想向标签标签添加两个属性,如下所示:

将 text="hello" 替换为 i:text="hello" a:text="hello"

的代码是什么

我试过下面的代码:

import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.XmlElementFactory;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlToken;
import com.intellij.util.IncorrectOperationException;
import org.igu.plugins.nativescript.NsBundle;
import org.igu.plugins.nativescript.NsFacade;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;

/**
 */
public class PlatformSpecificPropertyValue extends PsiElementBaseIntentionAction {

    public PlatformSpecificPropertyValue() {
        setText(NsBundle.message("intention.declare.platform.specific.property.value"));
    }

    @Override
    public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement psiElement) throws IncorrectOperationException {
        if (psiElement instanceof XmlToken) {
            XmlToken xmlToken = (XmlToken) psiElement;
            final PsiElement parent = xmlToken.getParent();
            if (parent instanceof XmlAttribute) {
                XmlAttribute xmlAttribute = (XmlAttribute) parent;
                String localName = xmlAttribute.getLocalName();
                String value = xmlAttribute.getValue();
                final XmlTag tag = xmlAttribute.getParent();
                final XmlAttribute iAttribute = XmlElementFactory.getInstance(project).createAttribute("i:"+localName, value, tag);
                final XmlAttribute aAttribute = XmlElementFactory.getInstance(project).createAttribute("a:"+localName, value, tag);
                if (!FileModificationService.getInstance().prepareFileForWrite(xmlAttribute.getContainingFile())) {
                    return;
                }

                new WriteCommandAction(project, tag.getContainingFile()) {
                    @Override
                    protected void run(@NotNull Result result) throws Throwable {
                        tag.addAfter(xmlAttribute, iAttribute);
                        tag.addBefore(xmlAttribute, aAttribute);
                        xmlAttribute.delete();
                    }
                }.execute();


            }
        }
    }

    @Override
    public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement psiElement) {
        return psiElement instanceof XmlToken;
    }

    @Nls
    @NotNull
    @Override
    public String getFamilyName() {
        return getText();
    }
}

谢谢。

您交换了 addAfter()addBefore() 的两个参数:

/**
 * Adds a child to this PSI element, after the specified anchor element.
 *
 * @param element the child element to add.
 * @param anchor  the anchor after which the child element is inserted (must be a child of this PSI element)
 * @return the element which was actually added (either <code>element</code> or its copy).
 * @throws IncorrectOperationException if the modification is not supported or not possible for some reason.
 */
PsiElement addAfter(@NotNull PsiElement element, @Nullable PsiElement anchor) throws IncorrectOperationException;

正确的代码应该是:

tag.addAfter(iAttribute, xmlAttribute);
tag.addBefore(aAttribute, xmlAttribute);
xmlAttribute.delete();