Browse Source

Support commenting selected lines in IronPython and IronRuby code.

pull/2/head
mrward 15 years ago
parent
commit
bdaa742a0b
  1. 1
      src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj
  2. 79
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormattingStrategy.cs
  3. 46
      src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonLineIndenter.cs
  4. 137
      src/AddIns/BackendBindings/Python/PythonBinding/Test/Gui/PythonFormattingStrategyTests.cs
  5. 2
      src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj
  6. 2
      src/AddIns/BackendBindings/Ruby/RubyBinding.sln
  7. 1
      src/AddIns/BackendBindings/Ruby/RubyBinding/Project/RubyBinding.csproj
  8. 194
      src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyFormattingStrategy.cs
  9. 134
      src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyLineIndenter.cs
  10. 242
      src/AddIns/BackendBindings/Ruby/RubyBinding/Test/Gui/RubyFormattingStrategyTests.cs
  11. 2
      src/AddIns/BackendBindings/Ruby/RubyBinding/Test/RubyBinding.Tests.csproj
  12. 2
      src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj
  13. 125
      src/AddIns/BackendBindings/Scripting/Project/Src/LineIndenter.cs
  14. 30
      src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingFormattingStrategy.cs

1
src/AddIns/BackendBindings/Python/PythonBinding/Project/PythonBinding.csproj

@ -104,6 +104,7 @@ @@ -104,6 +104,7 @@
<Compile Include="Src\PythonFromImport.cs" />
<Compile Include="Src\PythonImport.cs" />
<Compile Include="Src\PythonLanguageBinding.cs" />
<Compile Include="Src\PythonLineIndenter.cs" />
<Compile Include="Src\PythonLocalVariableResolver.cs" />
<Compile Include="Src\PythonMemberResolver.cs" />
<Compile Include="Src\PythonMethod.cs" />

79
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonFormattingStrategy.cs

@ -2,87 +2,20 @@ @@ -2,87 +2,20 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Text;
using ICSharpCode.Scripting;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.PythonBinding
{
public class PythonFormattingStrategy : DefaultFormattingStrategy
public class PythonFormattingStrategy : ScriptingFormattingStrategy
{
public PythonFormattingStrategy()
{
}
public override void IndentLine(ITextEditor editor, IDocumentLine line)
{
if (line.LineNumber == 1) {
base.IndentLine(editor, line);
return;
}
IDocument document = editor.Document;
IDocumentLine previousLine = document.GetLine(line.LineNumber - 1);
string previousLineText = previousLine.Text.Trim();
if (previousLineText.EndsWith(":")) {
IncreaseLineIndent(editor, line);
} else if (previousLineText == "pass") {
DecreaseLineIndent(editor, line);
} else if ((previousLineText == "return") || (previousLineText.StartsWith("return "))) {
DecreaseLineIndent(editor, line);
} else if ((previousLineText == "raise") || (previousLineText.StartsWith("raise "))) {
DecreaseLineIndent(editor, line);
} else if (previousLineText == "break") {
DecreaseLineIndent(editor, line);
} else {
base.IndentLine(editor, line);
}
}
void IncreaseLineIndent(ITextEditor editor, IDocumentLine line)
{
ModifyLineIndent(editor, line, true);
}
void DecreaseLineIndent(ITextEditor editor, IDocumentLine line)
{
ModifyLineIndent(editor, line, false);
}
void ModifyLineIndent(ITextEditor editor, IDocumentLine line, bool increaseIndent)
{
string indentation = GetLineIndentation(editor, line.LineNumber - 1);
indentation = GetNewLineIndentation(indentation, editor.Options.IndentationString, increaseIndent);
string newIndentedText = indentation + line.Text;
editor.Document.Replace(line.Offset, line.Length, newIndentedText);
}
string GetLineIndentation(ITextEditor editor, int line)
{
IDocumentLine documentLine = editor.Document.GetLine(line);
StringBuilder whitespace = new StringBuilder();
foreach (char ch in documentLine.Text) {
if (Char.IsWhiteSpace(ch)) {
whitespace.Append(ch);
} else {
break;
}
}
return whitespace.ToString();
public override string LineComment {
get { return "#"; }
}
string GetNewLineIndentation(string previousLineIndentation, string singleIndent, bool increaseIndent)
protected override LineIndenter CreateLineIndenter(ITextEditor editor, IDocumentLine line)
{
if (increaseIndent) {
return previousLineIndentation + singleIndent;
}
// Decrease the new line indentation.
int decreaselength = previousLineIndentation.Length - singleIndent.Length;
if (decreaselength < 0) {
decreaselength = 0;
}
return previousLineIndentation.Substring(0, decreaselength);
return new PythonLineIndenter(editor, line);
}
}
}

46
src/AddIns/BackendBindings/Python/PythonBinding/Project/Src/PythonLineIndenter.cs

@ -0,0 +1,46 @@ @@ -0,0 +1,46 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.Scripting;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.PythonBinding
{
public class PythonLineIndenter : LineIndenter
{
public PythonLineIndenter(ITextEditor editor, IDocumentLine line)
: base(editor, line)
{
}
protected override bool ShouldIncreaseLineIndent()
{
return PreviousLine.EndsWith(":");
}
protected override bool ShouldDecreaseLineIndent()
{
if (PreviousLine == "pass") {
return true;
} else if (PreviousLineIsReturnStatement()) {
return true;
} else if (PreviousLineIsRaiseStatement()) {
return true;
} else if (PreviousLine == "break") {
return true;
}
return false;
}
bool PreviousLineIsReturnStatement()
{
return (PreviousLine == "return") || PreviousLine.StartsWith("return ");
}
bool PreviousLineIsRaiseStatement()
{
return (PreviousLine == "raise") || PreviousLine.StartsWith("raise ");
}
}
}

137
src/AddIns/BackendBindings/Python/PythonBinding/Test/Gui/PythonIndentationTests.cs → src/AddIns/BackendBindings/Python/PythonBinding/Test/Gui/PythonFormattingStrategyTests.cs

@ -5,26 +5,20 @@ using System; @@ -5,26 +5,20 @@ using System;
using ICSharpCode.AvalonEdit;
using ICSharpCode.PythonBinding;
using ICSharpCode.Scripting.Tests.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Editor;
using ICSharpCode.SharpDevelop.Editor.AvalonEdit;
using NUnit.Framework;
using PythonBinding.Tests.Utils;
namespace PythonBinding.Tests.Gui
{
/// <summary>
/// Tests that the PythonFormattingStrategy indents the new line added after pressing the ':' character.
/// </summary>
[TestFixture]
public class PythonIndentationTestFixture
public class PythonFormattingStrategyTests
{
TextEditor textEditor;
AvalonEditTextEditorAdapter textEditorAdapter;
PythonFormattingStrategy formattingStrategy;
[SetUp]
public void Init()
void CreatePythonFormattingStrategy()
{
MockTextEditorOptions textEditorOptions = new MockTextEditorOptions();
textEditorOptions.IndentationSize = 4;
@ -35,62 +29,74 @@ namespace PythonBinding.Tests.Gui @@ -35,62 +29,74 @@ namespace PythonBinding.Tests.Gui
formattingStrategy = new PythonFormattingStrategy();
}
[Test]
public void NewMethodDefinition()
public void IndentLine_IndentLineAfterNewMethodDefinition_LineIsIndentedByOneTab()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"def newMethod:\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def newMethod:\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void NoExtraIndentationRequired()
public void IndentLine_NoExtraIndentationRequiredAfterPrintLineStatement_SecondLineIsIndentedToSameLevelAsPrintStatementLine()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"\tprint 'abc'\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"\tprint 'abc'\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void PassStatementDecreasesIndentOnThirdLine()
public void IndentLine_IndentAfterPassStatementOnSecondLine_DecreasesIndentOnThirdLine()
{
textEditor.Text =
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\tpass\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\tpass\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ReturnValueStatementDecreasesIndentOnThirdLine()
public void IndentLine_IndentAfterReturnValueStatementOnSecondLine_DecreasesIndentOnThirdLine()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\treturn 0\r\n" +
@ -98,173 +104,216 @@ namespace PythonBinding.Tests.Gui @@ -98,173 +104,216 @@ namespace PythonBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\treturn 0\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ReturnStatementDecreasesIndentOnThirdLine()
public void IndentLine_IndentAfterReturnStatementOnSecondLine_DecreasesIndentOnThirdLine()
{
textEditor.Text =
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\treturn\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\treturn\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ReturnStatementWithNoIndentOnPreviousLine()
public void IndentLine_ReturnStatementWithNoIndentPreviousLine_SecondLineIsNotIndented()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"return\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"return\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void StatementIsNotAReturnOnPreviousLine()
public void IndentLine_StatementIsNotReturnOnPreviousLineAndIsIndentedByOneTab_LineIsIndentedByOneTab()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"\treturnValue\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"\treturnValue\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void RaiseStatementWithObjectDecreasesIndentOnThirdLine()
public void IndentLine_RaiseStatementWithObjectOneSecondLine_DecreasesIndentOnThirdLineByOne()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\traise 'a'\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\traise 'a'\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void RaiseStatementDecreasesIndentOnThirdLine()
public void IndentLine_RaiseStatementOnSecondLine_IndentOnThirdLineIsDecreasedByOne()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\traise\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\traise\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void StatementIsNotARaiseStatementOnPreviousLine()
public void IndentLine_StatementIsNotRaiseStatementOnPreviousLine_LineIsIndentedToSameLevelAsPreviouisLine()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\traiseThis\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\traiseThis\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void BreakStatementDecreasesIndentOnThirdLine()
public void IndentLine_BreakStatementOnSecondLine_DecreasesIndentOnThirdLine()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\tbreak\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\tbreak\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void StatementIsNotABreakStatementOnPreviousLine()
public void IndentLine_StatementIsNotBreakStatementOnPreviousLine_LineIsIndentedToSameLevelAsPreviousLine()
{
CreatePythonFormattingStrategy();
textEditor.Text =
"def method1:\r\n" +
"\tbreakThis\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1:\r\n" +
"\tbreakThis\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void IndentingFirstLineDoesNotThrowArgumentOutOfRangeException()
public void IndentLine_LineNumberOutOfRange_DoesNotThrowArgumentOutOfRangeException()
{
CreatePythonFormattingStrategy();
textEditor.Text = "print 'hello'";
IDocumentLine line = textEditorAdapter.Document.GetLine(1);
Assert.DoesNotThrow(delegate {
formattingStrategy.IndentLine(textEditorAdapter, line); });
string text = textEditor.Text;
string expectedText = "print 'hello'";
Assert.AreEqual(expectedText, text);
}
[Test]
public void SurroundSelectionWithComment_CursorOnFirstLineAndNothingSelected_FirstLineIsCommented()
{
CreatePythonFormattingStrategy();
textEditor.Text = "print 'hello'";
formattingStrategy.SurroundSelectionWithComment(textEditorAdapter);
string text = textEditor.Text;
string expectedText = "#print 'hello'";
Assert.AreEqual("print 'hello'", textEditor.Text);
Assert.AreEqual(expectedText, text);
}
}
}

2
src/AddIns/BackendBindings/Python/PythonBinding/Test/PythonBinding.Tests.csproj

@ -315,7 +315,7 @@ @@ -315,7 +315,7 @@
<Compile Include="Gui\CompilingOptionsPanelTestFixture.cs" />
<Compile Include="Gui\DebugPythonCommandTests.cs" />
<Compile Include="Gui\FormsDesignerDisplayBindingTestFixture.cs" />
<Compile Include="Gui\PythonIndentationTests.cs" />
<Compile Include="Gui\PythonFormattingStrategyTests.cs" />
<Compile Include="Gui\PythonOptionsPanelTestFixture.cs" />
<Compile Include="Gui\RunPythonCommandTests.cs" />
<Compile Include="Parsing\ClassWithBaseClassTestFixture.cs" />

2
src/AddIns/BackendBindings/Ruby/RubyBinding.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.0.0.6676
# SharpDevelop 4.0.0.6737
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RubyBinding", "RubyBinding\Project\RubyBinding.csproj", "{C896FFFF-5B6C-4B0E-B6DF-049865F501B4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RubyBinding.Tests", "RubyBinding\Test\RubyBinding.Tests.csproj", "{01DF0475-0CB2-4E81-971B-BADC60CDE3A5}"

1
src/AddIns/BackendBindings/Ruby/RubyBinding/Project/RubyBinding.csproj

@ -111,6 +111,7 @@ @@ -111,6 +111,7 @@
<Compile Include="Src\RubyFormattingStrategy.cs" />
<Compile Include="Src\RubyFormsDesignerDisplayBinding.cs" />
<Compile Include="Src\RubyLanguageBinding.cs" />
<Compile Include="Src\RubyLineIndenter.cs" />
<Compile Include="Src\RubyProjectBinding.cs" />
<Compile Include="Src\RubyLanguageProperties.cs" />
<Compile Include="Src\RubyOptionsPanel.cs" />

194
src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyFormattingStrategy.cs

@ -2,202 +2,20 @@ @@ -2,202 +2,20 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.Text;
using ICSharpCode.Scripting;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.RubyBinding
{
public class RubyFormattingStrategy : DefaultFormattingStrategy
public class RubyFormattingStrategy : ScriptingFormattingStrategy
{
ITextEditor textEditor;
IDocumentLine currentLine;
IDocumentLine previousLine;
string previousLineTextTrimmed;
List<string> decreaseLineIndentStatements = new List<string>();
List<string> decreaseLineIndentStartsWithStatements = new List<string>();
List<string> increaseLineIndentStatements = new List<string>();
List<string> increaseLineIndentStartsWithStatements = new List<string>();
List<string> increaseLineIndentEndsWithStatements = new List<string>();
List<string> increaseLineIndentContainsStatements = new List<string>();
public RubyFormattingStrategy()
{
CreateDecreaseLineIndentStatements();
CreateDecreaseLineIndentStartsWithStatements();
CreateIncreaseLineIndentStatements();
CreateIncreaseLineIndentStartsWithStatements();
CreateIncreaseLineIndentEndsWithStatements();
CreateIncreaseLineIndentContainsStatements();
}
void CreateDecreaseLineIndentStatements()
{
decreaseLineIndentStatements.Add("break");
decreaseLineIndentStatements.Add("return");
decreaseLineIndentStatements.Add("raise");
}
void CreateDecreaseLineIndentStartsWithStatements()
{
decreaseLineIndentStartsWithStatements.Add("return ");
decreaseLineIndentStartsWithStatements.Add("raise ");
}
void CreateIncreaseLineIndentStatements()
{
increaseLineIndentStatements.Add("else");
increaseLineIndentStatements.Add("begin");
increaseLineIndentStatements.Add("rescue");
increaseLineIndentStatements.Add("ensure");
}
void CreateIncreaseLineIndentStartsWithStatements()
{
increaseLineIndentStartsWithStatements.Add("if ");
increaseLineIndentStartsWithStatements.Add("def ");
increaseLineIndentStartsWithStatements.Add("class ");
increaseLineIndentStartsWithStatements.Add("while ");
increaseLineIndentStartsWithStatements.Add("elsif ");
increaseLineIndentStartsWithStatements.Add("loop ");
increaseLineIndentStartsWithStatements.Add("unless ");
increaseLineIndentStartsWithStatements.Add("until ");
increaseLineIndentStartsWithStatements.Add("for ");
increaseLineIndentStartsWithStatements.Add("rescue ");
increaseLineIndentStartsWithStatements.Add("module ");
increaseLineIndentStartsWithStatements.Add("when ");
increaseLineIndentStartsWithStatements.Add("case ");
}
void CreateIncreaseLineIndentEndsWithStatements()
{
increaseLineIndentEndsWithStatements.Add(" then");
increaseLineIndentEndsWithStatements.Add(" do");
increaseLineIndentEndsWithStatements.Add(" {");
}
void CreateIncreaseLineIndentContainsStatements()
{
increaseLineIndentContainsStatements.Add(" case ");
}
public override void IndentLine(ITextEditor editor, IDocumentLine line)
{
this.textEditor = editor;
this.currentLine = line;
GetPreviousLineText();
if (ShouldDecreaseLineIndent()) {
DecreaseLineIndent();
} else if (ShouldIncreaseLineIndent()) {
IncreaseLineIndent();
} else {
base.IndentLine(editor, line);
}
}
void GetPreviousLineText()
{
previousLine = textEditor.Document.GetLine(currentLine.LineNumber - 1);
previousLineTextTrimmed = previousLine.Text.Trim();
}
bool ShouldIncreaseLineIndent()
{
if (increaseLineIndentStatements.Contains(previousLineTextTrimmed)) {
return true;
}
if (PreviousLineStartsWith(increaseLineIndentStartsWithStatements)) {
return true;
}
if (PreviousLineContains(increaseLineIndentContainsStatements)) {
return true;
}
return PreviousLineEndsWith(increaseLineIndentEndsWithStatements);
}
bool ShouldDecreaseLineIndent()
{
if (decreaseLineIndentStatements.Contains(previousLineTextTrimmed)) {
return true;
}
return PreviousLineStartsWith(decreaseLineIndentStartsWithStatements);
}
bool PreviousLineStartsWith(List<string> items)
{
foreach (string item in items) {
if (previousLineTextTrimmed.StartsWith(item)) {
return true;
}
}
return false;
}
bool PreviousLineEndsWith(List<string> items)
{
foreach (string item in items) {
if (previousLineTextTrimmed.EndsWith(item)) {
return true;
}
}
return false;
}
bool PreviousLineContains(List<string> items)
{
foreach (string item in items) {
if (previousLineTextTrimmed.Contains(item)) {
return true;
}
}
return false;
}
void IncreaseLineIndent()
{
ModifyLineIndent(true);
}
void DecreaseLineIndent()
{
ModifyLineIndent(false);
}
void ModifyLineIndent(bool increaseIndent)
{
string indentation = GetPreviousLineIndentation();
indentation = GetNewLineIndentation(indentation, textEditor.Options.IndentationString, increaseIndent);
string newIndentedText = indentation + currentLine.Text;
textEditor.Document.Replace(currentLine.Offset, currentLine.Length, newIndentedText);
}
string GetPreviousLineIndentation()
{
StringBuilder whitespace = new StringBuilder();
foreach (char ch in previousLine.Text) {
if (Char.IsWhiteSpace(ch)) {
whitespace.Append(ch);
} else {
break;
}
}
return whitespace.ToString();
public override string LineComment {
get { return "#"; }
}
string GetNewLineIndentation(string previousLineIndentation, string singleIndent, bool increaseIndent)
protected override LineIndenter CreateLineIndenter(ITextEditor editor, IDocumentLine line)
{
if (increaseIndent) {
return previousLineIndentation + singleIndent;
}
// Decrease the new line indentation.
int decreaselength = previousLineIndentation.Length - singleIndent.Length;
if (decreaselength < 0) {
decreaselength = 0;
}
return previousLineIndentation.Substring(0, decreaselength);
return new RubyLineIndenter(editor, line);
}
}
}

134
src/AddIns/BackendBindings/Ruby/RubyBinding/Project/Src/RubyLineIndenter.cs

@ -0,0 +1,134 @@ @@ -0,0 +1,134 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using ICSharpCode.Scripting;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.RubyBinding
{
public class RubyLineIndenter : LineIndenter
{
List<string> decreaseLineIndentStatements = new List<string>();
List<string> decreaseLineIndentStartsWithStatements = new List<string>();
List<string> increaseLineIndentStatements = new List<string>();
List<string> increaseLineIndentStartsWithStatements = new List<string>();
List<string> increaseLineIndentEndsWithStatements = new List<string>();
List<string> increaseLineIndentContainsStatements = new List<string>();
public RubyLineIndenter(ITextEditor editor, IDocumentLine line)
: base(editor, line)
{
CreateDecreaseLineIndentStatements();
CreateDecreaseLineIndentStartsWithStatements();
CreateIncreaseLineIndentStatements();
CreateIncreaseLineIndentStartsWithStatements();
CreateIncreaseLineIndentEndsWithStatements();
CreateIncreaseLineIndentContainsStatements();
}
void CreateDecreaseLineIndentStatements()
{
decreaseLineIndentStatements.Add("break");
decreaseLineIndentStatements.Add("return");
decreaseLineIndentStatements.Add("raise");
}
void CreateDecreaseLineIndentStartsWithStatements()
{
decreaseLineIndentStartsWithStatements.Add("return ");
decreaseLineIndentStartsWithStatements.Add("raise ");
}
void CreateIncreaseLineIndentStatements()
{
increaseLineIndentStatements.Add("else");
increaseLineIndentStatements.Add("begin");
increaseLineIndentStatements.Add("rescue");
increaseLineIndentStatements.Add("ensure");
}
void CreateIncreaseLineIndentStartsWithStatements()
{
increaseLineIndentStartsWithStatements.Add("if ");
increaseLineIndentStartsWithStatements.Add("def ");
increaseLineIndentStartsWithStatements.Add("class ");
increaseLineIndentStartsWithStatements.Add("while ");
increaseLineIndentStartsWithStatements.Add("elsif ");
increaseLineIndentStartsWithStatements.Add("loop ");
increaseLineIndentStartsWithStatements.Add("unless ");
increaseLineIndentStartsWithStatements.Add("until ");
increaseLineIndentStartsWithStatements.Add("for ");
increaseLineIndentStartsWithStatements.Add("rescue ");
increaseLineIndentStartsWithStatements.Add("module ");
increaseLineIndentStartsWithStatements.Add("when ");
increaseLineIndentStartsWithStatements.Add("case ");
}
void CreateIncreaseLineIndentEndsWithStatements()
{
increaseLineIndentEndsWithStatements.Add(" then");
increaseLineIndentEndsWithStatements.Add(" do");
increaseLineIndentEndsWithStatements.Add(" {");
}
void CreateIncreaseLineIndentContainsStatements()
{
increaseLineIndentContainsStatements.Add(" case ");
}
protected override bool ShouldIncreaseLineIndent()
{
if (increaseLineIndentStatements.Contains(PreviousLine)) {
return true;
}
if (PreviousLineStartsWith(increaseLineIndentStartsWithStatements)) {
return true;
}
if (PreviousLineContains(increaseLineIndentContainsStatements)) {
return true;
}
return PreviousLineEndsWith(increaseLineIndentEndsWithStatements);
}
protected override bool ShouldDecreaseLineIndent()
{
if (decreaseLineIndentStatements.Contains(PreviousLine)) {
return true;
}
return PreviousLineStartsWith(decreaseLineIndentStartsWithStatements);
}
bool PreviousLineStartsWith(List<string> items)
{
foreach (string item in items) {
if (PreviousLine.StartsWith(item)) {
return true;
}
}
return false;
}
bool PreviousLineEndsWith(List<string> items)
{
foreach (string item in items) {
if (PreviousLine.EndsWith(item)) {
return true;
}
}
return false;
}
bool PreviousLineContains(List<string> items)
{
foreach (string item in items) {
if (PreviousLine.Contains(item)) {
return true;
}
}
return false;
}
}
}

242
src/AddIns/BackendBindings/Ruby/RubyBinding/Test/Gui/RubyIndentationTests.cs → src/AddIns/BackendBindings/Ruby/RubyBinding/Test/Gui/RubyFormattingStrategyTests.cs

@ -13,18 +13,14 @@ using RubyBinding.Tests.Utils; @@ -13,18 +13,14 @@ using RubyBinding.Tests.Utils;
namespace RubyBinding.Tests.Gui
{
/// <summary>
/// Tests that the RubyFormattingStrategy indents the new line added after method and class definitions.
/// </summary>
[TestFixture]
public class RubyNewMethodIndentationTestFixture
public class RubyFormattingStrategyTests
{
TextEditor textEditor;
RubyFormattingStrategy formattingStrategy;
AvalonEditTextEditorAdapter textEditorAdapter;
[SetUp]
public void Init()
void CreateFormattingStrategy()
{
MockTextEditorOptions textEditorOptions = new MockTextEditorOptions();
textEditorOptions.IndentationSize = 4;
@ -37,76 +33,90 @@ namespace RubyBinding.Tests.Gui @@ -37,76 +33,90 @@ namespace RubyBinding.Tests.Gui
}
[Test]
public void NewMethodDefinition()
public void IndentLine_NewMethodDefinitionOnPreviousLine_NextLineIsIndented()
{
CreateFormattingStrategy();
textEditor.Text =
"def newMethod\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def newMethod\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void NewMethodDefinitionWithBrackets()
public void IndentLine_NewMethodDefinitionWithBracketsOnPreviousLine_NextLineIsIndented()
{
CreateFormattingStrategy();
textEditor.Text =
"def newMethod()\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def newMethod()\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void NewClassDefinition()
public void IndentLine_NewClassDefinitionOnPreviousLine_NextLineIsIndented()
{
CreateFormattingStrategy();
textEditor.Text =
"class MyClass\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"class MyClass\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void NoExtraIndentationRequired()
public void IndentLine_PrintStatementOnPreviousLineSoNoExtraIndentationRequired_NextLineIndentedToSameLevelAsPreviousLine()
{
CreateFormattingStrategy();
textEditor.Text =
"\tprint 'abc'\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"\tprint 'abc'\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ReturnValueStatementDecreasesIndentOnThirdLine()
public void IndentLine_ReturnValueStatementOnPreviousLine_DecreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"def method1\r\n" +
"\treturn 0\r\n" +
@ -114,18 +124,21 @@ namespace RubyBinding.Tests.Gui @@ -114,18 +124,21 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1\r\n" +
"\treturn 0\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ReturnStatementDecreasesIndentOnThirdLine()
public void IndentLine_ReturnStatementOnPreviousLine_DecreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"def method1\r\n" +
"\treturn\r\n" +
@ -133,51 +146,61 @@ namespace RubyBinding.Tests.Gui @@ -133,51 +146,61 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1\r\n" +
"\treturn\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
}
Assert.AreEqual(expectedText, text);
}
[Test]
public void ReturnStatementWithNoIndentOnPreviousLine()
public void IndentLine_ReturnStatementOnPreviousLineWithNoIndentOnPreviousLine_NextLineIsNotIndented()
{
CreateFormattingStrategy();
textEditor.Text =
"return\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"return\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void StatementIsNotAReturnOnPreviousLine()
public void IndentLine_StatementIsNotReturnOnPreviousLine_NextLineIndentedToSameLevelAsPreviousLine()
{
CreateFormattingStrategy();
textEditor.Text =
"\treturnValue\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"\treturnValue\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void RaiseStatementWithObjectDecreasesIndentOnThirdLine()
public void IndentLine_RaiseStatementWithObjectOnPreviousLine_DecreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"def method1\r\n" +
"\traise 'a'\r\n" +
@ -185,18 +208,21 @@ namespace RubyBinding.Tests.Gui @@ -185,18 +208,21 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1\r\n" +
"\traise 'a'\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void RaiseStatementDecreasesIndentOnThirdLine()
public void IndentLine_RaiseStatementOnPreviousLine_DecreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"def method1\r\n" +
"\traise\r\n" +
@ -204,18 +230,21 @@ namespace RubyBinding.Tests.Gui @@ -204,18 +230,21 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1\r\n" +
"\traise\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void StatementIsNotARaiseStatementOnPreviousLine()
public void IndentLine_StatementIsNotRaiseStatementOnPreviousLine_NextLineIsIndentedToSameLevelAsPreviousLine()
{
CreateFormattingStrategy();
textEditor.Text =
"def method1\r\n" +
"\traiseThis\r\n" +
@ -223,18 +252,21 @@ namespace RubyBinding.Tests.Gui @@ -223,18 +252,21 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1\r\n" +
"\traiseThis\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void BreakStatementDecreasesIndentOnThirdLine()
public void IndentLine_BreakStatementOnPreviousLine_DecreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"def method1\r\n" +
"\tbreak\r\n" +
@ -242,18 +274,21 @@ namespace RubyBinding.Tests.Gui @@ -242,18 +274,21 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1\r\n" +
"\tbreak\r\n" +
"";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void StatementIsNotABreakStatementOnPreviousLine()
public void IndentLine_StatementIsNotBreakStatementOnPreviousLine_LineIsIndentedToSameLevelAsPreviousLine()
{
CreateFormattingStrategy();
textEditor.Text =
"def method1\r\n" +
"\tbreakThis\r\n" +
@ -261,273 +296,321 @@ namespace RubyBinding.Tests.Gui @@ -261,273 +296,321 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"def method1\r\n" +
"\tbreakThis\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void IfThenStatementIncreasesIndentOnNextLine()
public void IndentLine_IfThenStatementOnPreviousLine_IndentIncreasedOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"if i > 0 then\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"if i > 0 then\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void IfStatementIncreasesIndentOnNextLine()
public void IndentLine_IfStatementOnPreviousLine_IndentIncreasedOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"if i > 0\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"if i > 0\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ElseStatementIncreasesIndentOnNextLine()
public void IndentLine_ElseStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"else\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"else\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ElseIfStatementIncreasesIndentOnNextLine()
public void IndentLine_ElseIfStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"elsif i > 0\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"elsif i > 0\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void LoopStatementIncreasesIndentOnNextLine()
public void IndentLine_LoopStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"loop do\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"loop do\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void UnlessStatementIncreasesIndentOnNextLine()
public void IndentLine_UnlessStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"unless i > 0\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"unless i > 0\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void UntilStatementIncreasesIndentOnNextLine()
public void IndentLine_UntilStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"until i > 0\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"until i > 0\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ForStatementIncreasesIndentOnNextLine()
public void IndentLine_ForStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"for i in 1..5\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"for i in 1..5\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void DoStatementAtEndOfLineIncreasesIndentOnNextLine()
public void IndentLine_DoStatementAtEndOfPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"expr do\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"expr do\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void OpenCurlyBraceAtEndOfLineIncreasesIndentOnNextLine()
public void IndentLine_OpenCurlyBraceAtEndOfPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"expr {\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"expr {\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void BeginStatementIncreasesIndentOnNextLine()
public void IndentLine_BeginStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"begin\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"begin\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void RescueStatementWithExceptionIncreasesIndentOnNextLine()
public void IndentLine_RescueStatementWithExceptionOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"rescue Exception => ex\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"rescue Exception => ex\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void RescueStatementIncreasesIndentOnNextLine()
public void IndentLine_RescueStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"rescue\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"rescue\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void EnsureStatementIncreasesIndentOnNextLine()
public void IndentLine_EnsureStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"ensure\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"ensure\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void ModuleStatementIncreasesIndentOnNextLine()
public void IndentLine_ModuleStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"module Foo\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"module Foo\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void CaseWhenStatementIncreasesIndentOnNextLine()
public void IndentLine_CaseWhenStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"case num\r\n" +
"\twhen 0\r\n" +
@ -535,47 +618,68 @@ namespace RubyBinding.Tests.Gui @@ -535,47 +618,68 @@ namespace RubyBinding.Tests.Gui
IDocumentLine line = textEditorAdapter.Document.GetLine(3);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"case num\r\n" +
"\twhen 0\r\n" +
"\t\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void CaseStatementIncreasesIndentOnNextLine()
public void IndentLine_CaseStatementOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"case num\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"case num\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void CaseStatementInMiddleOfLineIncreasesIndentOnNextLine()
public void IndentLine_CaseStatementInMiddleOnPreviousLine_IncreasesIndentOnNextLine()
{
CreateFormattingStrategy();
textEditor.Text =
"value = case num\r\n" +
"";
IDocumentLine line = textEditorAdapter.Document.GetLine(2);
formattingStrategy.IndentLine(textEditorAdapter, line);
string text = textEditor.Text;
string expectedText =
"value = case num\r\n" +
"\t";
Assert.AreEqual(expectedText, textEditor.Text);
Assert.AreEqual(expectedText, text);
}
[Test]
public void SurroundSelectionWithComment_CursorOnFirstLineNothingSelected_CommentsFirstLine()
{
CreateFormattingStrategy();
textEditor.Text = "print 'hello'";
formattingStrategy.SurroundSelectionWithComment(textEditorAdapter);
string text = textEditor.Text;
string expectedText = "#print 'hello'";
Assert.AreEqual(expectedText, text);
}
}
}

2
src/AddIns/BackendBindings/Ruby/RubyBinding/Test/RubyBinding.Tests.csproj

@ -267,7 +267,7 @@ @@ -267,7 +267,7 @@
<Compile Include="Designer\TextBoxNotAddedToFormTestFixture.cs" />
<Compile Include="Designer\UnknownTypeTestFixture.cs" />
<Compile Include="Gui\DebugRunRubyCommandTests.cs" />
<Compile Include="Gui\RubyIndentationTests.cs" />
<Compile Include="Gui\RubyFormattingStrategyTests.cs" />
<Compile Include="Gui\RubyOptionsPanelTestFixture.cs" />
<Compile Include="Gui\RunRubyCommandTests.cs" />
<Compile Include="Parsing\ParseClassWithBaseClassTestFixture.cs" />

2
src/AddIns/BackendBindings/Scripting/Project/ICSharpCode.Scripting.csproj

@ -80,6 +80,7 @@ @@ -80,6 +80,7 @@
<Compile Include="Src\IScriptingDesignerGenerator.cs" />
<Compile Include="Src\IScriptingFileService.cs" />
<Compile Include="Src\IScriptingWorkbench.cs" />
<Compile Include="Src\LineIndenter.cs" />
<Compile Include="Src\PauseCommandPromptProcessStartInfo.cs" />
<Compile Include="Src\RunScriptingConsoleApplicationCommand.cs" />
<Compile Include="Src\ScriptingCodeBuilder.cs" />
@ -96,6 +97,7 @@ @@ -96,6 +97,7 @@
<Compile Include="Src\ScriptingDesignerGenerator.cs" />
<Compile Include="Src\ScriptingDesignerLoader.cs" />
<Compile Include="Src\ScriptingFileService.cs" />
<Compile Include="Src\ScriptingFormattingStrategy.cs" />
<Compile Include="Src\ScriptingLocalMethod.cs" />
<Compile Include="Src\ScriptingNameCreationService.cs" />
<Compile Include="Src\ScriptingStyle.cs" />

125
src/AddIns/BackendBindings/Scripting/Project/Src/LineIndenter.cs

@ -0,0 +1,125 @@ @@ -0,0 +1,125 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Text;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.Scripting
{
public class LineIndenter
{
ITextEditor editor;
IDocument document;
IDocumentLine line;
IDocumentLine previousLine;
string previousLineText;
public LineIndenter(ITextEditor editor, IDocumentLine line)
{
this.editor = editor;
this.line = line;
this.document = editor.Document;
}
public bool Indent()
{
if (IsFirstLine()) {
return false;
}
GetPreviousLine();
if (ShouldIncreaseLineIndent()) {
IncreaseLineIndent();
return true;
} else if (ShouldDecreaseLineIndent()) {
DecreaseLineIndent();
return true;
}
return false;
}
bool IsFirstLine()
{
return line.LineNumber == 1;
}
void GetPreviousLine()
{
int lineNumber = line.LineNumber - 1;
previousLine = document.GetLine(lineNumber);
previousLineText = previousLine.Text.Trim();
}
protected string PreviousLine {
get { return previousLineText; }
}
protected virtual bool ShouldIncreaseLineIndent()
{
return false;
}
protected virtual bool ShouldDecreaseLineIndent()
{
return false;
}
void IncreaseLineIndent()
{
ModifyLineIndent(true);
}
void DecreaseLineIndent()
{
ModifyLineIndent(false);
}
void ModifyLineIndent(bool increaseIndent)
{
string previousLineIndentation = GetPreviousLineIndentation();
string indentation = GetNewLineIndentation(previousLineIndentation, increaseIndent);
string newLineText = indentation + line.Text;
ReplaceLine(newLineText);
}
string GetPreviousLineIndentation()
{
return GetIndentation(previousLine);
}
string GetIndentation(IDocumentLine documentLine)
{
StringBuilder whitespace = new StringBuilder();
foreach (char ch in documentLine.Text) {
if (Char.IsWhiteSpace(ch)) {
whitespace.Append(ch);
} else {
break;
}
}
return whitespace.ToString();
}
string GetNewLineIndentation(string previousLineIndentation, bool increaseIndent)
{
string singleIndent = editor.Options.IndentationString;
if (increaseIndent) {
return previousLineIndentation + singleIndent;
}
// Decrease the new line indentation.
int decreaselength = previousLineIndentation.Length - singleIndent.Length;
if (decreaselength < 0) {
decreaselength = 0;
}
return previousLineIndentation.Substring(0, decreaselength);
}
void ReplaceLine(string newLineText)
{
document.Replace(line.Offset, line.Length, newLineText);
}
}
}

30
src/AddIns/BackendBindings/Scripting/Project/Src/ScriptingFormattingStrategy.cs

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.SharpDevelop.Editor;
namespace ICSharpCode.Scripting
{
public abstract class ScriptingFormattingStrategy : DefaultFormattingStrategy
{
public override void IndentLine(ITextEditor editor, IDocumentLine line)
{
LineIndenter indenter = CreateLineIndenter(editor, line);
if (!indenter.Indent()) {
base.IndentLine(editor, line);
}
}
protected abstract LineIndenter CreateLineIndenter(ITextEditor editor, IDocumentLine line);
public override void SurroundSelectionWithComment(ITextEditor editor)
{
SurroundSelectionWithSingleLineComment(editor, LineComment);
}
public virtual string LineComment {
get { return String.Empty; }
}
}
}
Loading…
Cancel
Save