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 @@
<Compile Include="Src\Snippets\CodeSnippet.cs" /> <Compile Include="Src\Snippets\CodeSnippet.cs" />
<Compile Include="Src\Snippets\CodeSnippetCompletionWindow.cs" /> <Compile Include="Src\Snippets\CodeSnippetCompletionWindow.cs" />
<Compile Include="Src\Snippets\CodeSnippetGroup.cs" /> <Compile Include="Src\Snippets\CodeSnippetGroup.cs" />
<Compile Include="Src\Snippets\DefaultSnippetElementProvider.cs" />
<Compile Include="Src\Snippets\SnippetCompletionItem.cs" /> <Compile Include="Src\Snippets\SnippetCompletionItem.cs" />
<Compile Include="Src\Snippets\SnippetManager.cs" /> <Compile Include="Src\Snippets\SnippetManager.cs" />
<Compile Include="Src\Snippets\SnippetOptionPanel.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
return srte; return srte;
} }
} }
if ("Selection".Equals(val, StringComparison.OrdinalIgnoreCase))
return new SnippetSelectionElement() { Indentation = GetWhitespaceBefore(snippetText, offset).Length }; int typeSeparator = val.IndexOf(':');
if ("Caret".Equals(val, StringComparison.OrdinalIgnoreCase)) if (typeSeparator > 0) {
return new SnippetCaretElement(); 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) { foreach (ISnippetElementProvider provider in SnippetManager.Instance.SnippetElementProviders) {
SnippetElement element = provider.GetElement(val); SnippetElement element = provider.GetElement(new SnippetInfo(val, snippetText, offset));
if (element != null) if (element != null)
return element; return element;
} }
if (replaceableElements.TryGetValue(val, out srte)) if (replaceableElements.TryGetValue(val, out srte))
return new SnippetBoundElement { TargetElement = srte }; return new SnippetBoundElement { TargetElement = srte };
Match m = functionPattern.Match(val); Match m = functionPattern.Match(val);
@ -188,12 +196,6 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
return new SnippetReplaceableTextElement { Text = val }; // ${unknown} -> replaceable element 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) static string GetValue(ITextEditor editor, string propertyName)
{ {
if ("ClassName".Equals(propertyName, StringComparison.OrdinalIgnoreCase)) { if ("ClassName".Equals(propertyName, StringComparison.OrdinalIgnoreCase)) {

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

@ -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
new CodeSnippet { new CodeSnippet {
Name = "ctor", Name = "ctor",
Description = "Constructor", Description = "Constructor",
Text = "${refactoring:ctor}", Text = "public ${ClassName}(${anchor:parameterList})\n{\n\t${refactoring:ctor}\n}",
Keyword = "event" Keyword = "event"
}, },
new CodeSnippet { new CodeSnippet {

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

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

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

@ -11,6 +11,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media; using System.Windows.Media;
using ICSharpCode.AvalonEdit.Document; using ICSharpCode.AvalonEdit.Document;
@ -28,10 +29,12 @@ namespace SharpRefactoring.Gui
class InlineRefactorSnippetElement : SnippetElement class InlineRefactorSnippetElement : SnippetElement
{ {
Func<InsertionContext, AbstractInlineRefactorDialog> createDialog; Func<InsertionContext, AbstractInlineRefactorDialog> createDialog;
string previewText;
public InlineRefactorSnippetElement(Func<InsertionContext, AbstractInlineRefactorDialog> createDialog) public InlineRefactorSnippetElement(Func<InsertionContext, AbstractInlineRefactorDialog> createDialog, string previewText)
{ {
this.createDialog = createDialog; this.createDialog = createDialog;
this.previewText = previewText;
} }
public override void Insert(InsertionContext context) public override void Insert(InsertionContext context)
@ -40,5 +43,10 @@ namespace SharpRefactoring.Gui
if (dialog != null) if (dialog != null)
context.RegisterActiveElement(this, dialog); 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
{ {
InitializeComponent(); 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 // "Add check for null" is checked for every item by default
//Select(w => { if(w.IsNullable) w.AddCheckForNull = true; return w; }). //Select(w => { if(w.IsNullable) w.AddCheckForNull = true; return w; }).
ToList(); .ToList();
} }
IEnumerable<CtorParamWrapper> CreateCtorParams(IEnumerable<IField> fields, IEnumerable<IProperty> properties) IEnumerable<CtorParamWrapper> CreateCtorParams(IEnumerable<IField> fields, IEnumerable<IProperty> properties)
@ -56,8 +56,6 @@ namespace SharpRefactoring.Gui
protected override string GenerateCode(LanguageProperties language, IClass currentClass) protected override string GenerateCode(LanguageProperties language, IClass currentClass)
{ {
StringBuilder builder = new StringBuilder();
var line = editor.Document.GetLineForOffset(editor.Caret.Offset); var line = editor.Document.GetLineForOffset(editor.Caret.Offset);
string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset); string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset);
@ -105,13 +103,35 @@ namespace SharpRefactoring.Gui
foreach (CtorParamWrapper w in filtered) foreach (CtorParamWrapper w in filtered)
block.AddChild(new ExpressionStatement(new AssignmentExpression(new MemberReferenceExpression(new ThisReferenceExpression(), w.MemberName), AssignmentOperatorType.Assign, new IdentifierExpression(w.ParameterName)))); 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) { AnchorSnippetElement parameterList = context.ActiveElements
Body = block .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) void UpClick(object sender, System.Windows.RoutedEventArgs e)

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

@ -18,10 +18,10 @@ namespace SharpRefactoring
{ {
public class InsertCtorSnippetRefactoring : ISnippetElementProvider public class InsertCtorSnippetRefactoring : ISnippetElementProvider
{ {
public SnippetElement GetElement(string tag) public SnippetElement GetElement(SnippetInfo snippetInfo)
{ {
if (tag.Equals("refactoring:ctor", StringComparison.InvariantCultureIgnoreCase)) if ("refactoring:ctor".Equals(snippetInfo.Tag, StringComparison.OrdinalIgnoreCase))
return new InlineRefactorSnippetElement(context => CreateDialog(context)); return new InlineRefactorSnippetElement(context => CreateDialog(context), "{" + snippetInfo.Tag + "}");
return null; return null;
} }
@ -45,7 +45,10 @@ namespace SharpRefactoring
CodeGenerator generator = parseInfo.CompilationUnit.Language.CodeGenerator; 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); IClass current = parseInfo.CompilationUnit.GetInnermostClass(loc.Line, loc.Column);
@ -53,7 +56,7 @@ namespace SharpRefactoring
return null; return null;
ITextAnchor anchor = textEditor.Document.CreateAnchor(context.InsertionPosition); ITextAnchor anchor = textEditor.Document.CreateAnchor(context.InsertionPosition);
anchor.MovementType = AnchorMovementType.AfterInsertion; anchor.MovementType = AnchorMovementType.BeforeInsertion;
InsertCtorDialog dialog = new InsertCtorDialog(context, textEditor, anchor, current); InsertCtorDialog dialog = new InsertCtorDialog(context, textEditor, anchor, current);

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

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

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

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

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

@ -92,6 +92,15 @@ namespace ICSharpCode.AvalonEdit.Snippets
AnchorSegment wholeSnippetAnchor; AnchorSegment wholeSnippetAnchor;
bool deactivateIfSnippetEmpty; bool deactivateIfSnippetEmpty;
public int StartPosition {
get {
if (wholeSnippetAnchor != null)
return wholeSnippetAnchor.Offset;
else
return startPosition;
}
}
/// <summary> /// <summary>
/// Inserts text at the insertion position and advances the insertion position. /// 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 /// 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 @@
// <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
{ {
} }
public bool IsEditable { public bool IsEditable {
get { return false; } get { return false; }
} }

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

@ -15,6 +15,20 @@ namespace ICSharpCode.SharpDevelop.Editor.AvalonEdit
/// </summary> /// </summary>
public interface ISnippetElementProvider 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