Browse Source

- finished implementation of Ctrl+J snippets.

- added props snippet
- enhanced existing snippets

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@5214 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 16 years ago
parent
commit
3c5585e0a2
  1. 6
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs
  2. 4
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs
  3. 13
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetManager.cs
  4. 1
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/ICSharpCode.AvalonEdit.csproj
  5. 10
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/InsertionContext.cs
  6. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetCaretElement.cs
  7. 61
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetEventArgs.cs
  8. 9
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetInputHandler.cs
  9. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetReplaceableTextElement.cs
  10. 2
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetSelectionElement.cs
  11. 2
      src/Main/Base/Project/Src/Util/ExtensionMethods.cs

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

@ -73,7 +73,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
public ICompletionItem CreateCompletionItem(ITextEditor context) public ICompletionItem CreateCompletionItem(ITextEditor context)
{ {
return new SnippetCompletionItem(context, this); return new SnippetCompletionItem(context, this) { AlwaysInsertSnippet = context.SelectionLength > 0 };
} }
readonly static Regex pattern = new Regex(@"\$\{([^\}]*)\}", RegexOptions.CultureInvariant); readonly static Regex pattern = new Regex(@"\$\{([^\}]*)\}", RegexOptions.CultureInvariant);
@ -104,8 +104,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
if (pos < snippetText.Length) { if (pos < snippetText.Length) {
snippet.Elements.Add(new SnippetTextElement { Text = snippetText.Substring(pos) }); snippet.Elements.Add(new SnippetTextElement { Text = snippetText.Substring(pos) });
} }
if (!snippet.Elements.Any(e2 => e2 is SnippetCaretElement)) { if (!snippet.Elements.Any(e => e is SnippetCaretElement)) {
int index = snippet.Elements.IndexOf(e => e is SnippetSelectionElement); int index = snippet.Elements.FindIndex(e2 => e2 is SnippetSelectionElement);
if (index > -1) if (index > -1)
snippet.Elements.Insert(index + 1, new SnippetCaretElement()); snippet.Elements.Insert(index + 1, new SnippetCaretElement());
} }

4
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs

@ -40,6 +40,8 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
this.codeSnippet = codeSnippet; this.codeSnippet = codeSnippet;
} }
public bool AlwaysInsertSnippet { get; set; }
public string Text { public string Text {
get { return codeSnippet.Name; } get { return codeSnippet.Name; }
} }
@ -62,7 +64,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
if (context.Editor != this.textEditor) if (context.Editor != this.textEditor)
throw new ArgumentException("wrong editor"); throw new ArgumentException("wrong editor");
using (context.Editor.Document.OpenUndoGroup()) { using (context.Editor.Document.OpenUndoGroup()) {
if (context.CompletionChar == '\t') { if (context.CompletionChar == '\t' || AlwaysInsertSnippet) {
context.Editor.Document.Remove(context.StartOffset, context.Length); context.Editor.Document.Remove(context.StartOffset, context.Length);
CreateSnippet().Insert(textArea); CreateSnippet().Insert(textArea);
} else { } else {

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

@ -53,7 +53,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
new CodeSnippet { new CodeSnippet {
Name = "prop", Name = "prop",
Description = "Property", Description = "Property",
Text = "${type} ${toFieldName(name)};\n\npublic ${type=int} ${name=Property} {\n\tget { return ${toFieldName(name)}; }\n\tset { ${toFieldName(name)} = value; }\n}" Text = "${type} ${toFieldName(name)};\n\npublic ${type=int} ${name=Property} {\n\tget { return ${toFieldName(name)}; }\n\tset { ${toFieldName(name)} = value; }\n}${Caret}"
}, },
new CodeSnippet { new CodeSnippet {
Name = "propdp", Name = "propdp",
@ -65,17 +65,22 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
+ "public ${type=int} ${name=Property} {" + Environment.NewLine + "public ${type=int} ${name=Property} {" + Environment.NewLine
+ "\tget { return (${type})GetValue(${name}Property); }" + Environment.NewLine + "\tget { return (${type})GetValue(${name}Property); }" + Environment.NewLine
+ "\tset { SetValue(${name}Property, value); }" + "\tset { SetValue(${name}Property, value); }"
+ Environment.NewLine + "}" + Environment.NewLine + "}${Caret}"
},
new CodeSnippet {
Name = "props",
Description = "Property",
Text = "public ${Type=object} ${Property=Property} { get; set; }${Caret}"
}, },
new CodeSnippet { new CodeSnippet {
Name = "ctor", Name = "ctor",
Description = "Constructor", Description = "Constructor",
Text = "public ${ClassName}()\n{\t\n${Selection}\n}" Text = "public ${ClassName}(${Caret})\n{\t\n${Selection}\n}"
}, },
new CodeSnippet { new CodeSnippet {
Name = "switch", Name = "switch",
Description = "Switch statement", Description = "Switch statement",
Text = "switch (${condition}) {\n\tcase ${firstcase=0}:\n\t\tbreak;\n\tdefault:\n\t\t${Selection}\n\t\tbreak;\n}" Text = "switch (${condition}) {\n\tcase ${firstcase=0}:\n\t\t${Caret}\n\t\tbreak;\n\tdefault:\n\t\t${Selection}\n\t\tbreak;\n}"
}, },
new CodeSnippet { new CodeSnippet {
Name = "try", Name = "try",

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

@ -279,6 +279,7 @@
<DependentUpon>VisualLine.cs</DependentUpon> <DependentUpon>VisualLine.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Snippets\IActiveElement.cs" /> <Compile Include="Snippets\IActiveElement.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" />
<Compile Include="Snippets\SnippetBoundElement.cs" /> <Compile Include="Snippets\SnippetBoundElement.cs" />

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

@ -188,7 +188,7 @@ namespace ICSharpCode.AvalonEdit.Snippets
currentStatus = Status.Interactive; currentStatus = Status.Interactive;
if (registeredElements.Count == 0) { if (registeredElements.Count == 0) {
// deactivate immediately if there are no interactive elements // deactivate immediately if there are no interactive elements
Deactivate(EventArgs.Empty); Deactivate(new SnippetEventArgs(DeactivateReason.NoActiveElements));
} else { } else {
myInputHandler = new SnippetInputHandler(this); myInputHandler = new SnippetInputHandler(this);
// disable existing snippet input handlers - there can be only 1 active snippet // disable existing snippet input handlers - there can be only 1 active snippet
@ -211,14 +211,14 @@ namespace ICSharpCode.AvalonEdit.Snippets
/// Calls the <see cref="IActiveElement.Deactivate"/> method on all registered active elements. /// Calls the <see cref="IActiveElement.Deactivate"/> method on all registered active elements.
/// </summary> /// </summary>
/// <param name="e">The EventArgs to use</param> /// <param name="e">The EventArgs to use</param>
public void Deactivate(EventArgs e) public void Deactivate(SnippetEventArgs e)
{ {
if (currentStatus == Status.Deactivated || currentStatus == Status.RaisingDeactivated) if (currentStatus == Status.Deactivated || currentStatus == Status.RaisingDeactivated)
return; return;
if (currentStatus != Status.Interactive) if (currentStatus != Status.Interactive)
throw new InvalidOperationException("Cannot call Deactivate() until RaiseInsertionCompleted() has finished."); throw new InvalidOperationException("Cannot call Deactivate() until RaiseInsertionCompleted() has finished.");
if (e == null) if (e == null)
e = EventArgs.Empty; e = new SnippetEventArgs(DeactivateReason.Unknown);
TextDocumentWeakEventManager.UpdateFinished.RemoveListener(Document, this); TextDocumentWeakEventManager.UpdateFinished.RemoveListener(Document, this);
currentStatus = Status.RaisingDeactivated; currentStatus = Status.RaisingDeactivated;
@ -234,7 +234,7 @@ namespace ICSharpCode.AvalonEdit.Snippets
/// <summary> /// <summary>
/// Occurs when the interactive mode is deactivated. /// Occurs when the interactive mode is deactivated.
/// </summary> /// </summary>
public event EventHandler Deactivated; public event EventHandler<SnippetEventArgs> Deactivated;
bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e) bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{ {
@ -248,7 +248,7 @@ namespace ICSharpCode.AvalonEdit.Snippets
// Deactivate if snippet is deleted. This is necessary for correctly leaving interactive // Deactivate if snippet is deleted. This is necessary for correctly leaving interactive
// mode if Undo is pressed after a snippet insertion. // mode if Undo is pressed after a snippet insertion.
if (wholeSnippetAnchor.Length == 0) if (wholeSnippetAnchor.Length == 0)
Deactivate(e); Deactivate(new SnippetEventArgs(DeactivateReason.Deleted));
return true; return true;
} }
return false; return false;

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

@ -19,12 +19,17 @@ namespace ICSharpCode.AvalonEdit.Snippets
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override void Insert(InsertionContext context) public override void Insert(InsertionContext context)
{
if (!string.IsNullOrEmpty(context.SelectedText))
SetCaret(context);
}
internal static void SetCaret(InsertionContext context)
{ {
TextAnchor pos = context.Document.CreateAnchor(context.InsertionPosition); TextAnchor pos = context.Document.CreateAnchor(context.InsertionPosition);
pos.SurviveDeletion = true; pos.SurviveDeletion = true;
context.Deactivated += (sender, e) => { context.Deactivated += (sender, e) => {
KeyEventArgs ke = e as KeyEventArgs; if (e.Reason == DeactivateReason.ReturnPressed || e.Reason == DeactivateReason.NoActiveElements) {
if (ke != null && ke.Key == Key.Return) {
context.TextArea.Caret.Offset = pos.Offset; context.TextArea.Caret.Offset = pos.Offset;
} }
}; };

61
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetEventArgs.cs

@ -0,0 +1,61 @@
// <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;
namespace ICSharpCode.AvalonEdit.Snippets
{
/// <summary>
/// Provides information about the event that occured during use of snippets.
/// </summary>
public class SnippetEventArgs : EventArgs
{
/// <summary>
/// Gets the reason for deactivation.
/// </summary>
public DeactivateReason Reason { get; private set; }
/// <summary>
/// Creates a new SnippetEventArgs object, with a DeactivateReason.
/// </summary>
public SnippetEventArgs(DeactivateReason reason)
{
this.Reason = reason;
}
}
/// <summary>
/// Describes the reason for deactivation of a <see cref="SnippetElement" />.
/// </summary>
public enum DeactivateReason
{
/// <summary>
/// Unknown reason.
/// </summary>
Unknown,
/// <summary>
/// Snippet was deleted.
/// </summary>
Deleted,
/// <summary>
/// There are no active elements in the snippet.
/// </summary>
NoActiveElements,
/// <summary>
/// The SnippetInputHandler was detached.
/// </summary>
InputHandlerDetached,
/// <summary>
/// Return was pressed by the user.
/// </summary>
ReturnPressed,
/// <summary>
/// Escape was pressed by the user.
/// </summary>
EscapePressed
}
}

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

@ -36,14 +36,17 @@ namespace ICSharpCode.AvalonEdit.Snippets
public override void Detach() public override void Detach()
{ {
base.Detach(); base.Detach();
context.Deactivate(EventArgs.Empty); context.Deactivate(new SnippetEventArgs(DeactivateReason.InputHandlerDetached));
} }
public override void OnPreviewKeyDown(KeyEventArgs e) public override void OnPreviewKeyDown(KeyEventArgs e)
{ {
base.OnPreviewKeyDown(e); base.OnPreviewKeyDown(e);
if (e.Key == Key.Escape || e.Key == Key.Return) { if (e.Key == Key.Escape) {
context.Deactivate(e); context.Deactivate(new SnippetEventArgs(DeactivateReason.EscapePressed));
e.Handled = true;
} else if (e.Key == Key.Return) {
context.Deactivate(new SnippetEventArgs(DeactivateReason.ReturnPressed));
e.Handled = true; e.Handled = true;
} else if (e.Key == Key.Tab) { } else if (e.Key == Key.Tab) {
bool backwards = e.KeyboardDevice.Modifiers == ModifierKeys.Shift; bool backwards = e.KeyboardDevice.Modifiers == ModifierKeys.Shift;

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetReplaceableTextElement.cs

@ -71,7 +71,7 @@ namespace ICSharpCode.AvalonEdit.Snippets
void AnchorDeleted(object sender, EventArgs e) void AnchorDeleted(object sender, EventArgs e)
{ {
context.Deactivate(EventArgs.Empty); context.Deactivate(new SnippetEventArgs(DeactivateReason.Deleted));
} }
public void OnInsertionCompleted() public void OnInsertionCompleted()

2
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetSelectionElement.cs

@ -21,6 +21,8 @@ namespace ICSharpCode.AvalonEdit.Snippets
public override void Insert(InsertionContext context) public override void Insert(InsertionContext context)
{ {
context.InsertText(context.SelectedText); context.InsertText(context.SelectedText);
if (string.IsNullOrEmpty(context.SelectedText))
SnippetCaretElement.SetCaret(context);
} }
} }
} }

2
src/Main/Base/Project/Src/Util/ExtensionMethods.cs

@ -410,7 +410,7 @@ namespace ICSharpCode.SharpDevelop
/// Returns the index of the first element for which constraint returns true. /// Returns the index of the first element for which constraint returns true.
/// If none of the items in the list fits the constraint -1 is returned. /// If none of the items in the list fits the constraint -1 is returned.
/// </summary> /// </summary>
public static int IndexOf<T>(this IList<T> list, Func<T, bool> constraint) { public static int FindIndex<T>(this IList<T> list, Func<T, bool> constraint) {
for (int i = 0; i < list.Count; i++) { for (int i = 0; i < list.Count; i++) {
if (constraint(list[i])) if (constraint(list[i]))
return i; return i;

Loading…
Cancel
Save