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>
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)
{
/// </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);
}
}
//行テーブルを更新する
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)
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)
}
/// <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>
/// <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>
/// </summary>
public void ClearFolding()
{
- this.FoldingCollection.Clear();
- this._IsSync = false;
+ this._generators[FOLDING_INDEX].Clear(this);
}
/// <summary>
/// </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>
/// </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>
internal void Clear()
{
this.ClearLayoutCache();
- this.FoldingCollection.Clear();
+ this.ClearFolding();
this.Lines.Clear();
LineToIndexTableData dummy = new LineToIndexTableData();
this.Lines.Add(dummy);
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>