Пример #1
0
			// Update after an insertion.
			public static unsafe void InsertionUpdate
						(TextTree tree, TextBuffer buffer,
						 int offset, int length)
					{
						// NOTE: this is here to keep the method calls down to
						//       a minimum... technically, this belongs in the
						//       tree, but it's more efficient to do this here,
						//       where we can access the line/node fields
						//       directly

						// declare the start offset of the insertion line
						int lineStart;

						// find the insertion line
						TextLine line = tree.FindLineByCharOffset
							(offset, out lineStart);

						// get the parent of the insertion line
						TextNode parent = line.Parent;

						// get the end offset of the insertion line
						int lineEnd = line.end.Offset;

						// create a text slice
						TextSlice slice = new TextSlice();

						// get the inserted data into the slice
						buffer.GetSlice(offset, length, slice);

						// get the current line start position
						int currStart = lineStart;

						// get the current line end position
						int currEnd = (offset + 1);

						// set the default new line list
						TextLine first = null;

						// set the default previous new line
						TextLine prev = null;

						// find and create new lines, quickly
						fixed(char* start = &slice.chars[slice.start])
						{
							char* curr = start;
							// get the insertion end position
							char* end = (curr + slice.length);

							// find and create new lines
							while(curr != end)
							{
								if(*curr == '\n')
								{
									if(currStart == lineStart)
									{
										// shorten the insertion line
										line.end.Move(currEnd);
									}
									else
									{
										// create a new line
										TextLine newline = new TextLine
											(buffer.MarkPosition(currStart, true),
											 buffer.MarkPosition(currEnd, true));

										// update list links
										if(first == null)
										{
											// set the current line as the first
											first = newline;
										}
										else
										{
											// set the current line's prev
											newline.prev = prev;

											// set the previous line's next
											prev.next = newline;
										}

										// set the previous line to the current
										prev = newline;
									}

									// update the current line start position
									currStart = currEnd;
								}

								// increment the current input pointer
								++curr;

								// increment the current line end position
								++currEnd;
							}
						}

						// insert new lines and rebalance parent, if needed
						if(first != null)
						{
							// add any remaining characters to new line
							if(currEnd < lineEnd)
							{
								// create a new line
								TextLine newline = new TextLine
									(buffer.MarkPosition(currStart, true),
									 buffer.MarkPosition(currEnd, true));

								// set the current line's prev reference
								newline.prev = prev;

								// set the previous line's next reference
								prev.next = newline;
							}

							// insert the new lines
							parent.InsertChildren(line, first);

							// rebalance, starting at the new lines' parent
							parent.Rebalance(tree);
						}
					}