syntaxdocument.cs
来自「Fireball.CodeEditor is an source code ed」· CS 代码 · 共 1,880 行 · 第 1/3 页
CS
1,880 行
}
/// <summary>
/// Gets a Range from a given text
/// </summary>
/// <param name="text"></param>
/// <param name="xPos"></param>
/// <param name="yPos"></param>
/// <returns></returns>
public TextRange GetRangeFromText(string text, int xPos, int yPos)
{
string t = text.Replace(Environment.NewLine, "\n");
string[] lines = t.Split("\n".ToCharArray());
TextRange r = new TextRange();
r.FirstColumn = xPos;
r.FirstRow = yPos;
r.LastRow = lines.Length - 1 + yPos;
r.LastColumn = lines[lines.Length - 1].Length;
if (r.FirstRow == r.LastRow)
r.LastColumn += r.FirstColumn;
return r;
}
public void AddToUndoList(UndoBlock undo)
{
//store the undo action in a actiongroup
UndoBlockCollection ActionGroup = new UndoBlockCollection();
ActionGroup.Add(undo);
AddToUndoList(ActionGroup);
}
/// <summary>
/// Add an action to the undo stack
/// </summary>
/// <param name="ActionGroup">action to add</param>
public void AddToUndoList(UndoBlockCollection ActionGroup)
{
//int count=UndoBuffer.Count-UndoStep;
// if (count>0)
// {
// System.Windows.Forms.MessageBox.Show (UndoStep.ToString ());
// System.Windows.Forms.MessageBox.Show (count.ToString ());
// }
UndoBuffer.ClearFrom(UndoStep);
// System.Windows.Forms.MessageBox.Show (UndoBuffer.Count.ToString());
UndoBuffer.Add(ActionGroup);
UndoStep++;
this.OnUndoBufferChanged();
}
/// <summary>
/// Perform an undo action
/// </summary>
/// <returns>The position where the caret should be placed</returns>
public TextPoint Undo()
{
if (UndoStep == 0)
return new TextPoint(-1, -1);
UndoBlockCollection ActionGroup = (UndoBlockCollection) this.UndoBuffer[UndoStep - 1];
UndoBlock undo = (UndoBlock) ActionGroup[0];
for (int i = ActionGroup.Count - 1; i >= 0; i--)
{
undo = (UndoBlock) ActionGroup[i];
//TextPoint tp=new TextPoint (undo.Position.X,undo.Position.Y);
switch (undo.Action)
{
case UndoAction.DeleteRange:
InsertText(undo.Text, undo.Position.X, undo.Position.Y, false);
break;
case UndoAction.InsertRange:
{
TextRange r = GetRangeFromText(undo.Text, undo.Position.X, undo.Position.Y);
DeleteRange(r, false);
}
break;
default:
break;
}
}
UndoStep--;
this.ResetVisibleRows();
//no undo steps left , the document is not dirty
if (UndoStep == 0)
Modified = false;
TextPoint tp = new TextPoint(undo.Position.X, undo.Position.Y);
OnUndoBufferChanged();
return tp;
}
public void AutoIndentSegment(Segment Segment)
{
if (Segment == null)
Segment = this[0].StartSegment;
Row start = Segment.StartRow;
Row end = Segment.EndRow;
if (start == null)
start = this[0];
if (end == null)
end = this[this.Count - 1];
for (int i = start.Index; i <= end.Index; i++)
{
Row r = this[i];
int depth = r.Indent;
string text = r.Text.Substring(r.GetLeadingWhitespace().Length);
string indent = new string('\t', depth);
r.Text = indent + text;
}
this.ResetVisibleRows();
}
//Returns the segment object at the given position
/// <summary>
/// Gets a Segment object form a given column , Row index
/// (This only applies if the row is fully parsed)
/// </summary>
/// <param name="p">Column and Rowindex</param>
/// <returns>Segment object at the given position</returns>
public Segment GetSegmentFromPos(TextPoint p)
{
Row xtr = this[p.Y];
int CharNo = 0;
if (xtr.Count == 0)
return xtr.StartSegment;
Segment prev = xtr.StartSegment;
Word w;
//foreach (Word w in xtr)
for (int i = 0; i < xtr.Count; i++)
{
w = xtr[i];
if (w.Text.Length + CharNo > p.X)
{
if (CharNo == p.X)
return prev;
else
return w.Segment;
}
else
{
CharNo += w.Text.Length;
prev = w.Segment;
}
}
return xtr.EndSegment;
}
//the specific word that contains the char in point p
/// <summary>
/// Gets a Word object form a given column , Row index
/// (this only applies if the row is fully parsed)
/// </summary>
/// <param name="p">Column and Rowindex</param>
/// <returns>Word object at the given position</returns>
public Word GetWordFromPos(TextPoint p)
{
Row xtr = this[p.Y];
int CharNo = 0;
Word CorrectWord = null;
Word w;
//foreach (Word w in xtr)
for(int i = 0; i< xtr.Count;i++)
{
w = xtr[i];
if (CorrectWord != null)
{
if (w.Text == "")
return w;
else
return CorrectWord;
}
if (w.Text.Length + CharNo > p.X || w == xtr[xtr.Count - 1])
{
//return w;
CorrectWord = w;
}
else
{
CharNo += w.Text.Length;
}
}
return CorrectWord;
}
//the specific word that contains the char in point p
/// <summary>
/// Gets a Word object form a given column , Row index
/// (this only applies if the row is fully parsed)
/// </summary>
/// <param name="p">Column and Rowindex</param>
/// <returns>Word object at the given position</returns>
public Word GetFormatWordFromPos(TextPoint p)
{
Row xtr = this[p.Y];
int CharNo = 0;
Word CorrectWord = null;
//foreach (Word w in xtr.FormattedWords)
for(int i = 0; i< xtr.FormattedWords.Count;i++)
{
Word w = xtr.FormattedWords[i];
if (CorrectWord != null)
{
if (w.Text == "")
return w;
else
return CorrectWord;
}
if (w.Text.Length + CharNo > p.X || w == xtr[xtr.Count - 1])
{
//return w;
CorrectWord = w;
}
else
{
CharNo += w.Text.Length;
}
}
return CorrectWord;
}
/// <summary>
/// Call this method to make the document raise the RowParsed event
/// </summary>
/// <param name="row"></param>
public void InvokeRowParsed(Row row)
{
this.OnRowParsed(row);
}
/// <summary>
/// Call this method to recalculate the visible rows
/// </summary>
public void ResetVisibleRows()
{
InternalResetVisibleRows();
}
private void InternalResetVisibleRows()
{
// if (System.DateTime.Now > new DateTime (2002,12,31))
// {
//
// this.mDocument = new RowCollection ();
// this.Add ("BETA VERSION EXPIRED");
// VisibleRows = this.mDocument;
// return;
// }
if (!this.mFolding)
{
VisibleRows = mDocument;
this.NeedResetRows = false;
}
else
{
this.NeedResetRows = false;
VisibleRows = new RowCollection(); //.Clear ();
int RealRow = 0;
Row r = null;
for (int i = 0; i < this.Count; i++)
{
r = this[RealRow];
VisibleRows.Add(r);
bool collapsed = false;
if (r.CanFold)
if (r.Expansion_StartSegment.Expanded == false)
{
if (r.Expansion_StartSegment.EndWord == null)
{
}
else
{
r = r.Expansion_EndRow; // .Expansion_StartSegment.EndRow;
collapsed = true;
}
}
if (!collapsed)
RealRow++;
else
RealRow = this.IndexOf(r) + 1;
if (RealRow >= this.Count)
break;
}
}
}
/// <summary>
/// Converts a Column/Row index position into a char index
/// </summary>
/// <param name="pos">TextPoint where x is column and y is row index</param>
/// <returns>Char index in the document text</returns>
public int PointToIntPos(TextPoint pos)
{
int y = 0;
int p = 0;
foreach (Row r in this)
{
if (y == pos.Y)
break;
p += r.Text.Length + Environment.NewLine.Length;
y++;
}
return p + Math.Min(pos.X, this[pos.Y].Text.Length);
}
/// <summary>
/// Converts a char index into a Column/Row index
/// </summary>
/// <param name="pos">Char index to convert</param>
/// <returns>Point where x is column and y is row index</returns>
public TextPoint IntPosToPoint(int pos)
{
int p = 0;
int y = 0;
int x = 0;
foreach (Row r in this)
{
p += r.Text.Length + Environment.NewLine.Length;
if (p > pos)
{
p -= r.Text.Length + Environment.NewLine.Length;
x = pos - p;
return new TextPoint(x, y);
}
y++;
}
return new TextPoint(-1, -1);
}
/// <summary>
/// Toggle expansion of a given row
/// </summary>
/// <param name="r"></param>
public void ToggleRow(Row r)
{
if (!mFolding)
return;
if (r.Expansion_EndRow == null || r.Expansion_StartRow == null)
return;
// if (r.IsCollapsed)
// {
// r.Expansion_StartSegment.Expanded = true;
// ExpandRow(r);
// }
// else
// {
// r.Expansion_StartSegment.Expanded = false;
// CollapseRow(r);
// }
if (r.CanFold)
r.Expanded = !r.Expanded;
ResetVisibleRows();
OnChange();
}
/// <summary>
/// Collapse a given row
/// </summary>
/// <param name="r">Row to collapse</param>
private void CollapseRow(Row r)
{
//remove rows from visible list
Row start = r.Expansion_StartRow;
Row end = r.Expansion_EndRow;
int count = end.VisibleIndex - start.VisibleIndex - 1;
int startIndex = start.VisibleIndex + 1;
for (int i = 0; i <= count; i++)
{
this.VisibleRows.RemoveAt(startIndex);
}
}
/// <summary>
/// Expand a given row
/// </summary>
/// <param name="r">Row to expand</param>
private void ExpandRow(Row r)
{
//add rows to visible list...
Row start = r.Expansion_StartRow;
Row end = r.Expansion_EndRow;
int count = end.Index - start.Index - 1;
int startIndex = start.Index + 1;
int visIndex = start.VisibleIndex + 1;
int i = 0;
while (i <= count)
{
Row tmpRow = this[startIndex + i];
this.VisibleRows.Insert(visIndex, tmpRow);
if (tmpRow.Expansion_StartSegment != null)
if (tmpRow.Expansion_StartSegment.Expanded == false)
{
tmpRow = tmpRow.Expansion_StartSegment.EndRow;
i = tmpRow.Index - startIndex;
}
visIndex++;
i++;
}
//ResetVisibleRows ();
}
/// <summary>
/// Perform an redo action
/// </summary>
/// <returns>The position where the caret should be placed</returns>
public TextPoint Redo()
{
if (UndoStep >= UndoBuffer.Count)
return new TextPoint(-1, -1);
UndoBlockCollection ActionGroup = (UndoBlockCollection) this.UndoBuffer[UndoStep];
UndoBlock undo = (UndoBlock) ActionGroup[0];
for (int i = 0; i < ActionGroup.Count; i++)
{
undo = (UndoBlock) ActionGroup[i];
switch (undo.Action)
{
case UndoAction.InsertRange:
{
InsertText(undo.Text, undo.Position.X, undo.Position.Y, false);
}
break;
case UndoAction.DeleteRange:
{
TextRange r = GetRangeFromText(undo.Text, undo.Position.X, undo.Position.Y);
DeleteRange(r, false);
}
break;
default:
break;
}
}
TextRange ran = GetRangeFromText(undo.Text, undo.Position.X, undo.Position.Y);
UndoStep++;
this.ResetVisibleRows();
OnUndoBufferChanged();
return new TextPoint(ran.LastColumn, ran.LastRow);
}
public Word GetStartBracketWord(Word Start, Pattern End, Segment FindIn)
{
if (Start == null || Start.Pattern == null || Start.Segment == null)
return null;
int CurrentRow = Start.Row.Index;
int FirstRow = FindIn.StartRow.Index;
int x = Start.Index;
int count = 0;
while (CurrentRow >= FirstRow)
{
for (int i = x; i >= 0; i--)
{
Word w = this[CurrentRow][i];
if (w.Segment == FindIn && w.Type == WordType.xtWord)
{
if (w.Pattern == Start.Pattern)
count++;
if (w.Pattern == End)
count--;
if (count == 0)
return w;
}
}
if (!Start.Pattern.IsMultiLineBracket)
break;
CurrentRow--;
if (CurrentRow >= 0)
x = this[CurrentRow].Count - 1;
}
return null;
}
public Word GetEndBracketWord(Word Start, Pattern End, Segment FindIn)
{
if (Start == null || Start.Pattern == null || Start.Segment == null)
return null;
int CurrentRow = Start.Row.Index;
int LastRow = this.Count - 1;
if (FindIn.EndRow != null)
LastRow = FindIn.EndRow.Index;
int x = Start.Index;
int count = 0;
while (CurrentRow <= LastRow)
{
for (int i = x; i < this[CurrentRow].Count; i++)
{
Word w = this[CurrentRow][i];
if (w.Segment == FindIn && w.Type == WordType.xtWord)
{
if (w.Pattern == Start.Pattern)
count++;
if (w.Pattern == End)
count--;
if (count == 0)
return w;
}
}
if (!Start.Pattern.IsMultiLineBracket)
break;
CurrentRow++;
x = 0;
}
return null;
}
/// <summary>
///
/// </summary>
~SyntaxDocument()
{
}
protected internal void OnApplyFormatRanges(Row row)
{
if (this.FormatRanges == null)
return;
if (!this.FormatRanges.RowContainsFormats(row) || row.RowState != RowState.AllParsed)
{
row.FormattedWords = row.mWords;
}
else
{
row.FormattedWords = new WordCollection();
int i = 0;
int l = 0;
int x = 0;
int ri = row.Index;
foreach (char c in row.Text)
{
Word w = row[i];
FormatRange fr = FormatRanges.MergeFormats(x, ri);
Word wn = new Word();
wn.Text = c.ToString();
if (fr == null)
{
wn.Style = w.Style;
}
else
{
wn.Style = new TextStyle();
if (w.Style == null)
w.Style = new TextStyle();
wn.Style.BackColor = (fr.BackColor == Color.Empty) ? w.Style.BackColor : fr.BackColor;
wn.Style.ForeColor = (fr.ForeColor == Color.Empty) ? w.Style.ForeColor : fr.ForeColor;
wn.InfoTip = fr.InfoTip;
/*wn.Style.Bold = false;
wn.Style.Italic = true;
wn.Style.Underline = false;*/
if (fr.WaveColor != Color.Empty)
{
wn.HasError = true;
wn.ErrorColor = fr.WaveColor;
}
}
wn.Type = w.Type;
wn.Segment = w.Segment;
row.FormattedWords.Add(wn);
l++;
if (l == row[i].Text.Length)
{
i++;
l = 0;
}
x++;
}
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?