private void DoFormatStatementOnSemicolon(ITextControl textControl) { IFile file = CommitPsi(textControl); if (file == null) { return; } int charPos = TextControlToLexer(textControl, textControl.Caret.Offset()); if (charPos < 0) { return; } var tokenNode = file.FindTokenAt(textControl.Document, charPos - 1) as ITokenNode; if (tokenNode == null || tokenNode.GetTokenType() != PsiTokenType.SEMICOLON) { return; } var node = tokenNode.Parent; // do format if semicolon finished the statement if (node == null || tokenNode.NextSibling != null) { return; } // Select the correct start node for formatting ITreeNode startNode = node.FindFormattingRangeToLeft(); if (startNode == null) { startNode = node.FirstChild; } PsiCodeFormatter codeFormatter = GetCodeFormatter(tokenNode); using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(PsiServices, "Format code")) { using (WriteLockCookie.Create()) { codeFormatter.Format(startNode, tokenNode, CodeFormatProfile.DEFAULT); } } DocumentRange newPosition = tokenNode.GetDocumentRange(); if (newPosition.IsValid()) { textControl.Caret.MoveTo(newPosition.TextRange.EndOffset, CaretVisualPlacement.DontScrollIfVisible); } }
protected override ITreeNode Move(Direction direction) { using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(myRuleDeclaration.GetPsiServices(), "Rearrange code")) { if (direction == Direction.Up) { var sibling = myRuleDeclaration.PrevSibling; while (sibling is IWhitespaceNode) { sibling = sibling.PrevSibling; } var ruleDeclaration = sibling as IRuleDeclaration; if (ruleDeclaration != null) { using (WriteLockCookie.Create()) { LowLevelModificationUtil.AddChildBefore(ruleDeclaration, myRuleDeclaration); LowLevelModificationUtil.AddChildBefore(ruleDeclaration, new NewLine("\r\n")); } } } if (direction == Direction.Down) { var sibling = myRuleDeclaration.NextSibling; while (sibling is IWhitespaceNode) { sibling = sibling.NextSibling; } var ruleDeclaration = sibling as IRuleDeclaration; if (ruleDeclaration != null) { using (WriteLockCookie.Create()) { LowLevelModificationUtil.AddChildAfter(ruleDeclaration, myRuleDeclaration); LowLevelModificationUtil.AddChildAfter(ruleDeclaration, new NewLine("\r\n")); } } } } return(myRuleDeclaration); }
protected void FormatStatementOnSemicolon([NotNull] TStatement statement) { var settingsStore = statement.GetSettingsStore(); if (settingsStore.GetValue(TypingAssistOptions.FormatStatementOnSemicolonExpression)) { var psiServices = statement.GetPsiServices(); using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(psiServices, "Format code")) { var languageService = statement.Language.LanguageService().NotNull(); var codeFormatter = languageService.CodeFormatter.NotNull(); codeFormatter.Format(statement, CodeFormatProfile.SOFT); } Assertion.Assert(statement.IsValid(), "statement.IsValid()"); Assertion.Assert(statement.IsPhysical(), "statement.IsPhysical()"); } }
public void Execute(ISolution solution, ITextControl textControl) { var formatter = JavaScriptResearchFormatter.Instance; var startOffset = myProvider.Selection.StartOffset; var endOffset = myProvider.Selection.EndOffset; var nodeFirst = myProvider.PsiFile.FindTokenAt(new TreeOffset(startOffset)); var nodeLast = myProvider.PsiFile.FindTokenAt(new TreeOffset(endOffset - 1)); var psiServices = myProvider.PsiServices; using (new DisableCodeFormatter()) { using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(psiServices, "Format code")) { using (WriteLockCookie.Create()) { formatter.Format(nodeFirst, nodeLast, CodeFormatProfile.DEFAULT); } } } }
private bool ReformatForSmartEnter(string dummyText, ITextControl textControl, IFile file, TreeTextRange reparseTreeOffset, TreeOffset lBraceTreePos, TreeOffset rBraceTreePos, bool insertEnterAfter = false) { // insert dummy text and reformat TreeOffset newCaretPos; var codeFormatter = GetCodeFormatter(file); using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(PsiServices, "Typing assist")) { string newLine = Environment.NewLine; string textToInsert = newLine + dummyText; if (insertEnterAfter) { textToInsert = textToInsert + newLine; } file = file.ReParse(reparseTreeOffset, textToInsert); if (file == null) { return(false); } ITreeNode lBraceNode = file.FindTokenAt(lBraceTreePos); if (lBraceNode == null) { return(false); } var dummyNode = file.FindTokenAt(reparseTreeOffset.StartOffset + newLine.Length) as ITokenNode; var languageService = file.Language.LanguageService(); if (languageService == null) { return(false); } while (dummyNode != null && languageService.IsFilteredNode(dummyNode)) { dummyNode = dummyNode.GetNextToken(); } if (dummyNode == null) { return(false); } var rBraceNode = file.FindTokenAt(rBraceTreePos + newLine.Length + dummyText.Length + (insertEnterAfter ? newLine.Length : 0)); var boundSettingsStore = SettingsStore.BindToContextTransient(textControl.ToContextRange()); codeFormatter.Format(lBraceNode, CodeFormatProfile.DEFAULT, null, boundSettingsStore); codeFormatter.Format( rBraceNode.FindFormattingRangeToLeft(), rBraceNode, CodeFormatProfile.DEFAULT, null, boundSettingsStore); codeFormatter.Format(lBraceNode.Parent, CodeFormatProfile.INDENT, null); newCaretPos = dummyNode.GetTreeStartOffset(); file = file.ReParse(new TreeTextRange(newCaretPos, newCaretPos + dummyText.Length), ""); Assertion.Assert(file != null, "file != null"); } // dposition cursor DocumentRange newCaretPosition = file.GetDocumentRange(newCaretPos); if (newCaretPosition.IsValid()) { textControl.Caret.MoveTo(newCaretPosition.TextRange.StartOffset, CaretVisualPlacement.DontScrollIfVisible); } return(true); }
private void DoSmartIndentOnEnter(ITextControl textControl) { var originalOffset = textControl.Caret.Offset(); var offset = TextControlToLexer(textControl, originalOffset); var mixedLexer = GetCachingLexer(textControl); // if there is something on that line, then use existing text if (offset <= 0 || !mixedLexer.FindTokenAt(offset - 1)) { return; } if (mixedLexer.TokenType == PsiTokenType.C_STYLE_COMMENT || mixedLexer.TokenType == PsiTokenType.STRING_LITERAL) { return; } if (offset <= 0 || !mixedLexer.FindTokenAt(offset)) { return; } while (mixedLexer.TokenType == PsiTokenType.WHITE_SPACE) { mixedLexer.Advance(); } offset = mixedLexer.TokenType == null ? offset : mixedLexer.TokenStart; var extraText = (mixedLexer.TokenType == PsiTokenType.NEW_LINE || mixedLexer.TokenType == null) ? "foo " : String.Empty; var projectItem = textControl.Document.GetPsiSourceFile(Solution); if (projectItem == null || !projectItem.IsValid()) { return; } using (PsiManager.GetInstance(Solution).DocumentTransactionManager.CreateTransactionCookie(DefaultAction.Commit, "Typing assist")) { // If the new line is empty, the do default indentation int lexerOffset = offset; if (extraText.Length > 0) { textControl.Document.InsertText(lexerOffset, extraText); } PsiServices.PsiManager.CommitAllDocuments(); var file = projectItem.GetPsiFile <PsiLanguage>(new DocumentRange(textControl.Document, offset)); if (file == null) { return; } var rangeInJsTree = file.Translate(new DocumentOffset(textControl.Document, offset)); if (!rangeInJsTree.IsValid()) { if (extraText.Length > 0) { textControl.Document.DeleteText(new TextRange(lexerOffset, lexerOffset + extraText.Length)); } return; } var tokenNode = file.FindTokenAt(rangeInJsTree) as ITokenNode; if (tokenNode == null) { if (extraText.Length > 0) { textControl.Document.DeleteText(new TextRange(lexerOffset, lexerOffset + extraText.Length)); } return; } PsiCodeFormatter codeFormatter = GetCodeFormatter(file); int offsetInToken = rangeInJsTree.Offset - tokenNode.GetTreeStartOffset().Offset; using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(PsiServices, "Typing assist")) { Lifetimes.Using( lifetime => { var boundSettingsStore = SettingsStore.CreateNestedTransaction(lifetime, "PsiTypingAssist").BindToContextTransient(textControl.ToContextRange()); var prevToken = tokenNode.GetPrevToken(); if (prevToken == null) { return; } if (tokenNode.Parent is IParenExpression || prevToken.Parent is IParenExpression) { var node = tokenNode.Parent; if (prevToken.Parent is IParenExpression) { node = prevToken.Parent; } codeFormatter.Format(node.FirstChild, node.LastChild, CodeFormatProfile.DEFAULT, NullProgressIndicator.Instance, boundSettingsStore); } else { codeFormatter.Format(prevToken, tokenNode, CodeFormatProfile.INDENT, NullProgressIndicator.Instance, boundSettingsStore); } }); offset = file.GetDocumentRange(tokenNode.GetTreeStartOffset()).TextRange.StartOffset + offsetInToken; } if (extraText.Length > 0) { lexerOffset = offset; textControl.Document.DeleteText(new TextRange(lexerOffset, lexerOffset + extraText.Length)); } } textControl.Caret.MoveTo(offset, CaretVisualPlacement.DontScrollIfVisible); }
public async void Execute(ISolution solution, ITextControl textControl) { if (this.ExistingProjectFile != null) { await ShowProjectFile(solution, this.ExistingProjectFile, null); return; } using (ReadLockCookie.Create()) { using (var cookie = solution.CreateTransactionCookie(DefaultAction.Rollback, this.Text, NullProgressIndicator.Create())) { var declaration = this._provider.GetSelectedElement <ICSharpTypeDeclaration>(); var declaredType = declaration?.DeclaredElement; if (declaredType == null) { return; } var settingsStore = declaration.GetSettingsStore(); var helperSettings = ReSharperHelperSettings.GetSettings(settingsStore); var testProject = this.CachedTestProject ?? this.ResolveTargetTestProject(declaration, solution, helperSettings); if (testProject == null) { return; } var classNamespaceParts = TrimDefaultProjectNamespace(declaration.GetProject().NotNull(), declaredType.GetContainingNamespace().QualifiedName); var testFolderLocation = classNamespaceParts.Aggregate(testProject.Location, (current, part) => current.Combine(part)); var testNamespace = StringUtil.MakeFQName(testProject.GetDefaultNamespace(), StringUtil.MakeFQName(classNamespaceParts)); var testFolder = testProject.GetOrCreateProjectFolder(testFolderLocation, cookie); if (testFolder == null) { return; } var testClassName = declaredType.ShortName + helperSettings.TestClassNameSuffix; var testFileName = testClassName + ".cs"; var testFileTemplate = StoredTemplatesProvider.Instance.EnumerateTemplates(settingsStore, TemplateApplicability.File).FirstOrDefault(t => t.Description == TemplateDescription); if (testFileTemplate != null) { await FileTemplatesManager.Instance.CreateFileFromTemplateAsync(testFileName, new ProjectFolderWithLocation(testFolder), testFileTemplate); return; } var newFile = AddNewItemHelper.AddFile(testFolder, testFileName).ToSourceFile(); if (newFile == null) { return; } int?caretPosition; using (PsiTransactionCookie.CreateAutoCommitCookieWithCachesUpdate(newFile.GetPsiServices(), "CreateTestClass")) { var csharpFile = newFile.GetDominantPsiFile <CSharpLanguage>() as ICSharpFile; if (csharpFile == null) { return; } var elementFactory = CSharpElementFactory.GetInstance(csharpFile); var namespaceDeclaration = elementFactory.CreateNamespaceDeclaration(testNamespace); var addedNs = csharpFile.AddNamespaceDeclarationAfter(namespaceDeclaration, null); var classLikeDeclaration = (IClassLikeDeclaration)elementFactory.CreateTypeMemberDeclaration("public class $0 {}", testClassName); var addedTypeDeclaration = addedNs.AddTypeDeclarationAfter(classLikeDeclaration, null) as IClassDeclaration; caretPosition = addedTypeDeclaration?.Body?.GetDocumentRange().TextRange.StartOffset + 1; } cookie.Commit(NullProgressIndicator.Create()); await ShowProjectFile(solution, newFile.ToProjectFile().NotNull(), caretPosition); } } }