Problem with rename in LocalFileOperationsHandler

I am having a problem with the rename command in the Mercurial plugin. Mercurial has a rename command and that is working fine. The issue is that Idea comes along after the rename command has executed and refactors the class to reflect the name change. The problem seems to be that the refactor is only changing the memory version of the file and not the disk version. When you try and save the changed file (or the auto-save gets around to it) you get a message asking if you want to keep the memory version or the FS version. How can I sync the memory version and the file version when the refactor is happening after my context has returned?

7 comments

Hello Gary,

I am having a problem with the rename command in the Mercurial plugin.
Mercurial has a rename command and that is working fine. The issue is
that Idea comes along after the rename command has executed and
refactors the class to reflect the name change. The problem seems to
be that the refactor is only changing the memory version of the file
and not the disk version. When you try and save the changed file (or
the auto-save gets around to it) you get a message asking if you want
to keep the memory version or the FS version. How can I sync the
memory version and the file version when the refactor is happening
after my context has returned?


You should call VirtualFile.refresh() on the directory containing the renamed
file after you've called Mercurial to perform the operation.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Unfortunately that caused an assertion error -

ERROR - impl.file.impl.FileManagerImpl - Assertion failed: Invalid file: file://C:/Users/gevesson/IdeaProjects/testProject/src/com/test/Test17.java
java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:89)
at com.intellij.psi.impl.file.impl.FileManagerImpl.findFile(FileManagerImpl.java:264)
at com.intellij.psi.impl.PsiManagerImpl.findFile(PsiManagerImpl.java:368)
at com.intellij.psi.impl.file.PsiFileImplUtil.setName(PsiFileImplUtil.java:23)
at com.intellij.psi.impl.source.PsiFileImpl.setName(PsiFileImpl.java:126)
at com.intellij.psi.impl.source.PsiClassImpl.setName(PsiClassImpl.java:326)
at com.intellij.refactoring.rename.RenameUtil.a(RenameUtil.java:337)

The file name is the old name of the file (i.e. the assertion is quite correct. The file was deleted by Mercurial).

0

Hello Gary,

Do you return "true" from your implementation of rename() when you've handled
the rename operation?

Unfortunately that caused an assertion error -

ERROR - impl.file.impl.FileManagerImpl - Assertion failed:
Invalid file:
file://C:/Users/gevesson/IdeaProjects/testProject/src/com/test/Test17.
java
java.lang.Throwable
at com.intellij.openapi.diagnostic.Logger.assertTrue(Logger.java:89)
at
com.intellij.psi.impl.file.impl.FileManagerImpl.findFile(FileManagerIm
pl.java:264)
at
com.intellij.psi.impl.PsiManagerImpl.findFile(PsiManagerImpl.java:368)
at
com.intellij.psi.impl.file.PsiFileImplUtil.setName(PsiFileImplUtil.jav
a:23)
at
com.intellij.psi.impl.source.PsiFileImpl.setName(PsiFileImpl.java:126)
at
com.intellij.psi.impl.source.PsiClassImpl.setName(PsiClassImpl.java:32
6)
at com.intellij.refactoring.rename.RenameUtil.a(RenameUtil.java:337)
The file name is the old name of the file (i.e. the assertion is
quite correct. The file was deleted by Mercurial).

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Hello Gary,

Yep, that's right. Actually the correct place to call refresh() is on the
end of the current command: you need to add a CommandListener and call refresh()
from its commandFinished() method. You can look at SvnFileSystemListener
in the SVN plugin sources to get an example of a working implementation.

Yep. immediately after:

 public boolean rename( VirtualFile file, String newName ) throws
> IOException
> {
> MercurialCommand command = new MercurialCommand( project,
> host.getSettings(), MercurialUtil.getVcsRoot( project, file ) );
> try
> {
> // Get the parent for a refresh.
> VirtualFile parent = file.getParent();
> command.rename( file, newName );
> 
> if( parent != null )
> parent.refresh( false, true );
> // We have done the rename...
> return true;
> }
> catch( VcsException e )
> {
> LOG.error( e );
> }
> return false;
> }
> ]]>

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

I made those changes. Still does not work. Found how CommandListener was implemented in svn4idea, but I could not find where it ever called refresh.

0

Hello Gary,

I made those changes. Still does not work. Found how CommandListener
was implemented in svn4idea, but I could not find where it ever called
refresh.


It's done in SvnFileSystemListener.commandFinished(). The implementation
uses RefreshQueue and RefreshSession to perform a batch VFS refresh for all
files affected by the operation.

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0

Please sign in to leave a comment.