diff --git a/.gitignore b/.gitignore index bdc3535f..ca26b19c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ TestResults ## files generated by popular Visual Studio add-ons. # User-specific files +.vs/ *.suo *.user *.sln.docstates @@ -106,3 +107,4 @@ Generated_Code #added for RIA/Silverlight projects _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML +/mytest diff --git a/FastColoredTextBox.sln b/FastColoredTextBox.sln index 17b7d834..d9184863 100644 --- a/FastColoredTextBox.sln +++ b/FastColoredTextBox.sln @@ -1,9 +1,11 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30320.27 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tester", "Tester\Tester.csproj", "{EBE443EE-F4C7-49E6-AC22-959CA62FAA05}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastColoredTextBox", "FastColoredTextBox\FastColoredTextBox.csproj", "{6DD14A85-CCFC-4774-BD26-0F5772512319}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastColoredTextBox", "FastColoredTextBox\FastColoredTextBox.csproj", "{6DD14A85-CCFC-4774-BD26-0F5772512319}" EndProject Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "TesterVB", "TesterVB\TesterVB.vbproj", "{3EF3A5A0-2365-41FD-97A0-254A2CFC6577}" EndProject @@ -51,4 +53,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {742C02CF-4566-488A-A923-493BF132C1CA} + EndGlobalSection EndGlobal diff --git a/FastColoredTextBox/AutocompleteItem.cs b/FastColoredTextBox/AutocompleteItem.cs index 59feec4d..620ae588 100644 --- a/FastColoredTextBox/AutocompleteItem.cs +++ b/FastColoredTextBox/AutocompleteItem.cs @@ -59,7 +59,7 @@ public virtual string GetTextForReplace() /// public virtual CompareResult Compare(string fragmentText) { - if (Text.StartsWith(fragmentText, StringComparison.InvariantCultureIgnoreCase) && + if(string.IsNullOrEmpty(fragmentText) || Text.ToLowerInvariant().Contains(fragmentText.ToLowerInvariant()) && Text != fragmentText) return CompareResult.VisibleAndSelected; diff --git a/FastColoredTextBox/AutocompleteMenu.cs b/FastColoredTextBox/AutocompleteMenu.cs index 829783ac..ff34c2b0 100644 --- a/FastColoredTextBox/AutocompleteMenu.cs +++ b/FastColoredTextBox/AutocompleteMenu.cs @@ -402,7 +402,8 @@ internal void DoAutocomplete(bool forced) && (tb.Selection.Start > fragment.Start || text.Length == 0/*pops up only if caret is after first letter*/))) { Menu.Fragment = fragment; - bool foundSelected = false; + //bool foundSelected = false; + AutocompleteItem foundItem = null; //build popup menu foreach (var item in sourceItems) { @@ -410,15 +411,34 @@ internal void DoAutocomplete(bool forced) CompareResult res = item.Compare(text); if(res != CompareResult.Hidden) visibleItems.Add(item); - if (res == CompareResult.VisibleAndSelected && !foundSelected) + if (res == CompareResult.VisibleAndSelected && foundItem != null) { - foundSelected = true; - FocussedItemIndex = visibleItems.Count - 1; + foundItem = item; + //FocussedItemIndex = visibleItems.Count - 1; } } - if (foundSelected) + visibleItems.Sort((AutocompleteItem a, AutocompleteItem b)=> { + var indexA = a.Text.IndexOf(text, StringComparison.InvariantCultureIgnoreCase); + var indexB = b.Text.IndexOf(text, StringComparison.InvariantCultureIgnoreCase); + + if(indexA == indexB) { + if(a.Text.Length == b.Text.Length) return string.Compare(a.Text, b.Text, true); + return a.Text.Length - b.Text.Length; + } + else { + if(indexA == -1) return 1; + if(indexB == -1) return -1; + } + + return indexA - indexB; + }); + + if (foundItem != null) { + + FocussedItemIndex = visibleItems.IndexOf(foundItem); + AdjustScroll(); DoSelectedVisible(); } diff --git a/FastColoredTextBox/CharSizeCache.cs b/FastColoredTextBox/CharSizeCache.cs new file mode 100644 index 00000000..51dad64f --- /dev/null +++ b/FastColoredTextBox/CharSizeCache.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using System.Windows.Forms; + +namespace FastColoredTextBoxNS +{ + /// + /// Calling MeasureText on each char is extremly slow + /// Thankfully the size of the char does not change for the same font + /// However we would still need to indentify the font somehow + /// + static class CharSizeCache + { + static readonly Dictionary cache = new Dictionary(); + internal static SizeF GetCharSize(Font font, char c) + { + var key = GetKey(font, c); + if (!cache.ContainsKey(key)) + { + Size sz2 = TextRenderer.MeasureText("<" + c.ToString() + ">", font); + Size sz3 = TextRenderer.MeasureText("<>", font); + cache[key] = new SizeF(sz2.Width - sz3.Width + 1, /*sz2.Height*/font.Height); + } + return cache[key]; + } + + /// + /// Font is disposable, so we need to indentify it without keeping manged resources + /// + /// + /// + /// + private static string GetKey(Font font, char c) + { + return font.FontFamily.Name + + ":" + font.Size + + ":" + font.Style + + ":" + font.Unit + + ":" + font.GdiCharSet + + ":" + font.GdiVerticalFont + + ":" + c; + } + } +} diff --git a/FastColoredTextBox/FastColoredTextBox.cs b/FastColoredTextBox/FastColoredTextBox.cs index d7e2a1e9..aeec0473 100644 --- a/FastColoredTextBox/FastColoredTextBox.cs +++ b/FastColoredTextBox/FastColoredTextBox.cs @@ -169,8 +169,8 @@ public FastColoredTextBox() RightBracket = '\x0'; LeftBracket2 = '\x0'; RightBracket2 = '\x0'; - SyntaxHighlighter = new SyntaxHighlighter(this); language = Language.Custom; + SyntaxHighlighter = SyntaxHighlighter.CreateSyntaxHighlighter(this, language); PreferredLineWidth = 0; needRecalc = true; lastNavigatedDateTime = DateTime.Now; @@ -288,7 +288,7 @@ public override bool AllowDrop get { return base.AllowDrop; } set { base.AllowDrop = value; } } - + /// /// Collection of Hints. /// This is temporary buffer for currently displayed hints. @@ -821,7 +821,7 @@ public Style[] Styles /// [Description("Here you can change hotkeys for FastColoredTextBox.")] [Editor(typeof(HotkeysEditor), typeof(UITypeEditor))] - [DefaultValue("Tab=IndentIncrease, Escape=ClearHints, PgUp=GoPageUp, PgDn=GoPageDown, End=GoEnd, Home=GoHome, Left=GoLeft, Up=GoUp, Right=GoRight, Down=GoDown, Ins=ReplaceMode, Del=DeleteCharRight, F3=FindNext, Shift+Tab=IndentDecrease, Shift+PgUp=GoPageUpWithSelection, Shift+PgDn=GoPageDownWithSelection, Shift+End=GoEndWithSelection, Shift+Home=GoHomeWithSelection, Shift+Left=GoLeftWithSelection, Shift+Up=GoUpWithSelection, Shift+Right=GoRightWithSelection, Shift+Down=GoDownWithSelection, Shift+Ins=Paste, Shift+Del=Cut, Ctrl+Back=ClearWordLeft, Ctrl+Space=AutocompleteMenu, Ctrl+End=GoLastLine, Ctrl+Home=GoFirstLine, Ctrl+Left=GoWordLeft, Ctrl+Up=ScrollUp, Ctrl+Right=GoWordRight, Ctrl+Down=ScrollDown, Ctrl+Ins=Copy, Ctrl+Del=ClearWordRight, Ctrl+0=ZoomNormal, Ctrl+A=SelectAll, Ctrl+B=BookmarkLine, Ctrl+C=Copy, Ctrl+E=MacroExecute, Ctrl+F=FindDialog, Ctrl+G=GoToDialog, Ctrl+H=ReplaceDialog, Ctrl+I=AutoIndentChars, Ctrl+M=MacroRecord, Ctrl+N=GoNextBookmark, Ctrl+R=Redo, Ctrl+U=UpperCase, Ctrl+V=Paste, Ctrl+X=Cut, Ctrl+Z=Undo, Ctrl+Add=ZoomIn, Ctrl+Subtract=ZoomOut, Ctrl+OemMinus=NavigateBackward, Ctrl+Shift+End=GoLastLineWithSelection, Ctrl+Shift+Home=GoFirstLineWithSelection, Ctrl+Shift+Left=GoWordLeftWithSelection, Ctrl+Shift+Right=GoWordRightWithSelection, Ctrl+Shift+B=UnbookmarkLine, Ctrl+Shift+C=CommentSelected, Ctrl+Shift+N=GoPrevBookmark, Ctrl+Shift+U=LowerCase, Ctrl+Shift+OemMinus=NavigateForward, Alt+Back=Undo, Alt+Up=MoveSelectedLinesUp, Alt+Down=MoveSelectedLinesDown, Alt+F=FindChar, Alt+Shift+Left=GoLeft_ColumnSelectionMode, Alt+Shift+Up=GoUp_ColumnSelectionMode, Alt+Shift+Right=GoRight_ColumnSelectionMode, Alt+Shift+Down=GoDown_ColumnSelectionMode")] + [DefaultValue("Tab=IndentIncrease, Escape=ClearHints, PgUp=GoPageUp, PgDn=GoPageDown, End=GoEnd, Home=GoHome, Left=GoLeft, Up=GoUp, Right=GoRight, Down=GoDown, Ins=ReplaceMode, Del=DeleteCharRight, F3=FindNext, Shift+Tab=IndentDecrease, Shift+PgUp=GoPageUpWithSelection, Shift+PgDn=GoPageDownWithSelection, Shift+End=GoEndWithSelection, Shift+Home=GoHomeWithSelection, Shift+Left=GoLeftWithSelection, Shift+Up=GoUpWithSelection, Shift+Right=GoRightWithSelection, Shift+Down=GoDownWithSelection, Shift+Ins=Paste, Shift+Del=Cut, Ctrl+Back=ClearWordLeft, Ctrl+Space=AutocompleteMenu, Ctrl+End=GoLastLine, Ctrl+Home=GoFirstLine, Ctrl+Left=GoWordLeft, Ctrl+Up=ScrollUp, Ctrl+Right=GoWordRight, Ctrl+Down=ScrollDown, Ctrl+Ins=Copy, Ctrl+Del=ClearWordRight, Ctrl+0=ZoomNormal, Ctrl+A=SelectAll, Ctrl+B=BookmarkLine, Ctrl+C=Copy, Ctrl+E=MacroExecute, Ctrl+F=FindDialog, Ctrl+G=GoToDialog, Ctrl+H=ReplaceDialog, Ctrl+I=AutoIndentChars, Ctrl+M=MacroRecord, Ctrl+N=GoNextBookmark, Ctrl+R=Redo, Ctrl+U=UpperCase, Ctrl+V=Paste, Ctrl+X=Cut, Ctrl+Z=Undo, Ctrl+Add=ZoomIn, Ctrl+Subtract=ZoomOut, Ctrl+OemMinus=NavigateBackward, Ctrl+Shift+End=GoLastLineWithSelection, Ctrl+Shift+Home=GoFirstLineWithSelection, Ctrl+Shift+Left=GoWordLeftWithSelection, Ctrl+Shift+Right=GoWordRightWithSelection, Ctrl+Shift+B=UnbookmarkLine, Ctrl+Shift+C=CommentSelected, Ctrl+Shift+N=GoPrevBookmark, Ctrl+Shift+U=LowerCase, Ctrl+Shift+OemMinus=NavigateForward, Alt+Back=Undo, Alt+Up=MoveSelectedLinesUp, Alt+Down=MoveSelectedLinesDown, Alt+F=FindChar, Alt+Shift+Left=GoLeft_ColumnSelectionMode, Alt+Shift+Up=GoUp_ColumnSelectionMode, Alt+Shift+Right=GoRight_ColumnSelectionMode, Alt+Shift+Down=GoDown_ColumnSelectionMode, Ctrl+D=CloneLine")] public string Hotkeys { get { return HotkeysMapping.ToString(); } set { HotkeysMapping = HotkeysMapping.Parse(value); } @@ -1005,8 +1005,7 @@ public Language Language set { language = value; - if (SyntaxHighlighter != null) - SyntaxHighlighter.InitStyleSchema(language); + SyntaxHighlighter = SyntaxHighlighter.CreateSyntaxHighlighter(this, language); Invalidate(); } } @@ -1020,13 +1019,13 @@ public Language Language /// /// XML file with description of syntax highlighting. - /// This property works only with Language == Language.Custom. + /// This property works only with Language == Language.FromXMLfile. /// [Browsable(true)] [DefaultValue(null)] [Editor(typeof (FileNameEditor), typeof (UITypeEditor))] [Description( - "XML file with description of syntax highlighting. This property works only with Language == Language.Custom." + "XML file with description of syntax highlighting. This property works only with Language == Language.FromXMLfile." )] public string DescriptionFile { @@ -2901,10 +2900,7 @@ internal int GetOrSetStyleLayerIndex(Style style) public static SizeF GetCharSize(Font font, char c) { - Size sz2 = TextRenderer.MeasureText("<" + c.ToString() + ">", font); - Size sz3 = TextRenderer.MeasureText("<>", font); - - return new SizeF(sz2.Width - sz3.Width + 1, /*sz2.Height*/font.Height); + return CharSizeCache.GetCharSize(font, c); } [DllImport("Imm32.dll")] @@ -3752,6 +3748,10 @@ private void DoAction(FCTBAction action) BookmarkLine(Selection.Start.iLine); break; + case FCTBAction.CloneLine: + CloneLine(Selection); + break; + case FCTBAction.GoNextBookmark: GotoNextBookmark(Selection.Start.iLine); break; @@ -4118,6 +4118,21 @@ public virtual void BookmarkLine(int iLine) bookmarks.Add(iLine); } + /// + /// Clones current line + /// + public virtual void CloneLine(Range selection) + { + // expand selection + selection.Expand(); + // get text of selected lines + string text = Environment.NewLine + selection.Text; + // move caret to end of selected lines + selection.Start = selection.End; + // insert text + InsertText(text); + } + /// /// Unbookmarks current line /// @@ -4731,7 +4746,7 @@ public virtual int CalcAutoIndent(int iLine) EventHandler calculator = AutoIndentNeeded; if (calculator == null) - if (Language != Language.Custom && SyntaxHighlighter != null) + if (Language != Language.Custom && Language != Language.FromXMLfile && SyntaxHighlighter != null) calculator = SyntaxHighlighter.AutoIndentNeeded; else calculator = CalcAutoIndentShiftByCodeFolding; @@ -7265,10 +7280,7 @@ public virtual void OnSyntaxHighlight(TextChangedEventArgs args) if (SyntaxHighlighter != null) { - if (Language == Language.Custom && !string.IsNullOrEmpty(DescriptionFile)) - SyntaxHighlighter.HighlightSyntax(DescriptionFile, range); - else - SyntaxHighlighter.HighlightSyntax(Language, range); + SyntaxHighlighter.SyntaxHighlight(range); } #if debug diff --git a/FastColoredTextBox/FastColoredTextBox.csproj b/FastColoredTextBox/FastColoredTextBox.csproj index 0707e4e2..938e167a 100644 --- a/FastColoredTextBox/FastColoredTextBox.csproj +++ b/FastColoredTextBox/FastColoredTextBox.csproj @@ -1,37 +1,17 @@ - - + - Debug - AnyCPU - 9.0.21022 - 2.0 - {6DD14A85-CCFC-4774-BD26-0F5772512319} + netcoreapp3.1;net35 + true Library - Properties FastColoredTextBoxNS - FastColoredTextBox - v2.0 - 512 - + false + + + - true - full - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 bin\Debug\FastColoredTextBox.XML - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true @@ -39,110 +19,47 @@ FCTB_key.snk - - - - - - - - - - - Component - - - - - Component - - - - - - Form - - + + + + GoToForm.cs - - - Form - - + + HotkeysEditorForm.cs - - - - - - - UserControl - - + + Ruler.cs - - - - Form - - + + ReplaceForm.cs - - UserControl - - - - - Form - - + + + FindForm.cs - - - - - - - - - - - UserControl - - + - + FastColoredTextBox.cs - + FindForm.cs - + GoToForm.cs - + HotkeysEditorForm.cs - + ReplaceForm.cs Designer - - - - - \ No newline at end of file diff --git a/FastColoredTextBox/Hotkeys.cs b/FastColoredTextBox/Hotkeys.cs index 9bac1020..1bc2c522 100644 --- a/FastColoredTextBox/Hotkeys.cs +++ b/FastColoredTextBox/Hotkeys.cs @@ -91,7 +91,8 @@ public virtual void InitDefault() this[KEYS.Control | KEYS.Subtract] = FCTBAction.ZoomOut; this[KEYS.Control | KEYS.Add] = FCTBAction.ZoomIn; this[KEYS.Control | KEYS.D0] = FCTBAction.ZoomNormal; - this[KEYS.Control | KEYS.I] = FCTBAction.AutoIndentChars; + this[KEYS.Control | KEYS.I] = FCTBAction.AutoIndentChars; + this[KEYS.Control | KEYS.D] = FCTBAction.CloneLine; } public override string ToString() @@ -147,6 +148,7 @@ public enum FCTBAction ClearHints, ClearWordLeft, ClearWordRight, + CloneLine, CommentSelected, Copy, Cut, diff --git a/FastColoredTextBox/Style.cs b/FastColoredTextBox/Style.cs index 08b1833f..61b6b1b9 100644 --- a/FastColoredTextBox/Style.cs +++ b/FastColoredTextBox/Style.cs @@ -210,6 +210,16 @@ public override RTFStyleDescriptor GetRTF() return result; } + + public override bool Equals(object obj) + { + TextStyle ts = obj as TextStyle; + if (ts != null) + { + return (ForeBrush == ts.ForeBrush) && (BackgroundBrush == ts.BackgroundBrush) && (FontStyle == ts.FontStyle) && (stringFormat == ts.stringFormat); + } + else return false; + } } /// diff --git a/FastColoredTextBox/SyntaxHighlighter.cs b/FastColoredTextBox/SyntaxHighlighter.cs index 17914b3e..e487405c 100644 --- a/FastColoredTextBox/SyntaxHighlighter.cs +++ b/FastColoredTextBox/SyntaxHighlighter.cs @@ -1,1466 +1,253 @@ using System; using System.Collections.Generic; using System.Drawing; -using System.Globalization; -using System.IO; +using System.Text; using System.Text.RegularExpressions; -using System.Xml; +using FastColoredTextBoxNS.SyntaxSources; namespace FastColoredTextBoxNS { - public class SyntaxHighlighter : IDisposable + public abstract class SyntaxHighlighter : IDisposable { - //styles - protected static readonly Platform platformType = PlatformType.GetOperationSystemPlatform(); - public readonly Style BlueBoldStyle = new TextStyle(Brushes.Blue, null, FontStyle.Bold); - public readonly Style BlueStyle = new TextStyle(Brushes.Blue, null, FontStyle.Regular); - public readonly Style BoldStyle = new TextStyle(null, null, FontStyle.Bold | FontStyle.Underline); - public readonly Style BrownStyle = new TextStyle(Brushes.Brown, null, FontStyle.Italic); - public readonly Style GrayStyle = new TextStyle(Brushes.Gray, null, FontStyle.Regular); - public readonly Style GreenStyle = new TextStyle(Brushes.Green, null, FontStyle.Italic); - public readonly Style MagentaStyle = new TextStyle(Brushes.Magenta, null, FontStyle.Regular); - public readonly Style MaroonStyle = new TextStyle(Brushes.Maroon, null, FontStyle.Regular); - public readonly Style RedStyle = new TextStyle(Brushes.Red, null, FontStyle.Regular); - public readonly Style BlackStyle = new TextStyle(Brushes.Black, null, FontStyle.Regular); - // - protected readonly Dictionary descByXMLfileNames = - new Dictionary(); - - protected readonly List