Browse Source

New feature: Edit > Insert > Paste as comment/string.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@3832 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 17 years ago
parent
commit
f80ca05e61
  1. 15
      src/Libraries/NRefactory/Project/Src/Ast/General/PrimitiveExpression.cs
  2. 10
      src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs
  3. 2
      src/Libraries/NRefactory/Project/Src/AstBuilder/StatementBuilder.cs
  4. 47
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
  5. 6
      src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs
  6. 1
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  7. 174
      src/Main/Base/Project/Src/TextEditor/Commands/PasteAsCommands.cs

15
src/Libraries/NRefactory/Project/Src/Ast/General/PrimitiveExpression.cs

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
// <version>$Revision$</version>
// </file>
using ICSharpCode.NRefactory.PrettyPrinter;
using System;
namespace ICSharpCode.NRefactory.Ast
@ -18,6 +19,9 @@ namespace ICSharpCode.NRefactory.Ast @@ -18,6 +19,9 @@ namespace ICSharpCode.NRefactory.Ast
public string StringValue {
get {
if (stringValue == null)
return CSharpOutputVisitor.ToCSharpString(this);
else
return stringValue;
}
set {
@ -25,6 +29,11 @@ namespace ICSharpCode.NRefactory.Ast @@ -25,6 +29,11 @@ namespace ICSharpCode.NRefactory.Ast
}
}
public PrimitiveExpression(object val)
{
this.Value = val;
}
public PrimitiveExpression(object val, string stringValue)
{
this.Value = val;
@ -39,9 +48,9 @@ namespace ICSharpCode.NRefactory.Ast @@ -39,9 +48,9 @@ namespace ICSharpCode.NRefactory.Ast
public override string ToString()
{
return String.Format("[PrimitiveExpression: Value={1}, ValueType={2}, StringValue={0}]",
stringValue,
Value,
Value == null ? "null" : Value.GetType().FullName
this.StringValue,
this.Value,
this.Value == null ? "null" : this.Value.GetType().FullName
);
}
}

10
src/Libraries/NRefactory/Project/Src/AstBuilder/ExpressionBuilder.cs

@ -83,6 +83,16 @@ namespace ICSharpCode.NRefactory.AstBuilder @@ -83,6 +83,16 @@ namespace ICSharpCode.NRefactory.AstBuilder
return new PrimitiveExpression(null, "null");
}
}
/// <summary>
/// Just calls the BinaryOperatorExpression constructor,
/// but being an extension method; this allows for a nicer
/// infix syntax in some cases.
/// </summary>
public static BinaryOperatorExpression Operator(this Expression left, BinaryOperatorType op, Expression right)
{
return new BinaryOperatorExpression(left, op, right);
}
}
#endif
}

2
src/Libraries/NRefactory/Project/Src/AstBuilder/StatementBuilder.cs

@ -11,7 +11,6 @@ using ICSharpCode.NRefactory.Ast; @@ -11,7 +11,6 @@ using ICSharpCode.NRefactory.Ast;
namespace ICSharpCode.NRefactory.AstBuilder
{
#if NET35
/// <summary>
/// Extension methods for NRefactory.Ast.Expression.
/// </summary>
@ -57,5 +56,4 @@ namespace ICSharpCode.NRefactory.AstBuilder @@ -57,5 +56,4 @@ namespace ICSharpCode.NRefactory.AstBuilder
AddStatement(block, new AssignmentExpression(left, AssignmentOperatorType.Assign, right));
}
}
#endif
}

47
src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

@ -1748,69 +1748,68 @@ namespace ICSharpCode.NRefactory.PrettyPrinter @@ -1748,69 +1748,68 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
public override object TrackedVisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
{
if (primitiveExpression.Value == null) {
outputFormatter.PrintToken(Tokens.Null);
outputFormatter.PrintText(ToCSharpString(primitiveExpression));
return null;
}
internal static string ToCSharpString(PrimitiveExpression primitiveExpression)
{
if (primitiveExpression.Value == null) {
return "null";
}
object val = primitiveExpression.Value;
if (val is bool) {
if ((bool)val) {
outputFormatter.PrintToken(Tokens.True);
return "true";
} else {
outputFormatter.PrintToken(Tokens.False);
return "false";
}
return null;
}
if (val is string) {
outputFormatter.PrintText('"' + ConvertString(val.ToString()) + '"');
return null;
return "\"" + ConvertString(val.ToString()) + "\"";
}
if (val is char) {
outputFormatter.PrintText("'" + ConvertCharLiteral((char)val) + "'");
return null;
return "'" + ConvertCharLiteral((char)val) + "'";
}
if (val is decimal) {
outputFormatter.PrintText(((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m");
return null;
return ((decimal)val).ToString(NumberFormatInfo.InvariantInfo) + "m";
}
if (val is float) {
outputFormatter.PrintText(((float)val).ToString(NumberFormatInfo.InvariantInfo) + "f");
return null;
return ((float)val).ToString(NumberFormatInfo.InvariantInfo) + "f";
}
if (val is double) {
string text = ((double)val).ToString(NumberFormatInfo.InvariantInfo);
if (text.IndexOf('.') < 0 && text.IndexOf('E') < 0)
outputFormatter.PrintText(text + ".0");
return text + ".0";
else
outputFormatter.PrintText(text);
return null;
return text;
}
if (val is IFormattable) {
StringBuilder b = new StringBuilder();
if (primitiveExpression.LiteralFormat == LiteralFormat.HexadecimalNumber) {
outputFormatter.PrintText("0x");
outputFormatter.PrintText(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
b.Append("0x");
b.Append(((IFormattable)val).ToString("x", NumberFormatInfo.InvariantInfo));
} else {
outputFormatter.PrintText(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
b.Append(((IFormattable)val).ToString(null, NumberFormatInfo.InvariantInfo));
}
if (val is uint || val is ulong) {
outputFormatter.PrintText("u");
b.Append("u");
}
if (val is long || val is ulong) {
outputFormatter.PrintText("L");
b.Append("L");
}
return b.ToString();
} else {
outputFormatter.PrintText(val.ToString());
return val.ToString();
}
return null;
}
static bool IsNullLiteralExpression(Expression expr)

6
src/Libraries/NRefactory/Project/Src/Visitors/VBNetConstructsConvertVisitor.cs

@ -236,9 +236,9 @@ namespace ICSharpCode.NRefactory.Visitors @@ -236,9 +236,9 @@ namespace ICSharpCode.NRefactory.Visitors
if (methodDeclaration.TypeReference.Type != "System.Void" && methodDeclaration.Body.Children.Count > 0) {
if (IsAssignmentTo(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1], methodDeclaration.Name))
{
ReturnStatement rs = new ReturnStatement(GetAssignmentFromStatement(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1]).Right);
Expression returnValue = GetAssignmentFromStatement(methodDeclaration.Body.Children[methodDeclaration.Body.Children.Count - 1]).Right;
methodDeclaration.Body.Children.RemoveAt(methodDeclaration.Body.Children.Count - 1);
methodDeclaration.Body.AddChild(rs);
methodDeclaration.Body.Return(returnValue);
} else {
ReturnStatementForFunctionAssignment visitor = new ReturnStatementForFunctionAssignment(methodDeclaration.Name);
methodDeclaration.Body.AcceptVisitor(visitor, null);
@ -247,7 +247,7 @@ namespace ICSharpCode.NRefactory.Visitors @@ -247,7 +247,7 @@ namespace ICSharpCode.NRefactory.Visitors
init = ExpressionBuilder.CreateDefaultValueForType(methodDeclaration.TypeReference);
methodDeclaration.Body.Children.Insert(0, new LocalVariableDeclaration(new VariableDeclaration(FunctionReturnValueName, init, methodDeclaration.TypeReference)));
methodDeclaration.Body.Children[0].Parent = methodDeclaration.Body;
methodDeclaration.Body.AddChild(new ReturnStatement(new IdentifierExpression(FunctionReturnValueName)));
methodDeclaration.Body.Return(new IdentifierExpression(FunctionReturnValueName));
}
}
}

1
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -497,6 +497,7 @@ @@ -497,6 +497,7 @@
<Compile Include="Src\TextEditor\Commands\GenerateCodeCommand.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Src\TextEditor\Commands\PasteAsCommands.cs" />
<Compile Include="Src\TextEditor\Commands\SearchCommands.cs" />
<Compile Include="Src\TextEditor\Commands\TextAreaContextmenuCommands.cs" />
<Compile Include="Src\TextEditor\Commands\ToolCommands.cs" />

174
src/Main/Base/Project/Src/TextEditor/Commands/PasteAsCommands.cs

@ -0,0 +1,174 @@ @@ -0,0 +1,174 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <author name="Daniel Grunwald"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.AstBuilder;
using System;
using System.IO;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.Core.WinForms;
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Dom.Refactoring;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Actions;
using ICSharpCode.TextEditor.Document;
namespace ICSharpCode.SharpDevelop.DefaultEditor.Commands
{
public abstract class PasteAsCommand : AbstractMenuCommand
{
public override void Run()
{
string clipboardText = ClipboardWrapper.GetText();
if (string.IsNullOrEmpty(clipboardText))
return;
IViewContent viewContent = WorkbenchSingleton.Workbench.ActiveViewContent;
if (viewContent == null || !(viewContent is ITextEditorControlProvider)) {
return;
}
TextEditorControl textEditor = ((ITextEditorControlProvider)viewContent).TextEditorControl;
if (textEditor == null) {
return;
}
textEditor.BeginUpdate();
textEditor.Document.UndoStack.StartUndoGroup();
try {
Run(textEditor, clipboardText);
} finally {
textEditor.Document.UndoStack.EndUndoGroup();
textEditor.EndUpdate();
}
textEditor.Refresh();
}
protected abstract void Run(TextEditorControl editor, string clipboardText);
protected string GetIndentation(ICSharpCode.TextEditor.Document.IDocument document, int line)
{
string lineText = document.GetText(document.GetLineSegment(line));
return lineText.Substring(0, lineText.Length - lineText.TrimStart().Length);
}
}
/// <summary>
/// Pastes the clipboard text as a comment.
///
/// Does the following:
/// - Take clipboard text
/// - Get current indentation
/// - Wrap first line using 'IAmbience.WrapComment'
/// - If it's too long (according to the column ruler position), word-break
/// - Insert it
/// </summary>
public class PasteAsCommentCommand : PasteAsCommand
{
protected override void Run(TextEditorControl editor, string clipboardText)
{
TextArea textArea = editor.ActiveTextAreaControl.TextArea;
string indentation = GetIndentation(editor.Document, textArea.Caret.Line);
IAmbience ambience = AmbienceService.GetCurrentAmbience();
int maxLineLength = textArea.TextEditorProperties.VerticalRulerRow - VisualIndentationLength(textArea, indentation);
StringBuilder insertedText = new StringBuilder();
using (StringReader reader = new StringReader(clipboardText)) {
string line;
while ((line = reader.ReadLine()) != null) {
AppendTextLine(indentation, ambience, maxLineLength, insertedText, line);
}
}
var document = textArea.Document;
int insertionPos = document.GetLineSegment(textArea.Caret.Line).Offset + indentation.Length;
document.Insert(insertionPos, insertedText.ToString());
}
void AppendTextLine(string indentation, IAmbience ambience, int maxLineLength, StringBuilder insertedText, string line)
{
const int minimumLineLength = 10;
string commentedLine;
while (true) {
commentedLine = ambience.WrapComment(line);
int commentingOverhead = commentedLine.Length - line.Length;
if (commentingOverhead < 0 || (maxLineLength - commentingOverhead) < minimumLineLength)
break;
if (commentedLine.Length > maxLineLength) {
int pos = FindWrapPositionBefore(line, maxLineLength - commentingOverhead);
if (pos < minimumLineLength)
break;
insertedText.AppendLine(ambience.WrapComment(line.Substring(0, pos)));
insertedText.Append(indentation);
line = line.Substring(pos + 1);
} else {
break;
}
}
insertedText.AppendLine(commentedLine);
insertedText.Append(indentation); // indentation for next line
}
int FindWrapPositionBefore(string line, int pos)
{
return line.LastIndexOf(' ', pos);
}
int VisualIndentationLength(TextArea textArea, string indentation)
{
int length = 0;
foreach (char c in indentation) {
if (c == '\t')
length += textArea.TextEditorProperties.TabIndent;
else
length += 1;
}
return length;
}
}
/// <summary>
/// Pastes the clipboard text as a string.
///
/// Does the following:
/// - Take clipboard text
/// - Convert to string literal using CodeGenerator
/// - Insert it
/// </summary>
public class PasteAsStringCommand : PasteAsCommand
{
protected override void Run(TextEditorControl editor, string clipboardText)
{
CodeGenerator codeGenerator = ParserService.CurrentProjectContent.Language.CodeGenerator;
if (codeGenerator == null)
codeGenerator = LanguageProperties.CSharp.CodeGenerator;
Expression expression = null;
using (StringReader reader = new StringReader(clipboardText)) {
string line;
while ((line = reader.ReadLine()) != null) {
Expression newExpr = new PrimitiveExpression(line);
if (expression == null) {
expression = newExpr;
} else {
expression = expression
.Operator(BinaryOperatorType.Concat,
ExpressionBuilder.Identifier("Environment").Member("NewLine"))
.Operator(BinaryOperatorType.Concat,
newExpr);
}
}
}
if (expression == null)
return;
TextArea textArea = editor.ActiveTextAreaControl.TextArea;
string indentation = GetIndentation(editor.Document, textArea.Caret.Line);
textArea.InsertString(codeGenerator.GenerateCode(expression, indentation).Trim());
}
}
}
Loading…
Cancel
Save