Queue<ITextLayout> CacheEntries = new Queue<ITextLayout>();\r
GapBuffer<LineToIndexTableData> Lines = new GapBuffer<LineToIndexTableData>();\r
Document Document;\r
+ long lastUpdateTicks = DateTime.Now.Ticks;\r
+ const long AllowCallTicks = 1000 * 10000; //see.DateTime.Ticks プロパティ\r
bool _IsSync;\r
ITextRender render;\r
int stepRow = -1,stepLength = 0;\r
this.FoldingCollection.UpdateData(this.Document, index, insertedLength, removedLength); \r
this.FoldingCollection.CollectEmptyFolding(index, Document.Length - 1);\r
\r
- this.Hilight(startRow, newLines.Count);\r
-\r
this._IsSync = false;\r
+\r
+ this.lastUpdateTicks = DateTime.Now.Ticks;\r
}\r
\r
void GetRemoveRange(int index,int length,out int startRow,out int endRow)\r
/// <remarks>デフォルトではドキュメントが更新されている時にだけ再生成されます</remarks>\r
public bool GenerateFolding(bool force = false)\r
{\r
- if (force)\r
- this._IsSync = false;\r
- if (this.Document.Length == 0 || this._IsSync)\r
+ if (this.Document.Length == 0)\r
return false;\r
- this.GenerateFolding(0, this.Document.Length - 1);\r
- this._IsSync = true;\r
- return true;\r
+ long nowTick = DateTime.Now.Ticks;\r
+ if (force || Math.Abs(nowTick - this.lastUpdateTicks) >= AllowCallTicks)\r
+ {\r
+ this.GenerateFolding(0, this.Document.Length - 1);\r
+ this.lastUpdateTicks = nowTick;\r
+ return true;\r
+ }\r
+ return false;\r
}\r
\r
void GenerateFolding(int start, int end)\r
/// <summary>\r
/// すべての行に対しシンタックスハイライトを行います\r
/// </summary>\r
- public void HilightAll()\r
+ public bool HilightAll(bool force = false)\r
{\r
- this.Hilight(0, this.Lines.Count);\r
- this.ClearLayoutCache();\r
+ if (this.Hilighter == null)\r
+ return false;\r
+\r
+ long nowTick = DateTime.Now.Ticks;\r
+ if (force || Math.Abs(nowTick - this.lastUpdateTicks) >= AllowCallTicks)\r
+ {\r
+ for (int i = 0; i < this.Lines.Count; i++)\r
+ this.HilightLine(i);\r
+\r
+ this.Hilighter.Reset();\r
+ this.ClearLayoutCache();\r
+\r
+ this.lastUpdateTicks = nowTick;\r
+\r
+ return true;\r
+ }\r
+ return false;\r
}\r
\r
/// <summary>\r
Debug.WriteLine("Clear");\r
}\r
\r
- void Hilight(int row, int rowCount)\r
- {\r
- if (this.Hilighter == null || rowCount == 0)\r
- return;\r
-\r
- //シンタックスハイライトの開始行を求める\r
- int startRow = row;\r
- EncloserType type = this.Lines[startRow].EncloserType;\r
- EncloserType prevLineType = startRow > 0 ? this.Lines[startRow - 1].EncloserType : EncloserType.None;\r
- if (type == EncloserType.Now || type == EncloserType.End ||\r
- prevLineType == EncloserType.Now || prevLineType == EncloserType.End)\r
- startRow = SearchStartRow(startRow);\r
- else if (prevLineType == EncloserType.Begin)\r
- startRow = startRow - 1;\r
-\r
- //シンタックスハイライトの終了行を求める\r
- int endRow = row + rowCount - 1;\r
- type = this.Lines[endRow].EncloserType;\r
- prevLineType = endRow > 0 ? this.Lines[endRow - 1].EncloserType : EncloserType.None;\r
- if (type == EncloserType.Begin || type == EncloserType.Now ||\r
- prevLineType == EncloserType.Begin || prevLineType == EncloserType.Now)\r
- endRow = SearchEndRow(endRow);\r
- else if (endRow + 1 <= this.Lines.Count - 1 && this.Lines[endRow + 1].EncloserType == EncloserType.Now)\r
- endRow = SearchEndRow(endRow + 1);\r
-\r
- //シンタックスハイライトを行う\r
- bool hasBeginEncloser = false;\r
- int i;\r
- for (i = startRow; i <= endRow; i++)\r
- {\r
- this.HilightLine(i, ref hasBeginEncloser);\r
- }\r
-\r
- if (hasBeginEncloser) //終了エンクロージャーが見つかったかどうか\r
- {\r
- for (; i < this.Lines.Count; i++)\r
- {\r
- if (this.HilightLine(i, ref hasBeginEncloser) < 0)\r
- break;\r
- }\r
- }\r
-\r
- this.Hilighter.Reset();\r
- }\r
-\r
- private int HilightLine(int row, ref bool hasBeginEncloser)\r
+ private void HilightLine(int row)\r
{\r
//シンタックスハイライトを行う\r
List<SyntaxInfo> syntax = new List<SyntaxInfo>();\r
LineToIndexTableData lineData = this.Lines[row];\r
lineData.Syntax = syntax.ToArray();\r
\r
- if (level > 0 && hasBeginEncloser == false) //開始エンクロージャー\r
- {\r
- lineData.EncloserType = EncloserType.Begin;\r
- hasBeginEncloser = true;\r
- }\r
- else if (level < 0) //終了エンクロージャー\r
- {\r
- lineData.EncloserType = EncloserType.End;\r
- hasBeginEncloser = false;\r
- }\r
- else if (hasBeginEncloser) //エンクロージャーの範囲内\r
- lineData.EncloserType = EncloserType.Now;\r
- else\r
- lineData.EncloserType = EncloserType.None;\r
-\r
- return level;\r
- }\r
-\r
- private int SearchStartRow(int startRow)\r
- {\r
- for (startRow--; startRow >= 0; startRow--)\r
- {\r
- EncloserType type = this.Lines[startRow].EncloserType;\r
- if (type == EncloserType.Begin || type == EncloserType.None)\r
- return startRow;\r
- }\r
- return 0;\r
- }\r
-\r
- private int SearchEndRow(int startRow)\r
- {\r
- for (startRow++ ; startRow < this.Lines.Count; startRow++)\r
- {\r
- EncloserType type = this.Lines[startRow].EncloserType;\r
- if (type == EncloserType.End)\r
- return startRow;\r
- }\r
- return this.Lines.Count - 1;\r
}\r
\r
#region IEnumerable<string> メンバー\r