How to add text to an empty file? Follow
How can I update a IDocument object for an empty file? Everything I try throws an exception saying that a document can not be updated during a PSI transaction.
I've tried this
IProjectFile newFile = AddNewItemUtil.AddFile(folder, unitTest + ".cs"); IDocument doc = newFile.GetDocument(); doc.InsertText(0, "public class test {}");
And I've tried this
IProjectFile newFile = AddNewItemUtil.AddFile(folder, unitTest + ".cs"); IDocument doc = newFile.GetDocument(); pModule.GetPsiServices().Transactions.Execute("Write test class", () => { doc.InsertText(0, "public class test {}"); });
Please, can someone answer. I have googled, browse codeplex and github, searched these forums, but can not figure it out.
Please sign in to leave a comment.
You can't modify the document during a PSI transaction - ReSharper is expecting the PSI (that is, the abstract syntax tree) to be modified, and it will resync the document once the PSI transaction is committed. So, you could add content via the PSI, using something like CSharpElementFactory, or you need to start a document transaction, using DocumentTransactionManager.CreateTransactionCookie(DefaultAction.Commit, "useful debugging id")
Thanks Matt,
I've had success adding things to an existing ICSharpFile because I can get a reference to it from ICSharpContextActionDataProvider.PsiFile, but when I add a new file to a project I'm stuck.
How do I get a reference to ICSharpFile from the IProjectFile reference above?
Once I have ICSharpFile I think I'll be able to do the rest on my own.
You can use the ToSourceFile() extension method on IProjectFile.
Okay, but ToSourceFile() returns IPsiSourceFile and ICSharpFile does not implement that interface.
Am I to cast from IPsiSourceFile to ICSharpFile?
I think I figured it out.
Is this the correct way to get the ICSharpFile reference?
Gah! Half an answer. Sorry. That will do the trick, but it's better to call one of the overloaded GetPsiFiles methods. These defer to the cached files, but will also make sure the cache is primed first. There are also a couple of helper extension methods such as GetPrimaryPsiFile that simplify the method call (primary is the main language of the file, e.g. C#. Secondary is the tree for a "code behind file", e.g. the generated C# of an aspx file. Dominant is either the primary file, or the language of the code behind file, if there isn't a primary). And then once you've got the IFile, you need to downcast that to ICSharpFile.