void CheckBufferSize() { if (_BufferLines == -1) { // no limit defined return; } var buffer = Buffer; if (buffer.LineCount > _BufferLines) { Gtk.TextIter start_iter = buffer.StartIter; // TODO: maybe we should delete chunks instead of each line Gtk.TextIter end_iter = buffer.GetIterAtLine(buffer.LineCount - _BufferLines); int offset = end_iter.Offset; // release tags var toggled_tags = new List <Gtk.TextTag>(16); var start_tags = start_iter.GetToggledTags(true); toggled_tags.AddRange(start_tags); var tag_iter = start_iter; while (tag_iter.ForwardToTagToggle(null)) { if (tag_iter.Compare(end_iter) >= 0) { // tag is after line end break; } var iter_tags = tag_iter.GetToggledTags(true); toggled_tags.AddRange(iter_tags); } foreach (var tag in toggled_tags) { // don't remove color tags as they are shared wither other lines var tagName = tag.Name; if (tagName != null && (tagName.StartsWith("fg_color:") || tagName.StartsWith("bg_color:"))) { continue; } if (tag.IndentSet || tag is LinkTag || tag is PersonTag) { buffer.RemoveTag(tag, start_iter, end_iter); _MessageTextTagTable.Remove(tag); tag.Dispose(); } } buffer.Delete(ref start_iter, ref end_iter); // update markerline offset if present if (_MarkerlineBufferPosition != 0) { _MarkerlineBufferPosition -= offset; // remove markerline if it went out of buffer if (_MarkerlineBufferPosition < 0) { _MarkerlineBufferPosition = 0; } } } }