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 + -
显示快捷键?