You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
4.7 KiB
150 lines
4.7 KiB
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) |
|
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) |
|
|
|
using System; |
|
using System.Threading; |
|
using System.Windows; |
|
using System.Windows.Controls; |
|
using ICSharpCode.AvalonEdit.Document; |
|
using ICSharpCode.Core; |
|
using ICSharpCode.Editor; |
|
|
|
namespace ICSharpCode.AvalonEdit.AddIn |
|
{ |
|
/// <summary> |
|
/// Description of NewLineConsistencyCheck. |
|
/// </summary> |
|
public class NewLineConsistencyCheck |
|
{ |
|
public static void StartConsistencyCheck(CodeEditor editor) |
|
{ |
|
NewLineConsistencyCheck c = new NewLineConsistencyCheck(editor); |
|
ThreadPool.QueueUserWorkItem(c.CheckNewLinesForConsistency); |
|
} |
|
|
|
CodeEditor editor; |
|
ITextSource snapshot; |
|
|
|
private NewLineConsistencyCheck(CodeEditor editor) |
|
{ |
|
this.editor = editor; |
|
this.snapshot = editor.Document.CreateSnapshot(); |
|
} |
|
|
|
void CheckNewLinesForConsistency(object state) |
|
{ |
|
int numCRLF = 0; |
|
int numCR = 0; |
|
int numLF = 0; |
|
|
|
int offset = 0; |
|
while (offset >= 0) { |
|
string type; |
|
offset = TextUtilities.FindNextNewLine(snapshot, offset, out type); |
|
if (type != null) { |
|
offset += type.Length; |
|
switch (type) { |
|
case "\r\n": |
|
numCRLF++; |
|
break; |
|
case "\n": |
|
numLF++; |
|
break; |
|
case "\r": |
|
numCR++; |
|
break; |
|
} |
|
} |
|
} |
|
snapshot = null; // we don't need the snapshot anymore, allow the GC to collect it |
|
|
|
// don't allow mac-style newlines; accept either unix or windows-style newlines but avoid mixing them |
|
bool isConsistent = (numCR == 0) && (numLF == 0 || numCRLF == 0); |
|
if (!isConsistent) { |
|
SharpDevelop.Gui.WorkbenchSingleton.SafeThreadAsyncCall(ShowInconsistentWarning, numLF > numCRLF); |
|
} |
|
} |
|
|
|
|
|
GroupBox groupBox; |
|
Button normalizeButton, cancelButton; |
|
RadioButton windows, unix; |
|
|
|
void ShowInconsistentWarning(bool preferUnixNewLines) |
|
{ |
|
if (editor.Document == null) |
|
return; // editor was disposed |
|
// TODO: translate |
|
groupBox = new GroupBox(); |
|
groupBox.Background = SystemColors.WindowBrush; |
|
groupBox.Foreground = SystemColors.WindowTextBrush; |
|
groupBox.Header = "Inconsistent NewLines"; |
|
groupBox.HorizontalAlignment = HorizontalAlignment.Right; |
|
groupBox.VerticalAlignment = VerticalAlignment.Bottom; |
|
groupBox.MaxWidth = 300; |
|
groupBox.Margin = new Thickness(0, 0, 20, 20); |
|
Grid.SetRow(groupBox, 1); |
|
|
|
windows = new RadioButton { |
|
IsChecked = !preferUnixNewLines, |
|
Content = ResourceService.GetString("Dialog.Options.IDEOptions.LoadSaveOptions.WindowsRadioButton"), |
|
Margin = new Thickness(0, 0, 8, 0) |
|
}; |
|
unix = new RadioButton { |
|
IsChecked = preferUnixNewLines, |
|
Content = ResourceService.GetString("Dialog.Options.IDEOptions.LoadSaveOptions.UnixRadioButton") |
|
}; |
|
|
|
normalizeButton = new Button { Content = "Normalize" }; |
|
cancelButton = new Button { Content = ResourceService.GetString("Global.CancelButtonText") }; |
|
|
|
groupBox.Content = new StackPanel { |
|
Children = { |
|
new TextBlock { Text = "This file contains inconsistent newlines.", TextWrapping = TextWrapping.WrapWithOverflow }, |
|
windows, unix, |
|
new StackPanel { |
|
Margin = new Thickness(0, 2, 0, 0), |
|
Orientation = Orientation.Horizontal, |
|
Children = { normalizeButton, cancelButton } |
|
} |
|
} |
|
}; |
|
editor.Children.Add(groupBox); |
|
|
|
var featureUse = AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck)); |
|
|
|
EventHandler removeWarning = null; |
|
removeWarning = delegate { |
|
editor.Children.Remove(groupBox); |
|
editor.PrimaryTextEditor.TextArea.Focus(); |
|
editor.LoadedFileContent -= removeWarning; |
|
|
|
featureUse.EndTracking(); |
|
}; |
|
|
|
editor.LoadedFileContent += removeWarning; |
|
cancelButton.Click += delegate { |
|
AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck), "cancelButton"); |
|
removeWarning(null, null); |
|
}; |
|
normalizeButton.Click += delegate { |
|
AnalyticsMonitorService.TrackFeature(typeof(NewLineConsistencyCheck), "normalizeButton"); |
|
removeWarning(null, null); |
|
|
|
TextDocument document = editor.Document; |
|
string newNewLine = (unix.IsChecked == true) ? "\n" : "\r\n"; |
|
using (document.RunUpdate()) { |
|
for (int i = 1; i <= document.LineCount; i++) { |
|
// re-fetch DocumentLine for every iteration because we're modifying the newlines so that DocumentLines might get re-created |
|
DocumentLine line = document.GetLineByNumber(i); |
|
if (line.DelimiterLength > 0) { |
|
int endOffset = line.EndOffset; |
|
if (document.GetText(endOffset, line.DelimiterLength) != newNewLine) |
|
document.Replace(endOffset, line.DelimiterLength, newNewLine); |
|
} |
|
} |
|
} |
|
}; |
|
} |
|
} |
|
}
|
|
|