Browse Source

Redesigned replacement of editor options by language binding, now all C# code editors are updated, when changing IndentationSize or ConvertTabsToSpaces options in any policy.

pull/494/head
Andreas Weizel 11 years ago
parent
commit
c365dc4c6c
  1. 270
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs
  2. 2
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml
  3. 12
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs

270
src/AddIns/BackendBindings/CSharpBinding/Project/Src/CSharpLanguageBinding.cs

@ -19,7 +19,9 @@ @@ -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 @@ -62,6 +64,7 @@ namespace CSharpBinding
IList<IContextActionProvider> contextActionProviders;
CodeManipulation codeManipulation;
CaretReferenceHighlightRenderer renderer;
CodeEditorFormattingOptionsAdapter options;
public void Attach(ITextEditor editor)
{
@ -71,20 +74,44 @@ namespace CSharpBinding @@ -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<IContextActionProvider>("/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<TextEditor>();
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<TextEditor>();
if (textEditor != null) {
var textView = textEditor.TextArea.TextView;
// Unregister our ITextEditorOptions instance from editor
var optionsService = textView.GetService<ITextEditorOptions>();
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 @@ -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;
}
}
}
}
}

2
src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingEditor.xaml

@ -300,7 +300,7 @@ @@ -300,7 +300,7 @@
<Grid DockPanel.Dock="Top"
Visibility="{Binding Path=OverrideGlobalIndentation, Converter={StaticResource boolToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MaxWidth="400" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>

12
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/CodeEditorAdapter.cs

@ -38,12 +38,14 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -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 @@ -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<ITextEditorOptions>() ?? CodeEditorOptions.Instance;
}
@ -90,6 +95,13 @@ namespace ICSharpCode.AvalonEdit.AddIn @@ -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<ITextEditorOptions>() ?? CodeEditorOptions.Instance;
}
public override ITextEditorOptions Options {
get { return options; }
}
sealed class OptionControlledIndentationStrategy : IndentationStrategyAdapter

Loading…
Cancel
Save