Browse Source

Merge pull request #345 from RKlier/folding

Adapt folding commands from SharpDevelop (Fix #336)
pull/348/merge
Daniel Grunwald 13 years ago
parent
commit
62930f70ff
  1. 2
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 6
      ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs
  3. 12
      ICSharpCode.Decompiler/DecompilerSettings.cs
  4. 12
      ILSpy/ContextMenuEntry.cs
  5. 1
      ILSpy/ILSpy.csproj
  6. 1
      ILSpy/Options/DecompilerSettingsPanel.xaml
  7. 2
      ILSpy/Options/DecompilerSettingsPanel.xaml.cs
  8. 16
      ILSpy/TextView/DecompilerTextView.cs
  9. 90
      ILSpy/TextView/FoldingCommands.cs

2
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -160,7 +160,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -160,7 +160,7 @@ namespace ICSharpCode.Decompiler.Ast
RunTransformations();
astCompileUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
var outputFormatter = new TextOutputFormatter(output);
var outputFormatter = new TextOutputFormatter(output) { FoldBraces = context.Settings.FoldBraces };
var formattingPolicy = context.Settings.CSharpFormattingOptions;
astCompileUnit.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, formattingPolicy));
}

6
ICSharpCode.Decompiler/Ast/TextOutputFormatter.cs

@ -36,6 +36,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -36,6 +36,8 @@ namespace ICSharpCode.Decompiler.Ast
bool firstUsingDeclaration;
bool lastUsingDeclaration;
public bool FoldBraces = false;
public TextOutputFormatter(ITextOutput output)
{
if (output == null)
@ -183,7 +185,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -183,7 +185,7 @@ namespace ICSharpCode.Decompiler.Ast
{
if (braceLevelWithinType >= 0 || nodeStack.Peek() is TypeDeclaration)
braceLevelWithinType++;
if (nodeStack.OfType<BlockStatement>().Count() <= 1) {
if (nodeStack.OfType<BlockStatement>().Count() <= 1 || FoldBraces) {
output.MarkFoldStart(defaultCollapsed: braceLevelWithinType == 1);
}
output.WriteLine();
@ -195,7 +197,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -195,7 +197,7 @@ namespace ICSharpCode.Decompiler.Ast
{
output.Unindent();
output.Write('}');
if (nodeStack.OfType<BlockStatement>().Count() <= 1)
if (nodeStack.OfType<BlockStatement>().Count() <= 1 || FoldBraces)
output.MarkFoldEnd();
if (braceLevelWithinType >= 0)
braceLevelWithinType--;

12
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -254,6 +254,18 @@ namespace ICSharpCode.Decompiler @@ -254,6 +254,18 @@ namespace ICSharpCode.Decompiler
}
}
}
bool foldBraces = false;
public bool FoldBraces {
get { return foldBraces; }
set {
if (foldBraces != value) {
foldBraces = value;
OnPropertyChanged("FoldBraces");
}
}
}
#region Options to aid VB decompilation
bool introduceIncrementAndDecrement = true;

12
ILSpy/ContextMenuEntry.cs

@ -21,6 +21,8 @@ using System.ComponentModel.Composition; @@ -21,6 +21,8 @@ using System.ComponentModel.Composition;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.AvalonEdit;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.TreeView;
@ -59,15 +61,23 @@ namespace ICSharpCode.ILSpy @@ -59,15 +61,23 @@ namespace ICSharpCode.ILSpy
/// </summary>
public ReferenceSegment Reference { get; private set; }
/// <summary>
/// Returns the position in TextView the mouse cursor is currently hovering above.
/// Returns null, if TextView returns null;
/// </summary>
public TextViewPosition? Position { get; private set; }
public static TextViewContext Create(SharpTreeView treeView = null, DecompilerTextView textView = null)
{
var reference = textView != null ? textView.GetReferenceSegmentAtMousePosition() : null;
var position = textView != null ? textView.GetPositionFromMousePosition() : null;
var selectedTreeNodes = treeView != null ? treeView.GetTopLevelSelection().ToArray() : null;
return new TextViewContext {
TreeView = treeView,
SelectedTreeNodes = selectedTreeNodes,
TextView = textView,
Reference = reference
Reference = reference,
Position = position
};
}
}

1
ILSpy/ILSpy.csproj

@ -177,6 +177,7 @@ @@ -177,6 +177,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Commands\SimpleCommand.cs" />
<Compile Include="TextView\FoldingCommands.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzeContextMenuEntry.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedAssemblyTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedAttributeAppliedToTreeNode.cs" />

1
ILSpy/Options/DecompilerSettingsPanel.xaml

@ -9,5 +9,6 @@ @@ -9,5 +9,6 @@
<CheckBox IsChecked="{Binding QueryExpressions}" IsEnabled="{Binding AnonymousMethods}">Decompile query expressions</CheckBox>
<CheckBox IsChecked="{Binding UseDebugSymbols}">Use variable names from debug symbols, if available</CheckBox>
<CheckBox IsChecked="{Binding ShowXmlDocumentation}">Show XML documentation in decompiled code</CheckBox>
<CheckBox IsChecked="{Binding FoldBraces}">Enable folding on all blocks in braces</CheckBox>
</StackPanel>
</UserControl>

2
ILSpy/Options/DecompilerSettingsPanel.xaml.cs

@ -57,6 +57,7 @@ namespace ICSharpCode.ILSpy.Options @@ -57,6 +57,7 @@ namespace ICSharpCode.ILSpy.Options
s.QueryExpressions = (bool?)e.Attribute("queryExpressions") ?? s.QueryExpressions;
s.UseDebugSymbols = (bool?)e.Attribute("useDebugSymbols") ?? s.UseDebugSymbols;
s.ShowXmlDocumentation = (bool?)e.Attribute("xmlDoc") ?? s.ShowXmlDocumentation;
s.FoldBraces = (bool?)e.Attribute("foldBraces") ?? s.FoldBraces;
return s;
}
@ -70,6 +71,7 @@ namespace ICSharpCode.ILSpy.Options @@ -70,6 +71,7 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("queryExpressions", s.QueryExpressions);
section.SetAttributeValue("useDebugSymbols", s.UseDebugSymbols);
section.SetAttributeValue("xmlDoc", s.ShowXmlDocumentation);
section.SetAttributeValue("foldBraces", s.FoldBraces);
XElement existingElement = root.Element("DecompilerSettings");
if (existingElement != null)

16
ILSpy/TextView/DecompilerTextView.cs

@ -763,13 +763,18 @@ namespace ICSharpCode.ILSpy.TextView @@ -763,13 +763,18 @@ namespace ICSharpCode.ILSpy.TextView
internal ReferenceSegment GetReferenceSegmentAtMousePosition()
{
TextViewPosition? position = textEditor.TextArea.TextView.GetPosition(Mouse.GetPosition(textEditor.TextArea.TextView) + textEditor.TextArea.TextView.ScrollOffset);
TextViewPosition? position = GetPositionFromMousePosition();
if (position == null)
return null;
int offset = textEditor.Document.GetOffset(position.Value.Location);
return referenceElementGenerator.References.FindSegmentsContaining(offset).FirstOrDefault();
}
internal TextViewPosition? GetPositionFromMousePosition()
{
return textEditor.TextArea.TextView.GetPosition(Mouse.GetPosition(textEditor.TextArea.TextView) + textEditor.TextArea.TextView.ScrollOffset);
}
public DecompilerTextViewState GetState()
{
if (decompiledNodes == null)
@ -809,6 +814,13 @@ namespace ICSharpCode.ILSpy.TextView @@ -809,6 +814,13 @@ namespace ICSharpCode.ILSpy.TextView
// scroll to
textEditor.ScrollTo(lineNumber, 0);
}
public FoldingManager FoldingManager
{
get {
return foldingManager;
}
}
#endregion
}

90
ILSpy/TextView/FoldingCommands.cs

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
/*
* Created by SharpDevelop.
* User: Ronny Klier
* Date: 24.05.2012
* Time: 23:44
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.AvalonEdit;
using ICSharpCode.AvalonEdit.Folding;
namespace ICSharpCode.ILSpy.TextView
{
[ExportContextMenuEntryAttribute(Header = "Toggle All Folding", Category = "Folding")]
internal sealed class ToggleAllContextMenuEntry : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)
{
return context.TextView != null;
}
public bool IsEnabled(TextViewContext context)
{
return context.TextView != null && context.TextView.FoldingManager != null;
}
public void Execute(TextViewContext context)
{
if (null == context.TextView)
return;
FoldingManager foldingManager = context.TextView.FoldingManager;
if (null == foldingManager)
return;
bool doFold = true;
foreach (FoldingSection fm in foldingManager.AllFoldings) {
if (fm.IsFolded) {
doFold = false;
break;
}
}
foreach (FoldingSection fm in foldingManager.AllFoldings) {
fm.IsFolded = doFold;
}
}
}
[ExportContextMenuEntryAttribute(Header = "Toggle Folding", Category = "Folding")]
internal sealed class ToggleContextMenuEntry : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)
{
return context.TextView != null;
}
public bool IsEnabled(TextViewContext context)
{
return context.TextView != null && context.TextView.FoldingManager != null;
}
public void Execute(TextViewContext context)
{
var textView = context.TextView;
if (null == textView)
return;
var editor = textView.textEditor;
FoldingManager foldingManager = context.TextView.FoldingManager;
if (null == foldingManager)
return;
// TODO: or use Caret if position is not given?
var posBox = context.Position;
if (null == posBox)
return;
TextViewPosition pos = posBox.Value;
// look for folding on this line:
FoldingSection folding = foldingManager.GetNextFolding(editor.Document.GetOffset(pos.Line, 1));
if (folding == null || editor.Document.GetLineByOffset(folding.StartOffset).LineNumber != pos.Line) {
// no folding found on current line: find innermost folding containing the mouse position
folding = foldingManager.GetFoldingsContaining(editor.Document.GetOffset(pos.Line, pos.Column)).LastOrDefault();
}
if (folding != null) {
folding.IsFolded = !folding.IsFolded;
}
}
}
}
Loading…
Cancel
Save