internal static string FormatOnPaste(string original, PasteInfo pasteInfo) { var buffer = host.CreateTextBuffer(original); var prePastSnapshot = buffer.CurrentSnapshot; var bufferEdit = buffer.CreateEdit(); bufferEdit.Replace(pasteInfo.Start, pasteInfo.Length, pasteInfo.PasteString); var bufferApplied = bufferEdit.Apply(); SnapshotSpan? span = EditorUtilities.GetPasteSpan(prePastSnapshot, bufferApplied); if (span != null) { SnapshotSpan newSpan = (SnapshotSpan)span; var featureContainer = new LuaFeatureContainer(); SourceText sourceText = new SourceText(bufferApplied.GetText()); Range range = new Range(newSpan.Start.Position, newSpan.Length); List<TextEditInfo> edits = featureContainer.Formatter.Format(sourceText, range, new FormattingOptions(new List<DisableableRules>(), 4, 4, false)); var pastedBufferEdit = buffer.CreateEdit(); foreach (TextEditInfo edit in edits) { pastedBufferEdit.Replace(edit.Start, edit.Length, edit.ReplacingWith); } var pasteApplied = pastedBufferEdit.Apply(); return pasteApplied.GetText(); } return original; }
internal TextEditInfo(Range range, string replaceWith) { Requires.NotNull(replaceWith, nameof(replaceWith)); this.Start = range.Start; this.Length = range.Length; this.ReplacingWith = replaceWith; }
private static IEnumerable<ParsedToken> WalkTreeRangeKeepLevelAndParent(SyntaxNodeOrToken currentRoot, int blockLevel, SyntaxNode upperStatementNode, SyntaxNode immediateStatementNode, Range range) { if (!currentRoot.IsLeafNode) { SyntaxNode syntaxNode = (SyntaxNode)currentRoot; SyntaxNode nextUpperStatementNode = immediateStatementNode; SyntaxNode nextImmediateStatementNode = syntaxNode; if (SyntaxKind.TableConstructorExp != syntaxNode.Kind && SyntaxKind.TableConstructorArg != syntaxNode.Kind && !StatKinds.Contains(syntaxNode.Kind)) { nextImmediateStatementNode = immediateStatementNode; nextUpperStatementNode = upperStatementNode; } if (nextUpperStatementNode == null) { nextUpperStatementNode = nextImmediateStatementNode; } if ((syntaxNode.Kind == SyntaxKind.BlockNode && nextImmediateStatementNode != null) || syntaxNode.Kind == SyntaxKind.FieldList) { blockLevel++; } foreach (SyntaxNodeOrToken node in syntaxNode.Children) { foreach (ParsedToken parsedToken in WalkTreeRangeKeepLevelAndParent(node, blockLevel, nextUpperStatementNode, nextImmediateStatementNode, range)) { yield return parsedToken; } } } else { Token token = currentRoot as Token; if (token != null && token.Kind != SyntaxKind.MissingToken && token.Start >= range.Start) { if (token.FullStart > range.End) { yield break; } yield return new ParsedToken(token, blockLevel, upperStatementNode, immediateStatementNode); } } }
/// <summary> /// This is main entry point for the VS side of things. For now, the implementation /// of the function is not final and it just used as a way seeing results in VS. /// Ideally, Format will also take in a "formatting option" object that dictates /// the rules that should be enabled, spacing and tabs. /// </summary> /// <param name="sourceText">The SourceText that represents the text to be formatted</param> /// <param name="range">The range of indicies to be formatted</param> /// <param name="formattingOptions">The options to format with, null leaves the options as they were</param> /// <returns> /// A list of TextEditInfo objects are returned for the spacing between tokens (starting from the /// first token in the document to the last token. After the spacing text edits, the indentation /// text edits follow (starting again from the beginning of the document). I might separate the /// indentation text edits from the spacing text edits in the future but for now they are in /// the same list. /// </returns> public List<TextEditInfo> Format(SourceText sourceText, Range range, FormattingOptions formattingOptions) { Requires.NotNull(formattingOptions, nameof(formattingOptions)); Requires.NotNull(sourceText, nameof(sourceText)); this.formattingOptions = formattingOptions; this.ruleMap = RuleMap.Create(this.formattingOptions.OptionalRuleMap); List<TextEditInfo> textEdits = new List<TextEditInfo>(); SyntaxTree syntaxTree = this.parseTreeProvider.Get(sourceText); List<ParsedToken> parsedTokens = new List<ParsedToken>(ParsedToken.GetParsedTokens(syntaxTree, range)); if (syntaxTree.ErrorList.Count == 0) { for (int i = 0; i < parsedTokens.Count - 1; ++i) { FormattingContext formattingContext = new FormattingContext(parsedTokens[i], parsedTokens[i + 1], sourceText); Rule rule = this.ruleMap.Get(formattingContext); if (rule != null) { textEdits.AddRange(rule.Apply(formattingContext)); } } } textEdits.AddRange(Indenter.GetIndentations(parsedTokens, this.formattingOptions)); textEdits.Sort((x, y) => x.Start < y.Start ? 1 : x.Start == y.Start ? 0 : -1); return textEdits; }
private static string Format(string original, uint tabSize = 4, uint indentSize = 4, bool usingTabs = false, FormattingOptions formattingOptions = null) { LuaFeatureContainer featureContainer = new LuaFeatureContainer(); Range range = new Range(0, original.Length); if (formattingOptions == null) { formattingOptions = new FormattingOptions(new List<DisableableRules>(), tabSize, indentSize, usingTabs); } List<TextEditInfo> textEdits = featureContainer.Formatter.Format(new SourceText(original), range, formattingOptions); var buffer = host.CreateTextBuffer(original); var edit = buffer.CreateEdit(); foreach (var textEdit in textEdits) { edit.Replace(textEdit.Start, textEdit.Length, textEdit.ReplacingWith); } var applied = edit.Apply(); return applied.GetText(); }
private void Format() { SnapshotPoint caret = this.TextView.Caret.Position.BufferPosition; Range range = new Range(0, caret.Snapshot.Length); List<DisableableRules> disabledRules = this.GetDisabledRules(Settings); FormattingOptions formattingOptions = GetFormattingOptions(Settings); List<TextEditInfo> edits = luaLuaFeature.Formatter.Format(txtCache.Get(caret.Snapshot), range, formattingOptions); using (ITextEdit textEdit = this.TextView.TextBuffer.CreateEdit()) { foreach (TextEditInfo edit in edits) { textEdit.Replace(edit.Start, edit.Length, edit.ReplacingWith); } textEdit.Apply(); } }
private bool Format(SnapshotSpan span) { if (span.Snapshot.TextBuffer != this.textBuffer || span.IsEmpty || !this.CanFormatSpan(span)) { return false; } SnapshotPoint startLinePoint = span.Start.GetContainingLine().Start; span = new SnapshotSpan(startLinePoint, span.End); SourceText sourceText = this.core.SourceTextCache.Get(this.textBuffer.CurrentSnapshot); Range range = new Range(span.Start.Position, span.Length); FormattingOptions formattingOptions = this.GetFormattingOptions(this.core.FormattingUserSettings); List<TextEditInfo> edits = this.core.FeatureContainer.Formatter.Format(sourceText, range, formattingOptions); using (ITextEdit textEdit = this.textBuffer.CreateEdit()) { foreach (TextEditInfo edit in edits) { textEdit.Replace(edit.Start, edit.Length, edit.ReplacingWith); } textEdit.Apply(); } return true; }
internal static IEnumerable<ParsedToken> GetParsedTokens(SyntaxTree syntaxTree, Range range) { return WalkTreeRangeKeepLevelAndParent(syntaxTree.Root, 0, null, null, range); }