private void ShowDiffs(string oldText, string newText) { IDiffer differ = new Differ(); DiffResult diffResult = differ.CreateLineDiffs(oldText, newText, false); ISideBySideDiffBuilder diffBuilder = new SideBySideDiffBuilder(differ); SideBySideDiffModel model = diffBuilder.BuildDiffModel(oldText, newText); this.DisplayDiffPiece(this.rtbSnapshotLeft, model.OldText.Lines, string.IsNullOrEmpty(newText)); this.DisplayDiffPiece(this.rtbSnapshotRight, model.NewText.Lines, false); }
public void Format(Document document) { if (BeautifierTagger.CurrentContentType == null || !SettingsPage.IsEnabled) { return; } var typeName = BeautifierTagger.CurrentContentType.TypeName.ToUpper(); if (typeName != "CSS" && typeName != "SCSS") { return; } var currentDoc = dte.ActiveDocument; document.Activate(); var txtDoc = document.Object() as TextDocument; if (txtDoc != null) { var textManager = (IVsTextManager)Package.GetGlobalService(typeof(SVsTextManager)); IVsTextView textView; textManager.GetActiveView(1, null, out textView); int caretLine; int caretCol; textView.GetCaretPos(out caretLine, out caretCol); int firstVisibleUnit; int ignore; textView.GetScrollInfo(1, out ignore, out ignore, out ignore, out firstVisibleUnit); var startPt = txtDoc.StartPoint.CreateEditPoint(); var docText = startPt.GetText(txtDoc.EndPoint); var result = BeautifierCompiler.ProcessString(docText, BeautifierTagger.CurrentContentType); // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags const int flags = (int)(vsEPReplaceTextOptions.vsEPReplaceTextTabsSpaces | vsEPReplaceTextOptions.vsEPReplaceTextNormalizeNewlines); if (result != docText) { var differ = new Differ(); var diffResult = differ.CreateLineDiffs(docText, result, false); var beginEditPoint = txtDoc.StartPoint.CreateEditPoint(); var endEditPoint = txtDoc.StartPoint.CreateEditPoint(); var lineCountChange = 0; txtDoc.DTE.UndoContext.Open("PostCSS Format"); foreach (var block in diffResult.DiffBlocks) { var startLine = block.DeleteStartA + lineCountChange + 1; var endLine = block.DeleteStartA + block.DeleteCountA + lineCountChange + 1; lineCountChange += (block.InsertCountB - block.DeleteCountA); //beginEditPoint.ReplaceText(endEditPoint, "", flags); if (block.InsertCountB > 0) { beginEditPoint.MoveToLineAndOffset(startLine, 1); endEditPoint.MoveToLineAndOffset(endLine, 1); var newLines = new List <string>(); for (var i = 0; i < block.InsertCountB; i++) { var lineIndex = i + block.InsertStartB; var line = diffResult.PiecesNew[lineIndex]; newLines.Add(line); } var newText = string.Join("\r\n", newLines) + "\r\n"; beginEditPoint.ReplaceText(endEditPoint, newText, flags); } else if (block.DeleteCountA > 0) { beginEditPoint.MoveToLineAndOffset(startLine, 1); endEditPoint.MoveToLineAndOffset(startLine + block.DeleteCountA, 1); beginEditPoint.ReplaceText(endEditPoint, "", flags); } } txtDoc.DTE.UndoContext.Close(); //startPt.ReplaceText(txtDoc.EndPoint, result, flags); textView.SetCaretPos(caretLine, 0); textView.SetScrollPosition(1, firstVisibleUnit); } } currentDoc.Activate(); }
public void Refresh() { this.FindControl <StackPanel>("FileContainer").Children.Clear(); Editor editor = this.FindAncestorOfType <Editor>(); string autosaveDirectory = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetEntryAssembly().GetName().Name); string savePath = System.IO.Path.Combine(autosaveDirectory, editor.Guid); string[] files; try { files = System.IO.Directory.GetFiles(savePath, "*.md"); } catch { files = new string[0]; } long result = -1; List <(long, string)> sortedFiles = (from el in files let filename = System.IO.Path.GetFileNameWithoutExtension(el) where filename.StartsWith("autosave") || long.TryParse(filename, out result) let result2 = result orderby !filename.StartsWith("autosave") ? result2 : ((DateTimeOffset) new System.IO.FileInfo(el).LastWriteTimeUtc).ToUnixTimeSeconds() descending select !filename.StartsWith("autosave") ? (result2, el) : (((DateTimeOffset) new System.IO.FileInfo(el).LastWriteTimeUtc).ToUnixTimeSeconds(), el)).ToList(); sortedFiles.Add((editor.OriginalTimeStamp, "original")); sortedFiles.Sort((a, b) => Math.Sign(b.Item1 - a.Item1)); int diffWidth = (int)Math.Max(10, Math.Floor(this.Bounds.Width - 32 - 150 - 32 - 32 - 22)); string currentText = null; int lineCount = -1; Differ differ = new Differ(); if (sortedFiles.Any()) { currentText = editor.EditorControl.Text.ToString(); lineCount = editor.EditorControl.Text.Lines.Count; } foreach ((long timestamp, string file)file in sortedFiles) { Grid itemGrid = new Grid(); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(32, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(150, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Star)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(36, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(1, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(36, GridUnitType.Pixel)); itemGrid.ColumnDefinitions.Add(new ColumnDefinition(18, GridUnitType.Pixel)); if (System.IO.Path.GetFileNameWithoutExtension(file.file).StartsWith("autosave")) { AutosaveIcon icon = new DiagnosticIcons.AutosaveIcon(); ToolTip.SetTip(icon, "Autosave"); itemGrid.Children.Add(icon); } else if (file.file == "original") { StartingIcon icon = new DiagnosticIcons.StartingIcon(); ToolTip.SetTip(icon, "Original file"); itemGrid.Children.Add(icon); } else { SaveIcon icon = new DiagnosticIcons.SaveIcon(); ToolTip.SetTip(icon, "Manual save"); itemGrid.Children.Add(icon); } TextBlock timeBlock = new TextBlock() { Text = DateTimeOffset.FromUnixTimeSeconds(file.timestamp).DateTime.ToLocalTime().ToString("HH:mm:ss \\(dd MMM\\)", System.Globalization.CultureInfo.InvariantCulture), Margin = new Thickness(5, 2, 5, 2), VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center }; Grid.SetColumn(timeBlock, 2); itemGrid.Children.Add(timeBlock); DiffResult diffResult; if (file.file != "original") { diffResult = differ.CreateLineDiffs(currentText, System.IO.File.ReadAllText(file.file), false); } else { diffResult = differ.CreateLineDiffs(currentText, editor.OriginalText, false); } List <(int pos, int count, Colour colour)> diffLines = new List <(int pos, int count, Colour colour)>(from el in diffResult.DiffBlocks let pos = el.DeleteCountA > 0 ? el.DeleteStartA : el.InsertStartB orderby pos ascending select(pos, el.DeleteCountA > 0 ? el.DeleteCountA : el.InsertCountB, el.DeleteCountA > 0 ? RedColour : GreenColour)); int currPos = 0; List <(double width, Colour colour)> diffBlocks = new List <(double width, Colour colour)>(); for (int i = 0; i < diffLines.Count; i++) { if (diffLines[i].pos > currPos) { diffBlocks.Add((diffLines[i].pos - currPos, GreyColour)); currPos = diffLines[i].pos; } diffBlocks.Add((diffLines[i].count, diffLines[i].colour)); currPos += diffLines[i].count; } if (currPos < lineCount) { diffBlocks.Add((lineCount - currPos, GreyColour)); currPos = lineCount; } Page diff = new Page(diffWidth, 20); Graphics gpr = diff.Graphics; double currX = 0; for (int i = 0; i < diffBlocks.Count; i++) { double w = diffBlocks[i].width * diffWidth / currPos; gpr.FillRectangle(currX, 0, w, 20, diffBlocks[i].colour); currX += w; } Viewbox diffBox = new Viewbox() { Child = diff.PaintToCanvas(false), VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center, Height = 20, Stretch = Stretch.Fill }; Grid.SetColumn(diffBox, 4); itemGrid.Children.Add(diffBox); if (file.file != "original") { Button restoreButton = new Button() { Content = new DiagnosticIcons.RestoreIcon(), Margin = new Thickness(3) }; Grid.SetColumn(restoreButton, 6); ToolTip.SetTip(restoreButton, "Restore"); itemGrid.Children.Add(restoreButton); Button deleteButton = new Button() { Content = new DiagnosticIcons.DeleteIcon(), Margin = new Thickness(3) }; Grid.SetColumn(deleteButton, 8); ToolTip.SetTip(deleteButton, "Delete"); itemGrid.Children.Add(deleteButton); restoreButton.Click += async(s, e) => { try { string newText = System.IO.File.ReadAllText(file.file); await editor.EditorControl.SetText(newText); if (editor.EditorControl.ShowLineChanges) { DiffResult diffResultFromLastSaved = editor.Differ.CreateLineDiffs(editor.LastSavedText, newText, false); IEnumerable <int> changesFromLastSaved = (from el in diffResultFromLastSaved.DiffBlocks select Enumerable.Range(el.InsertStartB, Math.Max(1, el.InsertCountB))).Aggregate(Enumerable.Empty <int>(), (a, b) => a.Concat(b)); DiffResult diffResultFromOriginal = editor.Differ.CreateLineDiffs(editor.OriginalText, newText, false); IEnumerable <int> changesFromOriginal = (from el in diffResultFromOriginal.DiffBlocks select Enumerable.Range(el.InsertStartB, Math.Max(1, el.InsertCountB))).Aggregate(Enumerable.Empty <int>(), (a, b) => a.Concat(b)); editor.SetLineDiff(changesFromLastSaved, changesFromOriginal); } } catch { } Refresh(); }; deleteButton.Click += (s, e) => { try { System.IO.File.Delete(file.file); } catch { } Refresh(); }; } else { Button restoreButton = new Button() { Content = new DiagnosticIcons.RestoreIcon(), Margin = new Thickness(3) }; Grid.SetColumn(restoreButton, 6); ToolTip.SetTip(restoreButton, "Restore"); itemGrid.Children.Add(restoreButton); restoreButton.Click += async(s, e) => { string newText = editor.OriginalText; await editor.EditorControl.SetText(newText); if (editor.EditorControl.ShowLineChanges) { DiffResult diffResultFromLastSaved = editor.Differ.CreateLineDiffs(editor.LastSavedText, newText, false); IEnumerable <int> changesFromLastSaved = (from el in diffResultFromLastSaved.DiffBlocks select Enumerable.Range(el.InsertStartB, Math.Max(1, el.InsertCountB))).Aggregate(Enumerable.Empty <int>(), (a, b) => a.Concat(b)); DiffResult diffResultFromOriginal = editor.Differ.CreateLineDiffs(editor.OriginalText, newText, false); IEnumerable <int> changesFromOriginal = (from el in diffResultFromOriginal.DiffBlocks select Enumerable.Range(el.InsertStartB, Math.Max(1, el.InsertCountB))).Aggregate(Enumerable.Empty <int>(), (a, b) => a.Concat(b)); editor.SetLineDiff(changesFromLastSaved, changesFromOriginal); } Refresh(); }; } this.FindControl <StackPanel>("FileContainer").Children.Add(itemGrid); } }