Browse Source

- created DefaultSnippetElementProvider for standard SnippetElements

- introduced SnippetInfo and changed signature of ISnippetElementProvider
- added SnippetAnchorElement
- refactored InsertCtor to insert ctor body at the same time as the dialog
pull/1/head
Siegfried Pammer 15 years ago
parent
commit
6f0dacc881
  1. 1
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj
  2. 24
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
  3. 34
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/DefaultSnippetElementProvider.cs
  4. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetManager.cs
  5. 24
      src/AddIns/Misc/SharpRefactoring/Project/Src/Gui/AbstractInlineRefactorDialog.cs
  6. 10
      src/AddIns/Misc/SharpRefactoring/Project/Src/Gui/InlineRefactorSnippetElement.cs
  7. 38
      src/AddIns/Misc/SharpRefactoring/Project/Src/Gui/InsertCtorDialog.xaml.cs
  8. 13
      src/AddIns/Misc/SharpRefactoring/Project/Src/InsertCtorSnippetRefactoring.cs
  9. 8
      src/AddIns/Misc/SharpRefactoring/Project/Src/SwitchSnippetProvider.cs
  10. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  11. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/InsertionContext.cs
  12. 78
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetAnchorElement.cs
  13. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetBoundElement.cs
  14. 16
      src/Main/Base/Project/Src/Editor/AvalonEdit/ISnippetElementProvider.cs

1
src/AddIns/DisplayBindings/AvalonEdit.AddIn/AvalonEdit.AddIn.csproj

@ -137,6 +137,7 @@ @@ -137,6 +137,7 @@
<Compile Include="Src\Snippets\CodeSnippet.cs" />
<Compile Include="Src\Snippets\CodeSnippetCompletionWindow.cs" />
<Compile Include="Src\Snippets\CodeSnippetGroup.cs" />
<Compile Include="Src\Snippets\DefaultSnippetElementProvider.cs" />
<Compile Include="Src\Snippets\SnippetCompletionItem.cs" />
<Compile Include="Src\Snippets\SnippetManager.cs" />
<Compile Include="Src\Snippets\SnippetOptionPanel.cs">

24
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs

@ -156,15 +156,23 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets @@ -156,15 +156,23 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
return srte;
}
}
if ("Selection".Equals(val, StringComparison.OrdinalIgnoreCase))
return new SnippetSelectionElement() { Indentation = GetWhitespaceBefore(snippetText, offset).Length };
if ("Caret".Equals(val, StringComparison.OrdinalIgnoreCase))
return new SnippetCaretElement();
int typeSeparator = val.IndexOf(':');
if (typeSeparator > 0) {
string type = val.Substring(0, typeSeparator);
string name = val.Substring(typeSeparator + 1);
switch (type.ToLowerInvariant()) {
case "anchor":
return new SnippetAnchorElement(name);
}
}
foreach (ISnippetElementProvider provider in SnippetManager.Instance.SnippetElementProviders) {
SnippetElement element = provider.GetElement(val);
SnippetElement element = provider.GetElement(new SnippetInfo(val, snippetText, offset));
if (element != null)
return element;
}
if (replaceableElements.TryGetValue(val, out srte))
return new SnippetBoundElement { TargetElement = srte };
Match m = functionPattern.Match(val);
@ -188,12 +196,6 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets @@ -188,12 +196,6 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
return new SnippetReplaceableTextElement { Text = val }; // ${unknown} -> replaceable element
}
static string GetWhitespaceBefore(string snippetText, int offset)
{
int start = snippetText.LastIndexOfAny(new[] { '\r', '\n' }, offset) + 1;
return snippetText.Substring(start, offset - start);
}
static string GetValue(ITextEditor editor, string propertyName)
{
if ("ClassName".Equals(propertyName, StringComparison.OrdinalIgnoreCase)) {

34
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/DefaultSnippetElementProvider.cs

@ -0,0 +1,34 @@ @@ -0,0 +1,34 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com" />
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.AvalonEdit.Snippets;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
namespace ICSharpCode.AvalonEdit.AddIn.Snippets
{
/// <summary>
/// Description of DefaultSnippetElementProvider.
/// </summary>
public class DefaultSnippetElementProvider : ISnippetElementProvider
{
public SnippetElement GetElement(SnippetInfo snippetInfo)
{
if ("Selection".Equals(snippetInfo.Tag, StringComparison.OrdinalIgnoreCase))
return new SnippetSelectionElement() { Indentation = GetWhitespaceBefore(snippetInfo.SnippetText, snippetInfo.Position).Length };
if ("Caret".Equals(snippetInfo.Tag, StringComparison.OrdinalIgnoreCase))
return new SnippetCaretElement();
return null;
}
static string GetWhitespaceBefore(string snippetText, int offset)
{
int start = snippetText.LastIndexOfAny(new[] { '\r', '\n' }, offset) + 1;
return snippetText.Substring(start, offset - start);
}
}
}

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetManager.cs

@ -96,7 +96,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets @@ -96,7 +96,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
new CodeSnippet {
Name = "ctor",
Description = "Constructor",
Text = "${refactoring:ctor}",
Text = "public ${ClassName}(${anchor:parameterList})\n{\n\t${refactoring:ctor}\n}",
Keyword = "event"
},
new CodeSnippet {

24
src/AddIns/Misc/SharpRefactoring/Project/Src/Gui/AbstractInlineRefactorDialog.cs

@ -27,7 +27,7 @@ namespace SharpRefactoring.Gui @@ -27,7 +27,7 @@ namespace SharpRefactoring.Gui
protected ITextEditor editor;
ClassFinder classFinderContext;
InsertionContext context;
protected InsertionContext context;
public IInlineUIElement Element { get; set; }
@ -48,20 +48,16 @@ namespace SharpRefactoring.Gui @@ -48,20 +48,16 @@ namespace SharpRefactoring.Gui
{
ParseInformation parseInfo = ParserService.GetParseInformation(editor.FileName);
try {
if (optionBindings != null) {
foreach (OptionBinding binding in optionBindings)
binding.Save();
}
if (optionBindings != null) {
foreach (OptionBinding binding in optionBindings)
binding.Save();
}
if (parseInfo != null) {
LanguageProperties language = parseInfo.CompilationUnit.Language;
IClass current = parseInfo.CompilationUnit.GetInnermostClass(editor.Caret.Line, editor.Caret.Column);
if (parseInfo != null) {
LanguageProperties language = parseInfo.CompilationUnit.Language;
IClass current = parseInfo.CompilationUnit.GetInnermostClass(editor.Caret.Line, editor.Caret.Column);
editor.Document.Insert(anchor.Offset, GenerateCode(language, current) ?? "");
}
} catch (Exception ex) {
MessageService.ShowError(ex.Message);
editor.Document.Insert(anchor.Offset, GenerateCode(language, current) ?? "");
}
Deactivate();

10
src/AddIns/Misc/SharpRefactoring/Project/Src/Gui/InlineRefactorSnippetElement.cs

@ -11,6 +11,7 @@ using System.Linq; @@ -11,6 +11,7 @@ using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Document;
@ -28,10 +29,12 @@ namespace SharpRefactoring.Gui @@ -28,10 +29,12 @@ namespace SharpRefactoring.Gui
class InlineRefactorSnippetElement : SnippetElement
{
Func<InsertionContext, AbstractInlineRefactorDialog> createDialog;
string previewText;
public InlineRefactorSnippetElement(Func<InsertionContext, AbstractInlineRefactorDialog> createDialog)
public InlineRefactorSnippetElement(Func<InsertionContext, AbstractInlineRefactorDialog> createDialog, string previewText)
{
this.createDialog = createDialog;
this.previewText = previewText;
}
public override void Insert(InsertionContext context)
@ -40,5 +43,10 @@ namespace SharpRefactoring.Gui @@ -40,5 +43,10 @@ namespace SharpRefactoring.Gui
if (dialog != null)
context.RegisterActiveElement(this, dialog);
}
public override Inline ToTextRun()
{
return new Italic() { Inlines = { previewText } };
}
}
}

38
src/AddIns/Misc/SharpRefactoring/Project/Src/Gui/InsertCtorDialog.xaml.cs

@ -33,10 +33,10 @@ namespace SharpRefactoring.Gui @@ -33,10 +33,10 @@ namespace SharpRefactoring.Gui
{
InitializeComponent();
this.varList.ItemsSource = paramList = CreateCtorParams(current.Fields, current.Properties).
this.varList.ItemsSource = paramList = CreateCtorParams(current.Fields, current.Properties)
// "Add check for null" is checked for every item by default
//Select(w => { if(w.IsNullable) w.AddCheckForNull = true; return w; }).
ToList();
.ToList();
}
IEnumerable<CtorParamWrapper> CreateCtorParams(IEnumerable<IField> fields, IEnumerable<IProperty> properties)
@ -56,8 +56,6 @@ namespace SharpRefactoring.Gui @@ -56,8 +56,6 @@ namespace SharpRefactoring.Gui
protected override string GenerateCode(LanguageProperties language, IClass currentClass)
{
StringBuilder builder = new StringBuilder();
var line = editor.Document.GetLineForOffset(editor.Caret.Offset);
string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset);
@ -105,13 +103,35 @@ namespace SharpRefactoring.Gui @@ -105,13 +103,35 @@ namespace SharpRefactoring.Gui
foreach (CtorParamWrapper w in filtered)
block.AddChild(new ExpressionStatement(new AssignmentExpression(new MemberReferenceExpression(new ThisReferenceExpression(), w.MemberName), AssignmentOperatorType.Assign, new IdentifierExpression(w.ParameterName))));
ConstructorDeclaration ctor = new ConstructorDeclaration(currentClass.Name, Modifiers.Public, filtered.Select(p => new ParameterDeclarationExpression(ConvertType(p.Type), p.ParameterName)).ToList(), null) {
Body = block
};
AnchorSnippetElement parameterList = context.ActiveElements
.FirstOrDefault(
item => item is AnchorSnippetElement &&
(item as AnchorSnippetElement).Name.Equals("parameterList", StringComparison.OrdinalIgnoreCase)
) as AnchorSnippetElement;
if (parameterList != null) {
StringBuilder pList = new StringBuilder();
var parameters = filtered
.Select(p => new ParameterDeclarationExpression(ConvertType(p.Type), p.ParameterName))
.ToList();
for (int i = 0; i < parameters.Count; i++) {
if (i > 0)
pList.Append(", ");
pList.Append(language.CodeGenerator.GenerateCode(parameters[i], ""));
}
// parameterList.Text = pList.ToString();
}
builder.Append(language.CodeGenerator.GenerateCode(ctor, indent));
StringBuilder builder = new StringBuilder();
foreach (var element in block.Children.OfType<AbstractNode>()) {
builder.Append(language.CodeGenerator.GenerateCode(element, ""));
}
return builder.ToString().TrimStart();
return builder.ToString().Trim();
}
void UpClick(object sender, System.Windows.RoutedEventArgs e)

13
src/AddIns/Misc/SharpRefactoring/Project/Src/InsertCtorSnippetRefactoring.cs

@ -18,10 +18,10 @@ namespace SharpRefactoring @@ -18,10 +18,10 @@ namespace SharpRefactoring
{
public class InsertCtorSnippetRefactoring : ISnippetElementProvider
{
public SnippetElement GetElement(string tag)
public SnippetElement GetElement(SnippetInfo snippetInfo)
{
if (tag.Equals("refactoring:ctor", StringComparison.InvariantCultureIgnoreCase))
return new InlineRefactorSnippetElement(context => CreateDialog(context));
if ("refactoring:ctor".Equals(snippetInfo.Tag, StringComparison.OrdinalIgnoreCase))
return new InlineRefactorSnippetElement(context => CreateDialog(context), "{" + snippetInfo.Tag + "}");
return null;
}
@ -45,7 +45,10 @@ namespace SharpRefactoring @@ -45,7 +45,10 @@ namespace SharpRefactoring
CodeGenerator generator = parseInfo.CompilationUnit.Language.CodeGenerator;
var loc = context.Document.GetLocation(context.InsertionPosition);
// cannot use insertion position at this point, because it might not be
// valid, because we are still generating the elements.
// DOM is not updated
ICSharpCode.AvalonEdit.Document.TextLocation loc = context.Document.GetLocation(context.StartPosition);
IClass current = parseInfo.CompilationUnit.GetInnermostClass(loc.Line, loc.Column);
@ -53,7 +56,7 @@ namespace SharpRefactoring @@ -53,7 +56,7 @@ namespace SharpRefactoring
return null;
ITextAnchor anchor = textEditor.Document.CreateAnchor(context.InsertionPosition);
anchor.MovementType = AnchorMovementType.AfterInsertion;
anchor.MovementType = AnchorMovementType.BeforeInsertion;
InsertCtorDialog dialog = new InsertCtorDialog(context, textEditor, anchor, current);

8
src/AddIns/Misc/SharpRefactoring/Project/Src/SwitchSnippetProvider.cs

@ -16,13 +16,9 @@ namespace SharpRefactoring @@ -16,13 +16,9 @@ namespace SharpRefactoring
/// </summary>
public class SwitchSnippetProvider : ISnippetElementProvider
{
public SwitchSnippetProvider()
public SnippetElement GetElement(SnippetInfo snippetInfo)
{
}
public SnippetElement GetElement(string tag)
{
if (tag.Equals("refactoring:switchbody", StringComparison.InvariantCultureIgnoreCase))
if ("refactoring:switchbody".Equals(snippetInfo.Tag, StringComparison.OrdinalIgnoreCase))
return new SwitchBodySnippetElement();
return null;

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj

@ -286,6 +286,7 @@ @@ -286,6 +286,7 @@
<DependentUpon>VisualLine.cs</DependentUpon>
</Compile>
<Compile Include="Snippets\IActiveElement.cs" />
<Compile Include="Snippets\SnippetAnchorElement.cs" />
<Compile Include="Snippets\SnippetEventArgs.cs" />
<Compile Include="Snippets\SnippetInputHandler.cs" />
<Compile Include="Snippets\Snippet.cs" />

9
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/InsertionContext.cs

@ -92,6 +92,15 @@ namespace ICSharpCode.AvalonEdit.Snippets @@ -92,6 +92,15 @@ namespace ICSharpCode.AvalonEdit.Snippets
AnchorSegment wholeSnippetAnchor;
bool deactivateIfSnippetEmpty;
public int StartPosition {
get {
if (wholeSnippetAnchor != null)
return wholeSnippetAnchor.Offset;
else
return startPosition;
}
}
/// <summary>
/// Inserts text at the insertion position and advances the insertion position.
/// This method will add the current indentation to every line in <paramref name="text"/> and will

78
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetAnchorElement.cs

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Siegfried Pammer"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.AvalonEdit.Document;
namespace ICSharpCode.AvalonEdit.Snippets
{
public sealed class SnippetAnchorElement : SnippetElement
{
string textToInsert = "";
public string Name { get; private set; }
public SnippetAnchorElement(string name)
{
this.Name = name;
}
public override void Insert(InsertionContext context)
{
int start = context.InsertionPosition;
context.InsertText("");
int end = context.InsertionPosition;
AnchorSegment segment = new AnchorSegment(context.Document, start, end - start);
context.RegisterActiveElement(this, new AnchorSnippetElement(segment, "", Name, context));
}
}
public sealed class AnchorSnippetElement : IActiveElement
{
public bool IsEditable {
get { return false; }
}
AnchorSegment segment;
InsertionContext context;
public ISegment Segment {
get { return segment; }
}
public AnchorSnippetElement(AnchorSegment segment, string text, string name, InsertionContext context)
{
this.segment = segment;
this.context = context;
this.Text = text;
this.Name = name;
}
public string Text {
get { return context.Document.GetText(segment); }
set {
int offset = segment.Offset;
int length = segment.Length;
context.Document.Replace(offset, length, value);
if (length == 0) {
// replacing an empty anchor segment with text won't enlarge it, so we have to recreate it
segment = new AnchorSegment(context.Document, offset, value.Length);
}
}
}
public string Name { get; private set; }
public void OnInsertionCompleted()
{
}
public void Deactivate()
{
}
}
}

1
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetBoundElement.cs

@ -107,7 +107,6 @@ namespace ICSharpCode.AvalonEdit.Snippets @@ -107,7 +107,6 @@ namespace ICSharpCode.AvalonEdit.Snippets
{
}
public bool IsEditable {
get { return false; }
}

16
src/Main/Base/Project/Src/Editor/AvalonEdit/ISnippetElementProvider.cs

@ -15,6 +15,20 @@ namespace ICSharpCode.SharpDevelop.Editor.AvalonEdit @@ -15,6 +15,20 @@ namespace ICSharpCode.SharpDevelop.Editor.AvalonEdit
/// </summary>
public interface ISnippetElementProvider
{
SnippetElement GetElement(string tag);
SnippetElement GetElement(SnippetInfo snippetInfo);
}
public class SnippetInfo
{
public readonly string Tag;
public readonly string SnippetText;
public readonly int Position;
public SnippetInfo(string tag, string snippetText, int position)
{
this.Tag = tag;
this.SnippetText = snippetText;
this.Position = position;
}
}
}

Loading…
Cancel
Save