Exemple #1
0
        protected virtual int?GetSmartIndentation(ITextSnapshotLine line)
        {
            ITextSnapshot snapshot           = line.Snapshot;
            SnapshotPoint contextEndPosition = line.Start;
            SnapshotPoint endPosition        = line.EndIncludingLineBreak;
            SnapshotPoint endPositionOnLine  = line.End;

            IReferenceAnchors anchors  = FindNearestAnchors(contextEndPosition);
            IAnchor           previous = anchors.Previous;

            int     spanEnd = Math.Min(line.Snapshot.Length, endPosition.Position + 1);
            Span    span;
            IAnchor enclosing = anchors.Enclosing;

            if (enclosing != null)
            {
                span = Span.FromBounds(enclosing.TrackingSpan.GetStartPoint(snapshot).Position, spanEnd);
            }
            else if (previous != null)
            {
                // at least for now, include the previous span due to the way error handling places bounds on an anchor
                span = Span.FromBounds(previous.TrackingSpan.GetStartPoint(snapshot).Position, spanEnd);
            }
            else
            {
                span = Span.FromBounds(0, spanEnd);
            }

            var diagnosticsPane = DiagnosticsPane;

            if (diagnosticsPane != null)
            {
                diagnosticsPane.WriteLine(string.Format("Smart indent from anchor span: {0}", span));
            }

            ITokenSource bufferTokenSource = GetTokenSource(new SnapshotSpan(snapshot, span));
            ITokenSource tokenSource       = new CodeCompletionTokenSource(bufferTokenSource, endPosition);
            ITokenStream tokenStream       = new CommonTokenStream(tokenSource);

            IDictionary <RuleContext, CaretReachedException> parseTrees = GetParseTrees(tokenStream, anchors);

            if (parseTrees == null)
            {
                return(null);
            }

            var indentLevels = new SortedDictionary <int, IList <KeyValuePair <RuleContext, CaretReachedException> > >();

            foreach (var parseTree in parseTrees)
            {
                if (parseTree.Value == null)
                {
                    continue;
                }

                IParseTree firstNodeOnLine = FindFirstNodeAfterOffset(parseTree.Key, line.Start.Position);
                if (firstNodeOnLine == null)
                {
                    firstNodeOnLine = parseTree.Value.FinalContext;
                }

                if (firstNodeOnLine == null)
                {
                    continue;
                }

                int?indentationLevel = GetIndent(parseTree, firstNodeOnLine, line.Start);
                if (indentationLevel == null)
                {
                    continue;
                }

                IList <KeyValuePair <RuleContext, CaretReachedException> > indentList;
                if (!indentLevels.TryGetValue(indentationLevel.Value, out indentList))
                {
                    indentList = new List <KeyValuePair <RuleContext, CaretReachedException> >();
                    indentLevels[indentationLevel.Value] = indentList;
                }

                indentList.Add(parseTree);
            }

            if (indentLevels.Count == 0)
            {
                return(null);
            }

            int indentLevel = indentLevels.First().Key;

            if (indentLevels.Count > 1)
            {
                // TODO: resolve multiple possibilities
            }

            return(indentLevel);
        }
        protected virtual int? GetSmartIndentation(ITextSnapshotLine line)
        {
            ITextSnapshot snapshot = line.Snapshot;
            SnapshotPoint contextEndPosition = line.Start;
            SnapshotPoint endPosition = line.EndIncludingLineBreak;
            SnapshotPoint endPositionOnLine = line.End;

            IReferenceAnchors anchors = FindNearestAnchors(contextEndPosition);
            IAnchor previous = anchors.Previous;

            int spanEnd = Math.Min(line.Snapshot.Length, endPosition.Position + 1);
            Span span;
            IAnchor enclosing = anchors.Enclosing;
            if (enclosing != null)
            {
                span = Span.FromBounds(enclosing.TrackingSpan.GetStartPoint(snapshot).Position, spanEnd);
            }
            else if (previous != null)
            {
                // at least for now, include the previous span due to the way error handling places bounds on an anchor
                span = Span.FromBounds(previous.TrackingSpan.GetStartPoint(snapshot).Position, spanEnd);
            }
            else
            {
                span = Span.FromBounds(0, spanEnd);
            }

            var diagnosticsPane = DiagnosticsPane;
            if (diagnosticsPane != null)
                diagnosticsPane.WriteLine(string.Format("Smart indent from anchor span: {0}", span));

            ITokenSource bufferTokenSource = GetTokenSource(new SnapshotSpan(snapshot, span));
            ITokenSource tokenSource = new CodeCompletionTokenSource(bufferTokenSource, endPosition);
            ITokenStream tokenStream = new CommonTokenStream(tokenSource);

            IDictionary<RuleContext, CaretReachedException> parseTrees = GetParseTrees(tokenStream, anchors);
            if (parseTrees == null)
                return null;

            var indentLevels = new SortedDictionary<int, IList<KeyValuePair<RuleContext, CaretReachedException>>>();
            foreach (var parseTree in parseTrees)
            {
                if (parseTree.Value == null)
                    continue;

                IParseTree firstNodeOnLine = FindFirstNodeAfterOffset(parseTree.Key, line.Start.Position);
                if (firstNodeOnLine == null)
                    firstNodeOnLine = parseTree.Value.FinalContext;

                if (firstNodeOnLine == null)
                    continue;

                int? indentationLevel = GetIndent(parseTree, firstNodeOnLine, line.Start);
                if (indentationLevel == null)
                    continue;

                IList<KeyValuePair<RuleContext, CaretReachedException>> indentList;
                if (!indentLevels.TryGetValue(indentationLevel.Value, out indentList))
                {
                    indentList = new List<KeyValuePair<RuleContext, CaretReachedException>>();
                    indentLevels[indentationLevel.Value] = indentList;
                }

                indentList.Add(parseTree);
            }

            if (indentLevels.Count == 0)
                return null;

            int indentLevel = indentLevels.First().Key;
            if (indentLevels.Count > 1)
            {
                // TODO: resolve multiple possibilities
            }

            return indentLevel;
        }