From 721f543d99115e400f5dddbfa527110cd19f1511 Mon Sep 17 00:00:00 2001 From: iAmAsval Date: Sun, 27 Jun 2021 02:37:58 +0200 Subject: [PATCH] kinda useful folding shortcuts --- .../Controls/Aed/BraceFoldingStrategy.cs | 140 ++++++++---------- .../Resources/Controls/PropertiesPopout.xaml | 2 +- .../Controls/PropertiesPopout.xaml.cs | 16 ++ 3 files changed, 78 insertions(+), 80 deletions(-) diff --git a/FModel/Views/Resources/Controls/Aed/BraceFoldingStrategy.cs b/FModel/Views/Resources/Controls/Aed/BraceFoldingStrategy.cs index 033970db..54d72e17 100644 --- a/FModel/Views/Resources/Controls/Aed/BraceFoldingStrategy.cs +++ b/FModel/Views/Resources/Controls/Aed/BraceFoldingStrategy.cs @@ -5,60 +5,23 @@ using ICSharpCode.AvalonEdit.Folding; namespace FModel.Views.Resources.Controls { - /// - /// https://github.com/JTranOrg/JTranEdit/blob/master/JTranEdit/Classes/BraceFoldingStrategy.cs - /// - public interface IFoldingStrategy + public class JsonFoldingStrategies { - IEnumerable UpdateFoldings(TextDocument document); - void CollapseAll(); - void ExpandAll(); - } - - public class JsonFoldingStrategies : IFoldingStrategy - { - private readonly List _strategies = new(); + private readonly BraceFoldingStrategy _strategy; private readonly FoldingManager _foldingManager; - private readonly IComparer _comparer = new FoldingComparer(); public JsonFoldingStrategies(TextEditor avalonEditor) { _foldingManager = FoldingManager.Install(avalonEditor.TextArea); - _strategies.Add(new BraceFoldingStrategy(avalonEditor, '{', '}')); - _strategies.Add(new BraceFoldingStrategy(avalonEditor, '[', ']')); + _strategy = new BraceFoldingStrategy(avalonEditor); } - public IEnumerable UpdateFoldings(TextDocument document) + public void UpdateFoldings(TextDocument document) { - var foldings = new List(); - foreach (var strategy in _strategies) - { - foldings.AddRange(strategy.UpdateFoldings(document)); - } - - foldings.Sort(_comparer); - _foldingManager.UpdateFoldings(foldings, -1); - - return foldings; + _foldingManager.UpdateFoldings(_strategy.UpdateFoldings(document), -1); } - public void CollapseAll() - { - if (_foldingManager.AllFoldings == null) - return; - - foreach (var folding in _foldingManager.AllFoldings) - { - folding.IsFolded = true; - } - - // Unfold the first fold (if any) to give a useful overview on content - var foldSection = _foldingManager.GetNextFolding(0); - if (foldSection != null) - foldSection.IsFolded = false; - } - - public void ExpandAll() + public void UnfoldAll() { if (_foldingManager.AllFoldings == null) return; @@ -68,72 +31,91 @@ namespace FModel.Views.Resources.Controls folding.IsFolded = false; } } - - private class FoldingComparer : IComparer + + public void FoldToggle(int offset) { - public int Compare(NewFolding x, NewFolding y) + if (_foldingManager.AllFoldings == null) + return; + + var foldSection = _foldingManager.GetFoldingsContaining(offset); + if (foldSection.Count > 0) + foldSection[^1].IsFolded = !foldSection[^1].IsFolded; + } + + public void FoldAtLevel(int level = 0) + { + if (_foldingManager.AllFoldings == null) + return; + + foreach (var folding in _foldingManager.AllFoldings) { - return x.StartOffset.CompareTo(y.StartOffset); + if (folding.Tag is not CustomNewFolding realFolding) continue; + if (realFolding.Level == level) folding.IsFolded = true; } } } - public class BraceFoldingStrategy : IFoldingStrategy + public class BraceFoldingStrategy { - private readonly char _opening; - private readonly char _closing; - - public BraceFoldingStrategy(TextEditor editor, char o, char c) + public BraceFoldingStrategy(TextEditor editor) { - _opening = o; - _closing = c; UpdateFoldings(editor.Document); } - public IEnumerable UpdateFoldings(TextDocument document) + public IEnumerable UpdateFoldings(TextDocument document) { return CreateNewFoldings(document); } - public IEnumerable CreateNewFoldings(ITextSource document) + public IEnumerable CreateNewFoldings(ITextSource document) { - var newFoldings = new List(); + var newFoldings = new List(); var startOffsets = new Stack(); var lastNewLineOffset = 0; + var level = -1; for (var i = 0; i < document.TextLength; i++) { var c = document.GetCharAt(i); - if (c == _opening) + switch (c) { - startOffsets.Push(i); - } - else if (c == _closing && startOffsets.Count > 0) - { - var startOffset = startOffsets.Pop(); - if (startOffset < lastNewLineOffset) + case '{' or '[': + level++; + startOffsets.Push(i); + break; + case '}' or ']' when startOffsets.Count > 0: { - newFoldings.Add(new NewFolding(startOffset, i + 1)); + var startOffset = startOffsets.Pop(); + if (startOffset < lastNewLineOffset) + { + newFoldings.Add(new CustomNewFolding(startOffset, i + 1, level)); + } + level--; + break; } - } - else if (c is '\n' or '\r') - { - lastNewLineOffset = i + 1; + case '\n' or '\r': + lastNewLineOffset = i + 1; + break; } } newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset)); return newFoldings; } - - public void CollapseAll() - { - throw new System.NotImplementedException(); - } - - public void ExpandAll() - { - throw new System.NotImplementedException(); - } } + + public class CustomNewFolding : NewFolding + { + public int Level { get; } + + public CustomNewFolding(int start, int end, int level) : base(start, end) + { + Level = level; + } + + public override string ToString() + { + return $"[{Level}] {StartOffset} -> {EndOffset}"; + } + } } \ No newline at end of file diff --git a/FModel/Views/Resources/Controls/PropertiesPopout.xaml b/FModel/Views/Resources/Controls/PropertiesPopout.xaml index 717bdad8..36ed70af 100644 --- a/FModel/Views/Resources/Controls/PropertiesPopout.xaml +++ b/FModel/Views/Resources/Controls/PropertiesPopout.xaml @@ -5,7 +5,7 @@ xmlns:adonisUi="clr-namespace:AdonisUI;assembly=AdonisUI" xmlns:avalonEdit="http://icsharpcode.net/sharpdevelop/avalonedit" xmlns:adonisControls="clr-namespace:AdonisUI.Controls;assembly=AdonisUI" - WindowStartupLocation="CenterScreen" IconVisibility="Collapsed" + WindowStartupLocation="CenterScreen" IconVisibility="Collapsed" PreviewKeyDown="OnPreviewKeyDown" Width="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenWidth}, Converter={converters:RatioConverter}, ConverterParameter='0.40'}"> diff --git a/FModel/Views/Resources/Controls/PropertiesPopout.xaml.cs b/FModel/Views/Resources/Controls/PropertiesPopout.xaml.cs index e253a9f6..c6fbe181 100644 --- a/FModel/Views/Resources/Controls/PropertiesPopout.xaml.cs +++ b/FModel/Views/Resources/Controls/PropertiesPopout.xaml.cs @@ -67,6 +67,22 @@ namespace FModel.Views.Resources.Controls _ => fontSize }; } + + private void OnPreviewKeyDown(object sender, KeyEventArgs e) + { + switch (e.Key) + { + case Key.J when Keyboard.IsKeyDown(Key.K) && Keyboard.Modifiers.HasFlag(ModifierKeys.Control): + _manager.UnfoldAll(); + break; + case Key.L when Keyboard.IsKeyDown(Key.K) && Keyboard.Modifiers.HasFlag(ModifierKeys.Control): + _manager.FoldToggle(MyAvalonEditor.CaretOffset); + break; + case >= Key.D0 and <= Key.D9 when Keyboard.IsKeyDown(Key.K) && Keyboard.Modifiers.HasFlag(ModifierKeys.Control): + _manager.FoldAtLevel(int.Parse(e.Key.ToString()[1].ToString())); + break; + } + } private void OnMouseHoverStopped(object sender, MouseEventArgs e) {