syntaxdocument.cs
来自「Fireball.CodeEditor is an source code ed」· CS 代码 · 共 1,880 行 · 第 1/3 页
CS
1,880 行
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using Fireball.Syntax.SyntaxDocumentParsers;
namespace Fireball.Syntax
{
/// <summary>
///
/// </summary>
public class RowEventArgs : EventArgs
{
/// <summary>
///
/// </summary>
/// <param name="row"></param>
public RowEventArgs(Row row)
{
this.Row = row;
}
/// <summary>
///
/// </summary>
public Row Row = null;
}
/// <summary>
/// Parser event handler
/// </summary>
public delegate void ParserEventHandler(object sender, RowEventArgs e);
/// <summary>
///
/// </summary>
public delegate void RowEventHandler(object sender, RowEventArgs e);
/// <summary>
/// The SyntaxDocument is a component that is responsible for Parsing , Folding , Undo / Redo actions and various text actions.
/// </summary>
public class SyntaxDocument : Component, IEnumerable
{
#region General declarations
/// <summary>
/// List of rows that should be parsed
/// </summary>
public RowCollection ParseQueue = new RowCollection();
/// <summary>
///
/// </summary>
public RowCollection KeywordQueue = new RowCollection();
public FormatRangeCollection FormatRanges = null;
/// <summary>
/// List of rows that is not hidden by folding
/// </summary>
public RowCollection VisibleRows = new RowCollection();
private RowCollection mDocument = new RowCollection();
/// <summary>
/// Buffer containing undo actions
/// </summary>
public UndoBuffer UndoBuffer = new UndoBuffer();
/// <summary>
/// The active parser of the document
/// </summary>
public IParser Parser = new DefaultParser();
/// <summary>
/// For public use only
/// </summary>
private bool mIsParsed = true;
private string mSyntaxFile = "";
#region PUBLIC PROPERTY UNDOSTEP
private int _UndoStep;
public int UndoStep
{
get
{
if (_UndoStep > this.UndoBuffer.Count)
_UndoStep = this.UndoBuffer.Count;
return _UndoStep;
}
set { _UndoStep = value; }
}
#endregion
/// <summary>
/// Tag property , lets the user store custom data in the row.
/// </summary>
public object Tag = null;
/// <summary>
/// Gets or Sets if folding needs to be recalculated
/// </summary>
public bool NeedResetRows = false;
private bool mModified = false;
private bool mFolding = true;
private Container components = null;
private bool mCaptureMode = false;
private UndoBlockCollection mCaptureBlock = null;
/// <summary>
/// Event that is raised when there is no more rows to parse
/// </summary>
public event EventHandler ParsingCompleted;
public event EventHandler UndoBufferChanged = null;
/// <summary>
/// Raised when the parser is active
/// </summary>
public event EventHandler Parsing;
/// <summary>
/// Raised when the document content is changed
/// </summary>
public event EventHandler Change;
public event RowEventHandler BreakPointAdded;
public event RowEventHandler BreakPointRemoved;
public event RowEventHandler BookmarkAdded;
public event RowEventHandler BookmarkRemoved;
protected virtual void OnBreakPointAdded(Row r)
{
if (BreakPointAdded != null)
BreakPointAdded(this, new RowEventArgs(r));
}
protected virtual void OnBreakPointRemoved(Row r)
{
if (BreakPointRemoved != null)
BreakPointRemoved(this, new RowEventArgs(r));
}
protected virtual void OnBookmarkAdded(Row r)
{
if (BookmarkAdded != null)
BookmarkAdded(this, new RowEventArgs(r));
}
protected virtual void OnBookmarkRemoved(Row r)
{
if (BookmarkRemoved != null)
BookmarkRemoved(this, new RowEventArgs(r));
}
protected virtual void OnUndoBufferChanged()
{
if (UndoBufferChanged != null)
UndoBufferChanged(this, EventArgs.Empty);
}
public virtual void InvokeBreakPointAdded(Row r)
{
OnBreakPointAdded(r);
}
public virtual void InvokeBreakPointRemoved(Row r)
{
OnBreakPointRemoved(r);
}
public virtual void InvokeBookmarkAdded(Row r)
{
OnBookmarkAdded(r);
}
public virtual void InvokeBookmarkRemoved(Row r)
{
OnBookmarkRemoved(r);
}
//public event System.EventHandler CreateParser;
/// <summary>
/// Raised when the modified flag has changed
/// </summary>
public event EventHandler ModifiedChanged;
//----------------------------------------------
/// <summary>
/// Raised when a row have been parsed
/// </summary>
public event ParserEventHandler RowParsed;
// public event ParserEventHandler RowAdded;
/// <summary>
/// Raised when a row have been deleted
/// </summary>
public event ParserEventHandler RowDeleted;
#endregion
#region PUBLIC PROPERTY MAXUNDOBUFFERSIZE
/// <summary>
/// Gets or Sets the Maximum number of entries in the undobuffer
/// </summary>
public int MaxUndoBufferSize
{
get { return UndoBuffer.MaxSize; }
set { UndoBuffer.MaxSize = value; }
}
#endregion
#region PUBLIC PROPERTY VERSION
private long _Version = long.MinValue;
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public long Version
{
get { return _Version; }
set { _Version = value; }
}
#endregion
/// <summary>
/// For internal use only
/// </summary>
public void ChangeVersion()
{
this.Version ++;
if (this.Version > long.MaxValue - 10)
this.Version = long.MinValue;
}
/// <summary>
/// Starts an Undo Capture.
/// This method can be called if you with to collect multiple text operations into one undo action
/// </summary>
public void StartUndoCapture()
{
mCaptureMode = true;
mCaptureBlock = new UndoBlockCollection();
}
/// <summary>
/// Ends an Undo capture and pushes the collected actions onto the undostack
/// <seealso cref="StartUndoCapture"/>
/// </summary>
/// <returns></returns>
public UndoBlockCollection EndUndoCapture()
{
mCaptureMode = false;
AddToUndoList(mCaptureBlock);
return mCaptureBlock;
}
/// <summary>
/// ReParses the document
/// </summary>
public void ReParse()
{
this.Text = this.Text;
}
/// <summary>
/// Get or Set the Modified flag
/// </summary>
public bool Modified
{
get { return mModified; }
set
{
mModified = value;
OnModifiedChanged();
}
}
/// <summary>
/// Removes all bookmarks in the document
/// </summary>
public void ClearBookmarks()
{
foreach (Row r in this)
{
r.Bookmarked = false;
}
InvokeChange();
}
/// <summary>
/// Removes all breakpoints in the document.
/// </summary>
public void ClearBreakpoints()
{
foreach (Row r in this)
{
r.Breakpoint = false;
}
InvokeChange();
}
/// <summary>
/// Get or Set the Name of the Syntaxfile to use
/// </summary>
[DefaultValue("")]
public string SyntaxFile
{
get { return mSyntaxFile; }
set
{
mSyntaxFile = value;
// this.Parser=new Parser_Default();
this.Parser.Init(value);
this.Text = this.Text;
}
}
/// <summary>
/// Call this method to ensure that a specific row is fully parsed
/// </summary>
/// <param name="Row"></param>
public void EnsureParsed(Row Row)
{
this.ParseAll();
Parser.ParseLine(Row.Index, true);
}
/// <summary>
///
/// </summary>
/// <param name="container"></param>
public SyntaxDocument(IContainer container) : this()
{
container.Add(this);
InitializeComponent();
}
private void Init()
{
Language l = new Language();
l.MainBlock = new BlockType(l);
l.MainBlock.MultiLine = true;
this.Parser.Init(l);
}
/// <summary>
/// Call this method to make the SyntaxDocument raise the Changed event
/// </summary>
public void InvokeChange()
{
OnChange();
}
/// <summary>
/// Gets or Sets if the document should use folding or not
/// </summary>
[DefaultValue(true)]
public bool Folding
{
get { return mFolding; }
set
{
mFolding = value;
if (!value)
{
foreach (Row r in this)
{
r.Expanded = true;
}
}
ResetVisibleRows();
OnChange();
}
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
/// <summary>
///
/// </summary>
public SyntaxDocument()
{
Parser.Document = this;
Text = "";
ResetVisibleRows();
Init();
this.FormatRanges = new FormatRangeCollection(this);
}
/// <summary>
/// Performs a segment parse on all rows. No Keyword colorizing
/// </summary>
public void ParseAll()
{
while (ParseQueue.Count > 0)
ParseSome();
ParseQueue.Clear();
}
/// <summary>
/// Parses all rows , either a segment parse or a full parse with keyword colorizing
/// </summary>
public void ParseAll(bool ParseKeywords)
{
this.ParseAll();
if (ParseKeywords)
{
for (int i = 0; i < this.Count; i++)
{
if (this[i].RowState != RowState.AllParsed)
Parser.ParseLine(i, true);
}
ParseQueue.Clear();
KeywordQueue.Clear();
}
}
/// <summary>
/// Folds all foldable rows
/// </summary>
public void FoldAll()
{
this.ParseAll(false);
foreach (Row r in this)
{
r.Expanded = false;
}
this.ResetVisibleRows();
this.OnChange();
}
/// <summary>
/// UnFolds all foldable rows
/// </summary>
public void UnFoldAll()
{
this.ParseAll(false);
foreach (Row r in this)
{
r.Expanded = true;
}
this.ResetVisibleRows();
this.OnChange();
}
/// <summary>
/// Parses a chunk of 1000 rows , this is not thread safe
/// </summary>
public void ParseSome()
{
this.ParseSome(1000);
}
/// <summary>
/// Parse a chunk of rows, this is not thread safe
/// </summary>
/// <param name="RowCount">The number of rows to parse</param>
public void ParseSome(int RowCount)
{
if (this.ParseQueue.Count > 0)
{
mIsParsed = false;
int i = 0;
while (i < RowCount && this.ParseQueue.Count > 0)
{
Row row = this.ParseQueue[0];
i += ParseRows(row);
}
if (this.NeedResetRows)
this.ResetVisibleRows();
if (Parsing != null)
Parsing(this, new EventArgs());
}
else
{
if (!mIsParsed && !Modified)
{
mIsParsed = true;
foreach (Row r in this)
{
if (r.Expansion_StartSegment != null && r.Expansion_EndRow != null)
{
if (r.Expansion_StartSegment.Scope.DefaultExpanded == false)
r.Expanded = false;
}
}
ResetVisibleRows();
if (ParsingCompleted != null)
ParsingCompleted(this, new EventArgs());
}
}
if (this.ParseQueue.Count == 0 && this.KeywordQueue.Count > 0)
{
// Console.WriteLine (this.KeywordQueue.Count.ToString ());
int i = 0;
while (i < RowCount/20 && this.KeywordQueue.Count > 0)
{
Row row = this.KeywordQueue[0];
i += ParseRows(row, true);
}
}
}
/// <summary>
/// Gets if the document is fully parsed
/// </summary>
[Browsable(false)]
public bool IsParsed
{
get { return mIsParsed; }
}
/// <summary>
/// Returns the row at the specified index
/// </summary>
public Row this[int index]
{
get
{
if (index < 0 || index >= mDocument.Count)
{
// System.Diagnostics.Debugger.Break ();
return null;
}
return mDocument[index];
}
set { mDocument[index] = value; }
}
/// <summary>
/// Add a new row with the specified text to the bottom of the document
/// </summary>
/// <param name="Text">Text to add</param>
/// <returns>The row that was added</returns>
public Row Add(string Text)
{
return Add(Text, true);
}
/// <summary>
/// Add a new row with the specified text to the bottom of the document
/// </summary>
/// <param name="Text">Text to add</param>
/// <param name="StoreUndo">true if and undo action should be added to the undo stack</param>
/// <returns>The row that was added</returns>
public Row Add(string Text, bool StoreUndo)
{
Row xtl = new Row();
mDocument.Add(xtl);
xtl.Document = this;
xtl.Text = Text;
return xtl;
}
/// <summary>
/// Insert a text at the specified row index
/// </summary>
/// <param name="Text">Text to insert</param>
/// <param name="index">Row index where the text should be inserted</param>
/// <returns>The row that was inserted</returns>
public Row Insert(string Text, int index)
{
return Insert(Text, index, true);
}
/// <summary>
/// Insert a text at the specified row index
/// </summary>
/// <param name="Text">Text to insert</param>
/// <param name="index">Row index where the text should be inserted</param>
/// <param name="StoreUndo">true if and undo action should be added to the undo stack</param>
/// <returns>The row that was inserted</returns>
public Row Insert(string Text, int index, bool StoreUndo)
{
Row xtl = new Row();
xtl.Document = this;
mDocument.Insert(index, xtl);
xtl.Text = Text;
if (StoreUndo)
{
UndoBlock undo = new UndoBlock();
undo.Text = Text;
undo.Position.Y = this.IndexOf(xtl);
AddToUndoList(undo);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?