private int FindIndexOfBraceBefore(int position) { int first = 0; int last = this.braces.Count - 1; int candidate = -1; while (first <= last) { int mid = (first + last) / 2; BracePos midPos = braces[mid]; if (midPos.Position < position) { // keep looking in second half candidate = mid; first = mid + 1; } else if (midPos.Position > position) { // keep looking in first half last = mid - 1; } else { // we've got an exact match // but we're interested on an strict // order, so return the item before this one candidate = mid - 1; break; } } return(candidate); }
public BracePos Push(CharPos brace) { var bp = new BracePos(brace, this.pairs.Count); this.pairs.Push(bp); return(bp); }
private void ContinueParsing(int parseFrom, int parseUntil) { int startPosition = 0; int lastGoodBrace = 0; int lastState = 0; // figure out where to start parsing again var pairs = GetStacker(this.coloringMode); for (int i = 0; i < braces.Count; i++) { BracePos r = braces[i]; if (r.Position > parseFrom) { break; } if (IsOpeningBrace(r.Brace)) { pairs.Push(r.ToCharPos()); } else if (pairs.Count(r.Brace) > 0) { pairs.Pop(r.Brace); } startPosition = r.Position + 1; lastGoodBrace = i; lastState = r.State; } if (lastGoodBrace < braces.Count - 1) { braces.RemoveRange(lastGoodBrace + 1, braces.Count - lastGoodBrace - 1); } ExtractBraces(pairs, startPosition, parseUntil, lastState); }
// simple binary-search like for the closest // brace to this position private int FindIndexOfBraceAtOrAfter(int position) { int first = 0; int last = this.braces.Count - 1; int candidate = -1; while (first <= last) { int mid = (first + last) / 2; BracePos midPos = braces[mid]; if (midPos.Position < position) { // keep looking in second half first = mid + 1; } else if (midPos.Position > position) { // keep looking in first half candidate = mid; last = mid - 1; } else { // we've got an exact match candidate = mid; break; } } return(candidate); }
private void MatchBrace(IBraceStacker pairs, CharPos cp) { if (IsOpeningBrace(cp)) { Add(pairs.Push(cp)); } else if (pairs.Count(cp.Char) > 0) { // check if this is a closing brace matching // the opening on the stack BracePos p = pairs.Peek(cp.Char); if (braceList[p.Brace] == cp.Char) { // it does, add it pairs.Pop(cp.Char); Add(cp.AsBrace(p.Depth)); } else { // it doesn't; it's an error this.braceErrors.Add(cp); } } else { // closing brace has no opening brace this.braceErrors.Add(cp); } }
public IEnumerable <BracePos> BracesInSpans(NormalizedSnapshotSpanCollection spans) { if (ScanIsUnnecessary()) { yield break; } for (int i = 0; i < spans.Count; i++) { var wantedSpan = spans[i]; EnsureLinesInPreferredSpan(wantedSpan); int startIndex = FindIndexOfBraceAtOrAfter(wantedSpan.Start); if (startIndex < 0) { continue; } for (int j = startIndex; j < braces.Count; j++) { BracePos bp = braces[j]; if (bp.Position > wantedSpan.End) { break; } yield return(bp); } } }
private BracePos?FindClosestOpeningBrace(int position, out int openIndex) { openIndex = FindIndexOfBraceBefore(position); if (openIndex < 0) { return(null); } int pairs = 0; while (openIndex >= 0) { BracePos current = this.braces[openIndex]; if (!IsOpeningBrace(current.Brace)) { pairs++; } else if (pairs == 0) { return(current); } else { pairs--; } openIndex--; } return(null); }
// returns the brace pair when the point is already a brace public Tuple <BracePos, BracePos> GetBracePair(SnapshotPoint point) { if (point.Snapshot != this.Snapshot || point.Position >= Snapshot.Length) { return(null); } this.EnsureLinesInPreferredSpan(point.SpanUntil()); int index = FindIndexOfBraceAtOrAfter(point.Position); if (index < 0) { return(null); } BracePos one = this.braces[index]; if (one.Position != point.Position) { return(null); } if (IsOpeningBrace(one.Brace)) { return(GetBracePairFromPosition(point, RainbowHighlightMode.TrackNextScope)); } else { return(GetBracePairFromPosition(point, RainbowHighlightMode.TrackInsertionPoint)); } }
private void ExtractFromLine(Stack <BracePos> pairs, ITextSnapshotLine line, int lineOffset) { var lc = new LineChars(line, lineOffset); var bracesInLine = this.braceExtractor.Extract(lc) /*.ToArray() */; foreach (var cp in bracesInLine) { if (IsOpeningBrace(cp)) { BracePos p = cp.AsBrace(pairs.Count); pairs.Push(p); Add(p); // we don't need to check if it's a closing brace // because the extractor won't return anything else } else if (pairs.Count > 0) { BracePos p = pairs.Peek(); if (braceList[p.Brace] == cp.Char) { // yield closing brace pairs.Pop(); BracePos c = cp.AsBrace(p.Depth); Add(c); } } } this.LastParsedPosition = line.End; }
private void ContinueParsing(int parseFrom, int parseUntil) { int startPosition = 0; int lastGoodBrace = 0; // figure out where to start parsing again Stack <BracePos> pairs = new Stack <BracePos>(); for (int i = 0; i < braces.Count; i++) { BracePos r = braces[i]; if (r.Position > parseFrom) { break; } if (IsOpeningBrace(r.Brace)) { pairs.Push(r); } else if (pairs.Count > 0) { pairs.Pop(); } startPosition = r.Position + 1; lastGoodBrace = i; } if (lastGoodBrace < braces.Count - 1) { braces.RemoveRange(lastGoodBrace + 1, braces.Count - lastGoodBrace - 1); } ExtractBraces(pairs, startPosition, parseUntil); }
public BracePos Push(CharPos brace) { var pairs = this.stack[brace.Char]; var bp = new BracePos(brace, pairs.Count); pairs.Push(bp); return(bp); }
private BracePos?CheckForBraceAtPositionOrClosestOpeningBrace(int position, out int openIndex) { openIndex = FindIndexOfBraceAtOrAfter(position); if (openIndex >= 0) { BracePos pos = this.braces[openIndex]; if (IsOpeningBrace(pos.Brace) && pos.Position == position) { return(pos); } } return(FindClosestOpeningBrace(position, out openIndex)); }
// TODO: Avoid use of SnapshotPoint public Tuple <BracePos, BracePos> GetBracePairFromPosition(SnapshotPoint point, RainbowHighlightMode mode) { if (point.Snapshot != this.Snapshot || point.Position >= Snapshot.Length) { return(null); } var span = point.SpanUntil(); this.EnsureLinesInPreferredSpan(new TextSpan(span.Start, span.Length)); int openIndex = -1; BracePos?opening = null; if (mode == RainbowHighlightMode.TrackInsertionPoint) { opening = FindClosestOpeningBrace(point.Position, out openIndex); } else { opening = CheckForBraceAtPositionOrClosestOpeningBrace(point.Position, out openIndex); } if (opening == null) { return(null); } for (int i = openIndex + 1; i < this.braces.Count; i++) { if (i == this.braces.Count - 1) { // continue parsing the document if necessary this.ContinueParsing(this.LastParsedPosition, this.Snapshot.Length); } BracePos closing = this.braces[i]; if (this.IsOpeningBrace(closing.Brace)) { continue; } if (this.braceList[opening.Value.Brace] == closing.Brace && closing.Depth == opening.Value.Depth) { return(new Tuple <BracePos, BracePos>(opening.Value, closing)); } } return(null); }
private void ExtractFromLine(Stack <BracePos> pairs, ITextSnapshotLine line, int lineOffset) { var lc = new LineChars(line, lineOffset); CharPos cp = CharPos.Empty; while (!lc.EndOfLine) { if (!this.braceScanner.Extract(lc, ref cp)) { continue; } if (IsOpeningBrace(cp)) { BracePos p = cp.AsBrace(pairs.Count); pairs.Push(p); Add(p); // we don't need to check if it's a closing brace // because the extractor won't return anything else } else if (pairs.Count > 0) { BracePos p = pairs.Peek(); if (braceList[p.Brace] == cp.Char) { // yield closing brace pairs.Pop(); BracePos c = cp.AsBrace(p.Depth); Add(c); } else { // closing brace does not correspond // to opening brace at same depth this.braceErrors.Add(cp); } } else { // closing brace has no opening brace this.braceErrors.Add(cp); } } this.LastParsedPosition = line.End; }
private void Add(BracePos brace) { braces.Add(brace); LastParsedPosition = brace.Position; }