diff options
author | Michael Hutchinson <mhutchinson@novell.com> | 2011-01-07 13:02:06 +0300 |
---|---|---|
committer | Michael Hutchinson <mhutchinson@novell.com> | 2011-01-07 13:11:21 +0300 |
commit | a1c560325ecbaf91b0fb58ef0a4498dd4b33b21b (patch) | |
tree | 4213ff72585920c22fa51fbc1fc4b7d08b6311e8 /main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting | |
parent | 40c92f62bf90f927b6941ae2918319fee9321d65 (diff) |
Overhaul the code formatter extension points
* eliminated three redundant XML formatters
* made the remaining XML formatter work
* cleaned up the formatter extension points and made them
more consistent
* fixed some minor bugs related for handling of formatters
* formatter assemblies are no longer loaded until needed
* C# file reindentation now uses project policies
* cleaned up some naming typos
* removed lots of dead code
Diffstat (limited to 'main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting')
8 files changed, 454 insertions, 325 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatter.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatter.cs new file mode 100644 index 0000000000..d0817f959e --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatter.cs @@ -0,0 +1,126 @@ +// +// Formatter.cs +// +// Author: +// Lluis Sanchez Gual <lluis@novell.com> +// +// Copyright (c) 2010 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using MonoDevelop.Projects.Policies; +using MonoDevelop.Projects.Dom; +using MonoDevelop.Projects.Dom.Parser; +using Mono.TextEditor; +using System.Collections.Generic; + +namespace MonoDevelop.Ide.CodeFormatting +{ + public sealed class CodeFormatter + { + ICodeFormatter formatter; + IList<string> mimeTypeChain; + + internal CodeFormatter (IList<string> mimeTypeChain, ICodeFormatter formatter) + { + this.mimeTypeChain = mimeTypeChain; + this.formatter = formatter; + } + + public string FormatText (PolicyContainer policyParent, string input) + { + return formatter.FormatText (policyParent ?? PolicyService.DefaultPolicies, mimeTypeChain, input); + } + + /// <summary>Formats a subrange of the input text. + /// <returns>The formatted text of the range.</returns> + public string FormatText (PolicyContainer policyParent, string input, int fromOffset, int toOffset) + { + return formatter.FormatText (policyParent ?? PolicyService.DefaultPolicies, mimeTypeChain, + input, fromOffset, toOffset); + } + + public bool SupportsOnTheFlyFormatting { + get { + var adv = formatter as IAdvancedCodeFormatter; + return adv != null && adv.SupportsOnTheFlyFormatting; + } + } + + public bool SupportsCorrectingIndent { + get { + var adv = formatter as IAdvancedCodeFormatter; + return adv != null && adv.SupportsCorrectingIndent; + } + } + + public bool IsDefault { + get { + return formatter is DefaultCodeFormatter; + } + } + + /// <summary> + /// Formats a text document directly with insert/remove operations. + /// </summary> + /// <param name="textEditorData"> + /// A <see cref="System.Object"/> that must be from type Mono.TextEditorData. + /// </param> + /// <param name="dom"> + /// A <see cref="ProjectDom"/> + /// </param> + /// <param name="unit"> + /// A <see cref="ICompilationUnit"/> + /// </param> + /// <param name="caretLocation"> + /// A <see cref="DomLocation"/> that should be the end location to which the parsing should occur. + /// </param> + public void OnTheFlyFormat (PolicyContainer policyParent, TextEditorData data, + IType callingType, IMember callingMember, ProjectDom dom, ICompilationUnit unit, + DomLocation endLocation) + { + var adv = formatter as IAdvancedCodeFormatter; + if (adv == null || !adv.SupportsOnTheFlyFormatting) + throw new InvalidOperationException ("On the fly formatting not supported"); + + adv.OnTheFlyFormat (policyParent ?? PolicyService.DefaultPolicies, mimeTypeChain, + data, callingType, callingMember, dom, unit, endLocation); + } + + public void OnTheFlyFormat (PolicyContainer policyParent, TextEditorData data, + int startOffset, int endOffset) + { + var adv = formatter as IAdvancedCodeFormatter; + if (adv == null || !adv.SupportsOnTheFlyFormatting) + throw new InvalidOperationException ("On the fly formatting not supported"); + adv.OnTheFlyFormat (policyParent ?? PolicyService.DefaultPolicies, mimeTypeChain, + data, startOffset, endOffset); + } + + public void CorrectIndenting (PolicyContainer policyParent, TextEditorData data, int line) + { + var adv = formatter as IAdvancedCodeFormatter; + if (adv == null || !adv.SupportsCorrectingIndent) + throw new InvalidOperationException ("Indent correction not supported"); + adv.CorrectIndenting (policyParent ?? PolicyService.DefaultPolicies, mimeTypeChain, data, line); + } + } +} + diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatterExtensionNode.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatterExtensionNode.cs new file mode 100644 index 0000000000..a5e22d90c7 --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatterExtensionNode.cs @@ -0,0 +1,46 @@ +// +// CodeFormatterNode.cs +// +// Author: +// Michael Hutchinson <mhutchinson@novell.com> +// +// Copyright (c) 2011 Novell, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +using Mono.Addins; + +namespace MonoDevelop.Ide.CodeFormatting +{ + class CodeFormatterExtensionNode : TypeExtensionNode + { + [NodeAttribute ("mimeType", true, "The mimetype that this formatter can handle.")] + string mimeType; + + public string MimeType { + get { return mimeType; } + } + + public ICodeFormatter GetFormatter () + { + return (ICodeFormatter) this.GetInstance (); + } + } +} + diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatterService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatterService.cs index 8557e4ae3a..834881f688 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatterService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormatterService.cs @@ -28,30 +28,45 @@ using System; using System.Linq; using System.Collections.Generic; using Mono.Addins; +using MonoDevelop.Projects.Policies; namespace MonoDevelop.Ide.CodeFormatting { public sealed class CodeFormatterService { - /* static List<ICodeFormatter> formatter = new List<ICodeFormatter> (); + static List<CodeFormatterExtensionNode> nodes = new List<CodeFormatterExtensionNode> (); static CodeFormatterService () { - AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/CodeFormatters", delegate(object sender, ExtensionNodeEventArgs args) { - switch (args.Change) { - case ExtensionChange.Add: - formatters.Add ((IFormatter) args.ExtensionObject); - break; - case ExtensionChange.Remove: - formatters.Remove ((IFormatter) args.ExtensionObject); - break; - } - }); + AddinManager.AddExtensionNodeHandler ("/MonoDevelop/Ide/CodeFormatters", FormatterExtHandler); } - public static ICodeFormatter GetFormatter (string mimeType) + static void FormatterExtHandler (object sender, ExtensionNodeEventArgs args) { - return (from f in formatter where f.CanFormat (mimeType) select f).FirstOrDefault (); - }*/ + switch (args.Change) { + case ExtensionChange.Add: + nodes.Add ((CodeFormatterExtensionNode) args.ExtensionNode); + break; + case ExtensionChange.Remove: + nodes.Remove ((CodeFormatterExtensionNode) args.ExtensionNode); + break; + } + } + + public static CodeFormatter GetFormatter (string mimeType) + { + //find the most specific formatter that can handle the document + var chain = DesktopService.GetMimeTypeInheritanceChain (mimeType).ToList (); + foreach (var mt in chain) { + var node = nodes.FirstOrDefault (f => f.MimeType == mt); + if (node != null) + return new CodeFormatter (chain, node.GetFormatter ()); + } + + if (DesktopService.GetMimeTypeIsText (mimeType)) + return new CodeFormatter (chain, new DefaultCodeFormatter ()); + + return null; + } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormattingCommands.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormattingCommands.cs index 9cefd8bbd7..09c1fe7b6f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormattingCommands.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormattingCommands.cs @@ -43,7 +43,7 @@ namespace MonoDevelop.Ide.CodeFormatting { if (IdeApp.Workbench.ActiveDocument != null && IdeApp.Workbench.ActiveDocument.IsFile) { string mt = DesktopService.GetMimeTypeForUri (IdeApp.Workbench.ActiveDocument.FileName); - Formatter formatter = TextFileService.GetFormatter (mt); + var formatter = CodeFormatterService.GetFormatter (mt); if (formatter != null) return; } @@ -56,13 +56,16 @@ namespace MonoDevelop.Ide.CodeFormatting if (doc == null) return; string mt = DesktopService.GetMimeTypeForUri (doc.FileName); - Formatter formatter = TextFileService.GetFormatter (mt); + var formatter = CodeFormatterService.GetFormatter (mt); if (formatter == null) return; doc.Editor.Document.BeginAtomicUndo (); var loc = doc.Editor.Caret.Location; - doc.Editor.Replace (0, doc.Editor.Length, formatter.FormatText (doc.Project != null ? doc.Project.Policies : null, doc.Editor.Text)); - doc.Editor.Caret.Location = loc; + var text = formatter.FormatText (doc.Project != null ? doc.Project.Policies : null, doc.Editor.Text); + if (text != null) { + doc.Editor.Replace (0, doc.Editor.Length, text); + doc.Editor.Caret.Location = loc; + } doc.Editor.Document.EndAtomicUndo (); } } @@ -73,8 +76,8 @@ namespace MonoDevelop.Ide.CodeFormatting { if (IdeApp.Workbench.ActiveDocument != null && IdeApp.Workbench.ActiveDocument.IsFile) { string mt = DesktopService.GetMimeTypeForUri (IdeApp.Workbench.ActiveDocument.FileName); - Formatter formatter = TextFileService.GetFormatter (mt); - if (formatter != null && formatter.SupportsOnTheFlyFormatting) { + var formatter = CodeFormatterService.GetFormatter (mt); + if (formatter != null && !formatter.IsDefault) { info.Enabled = IdeApp.Workbench.ActiveDocument.Editor.IsSomethingSelected; return; } @@ -88,13 +91,22 @@ namespace MonoDevelop.Ide.CodeFormatting if (doc == null) return; string mt = DesktopService.GetMimeTypeForUri (doc.FileName); - Formatter formatter = TextFileService.GetFormatter (mt); + var formatter = CodeFormatterService.GetFormatter (mt); if (formatter == null || !doc.Editor.IsSomethingSelected) return; var selection = doc.Editor.SelectionRange; doc.Editor.Document.BeginAtomicUndo (); - formatter.OnTheFlyFormat (doc.Project != null ? doc.Project.Policies : null, doc.Editor, selection.Offset, selection.EndOffset); + if (formatter.SupportsOnTheFlyFormatting) { + formatter.OnTheFlyFormat (doc.Project != null ? doc.Project.Policies : null, doc.Editor, selection.Offset, selection.EndOffset); + } else { + var pol = doc.Project != null ? doc.Project.Policies : null; + string text = formatter.FormatText (pol, doc.Editor.Text, selection.Offset, selection.EndOffset); + if (text != null) { + doc.Editor.Replace (selection.Offset, selection.Length, text); + doc.Editor.SetSelection (selection.Offset, selection.Offset + text.Length - 1); + } + } doc.Editor.Document.EndAtomicUndo (); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormattingPolicyPanelWidget.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormattingPolicyPanelWidget.cs deleted file mode 100644 index 72ec5ceac0..0000000000 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/CodeFormattingPolicyPanelWidget.cs +++ /dev/null @@ -1,303 +0,0 @@ -// -// CodeFormattingPolicyPanel.cs -// -// Author: -// Mike Krüger <mkrueger@novell.com> -// -// Copyright (c) 2009 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; -using Gtk; -using MonoDevelop.Core; -using MonoDevelop.Core.Serialization; -using MonoDevelop.Ide.Projects; -using MonoDevelop.Projects.Text; -using MonoDevelop.Projects; - - - -namespace MonoDevelop.Ide.CodeFormatting -{ - public class TypedCodeFormattingPolicyPanelWidget<T> : CodeFormattingPolicyPanelWidget where T : class, IEquatable<T>, new () - { - T settings; - CodeFormatDescription description; - - Gtk.TreeStore store; - TreeModel model; - TreeIter iter; - CodeFormatOption option; - - CellRendererPixbuf pixbufCellRenderer; - - public TypedCodeFormattingPolicyPanelWidget () - { - store = new Gtk.TreeStore (typeof (string), typeof (string), typeof (string), typeof (object), typeof (string), typeof(bool), typeof(bool), typeof(bool)); - - TreeViewColumn column = new TreeViewColumn (); - - // pixbuf column - pixbufCellRenderer = new CellRendererPixbuf (); - column.PackStart (pixbufCellRenderer, false); - column.SetCellDataFunc (pixbufCellRenderer, new Gtk.TreeCellDataFunc (RenderIcon)); - - // text column - CellRendererText cellRendererText = new CellRendererText (); - cellRendererText.Ypad = 1; - column.PackStart (cellRendererText, true); - column.SetAttributes (cellRendererText, "text", keyColumn); - - TreeviewCategories.AppendColumn (column); - - column = new TreeViewColumn (); - CellRendererCombo cellRendererCombo = new CellRendererCombo (); - cellRendererCombo.Ypad = 1; - cellRendererCombo.Mode = CellRendererMode.Editable; - cellRendererCombo.TextColumn = 1; - cellRendererCombo.Model = comboBoxStore; - cellRendererCombo.HasEntry = false; - cellRendererCombo.Editable = true; - column.PackStart (cellRendererCombo, false); - column.SetAttributes (cellRendererCombo, "markup", valueDisplayTextColumn, "visible", comboVisibleColumn); - - CellRendererToggle cellRendererToggle = new CellRendererToggle (); - cellRendererToggle.Ypad = 1; - cellRendererToggle.Toggled += CellRendererToggleToggled; - column.PackStart (cellRendererToggle, false); - column.SetAttributes (cellRendererToggle, "active", toggleColumn, "visible", toggleVisibleColumn); - - TreeviewCategories.AppendColumn (column); - - cellRendererCombo.EditingStarted += delegate(object o, EditingStartedArgs args) { - CodeFormatType type = description.GetCodeFormatType (settings, option); - comboBoxStore.Clear (); - foreach (KeyValuePair<string, string> v in type.Values) { - comboBoxStore.AppendValues (v.Key, GettextCatalog.GetString (v.Value)); - } - }; - - cellRendererCombo.Edited += delegate(object o, EditedArgs args) { - CodeFormatType type = description.GetCodeFormatType (settings, option); - foreach (KeyValuePair<string, string> v in type.Values) { - if (args.NewText == GettextCatalog.GetString (v.Value)) { - description.SetValue (settings, option, v.Key); - TreeIter iter; - if (store.GetIterFromString (out iter, args.Path)) { - store.SetValue (iter, valueColumn, v.Key); - store.SetValue (iter, valueDisplayTextColumn, args.NewText); - } - break; - } - } - UpdateExample (); - }; - - TreeviewCategories.HeadersVisible = false; - - TreeviewCategories.Selection.Changed += TreeSelectionChanged; - TreeviewCategories.Model = store; - } - - void CellRendererToggleToggled (object o, ToggledArgs args) - { - TreeIter iter; - if (store.GetIterFromString (out iter, args.Path)) { - CodeFormatOption option = (CodeFormatOption) store.GetValue (iter, objectColumn); - bool value = !(bool) store.GetValue (iter, toggleColumn); - description.SetValue (settings, option, value ? "True" : "False"); - store.SetValue (iter, toggleColumn, value); - UpdateExample (); - } - - } - - void RenderIcon (TreeViewColumn col, CellRenderer cell, TreeModel model, TreeIter iter) - { - object o = store.GetValue (iter, objectColumn); - if (o is CodeFormatCategory) { - pixbufCellRenderer.Pixbuf = ImageService.GetPixbuf (TreeviewCategories.GetRowExpanded (store.GetPath (iter)) ? MonoDevelop.Ide.Gui.Stock.OpenFolder : MonoDevelop.Ide.Gui.Stock.ClosedFolder, IconSize.Menu); - } else { - pixbufCellRenderer.Pixbuf = ImageService.GetPixbuf (MonoDevelop.Ide.Gui.Stock.Property, IconSize.Menu); - } - } - - void UpdateExample () - { - Formatter formatter = TextFileService.GetFormatter (description.MimeType); - if (formatter == null) - return; - DotNetAssemblyProject parent = new DotNetAssemblyProject (); - parent.Policies.Set<T> (settings, description.MimeType); - texteditor1.Document.Text = formatter.FormatText (parent.Policies, texteditor1.Document.Text); - } - - protected override void HandleChanged (object sender, EditedArgs e) - { - } - - public void SetFormat (CodeFormatDescription description, T settings) - { - this.description = description; - this.settings = settings; - options.ShowLineNumberMargin = false; - options.ShowFoldMargin = false; - options.ShowIconMargin = false; - options.ShowInvalidLines = false; - options.ShowSpaces = options.ShowTabs = options.ShowEolMarkers = false; - options.ColorScheme = PropertyService.Get ("ColorScheme", "Default"); - options.Zoom = 0.8; - texteditor1.Options = options; - texteditor1.Document.ReadOnly = true; - texteditor1.Document.MimeType = description.MimeType; - store.Clear (); - - if (description != null) { - foreach (CodeFormatCategory category in description.SubCategories) { - AppendCategory (store, TreeIter.Zero, category); - } - } - TreeviewCategories.ShowAll (); - } - - const int keyColumn = 0; - const int valueColumn = 1; - const int valueDisplayTextColumn = 2; - const int objectColumn = 3; - const int iconColumn = 4; - const int toggleColumn = 5; - const int toggleVisibleColumn = 6; - const int comboVisibleColumn = 7; - - public new T Settings { - get { - return settings; - } - } - - void AppendCategory (Gtk.TreeStore store, TreeIter iter, CodeFormatCategory category) - { - TreeIter categoryIter = iter.Equals (TreeIter.Zero) - ? store.AppendValues (GettextCatalog.GetString (category.DisplayName), null, null, category) - : store.AppendValues (iter, GettextCatalog.GetString (category.DisplayName), null, null, category); - foreach (CodeFormatOption option in category.Options) { - CodeFormatType type = description.GetCodeFormatType (settings, option); - KeyValuePair<string, string> val = description.GetValue (settings, option); - bool isBool = type.Name == "Bool"; - bool boolVal = isBool && val.Value == "True"; - store.AppendValues (categoryIter, - GettextCatalog.GetString (option.DisplayName), - val.Key, - GettextCatalog.GetString (val.Value), - option, - null, - boolVal, - isBool, - !isBool); - } - foreach (CodeFormatCategory s in category.SubCategories) { - AppendCategory (store, categoryIter, s); - } - } - - /* - void AddCategoryPage (CodeFormatCategory category) - { - Gtk.Label label = new Gtk.Label (GettextCatalog.GetString (category.DisplayName)); - - foreach (CodeFormatCategory cat in category.SubCategories) { - AppendCategory (store, TreeIter.Zero, cat); - } - Gtk.TreeView tree = new Gtk.TreeView (store); - tree.AppendColumn (GettextCatalog.GetString ("Key"), new CellRendererText (), "text", keyColumn); - tree.AppendColumn (GettextCatalog.GetString ("Value"), new CellRendererText (), "text", valueDisplayTextColumn); - - ScrolledWindow sw = new ScrolledWindow (); - sw.Child = tree; - NotebookCategories.AppendPage (sw, label); - }*/ - - void TreeSelectionChanged (object sender, EventArgs e) - { - Gtk.TreeSelection treeSelection = (Gtk.TreeSelection)sender; - if (treeSelection.GetSelected (out model, out iter)) { - option = model.GetValue (iter, objectColumn) as CodeFormatOption; - this.store = model as TreeStore; - if (option == null) { - texteditor1.Document.Text = ""; - return; - } - CodeFormatType type = description.GetCodeFormatType (settings, option); - texteditor1.Document.Text = option.Example; - - comboBoxStore.Clear (); - foreach (KeyValuePair<string, string> v in type.Values) { - comboBoxStore.AppendValues (v.Key, GettextCatalog.GetString (v.Value)); - } - UpdateExample (); - } - } - } - - [System.ComponentModel.ToolboxItem(true)] - public partial class CodeFormattingPolicyPanelWidget : Gtk.Bin - { - protected ListStore comboBoxStore; - protected Mono.TextEditor.TextEditor texteditor1 = new Mono.TextEditor.TextEditor (); - protected Mono.TextEditor.TextEditorOptions options = new Mono.TextEditor.TextEditorOptions (); - - protected Gtk.TreeView TreeviewCategories { - get { - return treeviewCategories; - } - } - - public CodeFormattingPolicyPanelWidget () - { - this.Build(); - checkbuttonWhiteSpaces.Toggled += CheckbuttonWhiteSpacesToggled; - comboBoxStore = new ListStore (typeof (string), typeof (string)); - /* comboboxValue.Clear (); - Gtk.CellRendererText ctx = new Gtk.CellRendererText (); - comboboxValue.PackStart (ctx, true); - comboboxValue.AddAttribute (ctx, "text", 1); - - - comboboxValue.Model = comboBoxStore; - - comboboxValue.Changed += HandleChanged;*/ - scrolledwindow2.Child = texteditor1; - ShowAll (); - } - - protected virtual void HandleChanged (object sender, EditedArgs e) - { - } - - void CheckbuttonWhiteSpacesToggled (object sender, EventArgs e) - { - options.ShowSpaces = options.ShowTabs = options.ShowEolMarkers = checkbuttonWhiteSpaces.Active; - this.texteditor1.QueueDraw (); - } - - - } -} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs new file mode 100644 index 0000000000..0f89c56c1c --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/DefaultCodeFormatter.cs @@ -0,0 +1,85 @@ +// +// DefaultFormatter.cs +// +// Author: +// Mike Krüger <mkrueger@novell.com> +// +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Text; +using MonoDevelop.Ide.Gui.Content; +using MonoDevelop.Projects; +using MonoDevelop.Projects.Text; +using MonoDevelop.Projects.Policies; +using MonoDevelop.Ide; + +namespace MonoDevelop.Ide.CodeFormatting +{ + public class DefaultCodeFormatter : AbstractCodeFormatter + { + static int GetNextTabstop (int currentColumn, int tabSize) + { + int result = currentColumn - 1 + tabSize; + return 1 + (result / tabSize) * tabSize; + } + + public override string FormatText (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + string input, int startOffset, int endOffset) + { + var currentPolicy = policyParent.Get<TextStylePolicy> (mimeTypeChain); + + input = input ?? ""; + int line = 0, col = 0; + string eolMarker = currentPolicy.GetEolMarker (); + var result = new StringBuilder (); + + for (int i = startOffset; i <= endOffset; i++) { + char ch = input[i]; + switch (ch) { + case '\t': + if (currentPolicy.TabsToSpaces) { + int tabWidth = GetNextTabstop (col, currentPolicy.TabWidth) - col; + result.Append (new string (' ', tabWidth)); + col += tabWidth; + } else + goto default; + break; + case '\r': + if (i + 1 < input.Length && input[i + 1] == '\n') + i++; + goto case '\n'; + case '\n': + result.Append (eolMarker); + line++; + col = 0; + break; + default: + result.Append (ch); + col++; + break; + } + } + return result.ToString (); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/IAdvancedCodeFormatter.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/IAdvancedCodeFormatter.cs new file mode 100644 index 0000000000..ee3c88b6dd --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/IAdvancedCodeFormatter.cs @@ -0,0 +1,92 @@ +// +// IPrettyPrinter.cs +// +// Author: +// Mike Krüger <mkrueger@novell.com> +// +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using Mono.TextEditor; + +using MonoDevelop.Projects.Dom; +using MonoDevelop.Projects.Dom.Parser; +using MonoDevelop.Projects.Policies; + +namespace MonoDevelop.Ide.CodeFormatting +{ + public interface IAdvancedCodeFormatter : ICodeFormatter + { + bool SupportsOnTheFlyFormatting { get; } + bool SupportsCorrectingIndent { get; } + + void CorrectIndenting (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + TextEditorData textEditorData, int line); + + /// <summary> + /// Formats a text document directly with insert/remove operations. + /// </summary> + /// <param name="textEditorData"> + /// A <see cref="System.Object"/> that must be from type Mono.TextEditorData. + /// </param> + /// <param name="dom"> + /// A <see cref="ProjectDom"/> + /// </param> + /// <param name="unit"> + /// A <see cref="ICompilationUnit"/> + /// </param> + /// <param name="caretLocation"> + /// A <see cref="DomLocation"/> that should be the end location to which the parsing should occur. + /// </param> + void OnTheFlyFormat (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + TextEditorData textEditorData, IType callingType, IMember callingMember, ProjectDom dom, + ICompilationUnit unit, DomLocation endLocation); + + void OnTheFlyFormat (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + TextEditorData textEditorData, int startOffset, int endOffset); + } + + public abstract class AbstractAdvancedFormatter : AbstractCodeFormatter, IAdvancedCodeFormatter + { + public virtual bool SupportsOnTheFlyFormatting { get { return false; } } + public virtual bool SupportsCorrectingIndent { get { return false; } } + + public virtual void OnTheFlyFormat (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + TextEditorData data, IType callingType, IMember callingMember, ProjectDom dom, + ICompilationUnit unit, DomLocation endLocation) + { + throw new NotSupportedException (); + } + + public virtual void OnTheFlyFormat (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + TextEditorData data, int startOffset, int endOffset) + { + throw new NotSupportedException (); + } + + public virtual void CorrectIndenting (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + TextEditorData data, int line) + { + throw new NotSupportedException (); + } + } +} diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/ICodeFormatter.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/ICodeFormatter.cs new file mode 100644 index 0000000000..58faf7c4fc --- /dev/null +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeFormatting/ICodeFormatter.cs @@ -0,0 +1,56 @@ +// +// IFormatter.cs +// +// Author: +// Mike Krüger <mkrueger@novell.com> +// +// Copyright (c) 2009 Novell, Inc (http://www.novell.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System; +using System.Collections.Generic; +using MonoDevelop.Projects.Policies; + +namespace MonoDevelop.Ide.CodeFormatting +{ + public interface ICodeFormatter + { + string FormatText (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, string input); + + /// <summary> + /// Formats the text in a range. Returns only the modified range, or null if formatting failed. + /// </summary> + string FormatText (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + string input, int startOffset, int endOffset); + } + + public abstract class AbstractCodeFormatter : ICodeFormatter + { + public abstract string FormatText (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, + string input, int startOffset, int endOffset); + + public string FormatText (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, string input) + { + if (string.IsNullOrEmpty (input)) + return input; + return FormatText (policyParent, mimeTypeChain, input, 0, input.Length - 1); + } + } +}
\ No newline at end of file |