From 6ff259e9de55a372739419f2cd594a8dedb79103 Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Mon, 19 May 2014 01:43:31 +0200 Subject: [PATCH 1/5] IndentationSize and ConvertTabsToSpaces settings can now be defined in separate policies together with other formatting options. --- .../Src/FormattingStrategy/CSharpFormatter.cs | 9 +- .../CSharpFormattingOptionsContainer.cs | 138 ++++++++++++++++-- .../CSharpFormattingStrategy.cs | 67 ++++++--- .../FormattingOptionBinding.cs | 53 ++++--- .../OptionPanels/CSharpFormattingEditor.xaml | 35 ++++- .../CSharpFormattingEditor.xaml.cs | 33 +++-- .../TextEditorOptions.cs | 12 +- 7 files changed, 275 insertions(+), 72 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs index 028a43e6a8..7d3c9c5d76 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs @@ -31,7 +31,14 @@ namespace CSharpBinding.FormattingStrategy /// public static void Format(ITextEditor editor, int offset, int length, CSharpFormattingOptionsContainer optionsContainer) { - var formatter = new CSharpFormatter(optionsContainer.GetEffectiveOptions(), editor.ToEditorOptions()); + TextEditorOptions editorOptions = editor.ToEditorOptions(); + int? indentationSize = optionsContainer.GetEffectiveIndentationSize(); + if (indentationSize.HasValue) + editorOptions.IndentSize = indentationSize.Value; + bool? convertTabsToSpaces = optionsContainer.GetEffectiveConvertTabsToSpaces(); + if (convertTabsToSpaces.HasValue) + editorOptions.TabsToSpaces = convertTabsToSpaces.Value; + var formatter = new CSharpFormatter(optionsContainer.GetEffectiveOptions(), editorOptions); formatter.AddFormattingRegion(new DomRegion(editor.Document.GetLocation(offset), editor.Document.GetLocation(offset + length))); var changes = formatter.AnalyzeFormatting(editor.Document, SyntaxTree.Parse(editor.Document)); changes.ApplyChanges(offset, length); diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs index f3bc043736..e2f94692e4 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs @@ -34,8 +34,13 @@ namespace CSharpBinding.FormattingStrategy /// internal class CSharpFormattingOptionsContainer : INotifyPropertyChanged { + private const string IndentationSizePropertyName = "IndentationSize"; + private const string ConvertTabsToSpacesPropertyName = "ConvertTabsToSpaces"; + CSharpFormattingOptionsContainer parent; CSharpFormattingOptions cachedOptions; + int? indentationSize; + bool? convertTabsToSpaces; readonly HashSet activeOptions; @@ -106,6 +111,8 @@ namespace CSharpBinding.FormattingStrategy foreach (var activeOption in options.activeOptions) activeOptions.Add(activeOption); cachedOptions = options.cachedOptions.Clone(); + indentationSize = options.indentationSize; + convertTabsToSpaces = options.convertTabsToSpaces; OnPropertyChanged(null); } @@ -128,6 +135,14 @@ namespace CSharpBinding.FormattingStrategy // All properties might have changed -> update everything cachedOptions = CreateCachedOptions(); OnPropertyChanged(e.PropertyName); + } else if (e.PropertyName == IndentationSizePropertyName) { + if (!indentationSize.HasValue) { + indentationSize = GetEffectiveIndentationSize(); + } + } else if (e.PropertyName == ConvertTabsToSpacesPropertyName) { + if (!convertTabsToSpaces.HasValue) { + convertTabsToSpaces = GetEffectiveConvertTabsToSpaces(); + } } else { // Some other property has changed, check if we have our own value for it if (!activeOptions.Contains(e.PropertyName)) { @@ -150,10 +165,18 @@ namespace CSharpBinding.FormattingStrategy public object GetOption(string option) { // Run up the hierarchy until we find a defined value for property - if (activeOptions.Contains(option)) { - PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); - if (propertyInfo != null) { - return propertyInfo.GetValue(cachedOptions); + if (option == IndentationSizePropertyName) { + if (indentationSize.HasValue) + return indentationSize.Value; + } else if (option == ConvertTabsToSpacesPropertyName) { + if (convertTabsToSpaces.HasValue) + return convertTabsToSpaces.Value; + } else { + if (activeOptions.Contains(option)) { + PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); + if (propertyInfo != null) { + return propertyInfo.GetValue(cachedOptions); + } } } @@ -188,6 +211,68 @@ namespace CSharpBinding.FormattingStrategy return null; } + public int? IndentationSize + { + get { + return indentationSize; + } + set { + indentationSize = value; + OnPropertyChanged(IndentationSizePropertyName); + } + } + + /// + /// Retrieves the value of "IndentationSize" option by looking at current and (if nothing set here) parent + /// containers. + /// + public int? GetEffectiveIndentationSize() + { + // Run up the hierarchy until we find a defined value for property + CSharpFormattingOptionsContainer container = this; + do + { + int? val = container.indentationSize; + if (val.HasValue) { + return val.Value; + } + container = container.parent; + } while (container != null); + + return null; + } + + public bool? ConvertTabsToSpaces + { + get { + return convertTabsToSpaces; + } + set { + convertTabsToSpaces = value; + OnPropertyChanged(ConvertTabsToSpacesPropertyName); + } + } + + /// + /// Retrieves the value of v option by looking at current and (if nothing set here) parent + /// containers. + /// + public bool? GetEffectiveConvertTabsToSpaces() + { + // Run up the hierarchy until we find a defined value for property + CSharpFormattingOptionsContainer container = this; + do + { + bool? val = container.convertTabsToSpaces; + if (val.HasValue) { + return val.Value; + } + container = container.parent; + } while (container != null); + + return null; + } + /// /// Sets an option. /// @@ -197,18 +282,32 @@ namespace CSharpBinding.FormattingStrategy { if (value != null) { // Save value in option values and cached options - activeOptions.Add(option); - PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); - if ((propertyInfo != null) && (propertyInfo.PropertyType == value.GetType())) { - propertyInfo.SetValue(cachedOptions, value); + if (option == IndentationSizePropertyName) { + if (value is int) + indentationSize = (int) value; + } else if (option == ConvertTabsToSpacesPropertyName) { + if (value is bool) + convertTabsToSpaces = (bool) value; + } else { + activeOptions.Add(option); + PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); + if ((propertyInfo != null) && (propertyInfo.PropertyType == value.GetType())) { + propertyInfo.SetValue(cachedOptions, value); + } } } else { // Reset this option - activeOptions.Remove(option); - // Update formatting options object from parents - PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); - if (propertyInfo != null) { - propertyInfo.SetValue(cachedOptions, GetEffectiveOption(option)); + if (option == IndentationSizePropertyName) { + indentationSize = null; + } else if (option == ConvertTabsToSpacesPropertyName) { + convertTabsToSpaces = null; + } else { + activeOptions.Remove(option); + // Update formatting options object from parents + PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); + if (propertyInfo != null) { + propertyInfo.SetValue(cachedOptions, GetEffectiveOption(option)); + } } } OnPropertyChanged(option); @@ -221,6 +320,11 @@ namespace CSharpBinding.FormattingStrategy /// Option's type. public Type GetOptionType(string option) { + if (option == IndentationSizePropertyName) + return typeof(int); + if (option == ConvertTabsToSpacesPropertyName) + return typeof(bool); + PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); if (propertyInfo != null) { return propertyInfo.PropertyType; @@ -275,6 +379,9 @@ namespace CSharpBinding.FormattingStrategy // Silently ignore loading error, then this property will be "as parent" automatically } } + + indentationSize = formatProperties.Get(IndentationSizePropertyName, new int?()); + convertTabsToSpaces = formatProperties.Get(ConvertTabsToSpacesPropertyName, new bool?()); } } @@ -291,8 +398,13 @@ namespace CSharpBinding.FormattingStrategy formatProperties.Set(activeOption, val); } } + if (indentationSize.HasValue) + formatProperties.Set(IndentationSizePropertyName, indentationSize.Value); + if (convertTabsToSpaces.HasValue) + formatProperties.Set(ConvertTabsToSpacesPropertyName, convertTabsToSpaces.Value); parentProperties.SetNestedProperties("CSharpFormatting", formatProperties); } } } + \ No newline at end of file diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs index 5c365b2f66..e84c9b0ea1 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs @@ -48,7 +48,7 @@ namespace CSharpBinding.FormattingStrategy DocumentAccessor acc = new DocumentAccessor(editor.Document, lineNr, lineNr); CSharpIndentationStrategy indentStrategy = new CSharpIndentationStrategy(); - indentStrategy.IndentationString = editor.Options.IndentationString; + indentStrategy.IndentationString = GetIndentationString(editor); indentStrategy.Indent(acc, false); string t = acc.Text; @@ -62,33 +62,64 @@ namespace CSharpBinding.FormattingStrategy { DocumentAccessor acc = new DocumentAccessor(editor.Document, beginLine, endLine); CSharpIndentationStrategy indentStrategy = new CSharpIndentationStrategy(); - indentStrategy.IndentationString = editor.Options.IndentationString; + indentStrategy.IndentationString = GetIndentationString(editor); indentStrategy.Indent(acc, true); } + CSharpFormattingOptionsContainer GetOptionsContainerForEditor(ITextEditor editor) + { + var currentProject = SD.ProjectService.FindProjectContainingFile(editor.FileName); + if (currentProject != null) { + var persistence = CSharpFormattingOptionsPersistence.GetProjectOptions(currentProject); + if (persistence != null) { + return persistence.OptionsContainer; + } + } + + return null; + } + + string GetIndentationString(ITextEditor editor) + { + // Get current indentation option values + int indentationSize = editor.Options.IndentationSize; + bool convertTabsToSpaces = editor.Options.ConvertTabsToSpaces; + var container = GetOptionsContainerForEditor(editor); + if (container != null) { + int? effectiveIndentationSize = container.GetEffectiveIndentationSize(); + if (effectiveIndentationSize.HasValue) + indentationSize = effectiveIndentationSize.Value; + bool? effectiveConvertTabsToSpaces = container.GetEffectiveConvertTabsToSpaces(); + if (effectiveConvertTabsToSpaces.HasValue) + convertTabsToSpaces = effectiveConvertTabsToSpaces.Value; + } + + return ICSharpCode.AvalonEdit.TextEditorOptions.GetIndentationString(1, indentationSize, convertTabsToSpaces); + } + /* NR indent engine (temporarily?) disabled as per #447 static void IndentSingleLine(CacheIndentEngine engine, IDocument document, IDocumentLine line) { - engine.Update(line.EndOffset); - if (engine.NeedsReindent) { - var indentation = TextUtilities.GetWhitespaceAfter(document, line.Offset); - // replacing the indentation in two steps is necessary to make the caret move accordingly. - document.Replace(indentation.Offset, indentation.Length, ""); - document.Replace(indentation.Offset, 0, engine.ThisLineIndent); - engine.ResetEngineToPosition(line.Offset); - } + engine.Update(line.EndOffset); + if (engine.NeedsReindent) { + var indentation = TextUtilities.GetWhitespaceAfter(document, line.Offset); + // replacing the indentation in two steps is necessary to make the caret move accordingly. + document.Replace(indentation.Offset, indentation.Length, ""); + document.Replace(indentation.Offset, 0, engine.ThisLineIndent); + engine.ResetEngineToPosition(line.Offset); + } } static CacheIndentEngine CreateIndentEngine(IDocument document, TextEditorOptions options) { - IProject currentProject = null; - var projectService = SD.GetService(); - if (projectService != null) { - currentProject = projectService.FindProjectContainingFile(new FileName(document.FileName)); - } - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(currentProject); - var engine = new CSharpIndentEngine(document, options, formattingOptions.OptionsContainer.GetEffectiveOptions()); - return new CacheIndentEngine(engine); + IProject currentProject = null; + var projectService = SD.GetService(); + if (projectService != null) { + currentProject = projectService.FindProjectContainingFile(new FileName(document.FileName)); + } + var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(currentProject); + var engine = new CSharpIndentEngine(document, options, formattingOptions.OptionsContainer.GetEffectiveOptions()); + return new CacheIndentEngine(engine); } */ #endregion diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/FormattingOptionBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/FormattingOptionBinding.cs index 9caa50b055..b36677c142 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/FormattingOptionBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/FormattingOptionBinding.cs @@ -22,6 +22,7 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using ICSharpCode.NRefactory.CSharp; +using CSharpBinding.OptionPanels; namespace CSharpBinding.FormattingStrategy { @@ -32,11 +33,8 @@ namespace CSharpBinding.FormattingStrategy { public static readonly DependencyProperty ContainerProperty = DependencyProperty.RegisterAttached("Container", typeof(CSharpFormattingOptionsContainer), - typeof(FormattingOptionBinding), - new FrameworkPropertyMetadata()); - public static readonly DependencyProperty OptionProperty = - DependencyProperty.RegisterAttached("Option", typeof(string), typeof(FormattingOptionBinding), - new FrameworkPropertyMetadata(OnOptionPropertyChanged)); + typeof(FormattingOptionBinding), + new FrameworkPropertyMetadata((o, e) => UpdateOptionBinding(o))); public static CSharpFormattingOptionsContainer GetContainer(Selector element) { @@ -48,21 +46,26 @@ namespace CSharpBinding.FormattingStrategy element.SetValue(ContainerProperty, container); } - public static string GetOption(Selector element) + public static readonly DependencyProperty FormattingOptionProperty = + DependencyProperty.RegisterAttached("FormattingOption", typeof(FormattingOption), + typeof(FormattingOptionBinding), + new FrameworkPropertyMetadata((o, e) => UpdateOptionBinding(o))); + + public static FormattingOption GetFormattingOption(Selector element) { - return (string) element.GetValue(OptionProperty); + return (FormattingOption) element.GetValue(FormattingOptionProperty); } - public static void SetOption(Selector element, string option) + public static void SetFormattingOption(Selector element, FormattingOption container) { - element.SetValue(OptionProperty, option); + element.SetValue(FormattingOptionProperty, container); } - static void OnOptionPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + static void UpdateOptionBinding(DependencyObject o) { - string option = e.NewValue as string; ComboBox comboBox = o as ComboBox; CSharpFormattingOptionsContainer container = GetContainer(comboBox); + FormattingOption option = GetFormattingOption(comboBox); if ((option != null) && (comboBox != null) && (container != null)) { if (container != null) { if (container.Parent != null) { @@ -72,17 +75,24 @@ namespace CSharpBinding.FormattingStrategy Tag = null }); comboBox.SelectedIndex = 0; + } else if (option.AlwaysAllowDefault) { + // Also add "default" entry, but without changeable text by container + comboBox.Items.Add(new ComboBoxItem { + Content = "(default)", + Tag = null + }); + comboBox.SelectedIndex = 0; } - Type optionType = container.GetOptionType(option); + Type optionType = container.GetOptionType(option.Option); FillComboValues(comboBox, optionType); - UpdateComboBoxValue(container, option, comboBox); + UpdateComboBoxValue(container, option.Option, comboBox); comboBox.SelectionChanged += ComboBox_SelectionChanged; container.PropertyChanged += (sender, eventArgs) => { - if ((eventArgs.PropertyName == null) || (eventArgs.PropertyName == option)) - UpdateComboBoxValue(container, option, comboBox); + if ((eventArgs.PropertyName == null) || (eventArgs.PropertyName == option.Option)) + UpdateComboBoxValue(container, option.Option, comboBox); }; } } @@ -98,13 +108,13 @@ namespace CSharpBinding.FormattingStrategy { ComboBox comboBox = sender as ComboBox; if (comboBox != null) { - string option = GetOption(comboBox); + FormattingOption option = GetFormattingOption(comboBox); CSharpFormattingOptionsContainer container = GetContainer(comboBox); if ((container != null) && (option != null)) { ComboBoxItem selectedItem = comboBox.SelectedItem as ComboBoxItem; if (selectedItem != null) { // Set option to appropriate value - container.SetOption(option, selectedItem.Tag); + container.SetOption(option.Option, selectedItem.Tag); } } } @@ -140,11 +150,10 @@ namespace CSharpBinding.FormattingStrategy static void FillIntComboValues(ComboBox comboBox) { - comboBox.Items.Add(new ComboBoxItem { Content = "0", Tag = 0 }); - comboBox.Items.Add(new ComboBoxItem { Content = "1", Tag = 1 }); - comboBox.Items.Add(new ComboBoxItem { Content = "2", Tag = 2 }); - comboBox.Items.Add(new ComboBoxItem { Content = "3", Tag = 3 }); - comboBox.Items.Add(new ComboBoxItem { Content = "4", Tag = 4 }); + for (int i = 0; i < 11; i++) + { + comboBox.Items.Add(new ComboBoxItem { Content = i.ToString(), Tag = i }); + } } static void FillBraceStyleComboValues(ComboBox comboBox) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml index 259702aa7d..8398ae1e49 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml @@ -274,13 +274,13 @@ - + + format:FormattingOptionBinding.FormattingOption="{Binding}" /> + + + + + + + + + + + + + DockPanel.Dock="Top" Margin="0,5,0,0"> diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs index cd2c4cdf70..5180a1b404 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs @@ -29,21 +29,13 @@ using CSharpBinding.FormattingStrategy; namespace CSharpBinding.OptionPanels { - /// - /// Marker interface for group or option container. - /// It doesn't need to have any members. - /// - internal interface IFormattingItemContainer - { - } - /// /// Represents a container item for other container items in formatting editor list /// [ContentProperty("Children")] - internal class FormattingGroupContainer : DependencyObject, IFormattingItemContainer + internal class FormattingGroupContainer : DependencyObject { - readonly ObservableCollection children = new ObservableCollection(); + readonly ObservableCollection children = new ObservableCollection(); public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(FormattingGroupContainer), @@ -54,7 +46,7 @@ namespace CSharpBinding.OptionPanels set { SetValue(TextProperty, value); } } - public ObservableCollection Children + public ObservableCollection Children { get { return children; @@ -66,7 +58,7 @@ namespace CSharpBinding.OptionPanels /// Represents a container for formatting options. /// [ContentProperty("Children")] - internal class FormattingOptionContainer : DependencyObject, IFormattingItemContainer + internal class FormattingOptionContainer : DependencyObject { readonly ObservableCollection children = new ObservableCollection(); @@ -91,11 +83,26 @@ namespace CSharpBinding.OptionPanels set { SetValue(TextProperty, value); } } +// public static readonly DependencyProperty AlwaysAllowDefaultProperty = +// DependencyProperty.Register("AlwaysAllowDefault", typeof(bool), typeof(FormattingOption), +// new FrameworkPropertyMetadata()); +// +// public bool AlwaysAllowDefault { +// get { return (bool)GetValue(AlwaysAllowDefaultProperty); } +// set { SetValue(AlwaysAllowDefaultProperty, value); } +// } + public string Option { get; set; } + + public bool AlwaysAllowDefault + { + get; + set; + } } /// @@ -197,7 +204,7 @@ namespace CSharpBinding.OptionPanels } } - public ObservableCollection RootChildren + public ObservableCollection RootChildren { get { // rootEntries object is only the root container, its children should be shown directly diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs index 5b0fa5538e..e771f10e3c 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/TextEditorOptions.cs @@ -264,11 +264,19 @@ namespace ICSharpCode.AvalonEdit /// Gets text required to indent from the specified to the next indentation level. /// public virtual string GetIndentationString(int column) + { + return GetIndentationString(column, IndentationSize, ConvertTabsToSpaces); + } + + /// + /// Gets text required to indent from the specified to the next indentation level, + /// considering given and settings. + /// + public static string GetIndentationString(int column, int indentationSize, bool convertTabsToSpaces) { if (column < 1) throw new ArgumentOutOfRangeException("column", column, "Value must be at least 1."); - int indentationSize = this.IndentationSize; - if (ConvertTabsToSpaces) { + if (convertTabsToSpaces) { return new string(' ', indentationSize - ((column - 1) % indentationSize)); } else { return "\t"; From 519d5735c967eb4e909f5b80ce3e7b54d4fe61d6 Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Fri, 23 May 2014 01:56:40 +0200 Subject: [PATCH 2/5] Tried implementing automatical updating of editors after changing policy-specific indentation changes + some refactoring. --- .../CSharpBinding/Project/CSharpBinding.addin | 4 +- .../Project/Src/CSharpLanguageBinding.cs | 24 ++++ .../Src/Completion/CSharpCompletionBinding.cs | 2 +- .../Src/Completion/CSharpInsightItem.cs | 2 +- .../Src/Completion/OverrideCompletionData.cs | 2 +- ...OverrideEqualsGetHashCodeCompletionData.cs | 2 +- .../OverrideToStringCompletionData.cs | 2 +- .../Src/Completion/PartialCompletionData.cs | 2 +- .../Src/FormattingStrategy/CSharpFormatter.cs | 7 +- .../CSharpFormattingOptionsContainer.cs | 16 ++- .../CSharpFormattingOptionsPersistence.cs | 112 ++++++++++++------ .../CSharpFormattingStrategy.cs | 6 +- .../FormsDesigner/CSharpDesignerGenerator.cs | 2 +- .../OptionPanels/CSharpFormattingEditor.xaml | 3 +- .../CSharpFormattingEditor.xaml.cs | 9 ++ .../CSharpFormattingOptionPanel.xaml | 2 +- .../CSharpFormattingOptionPanel.xaml.cs | 15 +-- .../CSharpProjectFormattingOptions.xaml.cs | 15 +-- .../Src/Refactoring/InsertCtorDialog.xaml.cs | 2 +- .../MoveTypeToFileContextAction.cs | 2 +- .../Src/Refactoring/SDRefactoringContext.cs | 9 +- 21 files changed, 165 insertions(+), 75 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin index f2e4adf86b..c9bea23cba 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin @@ -510,7 +510,7 @@ - + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs index 411279933f..8c6912e98b 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs @@ -70,6 +70,13 @@ namespace CSharpBinding codeManipulation = new CodeManipulation(editor); renderer = new CaretReferenceHighlightRenderer(editor); + // Patch editor options (indentation) to project-specific settings + var optionsContainer = CSharpFormattingPolicies.Instance.GetProjectOptions( + SD.ProjectService.FindProjectContainingFile(editor.FileName)); + CustomizeEditorOptions(optionsContainer.OptionsContainer, editor.Options); + CSharpFormattingPolicies.Instance.FormattingPolicyUpdated += + (sender, e) => CustomizeEditorOptions(optionsContainer.OptionsContainer, this.editor.Options); + if (!editor.ContextActionProviders.IsReadOnly) { contextActionProviders = AddInTree.BuildItems("/SharpDevelop/ViewContent/TextEditor/C#/ContextActions", null); editor.ContextActionProviders.AddRange(contextActionProviders); @@ -89,5 +96,22 @@ namespace CSharpBinding renderer.Dispose(); this.editor = null; } + + private void CustomizeEditorOptions(CSharpFormattingOptionsContainer container, ITextEditorOptions editorOptions) + { + if (container == null) + return; + var textEditorOptions = editorOptions as ICSharpCode.AvalonEdit.TextEditorOptions; + if (textEditorOptions == null) + return; + + int? indentationSize = container.GetEffectiveIndentationSize(); + if (indentationSize.HasValue) { + textEditorOptions.IndentationSize = indentationSize.Value; + } + bool? convertTabsToSpaces = container.GetEffectiveConvertTabsToSpaces(); + if (convertTabsToSpaces.HasValue) + textEditorOptions.ConvertTabsToSpaces = convertTabsToSpaces.Value; + } } } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionBinding.cs index 3f3323cfbe..c81f2b3349 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpCompletionBinding.cs @@ -99,7 +99,7 @@ namespace CSharpBinding.Completion completionContext.ProjectContent, completionContext.TypeResolveContextAtCaret ); - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(completionContext.Compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(completionContext.Compilation.GetProject()); cce.FormattingPolicy = formattingOptions.OptionsContainer.GetEffectiveOptions(); cce.EolMarker = DocumentUtilities.GetLineTerminator(completionContext.Document, currentLocation.Line); diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs index 939333a453..7d1eb15a51 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpInsightItem.cs @@ -72,7 +72,7 @@ namespace CSharpBinding.Completion ambience.ConversionFlags = ConversionFlags.StandardConversionFlags; var stringBuilder = new StringBuilder(); var formatter = new ParameterHighlightingOutputFormatter(stringBuilder, highlightedParameterIndex); - ambience.ConvertSymbol(Method, formatter, CSharpFormattingOptionsPersistence.GlobalOptions.OptionsContainer.GetEffectiveOptions()); + ambience.ConvertSymbol(Method, formatter, CSharpFormattingPolicies.Instance.GlobalOptions.OptionsContainer.GetEffectiveOptions()); var documentation = XmlDocumentationElement.Get(Method); ambience.ConversionFlags = ConversionFlags.ShowTypeParameterList; diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideCompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideCompletionData.cs index ede72ab53e..f3d5c57eb4 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideCompletionData.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideCompletionData.cs @@ -98,7 +98,7 @@ namespace CSharpBinding.Completion var document = context.Editor.Document; StringWriter w = new StringWriter(); - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(contextAtCaret.Compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(contextAtCaret.Compilation.GetProject()); var segmentDict = SegmentTrackingOutputFormatter.WriteNode( w, entityDeclaration, formattingOptions.OptionsContainer.GetEffectiveOptions(), context.Editor.Options); diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideEqualsGetHashCodeCompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideEqualsGetHashCodeCompletionData.cs index 7b0ae25f0e..78f1ca6e89 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideEqualsGetHashCodeCompletionData.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideEqualsGetHashCodeCompletionData.cs @@ -84,7 +84,7 @@ namespace CSharpBinding.Completion var document = context.Editor.Document; StringWriter w = new StringWriter(); - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(contextAtCaret.Compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(contextAtCaret.Compilation.GetProject()); var segmentDict = SegmentTrackingOutputFormatter.WriteNode( w, entityDeclaration, formattingOptions.OptionsContainer.GetEffectiveOptions(), context.Editor.Options); diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideToStringCompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideToStringCompletionData.cs index 0d75f8f133..f0bcd41674 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideToStringCompletionData.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/OverrideToStringCompletionData.cs @@ -81,7 +81,7 @@ namespace CSharpBinding.Completion var document = context.Editor.Document; StringWriter w = new StringWriter(); - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(contextAtCaret.Compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(contextAtCaret.Compilation.GetProject()); var segmentDict = SegmentTrackingOutputFormatter.WriteNode( w, entityDeclaration, formattingOptions.OptionsContainer.GetEffectiveOptions(), context.Editor.Options); diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs index 7cd6f37a43..d05ff650c0 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/PartialCompletionData.cs @@ -64,7 +64,7 @@ namespace CSharpBinding.Completion var document = context.Editor.Document; StringWriter w = new StringWriter(); - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(contextAtCaret.Compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(contextAtCaret.Compilation.GetProject()); var segmentDict = SegmentTrackingOutputFormatter.WriteNode( w, entityDeclaration, formattingOptions.OptionsContainer.GetEffectiveOptions(), context.Editor.Options); diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs index 7d3c9c5d76..65bec18aca 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormatter.cs @@ -32,12 +32,7 @@ namespace CSharpBinding.FormattingStrategy public static void Format(ITextEditor editor, int offset, int length, CSharpFormattingOptionsContainer optionsContainer) { TextEditorOptions editorOptions = editor.ToEditorOptions(); - int? indentationSize = optionsContainer.GetEffectiveIndentationSize(); - if (indentationSize.HasValue) - editorOptions.IndentSize = indentationSize.Value; - bool? convertTabsToSpaces = optionsContainer.GetEffectiveConvertTabsToSpaces(); - if (convertTabsToSpaces.HasValue) - editorOptions.TabsToSpaces = convertTabsToSpaces.Value; + optionsContainer.CustomizeEditorOptions(editorOptions); var formatter = new CSharpFormatter(optionsContainer.GetEffectiveOptions(), editorOptions); formatter.AddFormattingRegion(new DomRegion(editor.Document.GetLocation(offset), editor.Document.GetLocation(offset + length))); var changes = formatter.AnalyzeFormatting(editor.Document, SyntaxTree.Parse(editor.Document)); diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs index e2f94692e4..be31b21acd 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs @@ -324,7 +324,7 @@ namespace CSharpBinding.FormattingStrategy return typeof(int); if (option == ConvertTabsToSpacesPropertyName) return typeof(bool); - + PropertyInfo propertyInfo = typeof(CSharpFormattingOptions).GetProperty(option); if (propertyInfo != null) { return propertyInfo.PropertyType; @@ -364,6 +364,19 @@ namespace CSharpBinding.FormattingStrategy return outputOptions; } + public void CustomizeEditorOptions(TextEditorOptions editorOptions) + { + int? indentationSize = GetEffectiveIndentationSize(); + if (indentationSize.HasValue) { + editorOptions.IndentSize = indentationSize.Value; + editorOptions.TabSize = indentationSize.Value; + editorOptions.ContinuationIndent = indentationSize.Value; + } + bool? convertTabsToSpaces = GetEffectiveConvertTabsToSpaces(); + if (convertTabsToSpaces.HasValue) + editorOptions.TabsToSpaces = convertTabsToSpaces.Value; + } + public void Load(Properties parentProperties) { if (parentProperties == null) @@ -407,4 +420,3 @@ namespace CSharpBinding.FormattingStrategy } } } - \ No newline at end of file diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsPersistence.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsPersistence.cs index df5b11e2aa..cd380eea9a 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsPersistence.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsPersistence.cs @@ -18,6 +18,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using ICSharpCode.Core; using ICSharpCode.NRefactory.CSharp; using ICSharpCode.SharpDevelop; @@ -25,42 +26,41 @@ using ICSharpCode.SharpDevelop.Project; namespace CSharpBinding.FormattingStrategy { - public class CSharpFormattingOptionsPersistenceInitCommand : SimpleCommand + public class CSharpFormattingOptionsPoliciesInitCommand : SimpleCommand { public override void Execute(object parameter) { // Initialize CSharpFormattingOptionsPersistence as early as possible (before solution is opened) - CSharpFormattingOptionsPersistence.Initialize(); + CSharpFormattingPolicies.Instance.Initialize(); } } /// - /// Persistence helper for C# formatting options. + /// Management class for formatting policies. /// - internal class CSharpFormattingOptionsPersistence + internal class CSharpFormattingPolicies { - static bool initialized; - static Dictionary projectOptions; + public static readonly CSharpFormattingPolicies Instance = new CSharpFormattingPolicies(); - static CSharpFormattingOptionsPersistence() - { - Initialize(); - } + public event EventHandler FormattingPolicyUpdated; + + static bool initialized; + static Dictionary projectOptions; - public static void Initialize() + public void Initialize() { if (initialized) return; initialized = true; - projectOptions = new Dictionary(); + projectOptions = new Dictionary(); // Load global settings - GlobalOptions = new CSharpFormattingOptionsPersistence( - SD.PropertyService.MainPropertiesContainer, new CSharpFormattingOptionsContainer() - { + GlobalOptions = new CSharpFormattingPolicy( + SD.PropertyService.MainPropertiesContainer, new CSharpFormattingOptionsContainer() { DefaultText = StringParser.Parse("${res:CSharpBinding.Formatting.GlobalOptionReference}") }); + GlobalOptions.FormattingPolicyUpdated += OnFormattingPolicyUpdated; GlobalOptions.Load(); // Handlers for solution loading/unloading @@ -71,8 +71,7 @@ namespace CSharpBinding.FormattingStrategy } } - public static bool AutoFormatting - { + public static bool AutoFormatting { get { return SD.PropertyService.Get("CSharpBinding.Formatting.AutoFormatting", false); } @@ -81,31 +80,32 @@ namespace CSharpBinding.FormattingStrategy } } - public static CSharpFormattingOptionsPersistence GlobalOptions - { + public CSharpFormattingPolicy GlobalOptions { get; private set; } - public static CSharpFormattingOptionsPersistence SolutionOptions - { + public CSharpFormattingPolicy SolutionOptions { get; private set; } - public static CSharpFormattingOptionsPersistence GetProjectOptions(IProject project) + public CSharpFormattingPolicy GetProjectOptions(IProject project) { + if (projectOptions == null) + return null; + var csproject = project as CSharpProject; if (csproject != null) { string key = project.FileName; if (!projectOptions.ContainsKey(key)) { // Lazily create options container for project - var projectFormattingPersistence = new CSharpFormattingOptionsPersistence( + var projectFormattingPersistence = new CSharpFormattingPolicy( csproject.GlobalPreferences, - new CSharpFormattingOptionsContainer((SolutionOptions ?? GlobalOptions).OptionsContainer) - { + new CSharpFormattingOptionsContainer((SolutionOptions ?? GlobalOptions).OptionsContainer) { DefaultText = StringParser.Parse("${res:CSharpBinding.Formatting.ProjectOptionReference}") }); + projectFormattingPersistence.FormattingPolicyUpdated += OnFormattingPolicyUpdated; projectFormattingPersistence.Load(); projectOptions[key] = projectFormattingPersistence; } @@ -116,34 +116,70 @@ namespace CSharpBinding.FormattingStrategy return SolutionOptions ?? GlobalOptions; } - static void SolutionOpened(object sender, SolutionEventArgs e) + void SolutionOpened(object sender, SolutionEventArgs e) { // Load solution settings - SolutionOptions = new CSharpFormattingOptionsPersistence( + SolutionOptions = new CSharpFormattingPolicy( e.Solution.SDSettings, - new CSharpFormattingOptionsContainer(GlobalOptions.OptionsContainer) - { + new CSharpFormattingOptionsContainer(GlobalOptions.OptionsContainer) { DefaultText = StringParser.Parse("${res:CSharpBinding.Formatting.SolutionOptionReference}") }); + SolutionOptions.FormattingPolicyUpdated += OnFormattingPolicyUpdated; SolutionOptions.Load(); } - static void SolutionClosed(object sender, SolutionEventArgs e) + void SolutionClosed(object sender, SolutionEventArgs e) { + SolutionOptions.FormattingPolicyUpdated -= OnFormattingPolicyUpdated; SolutionOptions = null; projectOptions.Clear(); } + void OnFormattingPolicyUpdated(object sender, CSharpFormattingPolicyUpdateEventArgs e) + { + if (FormattingPolicyUpdated != null) { + FormattingPolicyUpdated(sender, e); + } + } + } + + /// + /// Contains event data for formatting policy update events. + /// + internal class CSharpFormattingPolicyUpdateEventArgs : EventArgs + { + public CSharpFormattingPolicyUpdateEventArgs(CSharpFormattingOptionsContainer container) + { + OptionsContainer = container; + } + + /// + /// Returns updated options container. + /// + public CSharpFormattingOptionsContainer OptionsContainer + { + get; + private set; + } + } + + /// + /// Persistence helper for C# formatting options of a certain policy (e.g. global, solution, project). + /// + internal class CSharpFormattingPolicy + { + public event EventHandler FormattingPolicyUpdated; + readonly Properties propertiesContainer; - CSharpFormattingOptionsContainer optionsContainer; + readonly CSharpFormattingOptionsContainer optionsContainer; CSharpFormattingOptionsContainer optionsContainerWorkingCopy; /// - /// Creates a new instance of formatting options persistence helper, using given options to predefine the options container. + /// Creates a new instance of formatting options policy, using given options to predefine the options container. /// /// Properties container to load from and save to. /// Initial (empty) instance of formatting options container. - public CSharpFormattingOptionsPersistence(Properties propertiesContainer, CSharpFormattingOptionsContainer initialContainer) + public CSharpFormattingPolicy(Properties propertiesContainer, CSharpFormattingOptionsContainer initialContainer) { if (initialContainer == null) throw new ArgumentNullException("initialContainer"); @@ -153,7 +189,7 @@ namespace CSharpBinding.FormattingStrategy } /// - /// Returns the option container managed by this helper. + /// Returns the option container for this policy. /// public CSharpFormattingOptionsContainer OptionsContainer { @@ -196,7 +232,15 @@ namespace CSharpBinding.FormattingStrategy // Convert to SD properties optionsContainer.Save(propertiesContainer); + OnFormattingPolicyUpdated(this, optionsContainer); return true; } + + void OnFormattingPolicyUpdated(object sender, CSharpFormattingOptionsContainer container) + { + if (FormattingPolicyUpdated != null) { + FormattingPolicyUpdated(sender, new CSharpFormattingPolicyUpdateEventArgs(container)); + } + } } } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs index e84c9b0ea1..2ab802e950 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingStrategy.cs @@ -70,7 +70,7 @@ namespace CSharpBinding.FormattingStrategy { var currentProject = SD.ProjectService.FindProjectContainingFile(editor.FileName); if (currentProject != null) { - var persistence = CSharpFormattingOptionsPersistence.GetProjectOptions(currentProject); + var persistence = CSharpFormattingPolicies.Instance.GetProjectOptions(currentProject); if (persistence != null) { return persistence.OptionsContainer; } @@ -333,11 +333,11 @@ namespace CSharpBinding.FormattingStrategy { if ((offset > textArea.Document.TextLength) || ((offset + length) > textArea.Document.TextLength)) return false; - if (respectAutoFormattingSetting && !CSharpFormattingOptionsPersistence.AutoFormatting) + if (respectAutoFormattingSetting && !CSharpFormattingPolicies.AutoFormatting) return false; using (textArea.Document.OpenUndoGroup()) { - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(SD.ProjectService.CurrentProject); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(SD.ProjectService.CurrentProject); try { CSharpFormatterHelper.Format(textArea, offset, length, formattingOptions.OptionsContainer); } catch (Exception) { diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs index 2fd3560e6f..cc769eb9ee 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormsDesigner/CSharpDesignerGenerator.cs @@ -155,7 +155,7 @@ namespace CSharpBinding.FormsDesigner IDocument document = context.GetDocument(fileNameObj); var ctx = SDRefactoringContext.Create(fileNameObj, document); - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(compilation.GetProject()); script = new DocumentScript(document, formattingOptions.OptionsContainer.GetEffectiveOptions(), new TextEditorOptions()); scripts.Add(fileNameObj, script); return script; diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml index 8398ae1e49..fa5b5e54e0 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml @@ -297,7 +297,8 @@ - + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs index 5180a1b404..b1a6bba1ac 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml.cs @@ -140,6 +140,15 @@ namespace CSharpBinding.OptionPanels set { SetValue(AllowPresetsProperty, value); } } + public static readonly DependencyProperty OverrideGlobalIndentationProperty = + DependencyProperty.Register("OverrideGlobalIndentation", typeof(bool), typeof(CSharpFormattingEditor), + new FrameworkPropertyMetadata()); + + public bool OverrideGlobalIndentation { + get { return (bool)GetValue(OverrideGlobalIndentationProperty); } + set { SetValue(OverrideGlobalIndentationProperty, value); } + } + static void OnOptionsContainerPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { var editor = o as CSharpFormattingEditor; diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml index 4620821994..05e73ee15e 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml @@ -19,7 +19,7 @@ diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs index 56df385daa..346b2c02b1 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs @@ -40,7 +40,7 @@ namespace CSharpBinding.OptionPanels internal class CSharpGlobalFormattingOptionPanel : CSharpFormattingOptionPanel { public CSharpGlobalFormattingOptionPanel() - : base(CSharpFormattingOptionsPersistence.GlobalOptions, true) + : base(CSharpFormattingPolicies.Instance.GlobalOptions, true, false) { autoFormattingCheckBox.Visibility = Visibility.Visible; } @@ -52,7 +52,7 @@ namespace CSharpBinding.OptionPanels internal class CSharpSolutionFormattingOptionPanel : CSharpFormattingOptionPanel { public CSharpSolutionFormattingOptionPanel() - : base(CSharpFormattingOptionsPersistence.SolutionOptions, true) + : base(CSharpFormattingPolicies.Instance.SolutionOptions, true, true) { autoFormattingCheckBox.Visibility = Visibility.Collapsed; } @@ -63,28 +63,29 @@ namespace CSharpBinding.OptionPanels /// internal partial class CSharpFormattingOptionPanel : OptionPanel { - readonly CSharpFormattingOptionsPersistence persistenceHelper; + readonly CSharpFormattingPolicy formattingPolicy; - public CSharpFormattingOptionPanel(CSharpFormattingOptionsPersistence persistenceHelper, bool allowPresets) + public CSharpFormattingOptionPanel(CSharpFormattingPolicy persistenceHelper, bool allowPresets, bool overrideGlobalIndentation) { if (persistenceHelper == null) throw new ArgumentNullException("persistenceHelper"); - this.persistenceHelper = persistenceHelper; + this.formattingPolicy = persistenceHelper; InitializeComponent(); formattingEditor.AllowPresets = allowPresets; + formattingEditor.OverrideGlobalIndentation = overrideGlobalIndentation; } public override void LoadOptions() { base.LoadOptions(); - formattingEditor.OptionsContainer = persistenceHelper.StartEditing(); + formattingEditor.OptionsContainer = formattingPolicy.StartEditing(); } public override bool SaveOptions() { - return persistenceHelper.Save() && base.SaveOptions(); + return formattingPolicy.Save() && base.SaveOptions(); } } } \ No newline at end of file diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpProjectFormattingOptions.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpProjectFormattingOptions.xaml.cs index d3ca858d81..e12bdeaa8d 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpProjectFormattingOptions.xaml.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpProjectFormattingOptions.xaml.cs @@ -35,7 +35,7 @@ namespace CSharpBinding.OptionPanels /// internal partial class CSharpProjectFormattingOptionPanel : ProjectOptionPanel { - CSharpFormattingOptionsPersistence persistenceHelper; + CSharpFormattingPolicy formattingPolicy; public CSharpProjectFormattingOptionPanel() { @@ -45,18 +45,19 @@ namespace CSharpBinding.OptionPanels protected override void Load(ICSharpCode.SharpDevelop.Project.MSBuildBasedProject project, string configuration, string platform) { base.Load(project, configuration, platform); - if (persistenceHelper != null) { - persistenceHelper.OptionsContainer.PropertyChanged -= ContainerPropertyChanged; + if (formattingPolicy != null) { + formattingPolicy.OptionsContainer.PropertyChanged -= ContainerPropertyChanged; } - persistenceHelper = CSharpFormattingOptionsPersistence.GetProjectOptions(project); - formattingEditor.OptionsContainer = persistenceHelper.OptionsContainer; + formattingPolicy = CSharpFormattingPolicies.Instance.GetProjectOptions(project); + formattingEditor.OptionsContainer = formattingPolicy.OptionsContainer; formattingEditor.AllowPresets = true; - persistenceHelper.OptionsContainer.PropertyChanged += ContainerPropertyChanged; + formattingEditor.OverrideGlobalIndentation = true; + formattingPolicy.OptionsContainer.PropertyChanged += ContainerPropertyChanged; } protected override bool Save(ICSharpCode.SharpDevelop.Project.MSBuildBasedProject project, string configuration, string platform) { - bool success = (persistenceHelper != null) && persistenceHelper.Save(); + bool success = (formattingPolicy != null) && formattingPolicy.Save(); return base.Save(project, configuration, platform) && success; } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs index 2ff47fa0b7..973dbd97c7 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/InsertCtorDialog.xaml.cs @@ -171,7 +171,7 @@ namespace CSharpBinding.Refactoring using (StringWriter textWriter = new StringWriter(pList)) { // Output parameter list as string - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(refactoringContext.Compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(refactoringContext.Compilation.GetProject()); CSharpOutputVisitor outputVisitor = new CSharpOutputVisitor(textWriter, formattingOptions.OptionsContainer.GetEffectiveOptions()); for (int i = 0; i < parameters.Count; i++) { if (i > 0) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs index 6e42276226..014ea3a7cc 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs @@ -109,7 +109,7 @@ namespace CSharpBinding.Refactoring || ch is UsingAliasDeclaration || ch is ExternAliasDeclaration); StringBuilder newCode = new StringBuilder(header); - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(compilation.GetProject()); CSharpOutputVisitor visitor = new CSharpOutputVisitor(new StringWriter(newCode), formattingOptions.OptionsContainer.GetEffectiveOptions()); foreach (var topLevelUsing in topLevelUsings) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs index 134f7fc14a..1fa3af1f23 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/SDRefactoringContext.cs @@ -119,13 +119,16 @@ namespace CSharpBinding.Refactoring public Script StartScript() { - var formattingOptions = CSharpFormattingOptionsPersistence.GetProjectOptions(resolver.Compilation.GetProject()); + var formattingOptions = CSharpFormattingPolicies.Instance.GetProjectOptions(resolver.Compilation.GetProject()); if (editor != null) return new EditorScript(editor, this, formattingOptions.OptionsContainer.GetEffectiveOptions()); else if (document == null || document is ReadOnlyDocument) throw new InvalidOperationException("Cannot start a script in a read-only context"); - else - return new DocumentScript(document, formattingOptions.OptionsContainer.GetEffectiveOptions(), this.TextEditorOptions); + else { + var textEditorOptions = this.TextEditorOptions; + formattingOptions.OptionsContainer.CustomizeEditorOptions(textEditorOptions); + return new DocumentScript(document, formattingOptions.OptionsContainer.GetEffectiveOptions(), textEditorOptions); + } } public IDocument Document { From 0c1a36503fbd967f94d3c1f1325afe94fa786712 Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Sat, 24 May 2014 02:13:52 +0200 Subject: [PATCH 3/5] Fixed CSharpBinding tests. --- .../Project/CSharpBinding.csproj | 2 +- .../Project/Src/CSharpLanguageBinding.cs | 15 ++++---- ...istence.cs => CSharpFormattingPolicies.cs} | 34 ++++++++++++------- 3 files changed, 30 insertions(+), 21 deletions(-) rename src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/{CSharpFormattingOptionsPersistence.cs => CSharpFormattingPolicies.cs} (93%) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj index 2762300961..dbbd1b7739 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.csproj @@ -93,7 +93,7 @@ - + diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs index 8c6912e98b..5c53535de9 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs @@ -73,9 +73,9 @@ namespace CSharpBinding // Patch editor options (indentation) to project-specific settings var optionsContainer = CSharpFormattingPolicies.Instance.GetProjectOptions( SD.ProjectService.FindProjectContainingFile(editor.FileName)); - CustomizeEditorOptions(optionsContainer.OptionsContainer, editor.Options); + CustomizeEditorOptions(optionsContainer.OptionsContainer, editor.Options, this.editor); CSharpFormattingPolicies.Instance.FormattingPolicyUpdated += - (sender, e) => CustomizeEditorOptions(optionsContainer.OptionsContainer, this.editor.Options); + (sender, e) => CustomizeEditorOptions(optionsContainer.OptionsContainer, this.editor.Options, this.editor); if (!editor.ContextActionProviders.IsReadOnly) { contextActionProviders = AddInTree.BuildItems("/SharpDevelop/ViewContent/TextEditor/C#/ContextActions", null); @@ -97,7 +97,7 @@ namespace CSharpBinding this.editor = null; } - private void CustomizeEditorOptions(CSharpFormattingOptionsContainer container, ITextEditorOptions editorOptions) + private void CustomizeEditorOptions(CSharpFormattingOptionsContainer container, ITextEditorOptions editorOptions, ITextEditor editor) { if (container == null) return; @@ -107,11 +107,12 @@ namespace CSharpBinding int? indentationSize = container.GetEffectiveIndentationSize(); if (indentationSize.HasValue) { - textEditorOptions.IndentationSize = indentationSize.Value; +// textEditorOptions.IndentationSize = indentationSize.Value; } - bool? convertTabsToSpaces = container.GetEffectiveConvertTabsToSpaces(); - if (convertTabsToSpaces.HasValue) - textEditorOptions.ConvertTabsToSpaces = convertTabsToSpaces.Value; +// bool? convertTabsToSpaces = container.GetEffectiveConvertTabsToSpaces(); +// if (convertTabsToSpaces.HasValue) { +// textEditorOptions.ConvertTabsToSpaces = convertTabsToSpaces.Value; +// } } } } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsPersistence.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingPolicies.cs similarity index 93% rename from src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsPersistence.cs rename to src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingPolicies.cs index cd380eea9a..5999f1dd1f 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsPersistence.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingPolicies.cs @@ -30,7 +30,7 @@ namespace CSharpBinding.FormattingStrategy { public override void Execute(object parameter) { - // Initialize CSharpFormattingOptionsPersistence as early as possible (before solution is opened) + // Initialize CSharpFormattingPolicies as early as possible (before solution is opened) CSharpFormattingPolicies.Instance.Initialize(); } } @@ -40,21 +40,20 @@ namespace CSharpBinding.FormattingStrategy /// internal class CSharpFormattingPolicies { - public static readonly CSharpFormattingPolicies Instance = new CSharpFormattingPolicies(); + static readonly Lazy LazyInstance = + new Lazy(() => new CSharpFormattingPolicies()); + + public static CSharpFormattingPolicies Instance { + get { return LazyInstance.Value; } + } public event EventHandler FormattingPolicyUpdated; - static bool initialized; - static Dictionary projectOptions; + bool initialized; + Dictionary projectOptions; - public void Initialize() + public CSharpFormattingPolicies() { - if (initialized) - return; - - initialized = true; - projectOptions = new Dictionary(); - // Load global settings GlobalOptions = new CSharpFormattingPolicy( SD.PropertyService.MainPropertiesContainer, new CSharpFormattingOptionsContainer() { @@ -62,6 +61,15 @@ namespace CSharpBinding.FormattingStrategy }); GlobalOptions.FormattingPolicyUpdated += OnFormattingPolicyUpdated; GlobalOptions.Load(); + } + + public void Initialize() + { + if (initialized) + return; + + initialized = true; + projectOptions = new Dictionary(); // Handlers for solution loading/unloading var projectService = SD.GetService(); @@ -92,8 +100,8 @@ namespace CSharpBinding.FormattingStrategy public CSharpFormattingPolicy GetProjectOptions(IProject project) { - if (projectOptions == null) - return null; + if (!initialized) + return GlobalOptions; var csproject = project as CSharpProject; if (csproject != null) { From c365dc4c6c62b2bbdafdd3a12d73008a91a7694c Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Fri, 6 Jun 2014 01:18:22 +0200 Subject: [PATCH 4/5] Redesigned replacement of editor options by language binding, now all C# code editors are updated, when changing IndentationSize or ConvertTabsToSpaces options in any policy. --- .../Project/Src/CSharpLanguageBinding.cs | 270 ++++++++++++++++-- .../OptionPanels/CSharpFormattingEditor.xaml | 2 +- .../AvalonEdit.AddIn/Src/CodeEditorAdapter.cs | 12 + 3 files changed, 264 insertions(+), 20 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs index 5c53535de9..f34f52145c 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs @@ -19,7 +19,9 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Threading; +using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Highlighting; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.TypeSystem; @@ -62,6 +64,7 @@ namespace CSharpBinding IList contextActionProviders; CodeManipulation codeManipulation; CaretReferenceHighlightRenderer renderer; + CodeEditorFormattingOptionsAdapter options; public void Attach(ITextEditor editor) { @@ -71,20 +74,44 @@ namespace CSharpBinding renderer = new CaretReferenceHighlightRenderer(editor); // Patch editor options (indentation) to project-specific settings - var optionsContainer = CSharpFormattingPolicies.Instance.GetProjectOptions( - SD.ProjectService.FindProjectContainingFile(editor.FileName)); - CustomizeEditorOptions(optionsContainer.OptionsContainer, editor.Options, this.editor); - CSharpFormattingPolicies.Instance.FormattingPolicyUpdated += - (sender, e) => CustomizeEditorOptions(optionsContainer.OptionsContainer, this.editor.Options, this.editor); - if (!editor.ContextActionProviders.IsReadOnly) { contextActionProviders = AddInTree.BuildItems("/SharpDevelop/ViewContent/TextEditor/C#/ContextActions", null); editor.ContextActionProviders.AddRange(contextActionProviders); } + + // Create instance of options adapter and register it as service + var formattingPolicy = CSharpFormattingPolicies.Instance.GetProjectOptions( + SD.ProjectService.FindProjectContainingFile(editor.FileName)); + options = new CodeEditorFormattingOptionsAdapter(editor.Options, formattingPolicy.OptionsContainer); + var textEditor = editor.GetService(); + if (textEditor != null) { + var textViewServices = textEditor.TextArea.TextView.Services; + + // Unregister any previous ITextEditorOptions instance from editor, if existing, register our impl. + textViewServices.RemoveService(typeof(ITextEditorOptions)); + textViewServices.AddService(typeof(ITextEditorOptions), options); + + // Set TextEditor's options to same object + textEditor.Options = options; + } } public void Detach() { + var textEditor = editor.GetService(); + if (textEditor != null) { + var textView = textEditor.TextArea.TextView; + + // Unregister our ITextEditorOptions instance from editor + var optionsService = textView.GetService(); + if ((optionsService != null) && (optionsService == options)) + textView.Services.RemoveService(typeof(ITextEditorOptions)); + + // TODO Reset TextEditor options, too? + // if ((textEditor.Options != null) && (textEditor.Options == options)) + // textEditor.Options = SD.EditorControlService.GlobalOptions; + } + codeManipulation.Dispose(); if (inspectionManager != null) { inspectionManager.Dispose(); @@ -94,25 +121,230 @@ namespace CSharpBinding editor.ContextActionProviders.RemoveAll(contextActionProviders.Contains); } renderer.Dispose(); + options = null; this.editor = null; } + } + + class CodeEditorFormattingOptionsAdapter : TextEditorOptions, ITextEditorOptions, ICodeEditorOptions + { + CSharpFormattingOptionsContainer container; + readonly ITextEditorOptions globalOptions; + readonly ICodeEditorOptions globalCodeEditorOptions; - private void CustomizeEditorOptions(CSharpFormattingOptionsContainer container, ITextEditorOptions editorOptions, ITextEditor editor) + public CodeEditorFormattingOptionsAdapter(ITextEditorOptions globalOptions, CSharpFormattingOptionsContainer container) { + if (globalOptions == null) + throw new ArgumentNullException("globalOptions"); if (container == null) - return; - var textEditorOptions = editorOptions as ICSharpCode.AvalonEdit.TextEditorOptions; - if (textEditorOptions == null) - return; + throw new ArgumentNullException("container"); + + this.globalOptions = globalOptions; + this.globalCodeEditorOptions = globalOptions as ICodeEditorOptions; + this.container = container; - int? indentationSize = container.GetEffectiveIndentationSize(); - if (indentationSize.HasValue) { -// textEditorOptions.IndentationSize = indentationSize.Value; - } -// bool? convertTabsToSpaces = container.GetEffectiveConvertTabsToSpaces(); -// if (convertTabsToSpaces.HasValue) { -// textEditorOptions.ConvertTabsToSpaces = convertTabsToSpaces.Value; -// } + CSharpFormattingPolicies.Instance.FormattingPolicyUpdated += OnFormattingPolicyUpdated; + globalOptions.PropertyChanged += OnGlobalOptionsPropertyChanged; + } + + void OnFormattingPolicyUpdated(object sender, CSharpBinding.FormattingStrategy.CSharpFormattingPolicyUpdateEventArgs e) + { + OnPropertyChanged("IndentationSize"); + OnPropertyChanged("ConvertTabsToSpaces"); + } + + void OnGlobalOptionsPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + OnPropertyChanged(e.PropertyName); + } + + #region ITextEditorOptions implementation + + public override int IndentationSize { + get { + return container.GetEffectiveIndentationSize() ?? globalOptions.IndentationSize; + } + } + + public override bool ConvertTabsToSpaces { + get { + return container.GetEffectiveConvertTabsToSpaces() ?? globalOptions.ConvertTabsToSpaces; + } + } + + public bool AutoInsertBlockEnd { + get { + return globalOptions.AutoInsertBlockEnd; + } + } + + public int VerticalRulerColumn { + get { + return globalOptions.VerticalRulerColumn; + } + } + + public bool UnderlineErrors { + get { + return globalOptions.UnderlineErrors; + } + } + + public string FontFamily { + get { + return globalOptions.FontFamily; + } + } + + public double FontSize { + get { + return globalOptions.FontSize; + } + } + + #endregion + + public override bool AllowScrollBelowDocument { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.AllowScrollBelowDocument : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.AllowScrollBelowDocument = value; + } + } + } + + public bool ShowLineNumbers { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.ShowLineNumbers : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.ShowLineNumbers = value; + } + } + } + + public bool EnableChangeMarkerMargin { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.EnableChangeMarkerMargin : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.EnableChangeMarkerMargin = value; + } + } + } + + public bool WordWrap { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.WordWrap : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.WordWrap = value; + } + } + } + + public bool CtrlClickGoToDefinition { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.CtrlClickGoToDefinition : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.CtrlClickGoToDefinition = value; + } + } + } + + public bool MouseWheelZoom { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.MouseWheelZoom : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.MouseWheelZoom = value; + } + } + } + + public bool HighlightBrackets { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.HighlightBrackets : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.HighlightBrackets = value; + } + } + } + + public bool HighlightSymbol { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.HighlightSymbol : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.HighlightSymbol = value; + } + } + } + + public bool EnableAnimations { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.EnableAnimations : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.EnableAnimations = value; + } + } + } + + public bool UseSmartIndentation { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.UseSmartIndentation : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.UseSmartIndentation = value; + } + } + } + + public bool EnableFolding { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.EnableFolding : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.EnableFolding = value; + } + } + } + + public bool EnableQuickClassBrowser { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.EnableQuickClassBrowser : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.EnableQuickClassBrowser = value; + } + } + } + + public bool ShowHiddenDefinitions { + get { + return (globalCodeEditorOptions != null) ? globalCodeEditorOptions.ShowHiddenDefinitions : default(bool); + } + set { + if (globalCodeEditorOptions != null) { + globalCodeEditorOptions.ShowHiddenDefinitions = value; + } + } } } } diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml index fa5b5e54e0..4db4b5233e 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml @@ -300,7 +300,7 @@ - + diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs index 0873442d6d..df87075e87 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs @@ -38,12 +38,14 @@ namespace ICSharpCode.AvalonEdit.AddIn sealed class CodeEditorAdapter : CodeCompletionEditorAdapter { readonly CodeEditor codeEditor; + ITextEditorOptions options; public CodeEditorAdapter(CodeEditor codeEditor, CodeEditorView textEditor) : base(textEditor) { if (codeEditor == null) throw new ArgumentNullException("codeEditor"); this.codeEditor = codeEditor; + options = CodeEditorOptions.Instance; } public override FileName FileName { @@ -81,6 +83,9 @@ namespace ICSharpCode.AvalonEdit.AddIn foreach (var extension in extensions) extension.Detach(); } + + // Switch to global options, if no specific options service is registered + options = this.GetService() ?? CodeEditorOptions.Instance; } @@ -90,6 +95,13 @@ namespace ICSharpCode.AvalonEdit.AddIn foreach (var extension in extensions) extension.Attach(this); } + + // If we have any registered ITextEditorOptions service now, use it, otherwise global options + options = this.GetService() ?? CodeEditorOptions.Instance; + } + + public override ITextEditorOptions Options { + get { return options; } } sealed class OptionControlledIndentationStrategy : IndentationStrategyAdapter From 5c084ed695401eb7147e9f8c653dc86c68586c39 Mon Sep 17 00:00:00 2001 From: Andreas Weizel Date: Sat, 7 Jun 2014 12:47:09 +0200 Subject: [PATCH 5/5] Corrected reverting of editor options when C# binding's editor extension is detached. --- .../CSharpBinding/Project/Src/CSharpLanguageBinding.cs | 8 +++++--- .../AvalonEdit.AddIn/Src/CodeEditorAdapter.cs | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs index f34f52145c..48103a5acf 100644 --- a/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs +++ b/src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs @@ -65,6 +65,7 @@ namespace CSharpBinding CodeManipulation codeManipulation; CaretReferenceHighlightRenderer renderer; CodeEditorFormattingOptionsAdapter options; + TextEditorOptions originalEditorOptions; public void Attach(ITextEditor editor) { @@ -92,6 +93,7 @@ namespace CSharpBinding textViewServices.AddService(typeof(ITextEditorOptions), options); // Set TextEditor's options to same object + originalEditorOptions = textEditor.Options; textEditor.Options = options; } } @@ -107,9 +109,9 @@ namespace CSharpBinding if ((optionsService != null) && (optionsService == options)) textView.Services.RemoveService(typeof(ITextEditorOptions)); - // TODO Reset TextEditor options, too? - // if ((textEditor.Options != null) && (textEditor.Options == options)) - // textEditor.Options = SD.EditorControlService.GlobalOptions; + // Reset TextEditor options, too? + if ((textEditor.Options != null) && (textEditor.Options == options)) + textEditor.Options = originalEditorOptions; } codeManipulation.Dispose(); diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs index df87075e87..e747ab6177 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs @@ -80,8 +80,10 @@ namespace ICSharpCode.AvalonEdit.AddIn internal void DetachExtensions() { if (extensions != null) { - foreach (var extension in extensions) - extension.Detach(); + // Detach extensions in reverse order + for (int i = extensions.Count - 1; i >= 0; i--) { + extensions[i].Detach(); + } } // Switch to global options, if no specific options service is registered