OSDN Git Service

シンタックスハイライターと折り畳み関係を別のクラスに移した
[fooeditengine/FooEditEngine.git] / Core / LineToIndex.cs
index 25a6ce1..7f7094d 100644 (file)
@@ -121,6 +121,13 @@ namespace FooEditEngine
         End,
     }
 
+    interface ILineInfoGenerator
+    {
+        void Update(Document doc, int startIndex, int insertLength, int removeLength);
+        void Clear(LineToIndexTable lti);
+        bool Generate(Document doc, LineToIndexTable lti, bool force = true);
+    }
+
     internal class LineToIndexTableData : IDisposable
     {
         /// <summary>
@@ -212,20 +219,20 @@ namespace FooEditEngine
         Queue<ITextLayout> CacheEntries = new Queue<ITextLayout>();
         GapBuffer<LineToIndexTableData> Lines = new GapBuffer<LineToIndexTableData>();
         Document Document;
-        long lastUpdateTicks = DateTime.Now.Ticks;
-        const long AllowCallTicks = 1000 * 10000;   //see.DateTime.Ticks プロパティ
-        bool _IsSync;
         ITextRender render;
         int stepRow = -1,stepLength = 0;
         const int STEP_ROW_IS_NONE = -1;
-        IFoldingStrategy _folding;
+
+        const int FOLDING_INDEX = 0;
+        const int SYNTAX_HIGLITHER_INDEX = 1;
+        ILineInfoGenerator[] _generators = new ILineInfoGenerator[2];
 
         internal LineToIndexTable(Document buf)
         {
             this.Document = buf;
             this.Document.Markers.Updated += Markers_Updated;
-            this.FoldingCollection = new FoldingCollection();
-            this._IsSync = true;
+            this._generators[FOLDING_INDEX] = new FoldingGenerator();
+            this._generators[SYNTAX_HIGLITHER_INDEX] = new SyntaxHilightGenerator();
 #if DEBUG && !NETFX_CORE
             if (!Debugger.IsAttached)
             {
@@ -269,26 +276,43 @@ namespace FooEditEngine
         /// </summary>
         public FoldingCollection FoldingCollection
         {
-            get;
-            private set;
+            get
+            {
+                return ((FoldingGenerator)this._generators[FOLDING_INDEX]).FoldingCollection;
+            }
+            private set
+            {
+            }
         }
 
         /// <summary>
         /// シンタックスハイライター
         /// </summary>
-        internal IHilighter Hilighter { get; set; }
+        internal IHilighter Hilighter
+        {
+            get
+            {
+                return ((SyntaxHilightGenerator)this._generators[SYNTAX_HIGLITHER_INDEX]).Hilighter;
+            }
+            set
+            {
+                ((SyntaxHilightGenerator)this._generators[SYNTAX_HIGLITHER_INDEX]).Hilighter = value;
+                if (value == null)
+                    this._generators[FOLDING_INDEX].Clear(this);
+            }
+        }
 
         internal IFoldingStrategy FoldingStrategy
         {
             get
             {
-                return this._folding;
+                return ((FoldingGenerator)this._generators[FOLDING_INDEX]).FoldingStrategy;
             }
             set
             {
-                this._folding = value;
+                ((FoldingGenerator)this._generators[FOLDING_INDEX]).FoldingStrategy = value;
                 if (value == null)
-                    this.FoldingCollection.Clear();
+                    this._generators[FOLDING_INDEX].Clear(this);
             }
         }
 
@@ -354,11 +378,8 @@ namespace FooEditEngine
             //行テーブルを更新する
             this.UpdateLineHeadIndex(deltaLength, row, 1);
 
-            this.FoldingCollection.UpdateData(this.Document, this.GetLineHeadIndex(row), insertedLength, removedLength);
-
-            this._IsSync = false;
-
-            this.lastUpdateTicks = DateTime.Now.Ticks;
+            foreach(var generator in this._generators)
+                generator.Update(this.Document, this.GetLineHeadIndex(row), insertedLength, removedLength);
         }
 
         internal void UpdateAsReplace(int index, int removedLength, int insertedLength)
@@ -398,11 +419,8 @@ namespace FooEditEngine
 
             this.AddDummyLine();
 
-            this.FoldingCollection.UpdateData(this.Document, index, insertedLength, removedLength);            
-
-            this._IsSync = false;
-
-            this.lastUpdateTicks = DateTime.Now.Ticks;
+            foreach (var generator in this._generators)
+                generator.Update(this.Document, index, insertedLength, removedLength);
         }
 
         void GetRemoveRange(int index,int length,out int startRow,out int endRow)
@@ -550,6 +568,17 @@ namespace FooEditEngine
         }
 
         /// <summary>
+        /// 生データを取得します
+        /// </summary>
+        /// <param name="row">行</param>
+        /// <returns>LineToIndexTableData</returns>
+        /// <remarks>いくつかの値は実態とかけ離れた値を返します。詳しくはLineToIndexTableDataの注意事項を参照すること</remarks>
+        internal LineToIndexTableData GetRaw(int row)
+        {
+            return this.Lines[row];
+        }
+
+        /// <summary>
         /// 行番号をインデックスに変換します
         /// </summary>
         /// <param name="row">行番号</param>
@@ -729,43 +758,7 @@ namespace FooEditEngine
         /// <remarks>デフォルトではドキュメントが更新されている時にだけ再生成されます</remarks>
         public bool GenerateFolding(bool force = false)
         {
-            if (this.Document.Length == 0 || this.Document.IsLocked)
-                return false;
-            long nowTick = DateTime.Now.Ticks;
-            bool sync = force || !this._IsSync;
-            if (sync && Math.Abs(nowTick - this.lastUpdateTicks) >= AllowCallTicks)
-            {
-                this.GenerateFolding(0, this.Document.Length - 1);
-                this.lastUpdateTicks = nowTick;
-                this._IsSync = true;
-                return true;
-            }
-            return false;
-        }
-
-        void GenerateFolding(int start, int end)
-        {
-            if (start > end)
-                throw new ArgumentException("start <= endである必要があります");
-            if (this.FoldingStrategy != null)
-            {
-                //再生成するとすべて展開状態になってしまうので、閉じてるやつだけを保存しておく
-                FoldingItem[] closed_items =  this.FoldingCollection.Where((e)=> { return !e.Expand; }).ToArray();
-
-                this.FoldingCollection.Clear();
-
-                var items = this.FoldingStrategy.AnalyzeDocument(this.Document, start, end)
-                    .Where((item) =>
-                    {
-                        int startRow = this.GetLineNumberFromIndex(item.Start);
-                        int endRow = this.GetLineNumberFromIndex(item.End);
-                        return startRow != endRow;
-                    })
-                    .Select((item) => item);
-                this.FoldingCollection.AddRange(items);
-
-                this.FoldingCollection.ApplyExpandStatus(closed_items);
-            }
+            return this._generators[FOLDING_INDEX].Generate(this.Document, this, force);
         }
 
         /// <summary>
@@ -773,8 +766,7 @@ namespace FooEditEngine
         /// </summary>
         public void ClearFolding()
         {
-            this.FoldingCollection.Clear();
-            this._IsSync = false;
+            this._generators[FOLDING_INDEX].Clear(this);
         }
 
         /// <summary>
@@ -782,26 +774,7 @@ namespace FooEditEngine
         /// </summary>
         public bool HilightAll(bool force = false)
         {
-            if (this.Hilighter == null || this.Document.IsLocked)
-                return false;
-
-            long nowTick = DateTime.Now.Ticks;
-            bool sync = force || !this._IsSync;
-            if (sync || Math.Abs(nowTick - this.lastUpdateTicks) >= AllowCallTicks)
-            {
-                for (int i = 0; i < this.Lines.Count; i++)
-                    this.HilightLine(i);
-
-                this.Hilighter.Reset();
-                this.ClearLayoutCache();
-
-                this.lastUpdateTicks = nowTick;
-
-                this._IsSync = true;
-
-                return true;
-            }
-            return false;
+            return this._generators[SYNTAX_HIGLITHER_INDEX].Generate(this.Document, this, force);
         }
 
         /// <summary>
@@ -809,10 +782,7 @@ namespace FooEditEngine
         /// </summary>
         public void ClearHilight()
         {
-            foreach (LineToIndexTableData line in this.Lines)
-                line.Syntax = null;
-            this.ClearLayoutCache();
-            this._IsSync = false;
+            this._generators[SYNTAX_HIGLITHER_INDEX].Clear(this);
         }
 
         /// <summary>
@@ -821,7 +791,7 @@ namespace FooEditEngine
         internal void Clear()
         {
             this.ClearLayoutCache();
-            this.FoldingCollection.Clear();
+            this.ClearFolding();
             this.Lines.Clear();
             LineToIndexTableData dummy = new LineToIndexTableData();
             this.Lines.Add(dummy);
@@ -830,25 +800,6 @@ namespace FooEditEngine
             Debug.WriteLine("Clear");
         }
 
-        private void HilightLine(int row)
-        {
-            //シンタックスハイライトを行う
-            List<SyntaxInfo> syntax = new List<SyntaxInfo>();
-            string str = this[row];
-            int level = this.Hilighter.DoHilight(str, str.Length, (s) =>
-            {
-                if (s.type == TokenType.None || s.type == TokenType.Control)
-                    return;
-                if (str[s.index + s.length - 1] == Document.NewLine)
-                    s.length--;
-                syntax.Add(new SyntaxInfo(s.index, s.length, s.type));
-            });
-
-            LineToIndexTableData lineData = this.Lines[row];
-            lineData.Syntax = syntax.ToArray();
-
-        }
-
         #region IEnumerable<string> メンバー
 
         /// <summary>