Blame gtksourceview/gtksourcemarkssequence.c

Packit a7d494
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; coding: utf-8 -*- */
Packit a7d494
/* gtksourcemarkssequence.c
Packit a7d494
 * This file is part of GtkSourceView
Packit a7d494
 *
Packit a7d494
 * Copyright (C) 2013 - Sébastien Wilmet <swilmet@gnome.org>
Packit a7d494
 *
Packit a7d494
 * GtkSourceView is free software; you can redistribute it and/or
Packit a7d494
 * modify it under the terms of the GNU Lesser General Public
Packit a7d494
 * License as published by the Free Software Foundation; either
Packit a7d494
 * version 2.1 of the License, or (at your option) any later version.
Packit a7d494
 *
Packit a7d494
 * GtkSourceView is distributed in the hope that it will be useful,
Packit a7d494
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a7d494
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a7d494
 * Lesser General Public License for more details.
Packit a7d494
 *
Packit a7d494
 * You should have received a copy of the GNU Lesser General Public
Packit a7d494
 * License along with this library; if not, write to the Free Software
Packit a7d494
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
Packit a7d494
 */
Packit a7d494
Packit a7d494
#include "gtksourcemarkssequence.h"
Packit a7d494
Packit a7d494
/* An object for storing GtkTextMarks. The text marks are sorted internally with
Packit a7d494
 * a GSequence. Going to the previous or next text mark has a O(1) complexity.
Packit a7d494
 * Finding a text mark in the neighborhood of a text iter has a O(log n)
Packit a7d494
 * complexity, with 'n' the number of marks in the sequence.
Packit a7d494
 *
Packit a7d494
 * The GSequenceIter associated to a text mark is inserted into the text mark,
Packit a7d494
 * with g_object_set_qdata(). So the text mark knows its position in the
Packit a7d494
 * GSequence. This allows to use normal GtkTextMarks in the API, instead of
Packit a7d494
 * using a subclass or a custom iter.
Packit a7d494
 *
Packit a7d494
 * The MarksSequence has a weak reference to the text buffer.
Packit a7d494
 */
Packit a7d494
Packit a7d494
enum
Packit a7d494
{
Packit a7d494
	PROP_0,
Packit a7d494
	PROP_BUFFER,
Packit a7d494
};
Packit a7d494
Packit a7d494
struct _GtkSourceMarksSequencePrivate
Packit a7d494
{
Packit a7d494
	GtkTextBuffer *buffer;
Packit a7d494
	GSequence *seq;
Packit a7d494
Packit a7d494
	/* The quark used for storing the GSequenceIter into the text mark, with
Packit a7d494
	 * g_object_set_qdata().
Packit a7d494
	 */
Packit a7d494
	GQuark quark;
Packit a7d494
};
Packit a7d494
Packit a7d494
G_DEFINE_TYPE_WITH_PRIVATE (GtkSourceMarksSequence, _gtk_source_marks_sequence, G_TYPE_OBJECT)
Packit a7d494
Packit a7d494
static void
Packit a7d494
remove_qdata (GtkTextMark            *mark,
Packit a7d494
	      GtkSourceMarksSequence *seq)
Packit a7d494
{
Packit a7d494
	g_object_set_qdata (G_OBJECT (mark),
Packit a7d494
			    seq->priv->quark,
Packit a7d494
			    NULL);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
free_sequence (GtkSourceMarksSequence *seq)
Packit a7d494
{
Packit a7d494
	if (seq->priv->seq != NULL)
Packit a7d494
	{
Packit a7d494
		g_sequence_foreach (seq->priv->seq,
Packit a7d494
				    (GFunc)remove_qdata,
Packit a7d494
				    seq);
Packit a7d494
Packit a7d494
		g_sequence_free (seq->priv->seq);
Packit a7d494
		seq->priv->seq = NULL;
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static gint
Packit a7d494
compare_marks (GtkTextMark *mark1,
Packit a7d494
	       GtkTextMark *mark2)
Packit a7d494
{
Packit a7d494
	GtkTextBuffer *buffer;
Packit a7d494
	GtkTextIter iter1;
Packit a7d494
	GtkTextIter iter2;
Packit a7d494
Packit a7d494
	g_assert (GTK_IS_TEXT_MARK (mark1));
Packit a7d494
	g_assert (GTK_IS_TEXT_MARK (mark2));
Packit a7d494
Packit a7d494
	buffer = gtk_text_mark_get_buffer (mark1);
Packit a7d494
Packit a7d494
	g_assert (buffer == gtk_text_mark_get_buffer (mark2));
Packit a7d494
Packit a7d494
	gtk_text_buffer_get_iter_at_mark (buffer, &iter1, mark1);
Packit a7d494
	gtk_text_buffer_get_iter_at_mark (buffer, &iter2, mark2);
Packit a7d494
Packit a7d494
	return gtk_text_iter_compare (&iter1, &iter2);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
mark_set_cb (GtkTextBuffer          *buffer,
Packit a7d494
	     GtkTextIter            *location,
Packit a7d494
	     GtkTextMark            *mark,
Packit a7d494
	     GtkSourceMarksSequence *seq)
Packit a7d494
{
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
Packit a7d494
	seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
Packit a7d494
Packit a7d494
	if (seq_iter != NULL)
Packit a7d494
	{
Packit a7d494
		g_sequence_sort_changed (seq_iter,
Packit a7d494
					 (GCompareDataFunc)compare_marks,
Packit a7d494
					 NULL);
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
mark_deleted_cb (GtkTextBuffer          *buffer,
Packit a7d494
		 GtkTextMark            *mark,
Packit a7d494
		 GtkSourceMarksSequence *seq)
Packit a7d494
{
Packit a7d494
	_gtk_source_marks_sequence_remove (seq, mark);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
set_buffer (GtkSourceMarksSequence *seq,
Packit a7d494
	    GtkTextBuffer          *buffer)
Packit a7d494
{
Packit a7d494
	g_assert (seq->priv->buffer == NULL);
Packit a7d494
Packit a7d494
	seq->priv->buffer = buffer;
Packit a7d494
Packit a7d494
	g_object_add_weak_pointer (G_OBJECT (buffer),
Packit a7d494
				   (gpointer *)&seq->priv->buffer);
Packit a7d494
Packit a7d494
	g_signal_connect_object (buffer,
Packit a7d494
				 "mark-set",
Packit a7d494
				 G_CALLBACK (mark_set_cb),
Packit a7d494
				 seq,
Packit a7d494
				 0);
Packit a7d494
Packit a7d494
	g_signal_connect_object (buffer,
Packit a7d494
				 "mark-deleted",
Packit a7d494
				 G_CALLBACK (mark_deleted_cb),
Packit a7d494
				 seq,
Packit a7d494
				 0);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
_gtk_source_marks_sequence_dispose (GObject *object)
Packit a7d494
{
Packit a7d494
	GtkSourceMarksSequence *seq = GTK_SOURCE_MARKS_SEQUENCE (object);
Packit a7d494
Packit a7d494
	if (seq->priv->buffer != NULL)
Packit a7d494
	{
Packit a7d494
		g_object_remove_weak_pointer (G_OBJECT (seq->priv->buffer),
Packit a7d494
					      (gpointer *)&seq->priv->buffer);
Packit a7d494
Packit a7d494
		seq->priv->buffer = NULL;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	free_sequence (seq);
Packit a7d494
Packit a7d494
	G_OBJECT_CLASS (_gtk_source_marks_sequence_parent_class)->dispose (object);
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
_gtk_source_marks_sequence_get_property (GObject    *object,
Packit a7d494
					 guint       prop_id,
Packit a7d494
					 GValue     *value,
Packit a7d494
					 GParamSpec *pspec)
Packit a7d494
{
Packit a7d494
	GtkSourceMarksSequence *seq;
Packit a7d494
Packit a7d494
	g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (object));
Packit a7d494
Packit a7d494
	seq = GTK_SOURCE_MARKS_SEQUENCE (object);
Packit a7d494
Packit a7d494
	switch (prop_id)
Packit a7d494
	{
Packit a7d494
		case PROP_BUFFER:
Packit a7d494
			g_value_set_object (value, seq->priv->buffer);
Packit a7d494
			break;
Packit a7d494
Packit a7d494
		default:
Packit a7d494
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit a7d494
			break;
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
_gtk_source_marks_sequence_set_property (GObject      *object,
Packit a7d494
					 guint         prop_id,
Packit a7d494
					 const GValue *value,
Packit a7d494
					 GParamSpec   *pspec)
Packit a7d494
{
Packit a7d494
	GtkSourceMarksSequence *seq;
Packit a7d494
Packit a7d494
	g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (object));
Packit a7d494
Packit a7d494
	seq = GTK_SOURCE_MARKS_SEQUENCE (object);
Packit a7d494
Packit a7d494
	switch (prop_id)
Packit a7d494
	{
Packit a7d494
		case PROP_BUFFER:
Packit a7d494
			set_buffer (seq, g_value_get_object (value));
Packit a7d494
			break;
Packit a7d494
Packit a7d494
		default:
Packit a7d494
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit a7d494
			break;
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
_gtk_source_marks_sequence_class_init (GtkSourceMarksSequenceClass *klass)
Packit a7d494
{
Packit a7d494
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit a7d494
Packit a7d494
	object_class->dispose = _gtk_source_marks_sequence_dispose;
Packit a7d494
	object_class->get_property = _gtk_source_marks_sequence_get_property;
Packit a7d494
	object_class->set_property = _gtk_source_marks_sequence_set_property;
Packit a7d494
Packit a7d494
	g_object_class_install_property (object_class,
Packit a7d494
					 PROP_BUFFER,
Packit a7d494
					 g_param_spec_object ("buffer",
Packit a7d494
							      "Buffer",
Packit a7d494
							      "The text buffer",
Packit a7d494
							      GTK_TYPE_TEXT_BUFFER,
Packit a7d494
							      G_PARAM_READWRITE |
Packit a7d494
							      G_PARAM_CONSTRUCT_ONLY |
Packit a7d494
							      G_PARAM_STATIC_STRINGS));
Packit a7d494
}
Packit a7d494
Packit a7d494
static void
Packit a7d494
_gtk_source_marks_sequence_init (GtkSourceMarksSequence *seq)
Packit a7d494
{
Packit a7d494
	gchar *unique_str;
Packit a7d494
Packit a7d494
	seq->priv = _gtk_source_marks_sequence_get_instance_private (seq);
Packit a7d494
Packit a7d494
	seq->priv->seq = g_sequence_new ((GDestroyNotify)g_object_unref);
Packit a7d494
Packit a7d494
	unique_str = g_strdup_printf ("gtk-source-marks-sequence-%p", seq);
Packit a7d494
	seq->priv->quark = g_quark_from_string (unique_str);
Packit a7d494
	g_free (unique_str);
Packit a7d494
}
Packit a7d494
Packit a7d494
GtkSourceMarksSequence *
Packit a7d494
_gtk_source_marks_sequence_new (GtkTextBuffer *buffer)
Packit a7d494
{
Packit a7d494
	g_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), NULL);
Packit a7d494
Packit a7d494
	return g_object_new (GTK_SOURCE_TYPE_MARKS_SEQUENCE,
Packit a7d494
			     "buffer", buffer,
Packit a7d494
			     NULL);
Packit a7d494
}
Packit a7d494
Packit a7d494
gboolean
Packit a7d494
_gtk_source_marks_sequence_is_empty (GtkSourceMarksSequence *seq)
Packit a7d494
{
Packit a7d494
	g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), TRUE);
Packit a7d494
Packit a7d494
	return g_sequence_is_empty (seq->priv->seq);
Packit a7d494
}
Packit a7d494
Packit a7d494
void
Packit a7d494
_gtk_source_marks_sequence_add (GtkSourceMarksSequence *seq,
Packit a7d494
				GtkTextMark            *mark)
Packit a7d494
{
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
Packit a7d494
	g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq));
Packit a7d494
	g_return_if_fail (GTK_IS_TEXT_MARK (mark));
Packit a7d494
	g_return_if_fail (gtk_text_mark_get_buffer (mark) == seq->priv->buffer);
Packit a7d494
Packit a7d494
	seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
Packit a7d494
Packit a7d494
	if (seq_iter != NULL)
Packit a7d494
	{
Packit a7d494
		/* The mark is already added. */
Packit a7d494
		return;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	seq_iter = g_sequence_insert_sorted (seq->priv->seq,
Packit a7d494
					     mark,
Packit a7d494
					     (GCompareDataFunc)compare_marks,
Packit a7d494
					     NULL);
Packit a7d494
Packit a7d494
	g_object_ref (mark);
Packit a7d494
	g_object_set_qdata (G_OBJECT (mark),
Packit a7d494
			    seq->priv->quark,
Packit a7d494
			    seq_iter);
Packit a7d494
}
Packit a7d494
Packit a7d494
void
Packit a7d494
_gtk_source_marks_sequence_remove (GtkSourceMarksSequence *seq,
Packit a7d494
				   GtkTextMark            *mark)
Packit a7d494
{
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
Packit a7d494
	g_return_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq));
Packit a7d494
	g_return_if_fail (GTK_IS_TEXT_MARK (mark));
Packit a7d494
Packit a7d494
	seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
Packit a7d494
Packit a7d494
	if (seq_iter != NULL)
Packit a7d494
	{
Packit a7d494
		g_object_set_qdata (G_OBJECT (mark), seq->priv->quark, NULL);
Packit a7d494
		g_sequence_remove (seq_iter);
Packit a7d494
	}
Packit a7d494
}
Packit a7d494
Packit a7d494
GtkTextMark *
Packit a7d494
_gtk_source_marks_sequence_next (GtkSourceMarksSequence *seq,
Packit a7d494
				 GtkTextMark            *mark)
Packit a7d494
{
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
Packit a7d494
	g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), NULL);
Packit a7d494
	g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), NULL);
Packit a7d494
	g_return_val_if_fail (gtk_text_mark_get_buffer (mark) == seq->priv->buffer, NULL);
Packit a7d494
Packit a7d494
	seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
Packit a7d494
Packit a7d494
	g_return_val_if_fail (seq_iter != NULL, NULL);
Packit a7d494
Packit a7d494
	seq_iter = g_sequence_iter_next (seq_iter);
Packit a7d494
Packit a7d494
	return g_sequence_iter_is_end (seq_iter) ? NULL : g_sequence_get (seq_iter);
Packit a7d494
}
Packit a7d494
Packit a7d494
GtkTextMark *
Packit a7d494
_gtk_source_marks_sequence_prev (GtkSourceMarksSequence *seq,
Packit a7d494
				 GtkTextMark            *mark)
Packit a7d494
{
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
Packit a7d494
	g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), NULL);
Packit a7d494
	g_return_val_if_fail (GTK_IS_TEXT_MARK (mark), NULL);
Packit a7d494
	g_return_val_if_fail (gtk_text_mark_get_buffer (mark) == seq->priv->buffer, NULL);
Packit a7d494
Packit a7d494
	seq_iter = g_object_get_qdata (G_OBJECT (mark), seq->priv->quark);
Packit a7d494
Packit a7d494
	g_return_val_if_fail (seq_iter != NULL, NULL);
Packit a7d494
Packit a7d494
	if (g_sequence_iter_is_begin (seq_iter))
Packit a7d494
	{
Packit a7d494
		return NULL;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	seq_iter = g_sequence_iter_prev (seq_iter);
Packit a7d494
Packit a7d494
	return g_sequence_get (seq_iter);
Packit a7d494
}
Packit a7d494
Packit a7d494
/* Moves @iter forward to the next position where there is at least one mark.
Packit a7d494
 * Returns %TRUE if @iter was moved.
Packit a7d494
 */
Packit a7d494
gboolean
Packit a7d494
_gtk_source_marks_sequence_forward_iter (GtkSourceMarksSequence *seq,
Packit a7d494
					 GtkTextIter            *iter)
Packit a7d494
{
Packit a7d494
	GtkTextMark *mark;
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
Packit a7d494
	g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), FALSE);
Packit a7d494
	g_return_val_if_fail (iter != NULL, FALSE);
Packit a7d494
	g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == seq->priv->buffer, FALSE);
Packit a7d494
Packit a7d494
	mark = gtk_text_buffer_create_mark (seq->priv->buffer,
Packit a7d494
					    NULL,
Packit a7d494
					    iter,
Packit a7d494
					    TRUE);
Packit a7d494
Packit a7d494
	seq_iter = g_sequence_search (seq->priv->seq,
Packit a7d494
				      mark,
Packit a7d494
				      (GCompareDataFunc)compare_marks,
Packit a7d494
				      NULL);
Packit a7d494
Packit a7d494
	gtk_text_buffer_delete_mark (seq->priv->buffer, mark);
Packit a7d494
Packit a7d494
	while (!g_sequence_iter_is_end (seq_iter))
Packit a7d494
	{
Packit a7d494
		GtkTextMark *cur_mark = g_sequence_get (seq_iter);
Packit a7d494
		GtkTextIter cur_iter;
Packit a7d494
Packit a7d494
		gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
Packit a7d494
Packit a7d494
		if (gtk_text_iter_compare (iter, &cur_iter) < 0)
Packit a7d494
		{
Packit a7d494
			*iter = cur_iter;
Packit a7d494
			return TRUE;
Packit a7d494
		}
Packit a7d494
Packit a7d494
		seq_iter = g_sequence_iter_next (seq_iter);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	return FALSE;
Packit a7d494
}
Packit a7d494
Packit a7d494
/* Moves @iter backward to the previous position where there is at least one
Packit a7d494
 * mark. Returns %TRUE if @iter was moved.
Packit a7d494
 */
Packit a7d494
gboolean
Packit a7d494
_gtk_source_marks_sequence_backward_iter (GtkSourceMarksSequence *seq,
Packit a7d494
					  GtkTextIter            *iter)
Packit a7d494
{
Packit a7d494
	GtkTextMark *mark;
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
Packit a7d494
	g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), FALSE);
Packit a7d494
	g_return_val_if_fail (iter != NULL, FALSE);
Packit a7d494
	g_return_val_if_fail (gtk_text_iter_get_buffer (iter) == seq->priv->buffer, FALSE);
Packit a7d494
Packit a7d494
	mark = gtk_text_buffer_create_mark (seq->priv->buffer,
Packit a7d494
					    NULL,
Packit a7d494
					    iter,
Packit a7d494
					    TRUE);
Packit a7d494
Packit a7d494
	seq_iter = g_sequence_search (seq->priv->seq,
Packit a7d494
				      mark,
Packit a7d494
				      (GCompareDataFunc)compare_marks,
Packit a7d494
				      NULL);
Packit a7d494
Packit a7d494
	gtk_text_buffer_delete_mark (seq->priv->buffer, mark);
Packit a7d494
Packit a7d494
	if (g_sequence_iter_is_end (seq_iter))
Packit a7d494
	{
Packit a7d494
		seq_iter = g_sequence_iter_prev (seq_iter);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	if (g_sequence_iter_is_end (seq_iter))
Packit a7d494
	{
Packit a7d494
		/* The sequence is empty. */
Packit a7d494
		return FALSE;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	while (TRUE)
Packit a7d494
	{
Packit a7d494
		GtkTextMark *cur_mark;
Packit a7d494
		GtkTextIter cur_iter;
Packit a7d494
Packit a7d494
		cur_mark = g_sequence_get (seq_iter);
Packit a7d494
Packit a7d494
		gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
Packit a7d494
Packit a7d494
		if (gtk_text_iter_compare (&cur_iter, iter) < 0)
Packit a7d494
		{
Packit a7d494
			*iter = cur_iter;
Packit a7d494
			return TRUE;
Packit a7d494
		}
Packit a7d494
Packit a7d494
		if (g_sequence_iter_is_begin (seq_iter))
Packit a7d494
		{
Packit a7d494
			break;
Packit a7d494
		}
Packit a7d494
Packit a7d494
		seq_iter = g_sequence_iter_prev (seq_iter);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	return FALSE;
Packit a7d494
}
Packit a7d494
Packit a7d494
GSList *
Packit a7d494
_gtk_source_marks_sequence_get_marks_in_range (GtkSourceMarksSequence *seq,
Packit a7d494
					       const GtkTextIter      *iter1,
Packit a7d494
					       const GtkTextIter      *iter2)
Packit a7d494
{
Packit a7d494
	GtkTextIter start;
Packit a7d494
	GtkTextIter end;
Packit a7d494
	GtkTextMark *mark_start;
Packit a7d494
	GSequenceIter *seq_iter;
Packit a7d494
	GSequenceIter *first_seq_iter = NULL;
Packit a7d494
	GSList *ret = NULL;
Packit a7d494
Packit a7d494
	g_return_val_if_fail (GTK_SOURCE_IS_MARKS_SEQUENCE (seq), NULL);
Packit a7d494
	g_return_val_if_fail (iter1 != NULL, NULL);
Packit a7d494
	g_return_val_if_fail (iter2 != NULL, NULL);
Packit a7d494
	g_return_val_if_fail (gtk_text_iter_get_buffer (iter1) == seq->priv->buffer, NULL);
Packit a7d494
	g_return_val_if_fail (gtk_text_iter_get_buffer (iter2) == seq->priv->buffer, NULL);
Packit a7d494
Packit a7d494
	start = *iter1;
Packit a7d494
	end = *iter2;
Packit a7d494
Packit a7d494
	gtk_text_iter_order (&start, &end;;
Packit a7d494
Packit a7d494
	mark_start = gtk_text_buffer_create_mark (seq->priv->buffer,
Packit a7d494
						  NULL,
Packit a7d494
						  &start,
Packit a7d494
						  TRUE);
Packit a7d494
Packit a7d494
	seq_iter = g_sequence_search (seq->priv->seq,
Packit a7d494
				      mark_start,
Packit a7d494
				      (GCompareDataFunc)compare_marks,
Packit a7d494
				      NULL);
Packit a7d494
Packit a7d494
	gtk_text_buffer_delete_mark (seq->priv->buffer, mark_start);
Packit a7d494
Packit a7d494
	if (g_sequence_iter_is_end (seq_iter))
Packit a7d494
	{
Packit a7d494
		seq_iter = g_sequence_iter_prev (seq_iter);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	if (g_sequence_iter_is_end (seq_iter))
Packit a7d494
	{
Packit a7d494
		/* The sequence is empty. */
Packit a7d494
		return NULL;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	/* Find the first mark */
Packit a7d494
Packit a7d494
	while (TRUE)
Packit a7d494
	{
Packit a7d494
		GtkTextMark *cur_mark;
Packit a7d494
		GtkTextIter cur_iter;
Packit a7d494
Packit a7d494
		cur_mark = g_sequence_get (seq_iter);
Packit a7d494
		gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
Packit a7d494
Packit a7d494
		if (gtk_text_iter_compare (&cur_iter, &start) < 0)
Packit a7d494
		{
Packit a7d494
			break;
Packit a7d494
		}
Packit a7d494
Packit a7d494
		first_seq_iter = seq_iter;
Packit a7d494
Packit a7d494
		if (g_sequence_iter_is_begin (seq_iter))
Packit a7d494
		{
Packit a7d494
			break;
Packit a7d494
		}
Packit a7d494
Packit a7d494
		seq_iter = g_sequence_iter_prev (seq_iter);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	if (first_seq_iter == NULL)
Packit a7d494
	{
Packit a7d494
		/* The last mark in the sequence is before @start. */
Packit a7d494
		return NULL;
Packit a7d494
	}
Packit a7d494
Packit a7d494
	/* Go forward until @end to fill the list of marks */
Packit a7d494
Packit a7d494
	for (seq_iter = first_seq_iter;
Packit a7d494
	     !g_sequence_iter_is_end (seq_iter);
Packit a7d494
	     seq_iter = g_sequence_iter_next (seq_iter))
Packit a7d494
	{
Packit a7d494
		GtkTextMark *cur_mark;
Packit a7d494
		GtkTextIter cur_iter;
Packit a7d494
Packit a7d494
		cur_mark = g_sequence_get (seq_iter);
Packit a7d494
		gtk_text_buffer_get_iter_at_mark (seq->priv->buffer, &cur_iter, cur_mark);
Packit a7d494
Packit a7d494
		if (gtk_text_iter_compare (&end, &cur_iter) < 0)
Packit a7d494
		{
Packit a7d494
			break;
Packit a7d494
		}
Packit a7d494
Packit a7d494
		ret = g_slist_prepend (ret, cur_mark);
Packit a7d494
	}
Packit a7d494
Packit a7d494
	return ret;
Packit a7d494
}
Packit a7d494
Packit a7d494
GSList *
Packit a7d494
_gtk_source_marks_sequence_get_marks_at_iter (GtkSourceMarksSequence *seq,
Packit a7d494
					      const GtkTextIter      *iter)
Packit a7d494
{
Packit a7d494
	return _gtk_source_marks_sequence_get_marks_in_range (seq, iter, iter);
Packit a7d494
}