syntaxdocument.cs
来自「Fireball.CodeEditor is an source code ed」· CS 代码 · 共 1,880 行 · 第 1/3 页
CS
1,880 行
//this.ResetVisibleRows ();
return xtl;
}
/// <summary>
/// Remove a row at specified row index
/// </summary>
/// <param name="index">index of the row that should be removed</param>
public void Remove(int index)
{
Remove(index, true);
}
public void Remove(int index, bool StoreUndo)
{
this.Remove(index, StoreUndo, true);
}
/// <summary>
/// Remove a row at specified row index
/// </summary>
/// <param name="index">index of the row that should be removed</param>
/// <param name="StoreUndo">true if and undo action should be added to the undo stack</param>
public void Remove(int index, bool StoreUndo, bool RaiseChanged)
{
Row r = this[index];
if (StoreUndo)
{
TextRange ra = new TextRange();
if (index != this.Count - 1)
{
ra.FirstColumn = 0;
ra.FirstRow = index;
ra.LastRow = index + 1;
ra.LastColumn = 0;
}
else
{
ra.FirstColumn = r.PrevRow.Text.Length;
ra.FirstRow = index - 1;
ra.LastRow = index;
ra.LastColumn = r.Text.Length;
}
PushUndoBlock(UndoAction.DeleteRange, GetRange(ra), ra.FirstColumn, ra.FirstRow);
}
mDocument.RemoveAt(index);
if (r.InKeywordQueue)
this.KeywordQueue.Remove(r);
if (r.InQueue)
this.ParseQueue.Remove(r);
//this.ResetVisibleRows ();
OnRowDeleted(r);
if (RaiseChanged)
OnChange();
}
/// <summary>
/// Deletes a range of text
/// </summary>
/// <param name="Range">the range that should be deleted</param>
public void DeleteRange(TextRange Range)
{
DeleteRange(Range, true);
}
private int ParseRows(Row r)
{
return ParseRows(r, false);
}
private int ParseRows(Row r, bool Keywords)
{
if (!Keywords)
{
int index = this.IndexOf(r);
int count = 0;
//try
//{
while (r.InQueue && count < 100)
{
if (index >= 0)
{
if (index > 0)
if (this[index - 1].InQueue)
ParseRow(this[index - 1]);
Parser.ParseLine(index, false);
}
int i = this.ParseQueue.IndexOf(r);
if (i >= 0)
this.ParseQueue.RemoveAt(i);
r.InQueue = false;
index++;
count++;
r = this[index];
if (r == null)
break;
}
//}
//catch
//{
//}
return count;
}
else
{
int index = this.IndexOf(r);
if (index == -1 || r.InKeywordQueue == false)
{
this.KeywordQueue.Remove(r);
return 0;
}
int count = 0;
//try
//{
while (r.InKeywordQueue && count < 100)
{
if (index >= 0)
{
if (index > 0)
if (this[index - 1].InQueue)
ParseRow(this[index - 1]);
Parser.ParseLine(index, true);
}
index++;
count++;
r = this[index];
if (r == null)
break;
}
//}
//catch
//{
//}
return count;
}
}
/// <summary>
/// Forces a row to be parsed
/// </summary>
/// <param name="r">Row to parse</param>
/// <param name="ParseKeywords">true if keywords and operators should be parsed</param>
public void ParseRow(Row r, bool ParseKeywords)
{
int index = this.IndexOf(r);
if (index >= 0)
{
if (index > 0)
if (this[index - 1].InQueue)
ParseRow(this[index - 1]);
Parser.ParseLine(index, false);
if (ParseKeywords)
Parser.ParseLine(index, true);
}
int i = this.ParseQueue.IndexOf(r);
if (i >= 0)
this.ParseQueue.RemoveAt(i);
r.InQueue = false;
}
/// <summary>
/// Forces a row to be parsed
/// </summary>
/// <param name="r">Row to parse</param>
public void ParseRow(Row r)
{
ParseRow(r, false);
}
/// <summary>
/// Gets the row index of the next bookmarked row
/// </summary>
/// <param name="StartIndex">Start index</param>
/// <returns>Index of the next bookmarked row</returns>
public int GetNextBookmark(int StartIndex)
{
for (int i = StartIndex + 1; i < this.Count; i++)
{
Row r = this[i];
if (r.Bookmarked)
return i;
}
for (int i = 0; i < StartIndex; i++)
{
Row r = this[i];
if (r.Bookmarked)
return i;
}
return StartIndex;
}
/// <summary>
/// Gets the row index of the previous bookmarked row
/// </summary>
/// <param name="StartIndex">Start index</param>
/// <returns>Index of the previous bookmarked row</returns>
public int GetPreviousBookmark(int StartIndex)
{
for (int i = StartIndex - 1; i >= 0; i--)
{
Row r = this[i];
if (r.Bookmarked)
return i;
}
for (int i = this.Count - 1; i >= StartIndex; i--)
{
Row r = this[i];
if (r.Bookmarked)
return i;
}
return StartIndex;
}
/// <summary>
/// Deletes a range of text
/// </summary>
/// <param name="Range">Range to delete</param>
/// <param name="StoreUndo">true if the actions should be pushed onto the undo stack</param>
public void DeleteRange(TextRange Range, bool StoreUndo)
{
TextRange r = Range;
Modified = true;
if (StoreUndo)
{
string deltext = GetRange(Range);
PushUndoBlock(UndoAction.DeleteRange, deltext, r.FirstColumn, r.FirstRow);
}
if (r.FirstRow == r.LastRow)
{
Row xtr = this[r.FirstRow];
int max = Math.Min(r.FirstColumn, xtr.Text.Length);
string left = xtr.Text.Substring(0, max);
string right = "";
if (xtr.Text.Length >= r.LastColumn)
right = xtr.Text.Substring(r.LastColumn);
xtr.Text = left + right;
}
else
{
if (r.LastRow > this.Count - 1)
r.LastRow = this.Count - 1;
string row1 = "";
Row xtr = this[r.FirstRow];
if (r.FirstColumn > xtr.Text.Length)
{
int diff = r.FirstColumn - xtr.Text.Length;
string ws = new string(' ', diff);
this.InsertText(ws, xtr.Text.Length, r.FirstRow, true);
//return;
}
row1 = xtr.Text.Substring(0, r.FirstColumn);
string row2 = "";
Row xtr2 = this[r.LastRow];
int Max = Math.Min(xtr2.Text.Length, r.LastColumn);
row2 = xtr2.Text.Substring(Max);
string tot = row1 + row2;
//bool fold=this[r.LastRow].IsCollapsed | this[r.FirstRow].IsCollapsed ;
int start = r.FirstRow;
int end = r.LastRow;
for (int i = end - 1; i >= start; i--)
{
this.Remove(i, false, false);
}
//todo: DeleteRange error
//this.Insert ( tot ,r.FirstRow,false);
Row row = this[start];
bool f = row.IsCollapsed;
row.Expanded = true;
row.Text = tot;
row.StartSegments.Clear();
row.EndSegments.Clear();
row.StartSegment = null;
row.EndSegment = null;
row.Parse();
// if (row.CanFold)
// row.Expansion_StartSegment.Expanded = !fold;
}
//ShirinkFormatRanges
if (this.FormatRanges != null)
{
this.FormatRanges.Shrink(Range);
}
ResetVisibleRows();
OnChange();
}
/// <summary>
/// Get a range of text
/// </summary>
/// <param name="Range">The range to get</param>
/// <returns>string containing the text inside the given range</returns>
public string GetRange(TextRange Range)
{
if (Range.FirstRow >= this.Count)
Range.FirstRow = this.Count;
if (Range.LastRow >= this.Count)
Range.LastRow = this.Count;
if (Range.FirstRow != Range.LastRow)
{
//note:error has been tracked here
Row r1 = this[Range.FirstRow];
int mx = Math.Min(r1.Text.Length, Range.FirstColumn);
string s1 = r1.Text.Substring(mx) + Environment.NewLine;
//if (Range.LastRow >= this.Count)
// Range.LastRow=this.Count -1;
Row r2 = this[Range.LastRow];
if (r2 == null)
return "";
int Max = Math.Min(r2.Text.Length, Range.LastColumn);
string s2 = r2.Text.Substring(0, Max);
string s3 = "";
StringBuilder sb = new StringBuilder();
for (int i = Range.FirstRow + 1; i <= Range.LastRow - 1; i++)
{
Row r3 = this[i];
sb.Append(r3.Text + Environment.NewLine);
}
s3 = sb.ToString();
return s1 + s3 + s2;
}
else
{
Row r = this[Range.FirstRow];
int Max = Math.Min(r.Text.Length, Range.LastColumn);
int Length = Max - Range.FirstColumn;
if (Length <= 0)
return "";
string s = r.Text.Substring(Range.FirstColumn, Max - Range.FirstColumn);
return s;
}
}
/// <summary>
/// Gets the row count of the document
/// </summary>
[Browsable(false)]
public int Count
{
get { return mDocument.Count; }
}
/// <summary>
/// Returns the index of a given row
/// </summary>
/// <param name="xtr">row to find</param>
/// <returns>Index of the given row</returns>
public int IndexOf(Row xtr)
{
return mDocument.IndexOf(xtr);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
public IEnumerator GetEnumerator()
{
return mDocument.GetEnumerator();
}
/// <summary>
/// Clear all content in the document
/// </summary>
public void clear()
{
foreach (Row r in mDocument)
{
OnRowDeleted(r);
}
mDocument.Clear();
// this.FormatRanges.Clear ();
ParseQueue.Clear();
KeywordQueue.Clear();
UndoBuffer.Clear();
UndoStep = 0;
// this.Add ("");
// ResetVisibleRows();
// this.OnChange ();
}
/// <summary>
/// Gets or Sets the text of the entire document
/// </summary>
[Browsable(false)]
// [RefreshProperties (RefreshProperties.All)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public string Text
{
get
{
int i = 0;
StringBuilder sb = new StringBuilder();
ParseAll(true);
foreach (Row tr in mDocument)
{
if (i > 0)
sb.Append(Environment.NewLine);
tr.MatchCase();
sb.Append(tr.Text);
i++;
}
return sb.ToString();
}
set
{
this.clear();
this.Add("");
InsertText(value, 0, 0);
UndoBuffer.Clear();
UndoStep = 0;
Modified = false;
mIsParsed = false;
//OnChange();
InvokeChange();
}
}
public void Clear()
{
this.Text = "";
}
/// <summary>
/// Gets and string array containing the text of all rows.
/// </summary>
public string[] Lines
{
get
{
string s = this.Text.Replace(Environment.NewLine, "\n");
return Text.Split("\n".ToCharArray());
}
set
{
string s = "";
foreach (string sl in value)
s += sl + "\n";
Text = s.Substring(0, s.Length - 1);
}
}
/// <summary>
/// Inserts a text into the document at a given column,row.
/// </summary>
/// <param name="text">Text to insert</param>
/// <param name="xPos">Column</param>
/// <param name="yPos">Row index</param>
/// <returns>TextPoint containing the end of the inserted text</returns>
public TextPoint InsertText(string text, int xPos, int yPos)
{
return InsertText(text, xPos, yPos, true);
}
/// <summary>
/// Inserts a text into the document at a given column,row.
/// </summary>
/// <param name="text">Text to insert</param>
/// <param name="xPos">Column</param>
/// <param name="yPos">Row index</param>
/// <param name="StoreUndo">true if this action should be pushed onto the undo stack</param>
/// <returns>TextPoint containing the end of the inserted text</returns>
public TextPoint InsertText(string text, int xPos, int yPos, bool StoreUndo)
{
Modified = true;
Row xtr = this[yPos];
string lft, rgt;
if (xPos > xtr.Text.Length)
{
//virtualwhitespace fix
int Padd = xPos - xtr.Text.Length;
string PaddStr = new string(' ', Padd);
text = PaddStr + text;
xPos -= Padd;
}
lft = xtr.Text.Substring(0, xPos);
rgt = xtr.Text.Substring(xPos);
string NewText = lft + text + rgt;
string t = NewText.Replace(Environment.NewLine, "\n");
string[] lines = t.Split('\n');
xtr.Text = lines[0];
Row lastrow = xtr;
//this.Parser.ParsePreviewLine(xtr);
xtr.Parse();
if (!xtr.InQueue)
this.ParseQueue.Add(xtr);
xtr.InQueue = true;
int i = IndexOf(xtr);
for (int j = 1; j < lines.Length; j++)
{
lastrow = Insert(lines[j], j + i, false);
}
if (StoreUndo)
PushUndoBlock(UndoAction.InsertRange, text, xPos, yPos);
//ExpandFormatRanges
if (this.FormatRanges != null)
{
this.FormatRanges.Expand(xPos, yPos, text);
}
this.ResetVisibleRows();
OnChange();
return new TextPoint(lastrow.Text.Length - rgt.Length, IndexOf(lastrow));
}
private void OnModifiedChanged()
{
//System.Windows.Forms.MessageBox.Show ("on change");
if (ModifiedChanged != null)
ModifiedChanged(this, new EventArgs());
}
private void OnChange()
{
//System.Windows.Forms.MessageBox.Show ("on change");
if (Change != null)
Change(this, new EventArgs());
}
private void OnRowParsed(Row r)
{
if (RowParsed != null)
RowParsed(this, new RowEventArgs(r));
this.OnApplyFormatRanges(r);
}
// private void OnRowAdded(Row r)
// {
// if (RowAdded != null)
// RowAdded(this,new RowEventArgs(r));
// }
private void OnRowDeleted(Row r)
{
if (RowDeleted != null)
RowDeleted(this, new RowEventArgs(r));
}
public void PushUndoBlock(UndoAction Action, string Text, int x, int y)
{
UndoBlock undo = new UndoBlock();
undo.Action = Action;
undo.Text = Text;
undo.Position.Y = y;
undo.Position.X = x;
//AddToUndoList(undo);
if (mCaptureMode)
{
mCaptureBlock.Add(undo);
}
else
{
AddToUndoList(undo);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?