From 10f8d47731e515bbb90bfdb8e3bcf286e9fd0c37 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sun, 25 Jul 2010 16:16:11 +0000 Subject: [PATCH] fixed insertion of text in "surround with" git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@6219 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Src/Snippets/CodeSnippet.cs | 13 ++++++++---- .../Snippets/Snippet.cs | 12 +++++------ .../Snippets/SnippetSelectionElement.cs | 20 ++++++++++++++++++- .../Project/Src/Editor/DocumentUtilitites.cs | 12 +++++++++++ 4 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs index 2bc87ba7b2..9a2ba18cc9 100644 --- a/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs +++ b/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/CodeSnippet.cs @@ -14,7 +14,6 @@ using System.Text.RegularExpressions; using ICSharpCode.AvalonEdit.Snippets; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Dom; -using ICSharpCode.SharpDevelop.Dom.Refactoring; using ICSharpCode.SharpDevelop.Editor; using ICSharpCode.SharpDevelop.Editor.AvalonEdit; using ICSharpCode.SharpDevelop.Editor.CodeCompletion; @@ -132,7 +131,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets snippet.Elements.Add(new SnippetTextElement { Text = snippetText.Substring(pos, m.Index - pos) }); pos = m.Index; } - snippet.Elements.Add(CreateElementForValue(context, replaceableElements, m.Groups[1].Value)); + snippet.Elements.Add(CreateElementForValue(context, replaceableElements, m.Groups[1].Value, m.Index, snippetText)); pos = m.Index + m.Length; } if (pos < snippetText.Length) { @@ -148,7 +147,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets readonly static Regex functionPattern = new Regex(@"^([a-zA-Z]+)\(([^\)]*)\)$", RegexOptions.CultureInvariant); - static SnippetElement CreateElementForValue(ITextEditor context, Dictionary replaceableElements, string val) + static SnippetElement CreateElementForValue(ITextEditor context, Dictionary replaceableElements, string val, int offset, string snippetText) { SnippetReplaceableTextElement srte; int equalsSign = val.IndexOf('='); @@ -161,7 +160,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets } } if ("Selection".Equals(val, StringComparison.OrdinalIgnoreCase)) - return new SnippetSelectionElement(); + return new SnippetSelectionElement() { Indentation = GetWhitespaceBefore(snippetText, offset).Length }; if ("Caret".Equals(val, StringComparison.OrdinalIgnoreCase)) return new SnippetCaretElement(); foreach (ISnippetElementProvider provider in SnippetManager.Instance.SnippetElementProviders) { @@ -192,6 +191,12 @@ 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)) { diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/Snippet.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/Snippet.cs index 733b8f9cb9..95d10d3870 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/Snippet.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/Snippet.cs @@ -33,16 +33,16 @@ namespace ICSharpCode.AvalonEdit.Snippets int insertionPosition = textArea.Caret.Offset; if (selection != null) // if something is selected - insertionPosition = selection.Offset; // use selection start instead of caret position, - // because caret could be at end of selection or anywhere inside. - // Removal of the selected text causes the caret position to be invalid. + // use selection start instead of caret position, + // because caret could be at end of selection or anywhere inside. + // Removal of the selected text causes the caret position to be invalid. + insertionPosition = selection.Offset + TextUtilities.GetWhitespaceAfter(textArea.Document, selection.Offset).Length; InsertionContext context = new InsertionContext(textArea, insertionPosition); - if (selection != null) - textArea.Document.Remove(selection); - using (context.Document.RunUpdate()) { + if (selection != null) + textArea.Document.Remove(insertionPosition, selection.EndOffset - insertionPosition); Insert(context); context.RaiseInsertionCompleted(EventArgs.Empty); } diff --git a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetSelectionElement.cs b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetSelectionElement.cs index 34873a356e..6f4181597e 100644 --- a/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetSelectionElement.cs +++ b/src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Snippets/SnippetSelectionElement.cs @@ -6,6 +6,7 @@ // using System; +using System.Text; using System.Windows.Input; using ICSharpCode.AvalonEdit.Document; @@ -17,10 +18,27 @@ namespace ICSharpCode.AvalonEdit.Snippets [Serializable] public class SnippetSelectionElement : SnippetElement { + public int Indentation { get; set; } + /// public override void Insert(InsertionContext context) { - context.InsertText(context.SelectedText); + StringBuilder tabString = new StringBuilder(); + + for (int i = 0; i < Indentation; i++) { + tabString.Append(context.Tab); + } + + string indent = tabString.ToString(); + + string text = context.SelectedText.TrimStart(' ', '\t'); + + text = text.Replace(context.LineTerminator, + context.LineTerminator + indent); + + context.Document.Insert(context.InsertionPosition, text); + context.InsertionPosition += text.Length; + if (string.IsNullOrEmpty(context.SelectedText)) SnippetCaretElement.SetCaret(context); } diff --git a/src/Main/Base/Project/Src/Editor/DocumentUtilitites.cs b/src/Main/Base/Project/Src/Editor/DocumentUtilitites.cs index 38aff75132..e8d8db70ee 100644 --- a/src/Main/Base/Project/Src/Editor/DocumentUtilitites.cs +++ b/src/Main/Base/Project/Src/Editor/DocumentUtilitites.cs @@ -135,6 +135,18 @@ namespace ICSharpCode.SharpDevelop.Editor return textBuffer.GetText(segment.Offset, segment.Length); } + /// + /// Gets all indentation before the offset. + /// + /// The document. + /// The offset where the indentation ends. + /// The indentation text. + public static string GetWhitespaceBefore(ITextBuffer textBuffer, int offset) + { + ISegment segment = TextUtilities.GetWhitespaceBefore(GetTextSource(textBuffer), offset); + return textBuffer.GetText(segment.Offset, segment.Length); + } + /// /// Gets the line terminator for the document around the specified line number. ///