WriteCommandAction deleting values instead replacing

Answered

Here is my code written in one on AnAction classes:

@Override
public void actionPerformed(@NotNull AnActionEvent e) {
    //get current file
    PsiFile currentFile = e.getData(LangDataKeys.PSI_FILE);
    //find element for replacement
    final PsiElement[] last = new PsiElement[1];
    currentFile.accept(new PsiRecursiveElementWalkingVisitor() {
        @Override
        public void visitElement(@NotNull PsiElement element) {
            if(element.getText().equals("property")) {
                last[0] = findValue(element);
            }
            super.visitElement(element);
        }
    });


    WriteCommandAction.runWriteCommandAction(e.getProject(), () -> {
        var what = PsiFileFactory.getInstance(e.getProject())
                .createFileFromText(PlainTextLanguage.INSTANCE, "it's value");
        last[0].replace(what.getLastChild());
    });
}

one more function used within visitElement

private PsiElement findValue(PsiElement element) {
    if (element.getNextSibling() != null) {
        return findValue(element.getNextSibling());
    }
    return element;
}

Sample of properties when code is working and replacement is happen:

one=1
two=2
three=3
property=x

But once I change property position to this:  

one=1
two=2
property=x
three=3

and click 3 times my action button for created AnActionEvent, it will just remove whole line:

click 1: 

one=1
two=2
property=
three=3

click 2:

one=1
two=2
property
three=3

click 3:

one=1
two=2
three=3

 

Any suggestion on how to replace property regardles of it's position in the opened file ? 

0
5 comments

Is this in a .properties file? Why do you generate the new value using PlainTextLanguage.INSTANCE then and not com.intellij.lang.properties.PropertiesLanguage

0

Yann Cebron hi thx for reply, but this class is not available at least for me, should I add dependency for this pack ? 

0

Actually I just checked with proposed PropertiesLanguage.INSTANCE and seems this not help, still removing value on click

When this happen I got this ST: 

2023-08-30 22:45:30,577 [  23447] SEVERE - #c.i.f.RangesAssert - IdeaLoggingEvent[message=nonempty text is not covered by block in #Properties #formatter
Range: [21,32], text fragment: [21,32]
, throwable=com.intellij.diagnostic.PluginException:  [Plugin: com.intellij.properties]
    at com.intellij.diagnostic.PluginProblemReporterImpl.createPluginExceptionByClass(PluginProblemReporterImpl.java:23)
    at com.intellij.diagnostic.PluginException.createByClass(PluginException.java:83)
    at com.intellij.formatting.RangesAssert.assertInvalidRanges(RangesAssert.java:60)
    at com.intellij.formatting.WhiteSpace.changeEndOffset(WhiteSpace.java:127)
    at com.intellij.formatting.InitialInfoBuilder.buildFrom(InitialInfoBuilder.java:132)
    at com.intellij.formatting.InitialInfoBuilder.doIteration(InitialInfoBuilder.java:212)
    at com.intellij.formatting.InitialInfoBuilder.iteration(InitialInfoBuilder.java:109)
    at com.intellij.formatting.engine.WrapBlocksState.doIteration(WrapBlocksState.java:47)
    at com.intellij.formatting.engine.State.iteration(State.java:25)
    at com.intellij.formatting.engine.StateProcessor.iteration(StateProcessor.java:26)
    at com.intellij.formatting.FormatProcessor.iteration(FormatProcessor.java:108)
    at com.intellij.formatting.FormatterImpl$MyFormattingTask.iteration(FormatterImpl.java:687)
    at com.intellij.formatting.FormatterImpl.execute(FormatterImpl.java:267)
    at com.intellij.formatting.FormatterImpl.format(FormatterImpl.java:234)
    at com.intellij.psi.impl.source.codeStyle.CodeFormatterFacade.processText(CodeFormatterFacade.java:197)
    at com.intellij.formatting.service.CoreFormattingService.formatRanges(CoreFormattingService.java:63)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect$ReformatRangesAction.lambda$execute$0(PostprocessReformattingAspect.java:776)
    at com.intellij.util.SlowOperations.allowSlowOperations(SlowOperations.java:149)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect$ReformatRangesAction.execute(PostprocessReformattingAspect.java:776)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.lambda$doPostponedFormattingInner$8(PostprocessReformattingAspect.java:386)
    at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.runWithDocCommentFormattingDisabled(CodeStyleManagerImpl.java:656)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.doPostponedFormattingInner(PostprocessReformattingAspect.java:385)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.lambda$doPostponedFormatting$6(PostprocessReformattingAspect.java:263)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.lambda$disablePostprocessFormattingInside$2(PostprocessReformattingAspect.java:120)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.disablePostprocessFormattingInside(PostprocessReformattingAspect.java:128)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.disablePostprocessFormattingInside(PostprocessReformattingAspect.java:119)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.lambda$doPostponedFormatting$7(PostprocessReformattingAspect.java:263)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeNonCancelableSection$3(CoreProgressManager.java:223)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:683)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:639)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computeInNonCancelableSection(CoreProgressManager.java:238)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeNonCancelableSection(CoreProgressManager.java:222)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.doPostponedFormatting(PostprocessReformattingAspect.java:261)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.doPostponedFormatting(PostprocessReformattingAspect.java:248)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect.decrementPostponedCounter(PostprocessReformattingAspect.java:161)
    at com.intellij.psi.impl.source.PostprocessReformattingAspect$1.writeActionFinished(PostprocessReformattingAspect.java:112)
    at jdk.internal.reflect.GeneratedMethodAccessor37.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at com.intellij.util.EventDispatcher.dispatchVoidMethod(EventDispatcher.java:120)
    at com.intellij.util.EventDispatcher.lambda$createMulticaster$1(EventDispatcher.java:85)
    at jdk.proxy2/jdk.proxy2.$Proxy65.writeActionFinished(Unknown Source)
    at com.intellij.openapi.application.impl.ApplicationImpl.fireWriteActionFinished(ApplicationImpl.java:1406)
    at com.intellij.openapi.application.impl.ApplicationImpl.endWrite(ApplicationImpl.java:1244)
    at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1026)
    at com.intellij.openapi.command.WriteCommandAction$BuilderImpl.lambda$doRunWriteCommandAction$2(WriteCommandAction.java:148)
    at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:219)
    at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:184)
    at com.intellij.openapi.command.WriteCommandAction$BuilderImpl.doRunWriteCommandAction(WriteCommandAction.java:157)
    at com.intellij.openapi.command.WriteCommandAction$BuilderImpl.run(WriteCommandAction.java:124)
    at com.intellij.openapi.command.WriteCommandAction.runWriteCommandAction(WriteCommandAction.java:362)
    at com.intellij.openapi.command.WriteCommandAction.runWriteCommandAction(WriteCommandAction.java:350)
    at com.actions.FindAvailableEnv.actionPerformed(FindAvailableEnv.java:44)
    at com.intellij.openapi.actionSystem.impl.ActionButton.actionPerformed(ActionButton.java:190)
    at com.intellij.openapi.actionSystem.impl.ActionButton.lambda$performAction$0(ActionButton.java:166)
    at com.intellij.openapi.actionSystem.ex.ActionUtil.performDumbAwareWithCallbacks(ActionUtil.java:337)
    at com.intellij.openapi.actionSystem.impl.ActionButton.performAction(ActionButton.java:166)
    at com.intellij.openapi.actionSystem.impl.ActionButton.processMouseEvent(ActionButton.java:465)
    at java.desktop/java.awt.Component.processEvent(Component.java:6413)
    at java.desktop/java.awt.Container.processEvent(Container.java:2266)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5022)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2802)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4854)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:781)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:730)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:724)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:754)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:752)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:751)
    at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:918)
    at com.intellij.ide.IdeEventQueue.dispatchMouseEvent(IdeEventQueue.java:840)
    at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:763)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$6(IdeEventQueue.java:450)
    at com.intellij.openapi.progress.impl.CoreProgressManager.computePrioritized(CoreProgressManager.java:791)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$7(IdeEventQueue.java:449)
    at com.intellij.openapi.application.TransactionGuardImpl.performActivity(TransactionGuardImpl.java:113)
    at com.intellij.ide.IdeEventQueue.performActivity(IdeEventQueue.java:624)
    at com.intellij.ide.IdeEventQueue.lambda$dispatchEvent$8(IdeEventQueue.java:447)
    at com.intellij.openapi.application.impl.ApplicationImpl.runIntendedWriteActionOnCurrentThread(ApplicationImpl.java:881)
    at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:493)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:92)
]
0

Ok I managed to solve that, for those who stuck with the same: 

first need to find element you want to replace in PsiFile 

then create new PsiFile but first replace using regex content to desired ones

then in created PsiFile find element you replaced content for 

and finaly 

replace opened file with element you found in created file, like this:

  @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        PsiFile currentFile = e.getData(LangDataKeys.PSI_FILE);
        final PsiElement[] last = new PsiElement[1];
        Objects.requireNonNull(currentFile).accept(new PsiRecursiveElementWalkingVisitor() {
            @Override
            public void visitElement(@NotNull PsiElement element) {
                if (element.getText().equals(PROPERTY_NAME)) {
                    last[0] = element;
                }
                super.visitElement(element);
            }
        });
        var nextAvailableEnv = getNextAvailableEnvOrFirst(currentAvailableEnvironmentFiles(), findValue(last[0]).getText());
        if (nextAvailableEnv == null) {
            return;
        }
        var newContent = currentFile.getText()
                .replaceAll(REGEX, "=" + nextAvailableEnv.getFileName().toString());

        var created = PsiFileFactory.getInstance(Objects.requireNonNull(e.getProject()))
                .createFileFromText(PropertiesLanguage.INSTANCE, newContent);
        PsiElement[] replacer = new PsiElement[1];
        created.accept(new PsiRecursiveElementWalkingVisitor() {
            @Override
            public void visitElement(@NotNull PsiElement element) {
                if (element.getText().equals(PROPERTY_NAME)) {
                    replacer[0] = findValue(element);
                }
                super.visitElement(element);
            }
        });

        WriteCommandAction.runWriteCommandAction(e.getProject(), () -> {
            last[0].getParent().replace(replacer[0].getParent());
        });
    }
0

Please sign in to leave a comment.