diff options
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Folding/BraceFoldingStrategy.cs')
| -rw-r--r-- | Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Folding/BraceFoldingStrategy.cs | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Folding/BraceFoldingStrategy.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Folding/BraceFoldingStrategy.cs new file mode 100644 index 000000000..0b26184ee --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Folding/BraceFoldingStrategy.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Scripting.Editors.Document; + +namespace Tango.Scripting.Editors.Folding +{ + /// <summary> + /// Allows producing foldings from a document based on braces. + /// </summary> + public class BraceFoldingStrategy + { + private class FoldingDefinition + { + public String Open { get; set; } + public String Close { get; set; } + + public FoldingDefinition(String open, String close) + { + Open = open; + Close = close; + } + } + + private class FoldingOffset + { + public FoldingDefinition Definition { get; set; } + public int Offset { get; set; } + } + + private List<FoldingDefinition> foldings = new List<FoldingDefinition>() + { + new FoldingDefinition("namespace","}"), + new FoldingDefinition("public","}"), + new FoldingDefinition("private","}"), + new FoldingDefinition("internal","}"), + new FoldingDefinition("if","}"), + new FoldingDefinition("class","}"), + new FoldingDefinition("while","}"), + new FoldingDefinition("static void","}"), + new FoldingDefinition("/// <summary>","/// </summary>"), + }; + + /// <summary> + /// Gets/Sets the opening brace. The default value is '{'. + /// </summary> + public char OpeningBrace { get; set; } + + /// <summary> + /// Gets/Sets the closing brace. The default value is '}'. + /// </summary> + public char ClosingBrace { get; set; } + + /// <summary> + /// Creates a new BraceFoldingStrategy. + /// </summary> + public BraceFoldingStrategy() + { + this.OpeningBrace = '{'; + this.ClosingBrace = '}'; + } + + public void UpdateFoldings(FoldingManager manager, TextDocument document) + { + int firstErrorOffset; + IEnumerable<NewFolding> newFoldings = CreateNewFoldings(document, out firstErrorOffset); + manager.UpdateFoldings(newFoldings, firstErrorOffset); + } + + /// <summary> + /// Create <see cref="NewFolding"/>s for the specified document. + /// </summary> + public IEnumerable<NewFolding> CreateNewFoldings(TextDocument document, out int firstErrorOffset) + { + firstErrorOffset = -1; + return CreateNewFoldings(document); + } + + /// <summary> + /// Create <see cref="NewFolding"/>s for the specified document. + /// </summary> + public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) + { + List<NewFolding> newFoldings = new List<NewFolding>(); + + Stack<FoldingOffset> startOffsets = new Stack<FoldingOffset>(); + int lastNewLineOffset = 0; + char openingBrace = this.OpeningBrace; + char closingBrace = this.ClosingBrace; + + var doc = document as TextDocument; + + String current_line = String.Empty; + + foreach (var line in doc.Lines) + { + String lineTextFull = doc.GetText(line); + String lineText = lineTextFull.TrimStart('\t', ' ').TrimEnd('\t', ' '); + + var open_definition = foldings.SingleOrDefault(x => lineText.StartsWith(x.Open + " ") || lineText == x.Open); + + if (open_definition != null) + { + current_line = lineTextFull; + startOffsets.Push(new FoldingOffset() + { + Definition = open_definition, + Offset = line.EndOffset + }); + } + else if (foldings.Any(x => lineText.EndsWith(x.Close))) + { + if (startOffsets.Count > 0) + { + var startOffset = startOffsets.Pop(); + //if (startOffset < lastNewLineOffset) + //{ + newFoldings.Add(new NewFolding(startOffset.Offset, Math.Min(line.EndOffset, doc.TextLength)) + { + //Name = current_line, + }); + } + //} + } + else if (lineText.EndsWith("\n") || lineText.EndsWith("\r")) + { + lastNewLineOffset = line.Offset + 1; + } + } + + //for (int i = 0; i < document.TextLength; i++) + //{ + // char c = document.GetCharAt(i); + // if (c == openingBrace) + // { + // startOffsets.Push(i); + // } + // else if (c == closingBrace && startOffsets.Count > 0) + // { + // int startOffset = startOffsets.Pop(); + // // don't fold if opening and closing brace are on the same line + // if (startOffset < lastNewLineOffset) + // { + // newFoldings.Add(new NewFolding(startOffset, i + 1)); + // } + // } + // else if (c == '\n' || c == '\r') + // { + // lastNewLineOffset = i + 1; + // } + //} + + newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); + return newFoldings; + } + } +} |
