public void Update(TeXCommentTag tag, LineSpan lineSpan, double?lastLineWidthWithoutStartWhiteSpaces) { bool changed = this.DataTag.Text != tag.Text; this.DataTag = tag; LineSpan = lineSpan; if (lastLineWidthWithoutStartWhiteSpaces.HasValue) { this.lastLineWidthWithoutStartWhiteSpaces = lastLineWidthWithoutStartWhiteSpaces.Value; previewAdorner.OffsetX = -lastLineWidthWithoutStartWhiteSpaces.Value; } if (changed || isInvalidated) { switch (currentState) { case TeXCommentAdornmentState.Rendered: case TeXCommentAdornmentState.Rendering: CurrentState = TeXCommentAdornmentState.Rendering; break; case TeXCommentAdornmentState.EditingWithPreview: case TeXCommentAdornmentState.EditingAndRenderingPreview: CurrentState = TeXCommentAdornmentState.EditingAndRenderingPreview; break; default: break; } OnPropertyChanged(nameof(IsCaretInsideTeXBlock)); isInvalidated = false; } }
public void TestCreateProjectionBufferWithoutIndentation() { var exportProvider = TestExportProvider.ExportProviderWithCSharpAndVisualBasic; var contentTypeRegistryService = exportProvider.GetExportedValue <IContentTypeRegistryService>(); var textBuffer = exportProvider.GetExportedValue <ITextBufferFactoryService>().CreateTextBuffer( @" line 1 line 2 line 3 line 4", contentTypeRegistryService.GetContentType("text")); var projectionBuffer = IProjectionBufferFactoryServiceExtensions.CreateProjectionBufferWithoutIndentation( exportProvider.GetExportedValue <IProjectionBufferFactoryService>(), exportProvider.GetExportedValue <IContentTypeRegistryService>(), exportProvider.GetExportedValue <IEditorOptionsFactoryService>().GlobalOptions, textBuffer.CurrentSnapshot, "...", LineSpan.FromBounds(0, 1), LineSpan.FromBounds(2, 4)); var projectionSnapshot = projectionBuffer.CurrentSnapshot; Assert.Equal(4, projectionSnapshot.LineCount); var lines = projectionSnapshot.Lines.ToList(); Assert.Equal("line 1", lines[0].GetText()); Assert.Equal("...", lines[1].GetText()); Assert.Equal("line 3", lines[2].GetText()); Assert.Equal(" line 4", lines[3].GetText()); }
public void TestCreateProjectionBuffer() { var composition = EditorTestCompositions.EditorFeatures; var exportProvider = composition.ExportProviderFactory.CreateExportProvider(); var contentTypeRegistryService = exportProvider.GetExportedValue <IContentTypeRegistryService>(); var textBuffer = exportProvider.GetExportedValue <ITextBufferFactoryService>().CreateTextBuffer( @" line 1 line 2 line 3 line 4", contentTypeRegistryService.GetContentType("text")); var projectionBuffer = IProjectionBufferFactoryServiceExtensions.CreateProjectionBuffer( exportProvider.GetExportedValue <IProjectionBufferFactoryService>(), exportProvider.GetExportedValue <IContentTypeRegistryService>(), exportProvider.GetExportedValue <IEditorOptionsFactoryService>().GlobalOptions, textBuffer.CurrentSnapshot, "...", LineSpan.FromBounds(1, 2), LineSpan.FromBounds(3, 4)); var projectionSnapshot = projectionBuffer.CurrentSnapshot; Assert.Equal(4, projectionSnapshot.LineCount); var lines = projectionSnapshot.Lines.ToList(); Assert.Equal("...", lines[0].GetText()); Assert.Equal(" line 2", lines[1].GetText()); Assert.Equal("...", lines[2].GetText()); Assert.Equal(" line 4", lines[3].GetText()); }
private static List <LineSpan> GetExposedLineSpans(ITextSnapshot textSnapshot) { const string start = "//["; const string end = "//]"; var bufferText = textSnapshot.GetText().ToString(); var lineSpans = new List <LineSpan>(); var lastEndIndex = 0; while (true) { var startIndex = bufferText.IndexOf(start, lastEndIndex, StringComparison.Ordinal); if (startIndex == -1) { break; } var endIndex = bufferText.IndexOf(end, lastEndIndex, StringComparison.Ordinal); var startLine = textSnapshot.GetLineNumberFromPosition(startIndex) + 1; var endLine = textSnapshot.GetLineNumberFromPosition(endIndex); lineSpans.Add(LineSpan.FromBounds(startLine, endLine)); lastEndIndex = endIndex + end.Length; } return(lineSpans); }
public static string GetText(this LineSpan lineSpan, string context) { if (lineSpan == null) { return(""); } return(GetText(lineSpan.ToSpan(context), context)); }
private void WriteLine(LineSpan line, TextWriter writer) { writer.Write($"{line.Position}:"); foreach (var span in line.TextSpans) { writer.Write($@"{SpanStyle(span.Style)}({span.GetText()})"); } writer.WriteLine(); }
public static Location Location(string filePath = "", LineSpan line = null) { line = line ?? new LineSpan(); return(new Location { FilePath = filePath, Line = line, }); }
public TreeItemViewModel( TextSpan textSpan, SourceText sourceText, DocumentId documentId, string fileName, Glyph glyph, ImmutableArray <ClassifiedSpan> classifiedSpans, ValueTrackingTreeViewModel treeViewModel, IGlyphService glyphService, IThreadingContext threadingContext, Workspace workspace, ImmutableArray <TreeItemViewModel> children = default) : base() { FileName = fileName; TextSpan = textSpan; _sourceText = sourceText; ClassifiedSpans = classifiedSpans; TreeViewModel = treeViewModel; ThreadingContext = threadingContext; _glyph = glyph; _glyphService = glyphService; Workspace = workspace; DocumentId = documentId; if (!children.IsDefaultOrEmpty) { foreach (var child in children) { ChildItems.Add(child); } } sourceText.GetLineAndOffset(textSpan.Start, out var lineStart, out var _); sourceText.GetLineAndOffset(textSpan.End, out var lineEnd, out var _); LineSpan = LineSpan.FromBounds(lineStart, lineEnd); PropertyChanged += (s, e) => { if (e.PropertyName == nameof(IsLoading)) { NotifyPropertyChanged(nameof(ShowGlyph)); } }; TreeViewModel.PropertyChanged += (s, e) => { if (e.PropertyName == nameof(TreeViewModel.HighlightBrush)) { // If the highlight changes we need to recalculate the inlines so the // highlighting is correct NotifyPropertyChanged(nameof(Inlines)); } }; }
public static Span ToSpan(this LineSpan lineSpan, string context) { if (lineSpan == null) { return(Create.Span(1, 1)); } int start = lineSpan.Start.ToPosition(context); int end = lineSpan.End.ToPosition(context); return(Create.Span(start, end - start)); }
private static IList <SnapshotSpan> CreateSnapshotSpans( ITextSnapshot snapshot, LineSpan lineSpan ) { var result = new List <SnapshotSpan>(); for (var i = lineSpan.Start; i < lineSpan.End; i++) { var line = snapshot.GetLineFromLineNumber(i); result.Add(line.Extent); } return(result); }
protected override TeXCommentAdornment CreateAdornment(TeXCommentTag dataTag, ITextSnapshot snapshot) { var lineSpan = new LineSpan( snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.Start), snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.End)); var lastLine = snapshot.GetLineFromLineNumber(lineSpan.LastLine); var lastLineWidthWithoutStartWhiteSpaces = (lastLine.Extent.Length - dataTag.TeXBlock.LastLineWhiteSpacesAtStart) * TextView.FormattedLineSource?.ColumnWidth; var adornment = new TeXCommentAdornment( TextView, dataTag, lineSpan, lastLineWidthWithoutStartWhiteSpaces ?? 0, textHasBeenEdited ? TeXCommentAdornmentState.EditingAndRenderingPreview : TeXCommentAdornmentState.Rendering, span => { //var blockSpans = texCommentBlocks.GetBlockSpansWithLastLineBreakIntersectedBy(Snapshot, span); //foreach (var blockSpan in blockSpans) //{ // RaiseTagsChanged(new SnapshotSpan(Snapshot, blockSpan)); //} //RaiseTagsChanged(new SnapshotSpan(Snapshot, 0, Snapshot.Length)); InvalidateSpans(new List <SnapshotSpan>() { new SnapshotSpan(Snapshot, 0, Snapshot.Length) }); }, isInEditMode => { ForAllCurrentlyUsedAdornments(a => a.CurrentState = isInEditMode ? TeXCommentAdornmentState.EditingAndRenderingPreview : TeXCommentAdornmentState.Rendering, false); }, (tag, attributeText) => { var pos = tag.Span.Start + tag.TeXBlock.FirstLineWhiteSpacesAtStart + tag.TeXBlock.TeXCommentPrefix.Length + tag.TeXBlock.PropertiesSegmentLength; Snapshot.TextBuffer.Insert(pos, $"[{attributeText}]"); }, renderingManager, vsSettings); TextView.TextBuffer.Changed += adornment.HandleTextBufferChanged; MarkAdornmentLines(lineSpan, adornment); return(adornment); }
protected override void UpdateAdornment(TeXCommentAdornment adornment, TeXCommentTag dataTag, ITextSnapshot snapshot) { var lineSpan = new LineSpan( snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.Start), snapshot.GetLineNumberFromPosition(dataTag.TeXBlock.Span.End)); if (adornment.LineSpan != lineSpan) { MarkAdornmentLines(adornment.LineSpan, null); //remove old MarkAdornmentLines(lineSpan, adornment); //add new } var lastLine = snapshot.GetLineFromLineNumber(lineSpan.LastLine); var lastLineWidthWithoutStartWhiteSpaces = (lastLine.Extent.Length - dataTag.TeXBlock.LastLineWhiteSpacesAtStart) * TextView.FormattedLineSource?.ColumnWidth; adornment.Update(dataTag, lineSpan, lastLineWidthWithoutStartWhiteSpaces); }
public LineSpan[] GetLineSpans(int count) { int p = (int)position; int c = Math.Min(count, lines.Length - p); if (c <= 0) { return(new LineSpan[0]); } var spans = new LineSpan[c]; for (int i = 0; i < c; ++i) { spans[i] = new LineSpan(p + i, lines[p + i]); } return(spans); }
public override void AddLine(LineSpan line, bool willUpdateImmediately) { bool isTouching = false; if (line.FirstLine - 1 == LineNumber || line.LastLine + 1 == LineNumber) { isTouching = true; } if (line.Highlight != isTouching) { line.Highlight = isTouching; if (!willUpdateImmediately) { Modified.Add(line); } Modified.AddRange(line.LinkedLines); } }
// Adds a line span to the spans we've been collecting. If the line span overlaps or // abuts a previous span then the two are merged. private static void MergeLineSpans(List <LineSpan> lineSpans, LineSpan nextLineSpan) { if (lineSpans.Count > 0) { var lastLineSpan = lineSpans.Last(); // We merge them if there's no more than one line between the two. Otherwise // we'd show "..." between two spans where we could just show the actual code. if (nextLineSpan.Start >= lastLineSpan.Start && nextLineSpan.Start <= (lastLineSpan.End + 1)) { nextLineSpan = LineSpan.FromBounds(lastLineSpan.Start, nextLineSpan.End); lineSpans.RemoveAt(lineSpans.Count - 1); } } lineSpans.Add(nextLineSpan); }
public TeXCommentAdornment( IWpfTextView textView, TeXCommentTag tag, LineSpan lineSpan, double lastLineWidthWithoutStartWhiteSpaces, TeXCommentAdornmentState initialState, Action <Span> refreshTags, Action <bool> setIsInEditModeForAllAdornmentsInDocument, Action <TeXCommentTag, string> addAttribute, IRenderingManager renderingManager, IVsSettings vsSettings) { ExtensionSettings.Instance.CustomZoomChanged += CustomZoomChanged; textView.Caret.PositionChanged += Caret_PositionChanged; this.DataTag = tag; this.refreshTags = refreshTags; this.setIsInEditModeForAllAdornmentsInDocument = setIsInEditModeForAllAdornmentsInDocument; this.addAttribute = addAttribute; this.textView = textView; this.lastLineWidthWithoutStartWhiteSpaces = lastLineWidthWithoutStartWhiteSpaces; this.renderingManager = renderingManager; VsSettings = vsSettings; ResourcesManager = ResourcesManager.GetOrCreate(textView); LineSpan = lineSpan; InitializeComponent(); previewAdorner = new PreviewAdorner(this, ResourcesManager, vsSettings); Loaded += (s, e) => { if (previewAdorner.Parent == null) { previewAdorner.OffsetX = -this.lastLineWidthWithoutStartWhiteSpaces; //'this' is important because of lambda closure System.Windows.Documents.AdornerLayer.GetAdornerLayer(this).Add(previewAdorner); } }; //for correctly working binding NameScope.SetNameScope(btnShow.ContextMenu, NameScope.GetNameScope(this)); NameScope.SetNameScope(btnEdit.ContextMenu, NameScope.GetNameScope(this)); NameScope.SetNameScope((ToolTip)imgError.ToolTip, NameScope.GetNameScope(this)); CurrentState = initialState; }
// Find the lines that surround the span of the difference. Try to expand the span to // include both the previous and next lines so that we can show more context to the // user. private LineSpan GetLineSpan( ITextSnapshot snapshot, Span span) { var startLine = snapshot.GetLineNumberFromPosition(span.Start); var endLine = snapshot.GetLineNumberFromPosition(span.End); if (startLine > 0) { startLine--; } if (endLine < snapshot.LineCount) { endLine++; } return(LineSpan.FromBounds(startLine, endLine)); }
private void MarkAdornmentLines(LineSpan lineSpan, TeXCommentAdornment adornment) { lock (linesWithAdornments) { if (lineSpan.LastLine >= linesWithAdornments.Count) { int newItemsCount = lineSpan.LastLine - linesWithAdornments.Count + 1; for (int i = 0; i < newItemsCount; i++) { linesWithAdornments.Add(null); } } for (int i = lineSpan.FirstLine; i <= lineSpan.LastLine; i++) { linesWithAdornments[i] = adornment; } } }
public void GenerateShape(float divDuration, float divSize, DateTime zeroTime, Transform parent, Material baseMat) { DateTime now = DateTime.Now; List <Vector3> verts = new List <Vector3>(); List <int> tris = new List <int>(); pointList = new List <Coord2>(); if (shape) { Destroy(shape.gameObject); } if (guideSpan != SpanAlignment.None) { labels.DestroyAll(); } GameObject shapeObject = new GameObject(name); shape = shapeObject.transform; shapeObject.transform.parent = parent; // Debug.Log( "Generated color for " + name + ": " + color ); LineRenderer edgePrefabToUse = instance.edgePrefab; if (guideSpan == SpanAlignment.Months) { edgePrefabToUse = instance.monthEdgePrefab; } if (guideSpan == SpanAlignment.Years) { edgePrefabToUse = instance.yearEdgePrefab; } if (guideSpan == SpanAlignment.Decades) { edgePrefabToUse = instance.decadeEdgePrefab; } if (guideSpan != SpanAlignment.None) { blocks.Clear(); } switch (guideSpan) { case SpanAlignment.Months: { DateTime currStartDate = instance.mapStartTime; while (currStartDate <= now) { DateTime endDate = currStartDate.AddMonths(1).AddDays(1 - currStartDate.Day); if (endDate > now) { endDate = now; } blocks.Add(new TimeBlock(currStartDate, endDate, currStartDate.Month.ToString())); if (endDate == now) { break; } currStartDate = endDate; } } break; case SpanAlignment.Years: { DateTime currStartDate = calendarAligned ? instance.mapStartTime : instance.lifeStartTime; int age = 0; while (currStartDate <= now) { DateTime endDate = currStartDate.AddYears(1); if (calendarAligned) { endDate = endDate.AddDays(1 - endDate.DayOfYear); } if (endDate > now) { endDate = now; } blocks.Add(new TimeBlock(currStartDate, endDate, (calendarAligned ? currStartDate.Year : age).ToString())); if (endDate == now) { break; } currStartDate = endDate; age++; } } break; case SpanAlignment.Decades: { DateTime currStartDate = calendarAligned ? instance.mapStartTime : instance.lifeStartTime; int age = 0; while (currStartDate <= now) { DateTime endDate = currStartDate.AddYears(10); if (calendarAligned) { endDate = new DateTime(endDate.Year - endDate.Year % 10, 1, 1); } if (endDate > now) { endDate = now; } blocks.Add(new TimeBlock(currStartDate, endDate, (calendarAligned ? currStartDate.Year - currStartDate.Year % 10 : age) + "s")); if (endDate == now) { break; } currStartDate = endDate; age += 10; } } break; } foreach (var block in blocks) { int startDiv = (int)(block.startTime.Subtract(zeroTime).TotalDays / divDuration); int endDiv = (int)(block.endTime.Subtract(zeroTime).TotalDays / divDuration); bool[,] blockPoints = new bool[size, size]; bool[,] vertLines = new bool[size + 1, size + 1]; bool[,] horizLines = new bool[size + 1, size + 1]; List <Coord2> blockPointList = new List <Coord2>(); HashSet <Coord2> coveredPoints = new HashSet <Coord2>(); Dictionary <Coord2, int> rectSizes = new Dictionary <Coord2, int>(); /* * bool debug = Random.value < 0.1f; * /*/ bool debug = false; //*/ // Debug.Log( "Drawing shape for " + name + "; start: " + block.startTime + "; startDiv: " + startDiv // + "; end: " + block.endTime + "; endDiv: " + endDiv ); for (int i = startDiv; i < endDiv; i++) { int[] originCoords = HilbertCurve.IntToHilbert(i, 2); points [originCoords[0], originCoords[1]] = true; blockPoints[originCoords[0], originCoords[1]] = true; blockPointList.Add(new Coord2(originCoords[0], originCoords[1])); pointList.Add(new Coord2(originCoords[0], originCoords[1])); } blockPointList = blockPointList.OrderByDescending(p => Enumerable.Range(0, 8) .Select(n => (int)Mathf.Pow(2, n)) .Where(n => p.x % n == 0 && p.y % n == 0) .Max()).ToList(); if (debug) { Debug.Log("points in block: " + Utils.PrintVals(blockPointList.ToArray(), false, true)); } foreach (var point in blockPointList) { if (coveredPoints.Contains(point)) { continue; } //coveredPoints.Add( point ); int rectSize = 1; Coord2Range range = new Coord2Range(point); for (rectSize = 1; rectSize < 256; rectSize *= 2) { if (point.x % rectSize != 0 || point.y % rectSize != 0) { break; } if (point.x + rectSize > size || point.y + rectSize > size) { break; } var newRange = new Coord2Range(point, point + Coord2.one * (rectSize - 1)); if (newRange.Any(p => !blockPoints[p.x, p.y] || coveredPoints.Contains(p))) { break; } range = newRange; if (debug) { Debug.Log("rect size: " + rectSize + "; range: " + range + "; covered by range: " + Utils.PrintVals(range.ToArray(), false, true)); } } rectSize /= 2; foreach (var covered in range) { coveredPoints.Add(covered); } if (debug) { Debug.Log("covered points is now: " + Utils.PrintVals(coveredPoints.ToArray(), false, true)); } rectSizes[point] = rectSize; } if (debug) { Debug.Log("Rect sizes for block in " + name + ":\n" + string.Join("\n", rectSizes.Select(r => r.Key + ": " + r.Value).ToArray())); } foreach (var rect in rectSizes) { int vertInd = verts.Count; Vector3 origin = new Vector3(rect.Key.x, instance.elementMeshY, rect.Key.y) * divSize; verts.Add(origin); verts.Add(origin + Vector3.forward * divSize * rect.Value); verts.Add(origin + Vector3.right * divSize * rect.Value); verts.Add(origin + new Vector3(divSize, 0.0f, divSize) * rect.Value); tris.Add(vertInd); tris.Add(vertInd + 1); tris.Add(vertInd + 3); tris.Add(vertInd); tris.Add(vertInd + 3); tris.Add(vertInd + 2); } // add corners CornerDir[,] corners = new CornerDir[size + 1, size + 1]; // add individual edge segments for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { if (!blockPoints[x, y]) { continue; } if (((x == 0 || !blockPoints[x - 1, y]) && (y == 0 || !blockPoints[x, y - 1])) || ((x > 0 && blockPoints[x - 1, y]) && (y > 0 && blockPoints[x, y - 1]))) { corners[x, y] = CornerDir.LowerLeft; } if (((x == 0 || !blockPoints[x - 1, y]) && (y == size - 1 || !blockPoints[x, y + 1])) || ((x > 0 && blockPoints[x - 1, y]) && (y < size - 1 && blockPoints[x, y + 1]))) { corners[x, y + 1] = CornerDir.UpperLeft; } if (((x == size - 1 || !blockPoints[x + 1, y]) && (y == size - 1 || !blockPoints[x, y + 1])) || ((x < size - 1 && blockPoints[x + 1, y]) && (y < size - 1 && blockPoints[x, y + 1]))) { corners[x + 1, y + 1] = CornerDir.UpperRight; } if (((x == size - 1 || !blockPoints[x + 1, y]) && (y == 0 || !blockPoints[x, y - 1])) || ((x < size - 1 && blockPoints[x + 1, y]) && (y > 0 && blockPoints[x, y - 1]))) { corners[x + 1, y] = CornerDir.LowerRight; } if (x == 0 || !blockPoints[x - 1, y]) { vertLines[x, y] = true; } if (x == size - 1 || !blockPoints[x + 1, y]) { vertLines[x + 1, y] = true; } if (y == 0 || !blockPoints[x, y - 1]) { horizLines[x, y] = true; } if (y == size - 1 || !blockPoints[x, y + 1]) { horizLines[x, y + 1] = true; } } } // combine edge segments into lines List <LineSpan> spans = new List <LineSpan>(); // vertical lines first for (int x = 0; x <= size; x++) { for (int y = 0; y <= size; y++) { if (!vertLines[x, y]) { continue; } int startY = y; while (vertLines[x, y]) { y++; } spans.Add(new LineSpan(x, startY, x, y)); } } for (int y = 0; y <= size; y++) { for (int x = 0; x <= size; x++) { if (!horizLines[x, y]) { continue; } int startX = x; while (horizLines[x, y]) { x++; } spans.Add(new LineSpan(startX, y, x, y)); } } //Debug.Log( name + " block has " + spans.Count + " line spans" ); if (spans.Count == 0) { continue; } List <Coord2> lineCoords = new List <Coord2>(); LineSpan currSpan = spans.Random(); spans.Remove(currSpan); LineSpan nextSpan = null; Coord2 currEnd = currSpan.end; lineCoords.Add(currSpan.start); lineCoords.Add(currSpan.end); // Debug.Log( "currSpan is " + currEnd + "; all other spans:\n" // + Utils.PrintVals( spans.ToArray(), false, true ) ); // foreach (var span in spans) { // Debug.Log( "Match " + span + ": " + (span.start == currEnd || span.end == currEnd) ); // } while ((nextSpan = spans.FirstOrDefault(s => s.start == currEnd || s.end == currEnd)) != null) { currEnd = nextSpan.start == currEnd ? nextSpan.end : nextSpan.start; spans.Remove(nextSpan); currSpan = nextSpan; lineCoords.Add(currEnd); } LineRenderer lineRenderer = Instantiate(edgePrefabToUse, shapeObject.transform); lineRenderer.positionCount = lineCoords.Count; float yPosition = guideSpan == SpanAlignment.None ? instance.elementEdgeY : instance.guideEdgeY; lineRenderer.widthMultiplier *= divSize * 0.333f; float cornerShift = lineRenderer.widthMultiplier * 0.5f; // Vector3[] shunkLineVerts = instance.ShrinkPath( lineVerts.Select( c => ((Vector3) (Vector2) c) * divSize ).ToArray(), // lineRenderer.widthMultiplier * 0.5f ); Vector3[] lineVerts = lineCoords.Select(coord => { var cornerDir = corners[coord.x, coord.y]; Vector3 vert = new Vector3(coord.x * divSize, yPosition, coord.y * divSize); if (guideSpan != SpanAlignment.None) { return(vert); } if (cornerDir == CornerDir.UpperLeft || cornerDir == CornerDir.LowerLeft) { vert.x += cornerShift; } else { vert.x -= cornerShift; } if (cornerDir == CornerDir.UpperLeft || cornerDir == CornerDir.UpperRight) { vert.z -= cornerShift; } else { vert.z += cornerShift; } return(vert); }).ToArray(); lineRenderer.SetPositions(lineVerts); if (guideSpan == SpanAlignment.None) { Color edgeColor = color.ShiftLuma(0.1f); edgeColor.a = 1.0f; lineRenderer.startColor = lineRenderer.endColor = edgeColor; } // Debug.Log( "Generated edge color for " + name + ": " + edgeColor ); if (guideSpan != SpanAlignment.None) { Vector3 position = blockPointList.Select(v => new Vector3(v.x, 0.0f, v.y)).Average() * divSize + Vector3.up * instance.guideLabelY; if (!block.label) { block.label = Instantiate(labelPrefabToUse, labelParent.transform as RectTransform); //label.transform.position = position; block.label.localPosition = Utils.WorldToCanvasSpace(position, labelParent.transform as RectTransform, block.label); Text labelText = block.label.GetComponentInChildren <Text>(); labelText.text = block.labelString; labels.Add(block.label); } block.label.localPosition = Utils.WorldToCanvasSpace(position, labelParent.transform as RectTransform, block.label.transform as RectTransform); } } if (guideSpan == SpanAlignment.None) { Mesh mesh = new Mesh(); mesh.vertices = verts.ToArray(); mesh.triangles = tris.ToArray(); mesh.RecalculateBounds(); mesh.RecalculateNormals(); MeshFilter meshFilter = shapeObject.AddComponent <MeshFilter>(); meshFilter.sharedMesh = mesh; Material mat = new Material(baseMat); mat.color = color * 0.6f; // Debug.Log( "Applying mesh material color for " + name + ": " + color ); MeshRenderer meshRenderer = shapeObject.AddComponent <MeshRenderer>(); meshRenderer.sharedMaterial = mat; Vector3 position = pointList.Select(v => new Vector3(v.x, 0.0f, v.y)).Average() * divSize + Vector3.up * instance.elementLabelY; //Debug.Log( name + " average point position: " + position ); //label.transform.position = position; label.localPosition = Utils.WorldToCanvasSpace(position, labelParent.transform as RectTransform, label.transform as RectTransform); } }
public void UpdatePreview(string text) { const string start = "//["; const string end = "//]"; var service = MefV1HostServices.Create(_componentModel.DefaultExportProvider); var workspace = new PreviewWorkspace(service); var document = workspace.OpenDocument(DocumentId.CreateNewId("document"), SourceText.From(text), Language); var formatted = Formatter.FormatAsync(document, this.Options).WaitAndGetResult(CancellationToken.None); var textBuffer = _textBufferFactoryService.CreateTextBuffer(formatted.SourceText.ToString(), _contentType); var container = textBuffer.AsTextContainer(); var documentBackedByTextBuffer = document.WithText(container.CurrentText); var bufferText = textBuffer.CurrentSnapshot.GetText().ToString(); var startIndex = bufferText.IndexOf(start, StringComparison.Ordinal); var endIndex = bufferText.IndexOf(end, StringComparison.Ordinal); var startLine = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(startIndex) + 1; var endLine = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(endIndex); var projection = _projectionBufferFactory.CreateProjectionBufferWithoutIndentation(_contentTypeRegistryService, _editorOptions.CreateOptions(), textBuffer.CurrentSnapshot, "", LineSpan.FromBounds(startLine, endLine)); var textView = _textEditorFactoryService.CreateTextView(projection, _textEditorFactoryService.CreateTextViewRoleSet()); this.TextViewHost = _textEditorFactoryService.CreateTextViewHost(textView, setFocus: false); workspace.CloseDocument(document.Id); workspace.OpenDocument(document.Id, documentBackedByTextBuffer.SourceText, Language); //workspace.UpdateDocument(documentBackedByTextBuffer.Id, documentBackedByTextBuffer.SourceText); }
public void UpdatePreview(string text) { const string start = "//["; const string end = "//]"; var service = MefV1HostServices.Create(_componentModel.DefaultExportProvider); var workspace = new PreviewWorkspace(service); var fileName = string.Format("project.{0}", Language == "C#" ? "csproj" : "vbproj"); var project = workspace.CurrentSolution.AddProject(fileName, "assembly.dll", Language); // use the mscorlib, system, and system.core that are loaded in the current process. string[] references = { "mscorlib", "System", "System.Core" }; var metadataService = workspace.Services.GetService <IMetadataService>(); var referenceAssemblies = Thread.GetDomain().GetAssemblies() .Where(x => references.Contains(x.GetName(true).Name, StringComparer.OrdinalIgnoreCase)) .Select(a => metadataService.GetReference(a.Location, MetadataReferenceProperties.Assembly)); project = project.WithMetadataReferences(referenceAssemblies); var document = project.AddDocument("document", SourceText.From(text, Encoding.UTF8)); var formatted = Formatter.FormatAsync(document, this.Options).WaitAndGetResult(CancellationToken.None); var textBuffer = _textBufferFactoryService.CreateTextBuffer(formatted.GetTextAsync().Result.ToString(), _contentType); var container = textBuffer.AsTextContainer(); var documentBackedByTextBuffer = document.WithText(container.CurrentText); var bufferText = textBuffer.CurrentSnapshot.GetText().ToString(); var startIndex = bufferText.IndexOf(start, StringComparison.Ordinal); var endIndex = bufferText.IndexOf(end, StringComparison.Ordinal); var startLine = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(startIndex) + 1; var endLine = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(endIndex); var projection = _projectionBufferFactory.CreateProjectionBufferWithoutIndentation(_contentTypeRegistryService, _editorOptions.CreateOptions(), textBuffer.CurrentSnapshot, "", LineSpan.FromBounds(startLine, endLine)); var textView = _textEditorFactoryService.CreateTextView(projection, _textEditorFactoryService.CreateTextViewRoleSet(PredefinedTextViewRoles.Analyzable)); this.TextViewHost = _textEditorFactoryService.CreateTextViewHost(textView, setFocus: false); workspace.TryApplyChanges(documentBackedByTextBuffer.Project.Solution); workspace.OpenDocument(document.Id); this.TextViewHost.Closed += (s, a) => { workspace.Dispose(); workspace = null; }; }
public override void AddLine(LineSpan lineSpan, bool willUpdateImmediately) { if (lineSpan.Highlight) { lineSpan.Highlight = false; if (!willUpdateImmediately) { Modified.Add(lineSpan); } } }
// Adds a line span to the spans we've been collecting. If the line span overlaps or // abuts a previous span then the two are merged. private static void MergeLineSpans(List<LineSpan> lineSpans, LineSpan nextLineSpan) { if (lineSpans.Count > 0) { var lastLineSpan = lineSpans.Last(); // We merge them if there's no more than one line between the two. Otherwise // we'd show "..." between two spans where we could just show the actual code. if (nextLineSpan.Start >= lastLineSpan.Start && nextLineSpan.Start <= (lastLineSpan.End + 1)) { nextLineSpan = LineSpan.FromBounds(lastLineSpan.Start, nextLineSpan.End); lineSpans.RemoveAt(lineSpans.Count - 1); } } lineSpans.Add(nextLineSpan); }
private static IList<SnapshotSpan> CreateSnapshotSpans(ITextSnapshot snapshot, LineSpan lineSpan) { var result = new List<SnapshotSpan>(); for (int i = lineSpan.Start; i < lineSpan.End; i++) { var line = snapshot.GetLineFromLineNumber(i); result.Add(line.Extent); } return result; }
public override void AddLine(LineSpan line, bool willUpdateImmediately) { if (line.FirstLine <= LineNumber && LineNumber <= line.LastLine && ((line.LastLine - line.FirstLine) >= MinimumLength || line.LinkedLines.Any()) && line.Indent <= Position && (Nearest == null || line.Indent > Nearest.Indent)) { Nearest = line; } if (line.Highlight) { line.Highlight = false; if (!willUpdateImmediately) { Modified.Add(line); } Modified.AddRange(line.LinkedLines); } }
public override IEnumerable<LineSpan> GetModified() { if (Nearest != null) { while (Modified.Remove(Nearest)) { } Nearest.Highlight = true; Modified.Add(Nearest); Modified.AddRange(Nearest.LinkedLines); Nearest = null; } return Modified; }
public void UpdatePreview(string text) { const string start = "//["; const string end = "//]"; var sourceText = SourceText.From(text); var syntaxTree = SyntaxFactory.ParseSyntaxTree(sourceText); var edits = Formatter.GetEdits(syntaxTree, new TextSpan(sourceText, 0, text.Length), _optionsService.FormattingOptions); var formatted = Formatter.ApplyEdits(text, edits); var textBuffer = _textBufferFactoryService.CreateTextBuffer(formatted, _contentType); var bufferText = textBuffer.CurrentSnapshot.GetText().ToString(); var startIndex = bufferText.IndexOf(start, StringComparison.Ordinal); var endIndex = bufferText.IndexOf(end, StringComparison.Ordinal); var startLine = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(startIndex) + 1; var endLine = textBuffer.CurrentSnapshot.GetLineNumberFromPosition(endIndex); var projection = _projectionBufferFactory.CreateProjectionBufferWithoutIndentation(_contentTypeRegistryService, _editorOptions.CreateOptions(), textBuffer.CurrentSnapshot, "", LineSpan.FromBounds(startLine, endLine)); var textView = _textEditorFactoryService.CreateTextView(projection, _textEditorFactoryService.CreateTextViewRoleSet(PredefinedTextViewRoles.Analyzable)); this.TextViewHost = _textEditorFactoryService.CreateTextViewHost(textView, setFocus: false); }
// Calculate and draw the string by drawing each line. public void Draw (Graphics graphics, String text, Font font, Rectangle drawLayout, StringFormat format, Brush brush) { // set the current graphics this.graphics = graphics; // set the current toolkit graphics this.toolkitGraphics = graphics.ToolkitGraphics; // set the current text this.text = text; // set the current font this.font = font; // set the current layout rectangle this.layout = drawLayout; // set the current brush this.brush = brush; // ensure we have a string format if(format == null) { format = SF_DEFAULT; } // set the current string format this.format = format; // set the default hotkey index this.hotkeyIndex = -1; // set the current line height lineHeight = font.Height; // set the only whole lines flag onlyWholeLines = (((format.FormatFlags & StringFormatFlags.LineLimit) != 0) || ((format.Trimming & StringTrimming.None) != 0)); // set the index of the next character nextIndex = 0; // set the current line space usage lineSpaceUsedUp = 0; // set the current line number lineNumber = 0; // set the previous span ended in new line flag prevIsNewLine = false; // select the current font into the graphics context graphics.SelectFont(font); // select the current brush into the graphics context graphics.SelectBrush(brush); // set the current text start int textStart = 0; // set the current text length int textLength = 0; // set the current text width int textWidth = 0; // get the actual hotkey index, if needed if(format.HotkeyPrefix != HotkeyPrefix.None) { // get the hotkey index hotkeyIndex = text.IndexOf('&'); // handle the hotkey as needed if(hotkeyIndex != -1) { if(hotkeyIndex >= (text.Length - 1) || Char.IsControl(text[hotkeyIndex + 1])) { // no need for this anymore hotkeyIndex = -1; } else { // remove the hotkey character text = text.Substring(0, hotkeyIndex) + text.Substring(hotkeyIndex + 1); // set the current text this.text = text; // prepare to show or hide the underline if(format.HotkeyPrefix == HotkeyPrefix.Show) { // get the underline font underlineFont = new Font (font, font.Style | FontStyle.Underline); } else { // no need for this anymore hotkeyIndex = -1; } } } } // draw the text try { // handle drawing based on line alignment if(format.LineAlignment == StringAlignment.Near) { // set the current y position int y = layout.Top; // get the maximum y position int maxY = layout.Bottom; // adjust for whole lines, if needed if(onlyWholeLines) { maxY -= ((maxY - y) % lineHeight); } // get the last line y position int lastLineY = maxY - lineHeight; // create character spans CharSpan span = new CharSpan(); CharSpan prev = new CharSpan(); // set the first span flag bool firstSpan = true; // process the text while(nextIndex < text.Length) { // get the next span of characters GetNextSpan(span); // draw the pending line, as needed if(span.newline && !firstSpan) { // draw the line, if needed if(textWidth > 0) { // remove trailing spaces, if needed if(!firstSpan && text[prev.start] == ' ') { // update text width textWidth -= GetSpanWidth(prev); // update text length textLength -= prev.length; } // draw the line DrawLine (textStart, textLength, textWidth, y, (y > lastLineY)); } // update the y position y += lineHeight; // update the line number ++lineNumber; // update the text start textStart = span.start; // reset the text length textLength = 0; // reset the text width textWidth = 0; } // update the text length textLength += span.length; // update the text width textWidth += GetSpanWidth(span); // copy span values to previous span span.CopyTo(prev); // set the first span flag firstSpan = false; // break if the y position is out of bounds if(y > maxY) { break; } } // draw the last line, if needed if(textWidth > 0 && y <= maxY) { // draw the last line DrawLine (textStart, textLength, textWidth, y, (y > lastLineY)); } } else { // set default lines to draw int linesToDraw = 0; // calculate lines to draw if(onlyWholeLines) { linesToDraw = layout.Height / lineHeight; } else { linesToDraw = (int)Math.Ceiling((double)layout.Height / lineHeight); } // create line span list LineSpan[] lines = new LineSpan[linesToDraw]; // create character spans CharSpan span = new CharSpan(); CharSpan prev = new CharSpan(); // set the first span flag bool firstSpan = true; // set the current line position int linePos = 0; // populate line span list while(linePos < lines.Length && nextIndex < text.Length) { // get the next span of characters GetNextSpan(span); // handle span on new line if(span.newline && !firstSpan) { // remove trailing spaces, if needed if(!firstSpan && text[prev.start] == ' ') { // update text width textWidth -= GetSpanWidth(prev); // update text length textLength -= prev.length; } // create line span for current line LineSpan lineSpan = new LineSpan (textStart, textLength, textWidth); // add current line span to line span list lines[linePos++] = lineSpan; // update text start textStart = span.start; // update text length textLength = 0; // update text width textWidth = 0; } // update text length textLength += span.length; // update text width textWidth += GetSpanWidth(span); // copy span values to previous span span.CopyTo(prev); // set the first span flag firstSpan = false; } // add the last line to the line span list if(linePos < lines.Length) { // create line span for last line LineSpan lineSpan = new LineSpan (textStart, textLength, textWidth); // add last line span to the line span list lines[linePos++] = lineSpan; } // calculate the top line y int y = (layout.Height - (linePos * lineHeight)); // adjust y for center alignment, if needed if(format.LineAlignment == StringAlignment.Center) { y /= 2; } // translate y to layout rectangle y += layout.Top; // adjust line position to last line --linePos; // draw the lines for(int i = 0; i < linePos; ++i) { // get the current line LineSpan line = lines[i]; // draw the current line DrawLine (line.start, line.length, line.pixelWidth, y, false); // update the y position y += lineHeight; } // draw the last line DrawLine (lines[linePos].start, lines[linePos].length, lines[linePos].pixelWidth, y, true); } } finally { // dispose the underline font, if we have one if(underlineFont != null) { // dispose the underline font underlineFont.Dispose(); // reset the underline font underlineFont = null; } } }
/// <summary> /// Merge two text files, by performing a line-by-line, case-sensitive comparison /// </summary> /// <returns>Enum indicating Conflict, Warning or Exact Copy</returns> /// <param name="identifyConflictsOnly">Flag - if true, don't merge</param> /// <param name="fileBodyLeft">Contents of LEFT file</param> /// <param name="fileBodyRight">Contents of RIGHT file</param> /// <param name="leftConflictLines">Array of lines with conflict from LEFT file</param> /// <param name="rightConflictLines">Array of lines with conflict from RIGHT file</param> /// <param name="combinedText">Result of merging files.</param> public static TypeOfDiff PerformTwoWayDiff( bool identifyConflictsOnly, string fileBodyLeft, string fileBodyRight, out LineSpan[] leftConflictLines, out LineSpan[] rightConflictLines, out string combinedText) { TypeOfDiff returnValue = TypeOfDiff.ExactCopy; combinedText = ""; StringUtility.RemoveTrailingLineBreaks(ref fileBodyLeft); StringUtility.RemoveTrailingLineBreaks(ref fileBodyRight); // break files into arrays of lines string[] leftLines = Common.Utility.StandardizeLineBreaks(fileBodyLeft, Common.Utility.LineBreaks.Unix).Split('\n'); string[] rightLines = Common.Utility.StandardizeLineBreaks(fileBodyRight, Common.Utility.LineBreaks.Unix).Split('\n'); // handle case where at least one file is empty if (fileBodyLeft.Length == 0 || fileBodyRight.Length == 0) { // both files are empty (unlikely in practice) if (fileBodyLeft.Length == 0 && fileBodyRight.Length == 0) { leftConflictLines = new LineSpan[0]; rightConflictLines = new LineSpan[0]; return(TypeOfDiff.ExactCopy); } // one file is empty if (fileBodyLeft.Length > 0) { combinedText = fileBodyLeft; leftConflictLines = new[] { new LineSpan(0, leftLines.Length - 1) }; rightConflictLines = new LineSpan[0]; } else { combinedText = fileBodyRight; leftConflictLines = new LineSpan[0]; rightConflictLines = new[] { new LineSpan(0, rightLines.Length - 1) }; } return(TypeOfDiff.Warning); } // initialise variables for merging StringBuilder sbMerged = new StringBuilder(Math.Max(fileBodyLeft.Length, fileBodyRight.Length) + 1000); // DMW_Question Is a 'combinedLineCount' really a 'mergedLineCount'? int combinedLineCount = 0; ArrayList combinedLeftColouredLines = new ArrayList(); ArrayList combinedRightColouredLines = new ArrayList(); // perform the diff (case-sensitive, check white space) Diff diff = new Diff(leftLines, rightLines, true, true); // loop through parts of the diff foreach (Diff.Hunk hunk in diff) { if (hunk.Same) { for (int i = hunk.Left.Start; i <= hunk.Left.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(leftLines[i]); combinedLineCount++; } } else // hunks are different { if (hunk.Left.Count > 0 && hunk.Right.Count > 0) { returnValue = TypeOfDiff.Conflict; } else if (returnValue != TypeOfDiff.Conflict) { returnValue = TypeOfDiff.Warning; } // LEFT file for (int i = hunk.Left.Start; i <= hunk.Left.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(leftLines[i]); if (!identifyConflictsOnly || (hunk.Left.Count > 0 && hunk.Right.Count > 0)) { combinedLeftColouredLines.Add(new LineSpan(combinedLineCount, combinedLineCount)); } combinedLineCount++; } // RIGHT file for (int i = hunk.Right.Start; i <= hunk.Right.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(rightLines[i]); if (!identifyConflictsOnly || (hunk.Left.Count > 0 && hunk.Right.Count > 0)) { combinedRightColouredLines.Add(new LineSpan(combinedLineCount, combinedLineCount)); } combinedLineCount++; } } } leftConflictLines = (LineSpan[])combinedLeftColouredLines.ToArray(typeof(LineSpan)); rightConflictLines = (LineSpan[])combinedRightColouredLines.ToArray(typeof(LineSpan)); combinedText = sbMerged.ToString(); return(returnValue); }
/// <summary> /// Updates the internal state based on the line. All lines should be /// passed. /// </summary> /// <param name="lineSpan"> /// The line to use and potentially update. /// </param> /// <param name="willUpdateImmediately"> /// If True, lines modified directly will not be returned again by /// GetModified(). However, some lines may be modified indirectly, so a /// call to GetModified() is still required.</param> public abstract void AddLine(LineSpan lineSpan, bool willUpdateImmediately);
void UpdateGuide(LineSpan lineSpan, Line adornment, double left, double top, double bottom) { if (bottom <= top) { adornment.Visibility = Visibility.Collapsed; } else { adornment.X1 = left + 0.5; #if DEBUG adornment.X2 = left + 1.5; #else adornment.X2 = left + 0.5; #endif adornment.Y1 = top; adornment.Y2 = bottom; adornment.StrokeDashOffset = top; adornment.Visibility = Visibility.Visible; UpdateGuide(lineSpan, adornment); } }
private static IList<IList<SnapshotSpan>> CreateSnapshotSpanRanges(ITextSnapshot snapshot, LineSpan[] exposedLineSpans) { var result = new List<IList<SnapshotSpan>>(); foreach (var lineSpan in exposedLineSpans) { var snapshotSpans = CreateSnapshotSpans(snapshot, lineSpan); if (snapshotSpans.Count > 0) { result.Add(snapshotSpans); } } return result; }
/// <summary> /// Updates the line <paramref name="guide"/> with a new format. /// </summary> /// <param name="guide">The <see cref="Line"/> to update.</param> /// <param name="formatIndex">The new format index.</param> void UpdateGuide(LineSpan lineSpan, Line adornment) { if (lineSpan == null || adornment == null) return; LineFormat format; if (lineSpan.Type == LineSpanType.PageWidthMarker) { if (!Theme.PageWidthMarkers.TryGetValue(lineSpan.Indent, out format)) { format = Theme.DefaultLineFormat; } } else if (!Theme.LineFormats.TryGetValue(lineSpan.FormatIndex, out format)) { format = Theme.DefaultLineFormat; } if (!format.Visible) { adornment.Visibility = Visibility.Hidden; return; } bool highlight = lineSpan.Highlight || lineSpan.LinkedLines.Any(ls => ls.Highlight); var lineStyle = highlight ? format.HighlightStyle : format.LineStyle; var lineColor = (highlight && !lineStyle.HasFlag(LineStyle.Glow)) ? format.HighlightColor : format.LineColor; Brush brush; if (!GuideBrushCache.TryGetValue(lineColor, out brush)) { brush = new SolidColorBrush(lineColor.ToSWMC()); if (brush.CanFreeze) brush.Freeze(); GuideBrushCache[lineColor] = brush; } adornment.Stroke = brush; adornment.StrokeThickness = lineStyle.GetStrokeThickness(); adornment.StrokeDashArray = lineStyle.GetStrokeDashArray(); if (lineStyle.HasFlag(LineStyle.Dotted) || lineStyle.HasFlag(LineStyle.Dashed)) { adornment.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Unspecified); } else { adornment.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased); } if (lineStyle.HasFlag(LineStyle.Glow)) { Effect effect; var glowColor = highlight ? format.HighlightColor : format.LineColor; if (!GlowEffectCache.TryGetValue(glowColor, out effect)) { effect = new DropShadowEffect { Color = glowColor.ToSWMC(), BlurRadius = LineStyle.Thick.GetStrokeThickness(), Opacity = 1.0, ShadowDepth = 0.0, RenderingBias = RenderingBias.Performance }; if (effect.CanFreeze) effect.Freeze(); GlowEffectCache[glowColor] = effect; } try { adornment.Effect = effect; } catch (COMException) { // No sensible way to deal with this exception, so we'll // fall back on changing the color. adornment.Effect = null; if (!GuideBrushCache.TryGetValue(glowColor, out brush)) { brush = new SolidColorBrush(glowColor.ToSWMC()); if (brush.CanFreeze) brush.Freeze(); GuideBrushCache[glowColor] = brush; } adornment.Stroke = brush; } } else { adornment.Effect = null; } }
public TextSnapshotLine(ITextSnapshot snapshot, LineSpan lineSpan, int lineNumber) { _snapshot = snapshot; _lineSpan = lineSpan; _lineNumber = lineNumber; }
protected CaretNearestLeftBase(VirtualSnapshotPoint location, int tabSize, int minimumLength) : base(location, tabSize) { Nearest = null; MinimumLength = minimumLength - 1; }
/// <summary> /// Merge two text files, by performing a line-by-line, case-sensitive comparison /// </summary> /// <returns>Enum indicating Conflict, Warning or Exact Copy</returns> /// <param name="identifyConflictsOnly">Flag - if true, don't merge</param> /// <param name="fileBodyLeft">Contents of LEFT file</param> /// <param name="fileBodyRight">Contents of RIGHT file</param> /// <param name="leftConflictLines">Array of lines with conflict from LEFT file</param> /// <param name="rightConflictLines">Array of lines with conflict from RIGHT file</param> /// <param name="combinedText">Result of merging files.</param> public static TypeOfDiff PerformTwoWayDiff( bool identifyConflictsOnly, string fileBodyLeft, string fileBodyRight, out LineSpan[] leftConflictLines, out LineSpan[] rightConflictLines, out string combinedText) { TypeOfDiff returnValue = TypeOfDiff.ExactCopy; combinedText = ""; StringUtility.RemoveTrailingLineBreaks(ref fileBodyLeft); StringUtility.RemoveTrailingLineBreaks(ref fileBodyRight); // break files into arrays of lines string[] leftLines = Common.Utility.StandardizeLineBreaks(fileBodyLeft, Common.Utility.LineBreaks.Unix).Split('\n'); string[] rightLines = Common.Utility.StandardizeLineBreaks(fileBodyRight, Common.Utility.LineBreaks.Unix).Split('\n'); // handle case where at least one file is empty if (fileBodyLeft.Length == 0 || fileBodyRight.Length == 0) { // both files are empty (unlikely in practice) if (fileBodyLeft.Length == 0 && fileBodyRight.Length == 0) { leftConflictLines = new LineSpan[0]; rightConflictLines = new LineSpan[0]; return TypeOfDiff.ExactCopy; } // one file is empty if (fileBodyLeft.Length > 0) { combinedText = fileBodyLeft; leftConflictLines = new[] { new LineSpan(0, leftLines.Length - 1) }; rightConflictLines = new LineSpan[0]; } else { combinedText = fileBodyRight; leftConflictLines = new LineSpan[0]; rightConflictLines = new[] { new LineSpan(0, rightLines.Length - 1) }; } return TypeOfDiff.Warning; } // initialise variables for merging StringBuilder sbMerged = new StringBuilder(Math.Max(fileBodyLeft.Length, fileBodyRight.Length) + 1000); // DMW_Question Is a 'combinedLineCount' really a 'mergedLineCount'? int combinedLineCount = 0; ArrayList combinedLeftColouredLines = new ArrayList(); ArrayList combinedRightColouredLines = new ArrayList(); // perform the diff (case-sensitive, check white space) Diff diff = new Diff(leftLines, rightLines, true, true); // loop through parts of the diff foreach (Diff.Hunk hunk in diff) { if (hunk.Same) { for (int i = hunk.Left.Start; i <= hunk.Left.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(leftLines[i]); combinedLineCount++; } } else // hunks are different { if (hunk.Left.Count > 0 && hunk.Right.Count > 0) { returnValue = TypeOfDiff.Conflict; } else if (returnValue != TypeOfDiff.Conflict) { returnValue = TypeOfDiff.Warning; } // LEFT file for (int i = hunk.Left.Start; i <= hunk.Left.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(leftLines[i]); if (!identifyConflictsOnly || (hunk.Left.Count > 0 && hunk.Right.Count > 0)) { combinedLeftColouredLines.Add(new LineSpan(combinedLineCount, combinedLineCount)); } combinedLineCount++; } // RIGHT file for (int i = hunk.Right.Start; i <= hunk.Right.End; i++) { //DMW_Changed sbMerged.Append(leftLines[i] + Environment.NewLine); sbMerged.AppendLine(rightLines[i]); if (!identifyConflictsOnly || (hunk.Left.Count > 0 && hunk.Right.Count > 0)) { combinedRightColouredLines.Add(new LineSpan(combinedLineCount, combinedLineCount)); } combinedLineCount++; } } } leftConflictLines = (LineSpan[])combinedLeftColouredLines.ToArray(typeof(LineSpan)); rightConflictLines = (LineSpan[])combinedRightColouredLines.ToArray(typeof(LineSpan)); combinedText = sbMerged.ToString(); return returnValue; }
public override void AddLine(LineSpan line, bool willUpdateImmediately) { bool isTouching = false; if (line.FirstLine - 1 <= LineNumber && LineNumber <= line.LastLine + 1 && (line.LastLine - line.FirstLine) >= MinimumLength && line.Indent == Position) { isTouching = true; } if (line.Highlight != isTouching) { line.Highlight = isTouching; if (!willUpdateImmediately) { Modified.Add(line); } Modified.AddRange(line.LinkedLines); } }
public async Task <ActionResult> GoToDefinitionGetContentAsync(string projectId, string symbolId) { try { Requests.LogRequest(this); var definitions = await Storage.GetReferencesToSymbolAsync( this.GetSearchRepos(), new Symbol() { ProjectId = projectId, Id = SymbolId.UnsafeCreateWithValue(symbolId), Kind = nameof(ReferenceKind.Definition) }); definitions.Entries = definitions.Entries.Distinct(m_referenceEquator).ToList(); if (definitions.Entries.Count == 1) { var definitionReference = definitions.Entries[0]; var sourceFile = await GetSourceFileAsync(definitionReference.ReferringProjectId, definitionReference.File); if (sourceFile != null) { var referringSpan = definitions.Entries[0].ReferringSpan; var position = new LineSpan() { position = referringSpan.Start, length = referringSpan.Length, line = definitionReference.ReferringSpan.LineNumber + 1, column = definitionReference.ReferringSpan.LineSpanStart + 1 }; sourceFile.span = position; } return(WrapTheModel(sourceFile)); } else { var definitionResult = await Storage.GetDefinitionsAsync(this.GetSearchRepos(), projectId, symbolId); var symbolName = definitionResult?.FirstOrDefault()?.Span.Definition.DisplayName ?? symbolId; definitions.SymbolName = symbolName ?? definitions.SymbolName; if (definitions.Entries.Count == 0) { definitions = await Storage.GetReferencesToSymbolAsync( this.GetSearchRepos(), new Symbol() { ProjectId = projectId, Id = SymbolId.UnsafeCreateWithValue(symbolId) }); } var referencesText = ReferencesController.GenerateReferencesHtml(definitions); if (string.IsNullOrEmpty(referencesText)) { referencesText = "No definitions found."; } else { referencesText = "<!--Definitions-->" + referencesText; } Responses.PrepareResponse(Response); return(PartialView("~/Views/References/References.cshtml", referencesText)); } } catch (Exception ex) { return(Responses.Exception(ex)); } }