/* preserve-indent.c generated by valac 0.56.19, the Vala compiler
 * generated from preserve-indent.vala, do not modify */

/* -*- Mode: vala; indent-tabs-mode: nil; tab-width: 4 -*-*/

#include "preserve-indent.h"
#include "codecore.h"
#include <gee.h>
#include <glib-object.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <gio/gio.h>
#include <gtksourceview/gtksource.h>
#include <stdlib.h>
#include <string.h>
#include <libpeas.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

enum  {
	SCRATCH_PLUGINS_PRESERVE_INDENT_0_PROPERTY,
	SCRATCH_PLUGINS_PRESERVE_INDENT_OBJECT_PROPERTY,
	SCRATCH_PLUGINS_PRESERVE_INDENT_NUM_PROPERTIES
};
static GParamSpec* scratch_plugins_preserve_indent_properties[SCRATCH_PLUGINS_PRESERVE_INDENT_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))

struct _ScratchPluginsPreserveIndentPrivate {
	ScratchServicesInterface* plugins;
	GeeTreeSet* documents;
	ScratchServicesDocument* active_document;
	gint last_clipboard_indent_level;
	gboolean waiting_for_clipboard_text;
	GObject* _object;
};

static gint ScratchPluginsPreserveIndent_private_offset;
static gpointer scratch_plugins_preserve_indent_parent_class = NULL;
static ScratchServicesActivatablePluginIface * scratch_plugins_preserve_indent_scratch_services_activatable_plugin_parent_iface = NULL;
static GType scratch_plugins_preserve_indent_type_id = 0;

static void scratch_plugins_preserve_indent_real_activate (ScratchServicesActivatablePlugin* base);
static void __lambda4_ (ScratchPluginsPreserveIndent* self,
                 ScratchServicesDocument* d);
static void scratch_plugins_preserve_indent_on_cut_or_copy_clipboard (ScratchPluginsPreserveIndent* self);
static void _scratch_plugins_preserve_indent_on_cut_or_copy_clipboard_gtk_text_view_copy_clipboard (GtkTextView* _sender,
                                                                                             gpointer self);
static void _scratch_plugins_preserve_indent_on_cut_or_copy_clipboard_gtk_text_view_cut_clipboard (GtkTextView* _sender,
                                                                                            gpointer self);
static void scratch_plugins_preserve_indent_on_paste_clipboard (ScratchPluginsPreserveIndent* self);
static void _scratch_plugins_preserve_indent_on_paste_clipboard_gtk_text_view_paste_clipboard (GtkTextView* _sender,
                                                                                        gpointer self);
static void scratch_plugins_preserve_indent_on_paste_done (ScratchPluginsPreserveIndent* self);
static void _scratch_plugins_preserve_indent_on_paste_done_gtk_text_buffer_paste_done (GtkTextBuffer* _sender,
                                                                                GtkClipboard* clipboard,
                                                                                gpointer self);
static void ___lambda5_ (ScratchPluginsPreserveIndent* self,
                  ScratchServicesDocument* d);
static void ____lambda5__scratch_services_document_doc_closed (ScratchServicesDocument* _sender,
                                                        gpointer self);
static void ___lambda4__scratch_services_interface_hook_document (ScratchServicesInterface* _sender,
                                                           ScratchServicesDocument* doc,
                                                           gpointer self);
static void scratch_plugins_preserve_indent_real_deactivate (ScratchServicesActivatablePlugin* base);
static void scratch_plugins_preserve_indent_real_update_state (ScratchServicesActivatablePlugin* base);
static gint scratch_plugins_preserve_indent_measure_indent_at_iter (ScratchPluginsPreserveIndent* self,
                                                             ScratchWidgetsSourceView* view,
                                                             GtkTextIter* iter);
static void scratch_plugins_preserve_indent_increase_indent_in_region (ScratchPluginsPreserveIndent* self,
                                                                ScratchWidgetsSourceView* view,
                                                                GtkTextIter* region_begin,
                                                                GtkTextIter* region_end,
                                                                gint nchars);
static void scratch_plugins_preserve_indent_decrease_indent_in_region (ScratchPluginsPreserveIndent* self,
                                                                ScratchWidgetsSourceView* view,
                                                                GtkTextIter* region_begin,
                                                                GtkTextIter* region_end,
                                                                gint nchars);
static void scratch_plugins_preserve_indent_finalize (GObject * obj);
static void _vala_scratch_plugins_preserve_indent_get_property (GObject * object,
                                                         guint property_id,
                                                         GValue * value,
                                                         GParamSpec * pspec);
static void _vala_scratch_plugins_preserve_indent_set_property (GObject * object,
                                                         guint property_id,
                                                         const GValue * value,
                                                         GParamSpec * pspec);

static inline gpointer
scratch_plugins_preserve_indent_get_instance_private (ScratchPluginsPreserveIndent* self)
{
	return G_STRUCT_MEMBER_P (self, ScratchPluginsPreserveIndent_private_offset);
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static void
_scratch_plugins_preserve_indent_on_cut_or_copy_clipboard_gtk_text_view_copy_clipboard (GtkTextView* _sender,
                                                                                        gpointer self)
{
	scratch_plugins_preserve_indent_on_cut_or_copy_clipboard ((ScratchPluginsPreserveIndent*) self);
}

static void
_scratch_plugins_preserve_indent_on_cut_or_copy_clipboard_gtk_text_view_cut_clipboard (GtkTextView* _sender,
                                                                                       gpointer self)
{
	scratch_plugins_preserve_indent_on_cut_or_copy_clipboard ((ScratchPluginsPreserveIndent*) self);
}

static void
_scratch_plugins_preserve_indent_on_paste_clipboard_gtk_text_view_paste_clipboard (GtkTextView* _sender,
                                                                                   gpointer self)
{
	scratch_plugins_preserve_indent_on_paste_clipboard ((ScratchPluginsPreserveIndent*) self);
}

static void
_scratch_plugins_preserve_indent_on_paste_done_gtk_text_buffer_paste_done (GtkTextBuffer* _sender,
                                                                           GtkClipboard* clipboard,
                                                                           gpointer self)
{
	scratch_plugins_preserve_indent_on_paste_done ((ScratchPluginsPreserveIndent*) self);
}

static void
___lambda5_ (ScratchPluginsPreserveIndent* self,
             ScratchServicesDocument* d)
{
	GeeTreeSet* _tmp0_;
	g_return_if_fail (d != NULL);
	_tmp0_ = self->priv->documents;
	gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp0_, d);
}

static void
____lambda5__scratch_services_document_doc_closed (ScratchServicesDocument* _sender,
                                                   gpointer self)
{
	___lambda5_ ((ScratchPluginsPreserveIndent*) self, _sender);
}

static void
__lambda4_ (ScratchPluginsPreserveIndent* self,
            ScratchServicesDocument* d)
{
	ScratchServicesDocument* _tmp0_;
	GeeTreeSet* _tmp1_;
	g_return_if_fail (d != NULL);
	_tmp0_ = _g_object_ref0 (d);
	_g_object_unref0 (self->priv->active_document);
	self->priv->active_document = _tmp0_;
	_tmp1_ = self->priv->documents;
	if (gee_abstract_collection_add ((GeeAbstractCollection*) _tmp1_, d)) {
		ScratchWidgetsSourceView* _tmp2_;
		ScratchWidgetsSourceView* _tmp3_;
		ScratchWidgetsSourceView* _tmp4_;
		ScratchWidgetsSourceView* _tmp5_;
		ScratchWidgetsSourceView* _tmp6_;
		ScratchWidgetsSourceView* _tmp7_;
		ScratchWidgetsSourceView* _tmp8_;
		ScratchWidgetsSourceView* _tmp9_;
		GtkTextBuffer* _tmp10_;
		GtkTextBuffer* _tmp11_;
		_tmp2_ = scratch_services_document_get_source_view (d);
		_tmp3_ = _tmp2_;
		g_signal_connect_object ((GtkTextView*) _tmp3_, "copy-clipboard", (GCallback) _scratch_plugins_preserve_indent_on_cut_or_copy_clipboard_gtk_text_view_copy_clipboard, self, 0);
		_tmp4_ = scratch_services_document_get_source_view (d);
		_tmp5_ = _tmp4_;
		g_signal_connect_object ((GtkTextView*) _tmp5_, "cut-clipboard", (GCallback) _scratch_plugins_preserve_indent_on_cut_or_copy_clipboard_gtk_text_view_cut_clipboard, self, 0);
		_tmp6_ = scratch_services_document_get_source_view (d);
		_tmp7_ = _tmp6_;
		g_signal_connect_object ((GtkTextView*) _tmp7_, "paste-clipboard", (GCallback) _scratch_plugins_preserve_indent_on_paste_clipboard_gtk_text_view_paste_clipboard, self, 0);
		_tmp8_ = scratch_services_document_get_source_view (d);
		_tmp9_ = _tmp8_;
		_tmp10_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp9_);
		_tmp11_ = _tmp10_;
		g_signal_connect_object (_tmp11_, "paste-done", (GCallback) _scratch_plugins_preserve_indent_on_paste_done_gtk_text_buffer_paste_done, self, 0);
		g_signal_connect_object (d, "doc-closed", (GCallback) ____lambda5__scratch_services_document_doc_closed, self, 0);
	}
}

static void
___lambda4__scratch_services_interface_hook_document (ScratchServicesInterface* _sender,
                                                      ScratchServicesDocument* doc,
                                                      gpointer self)
{
	__lambda4_ ((ScratchPluginsPreserveIndent*) self, doc);
}

static void
scratch_plugins_preserve_indent_real_activate (ScratchServicesActivatablePlugin* base)
{
	ScratchPluginsPreserveIndent * self;
	GeeTreeSet* _tmp0_;
	GObject* _tmp1_;
	GObject* _tmp2_;
	ScratchServicesInterface* _tmp3_;
	self = (ScratchPluginsPreserveIndent*) base;
	_tmp0_ = gee_tree_set_new (SCRATCH_SERVICES_TYPE_DOCUMENT, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->documents);
	self->priv->documents = _tmp0_;
	_tmp1_ = scratch_services_activatable_plugin_get_object ((ScratchServicesActivatablePlugin*) self);
	_tmp2_ = _tmp1_;
	_g_object_unref0 (self->priv->plugins);
	self->priv->plugins = G_TYPE_CHECK_INSTANCE_CAST (_tmp2_, SCRATCH_SERVICES_TYPE_INTERFACE, ScratchServicesInterface);
	_tmp3_ = self->priv->plugins;
	g_signal_connect_object (_tmp3_, "hook-document", (GCallback) ___lambda4__scratch_services_interface_hook_document, self, 0);
}

static void
scratch_plugins_preserve_indent_real_deactivate (ScratchServicesActivatablePlugin* base)
{
	ScratchPluginsPreserveIndent * self;
	GeeTreeSet* _tmp0_;
	self = (ScratchPluginsPreserveIndent*) base;
	_tmp0_ = self->priv->documents;
	gee_abstract_collection_clear ((GeeAbstractCollection*) _tmp0_);
}

static void
scratch_plugins_preserve_indent_real_update_state (ScratchServicesActivatablePlugin* base)
{
	ScratchPluginsPreserveIndent * self;
	self = (ScratchPluginsPreserveIndent*) base;
}

static gint
scratch_plugins_preserve_indent_measure_indent_at_iter (ScratchPluginsPreserveIndent* self,
                                                        ScratchWidgetsSourceView* view,
                                                        GtkTextIter* iter)
{
	GtkTextIter line_begin = {0};
	GtkTextIter pos = {0};
	GtkTextBuffer* _tmp0_;
	GtkTextBuffer* _tmp1_;
	GtkTextIter _tmp2_ = {0};
	GtkTextIter _tmp3_;
	gint indent = 0;
	gint tabwidth = 0;
	GSettings* _tmp4_;
	gunichar ch = 0U;
	gint result;
	g_return_val_if_fail (self != NULL, -1);
	g_return_val_if_fail (view != NULL, -1);
	g_return_val_if_fail (iter != NULL, -1);
	_tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) view);
	_tmp1_ = _tmp0_;
	gtk_text_buffer_get_iter_at_line (_tmp1_, &_tmp2_, gtk_text_iter_get_line (iter));
	line_begin = _tmp2_;
	_tmp3_ = line_begin;
	pos = _tmp3_;
	indent = 0;
	_tmp4_ = scratch_settings;
	tabwidth = g_settings_get_int (_tmp4_, "indent-width");
	ch = gtk_text_iter_get_char (&pos);
	while (TRUE) {
		gboolean _tmp5_ = FALSE;
		gboolean _tmp6_ = FALSE;
		if (gtk_text_iter_get_offset (&pos) < gtk_text_iter_get_offset (iter)) {
			_tmp6_ = ch != ((gunichar) '\n');
		} else {
			_tmp6_ = FALSE;
		}
		if (_tmp6_) {
			_tmp5_ = g_unichar_isspace (ch);
		} else {
			_tmp5_ = FALSE;
		}
		if (!_tmp5_) {
			break;
		}
		if (ch == ((gunichar) '\t')) {
			indent += tabwidth;
		} else {
			gint _tmp7_;
			indent = indent + 1;
			_tmp7_ = indent;
		}
		gtk_text_iter_forward_char (&pos);
		ch = gtk_text_iter_get_char (&pos);
	}
	result = indent;
	return result;
}

static void
scratch_plugins_preserve_indent_on_cut_or_copy_clipboard (ScratchPluginsPreserveIndent* self)
{
	ScratchWidgetsSourceView* view = NULL;
	ScratchServicesDocument* _tmp0_;
	ScratchWidgetsSourceView* _tmp1_;
	ScratchWidgetsSourceView* _tmp2_;
	ScratchWidgetsSourceView* _tmp3_;
	ScratchWidgetsSourceView* _tmp4_;
	gboolean _tmp5_;
	gboolean _tmp6_;
	GtkTextIter select_begin = {0};
	GtkTextIter select_end = {0};
	GtkTextBuffer* buffer = NULL;
	ScratchWidgetsSourceView* _tmp7_;
	GtkTextBuffer* _tmp8_;
	GtkTextBuffer* _tmp9_;
	GtkTextBuffer* _tmp10_;
	GtkTextBuffer* _tmp11_;
	GtkTextIter _tmp12_ = {0};
	GtkTextIter _tmp13_ = {0};
	gboolean _tmp14_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->active_document;
	_tmp1_ = scratch_services_document_get_source_view (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	view = _tmp3_;
	_tmp4_ = view;
	_tmp5_ = gtk_source_view_get_auto_indent ((GtkSourceView*) _tmp4_);
	_tmp6_ = _tmp5_;
	if (!_tmp6_) {
		_g_object_unref0 (view);
		return;
	}
	_tmp7_ = view;
	_tmp8_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp7_);
	_tmp9_ = _tmp8_;
	_tmp10_ = _g_object_ref0 (_tmp9_);
	buffer = _tmp10_;
	_tmp11_ = buffer;
	_tmp14_ = gtk_text_buffer_get_selection_bounds (_tmp11_, &_tmp12_, &_tmp13_);
	select_begin = _tmp12_;
	select_end = _tmp13_;
	if (_tmp14_) {
		gint indent = 0;
		ScratchWidgetsSourceView* _tmp15_;
		GtkTextIter _tmp16_;
		_tmp15_ = view;
		_tmp16_ = select_begin;
		indent = scratch_plugins_preserve_indent_measure_indent_at_iter (self, _tmp15_, &_tmp16_);
		self->priv->last_clipboard_indent_level = indent;
	} else {
		self->priv->last_clipboard_indent_level = 0;
	}
	_g_object_unref0 (buffer);
	_g_object_unref0 (view);
}

static void
scratch_plugins_preserve_indent_on_paste_clipboard (ScratchPluginsPreserveIndent* self)
{
	ScratchWidgetsSourceView* view = NULL;
	ScratchServicesDocument* _tmp0_;
	ScratchWidgetsSourceView* _tmp1_;
	ScratchWidgetsSourceView* _tmp2_;
	ScratchWidgetsSourceView* _tmp3_;
	gboolean _tmp4_ = FALSE;
	ScratchWidgetsSourceView* _tmp5_;
	gboolean _tmp6_;
	gboolean _tmp7_;
	GtkTextBuffer* buffer = NULL;
	ScratchWidgetsSourceView* _tmp8_;
	GtkTextBuffer* _tmp9_;
	GtkTextBuffer* _tmp10_;
	GtkTextBuffer* _tmp11_;
	GtkTextIter insert = {0};
	GtkTextBuffer* _tmp12_;
	GtkTextBuffer* _tmp13_;
	GtkTextMark* _tmp14_;
	GtkTextIter _tmp15_ = {0};
	GtkTextBuffer* _tmp16_;
	GtkTextIter _tmp17_;
	GtkTextBuffer* _tmp18_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->active_document;
	_tmp1_ = scratch_services_document_get_source_view (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	view = _tmp3_;
	_tmp5_ = view;
	_tmp6_ = gtk_source_view_get_auto_indent ((GtkSourceView*) _tmp5_);
	_tmp7_ = _tmp6_;
	if (!_tmp7_) {
		_tmp4_ = TRUE;
	} else {
		_tmp4_ = self->priv->waiting_for_clipboard_text;
	}
	if (_tmp4_) {
		_g_object_unref0 (view);
		return;
	}
	_tmp8_ = view;
	_tmp9_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp8_);
	_tmp10_ = _tmp9_;
	_tmp11_ = _g_object_ref0 (_tmp10_);
	buffer = _tmp11_;
	_tmp12_ = buffer;
	_tmp13_ = buffer;
	_tmp14_ = gtk_text_buffer_get_insert (_tmp13_);
	gtk_text_buffer_get_iter_at_mark (_tmp12_, &_tmp15_, _tmp14_);
	insert = _tmp15_;
	_tmp16_ = buffer;
	_tmp17_ = insert;
	gtk_text_buffer_create_mark (_tmp16_, "paste_start", &_tmp17_, TRUE);
	self->priv->waiting_for_clipboard_text = TRUE;
	_tmp18_ = buffer;
	gtk_text_buffer_begin_user_action (_tmp18_);
	_g_object_unref0 (buffer);
	_g_object_unref0 (view);
}

static void
scratch_plugins_preserve_indent_on_paste_done (ScratchPluginsPreserveIndent* self)
{
	ScratchWidgetsSourceView* view = NULL;
	ScratchServicesDocument* _tmp0_;
	ScratchWidgetsSourceView* _tmp1_;
	ScratchWidgetsSourceView* _tmp2_;
	ScratchWidgetsSourceView* _tmp3_;
	ScratchWidgetsSourceView* _tmp4_;
	gboolean _tmp5_;
	gboolean _tmp6_;
	GtkTextIter paste_begin = {0};
	GtkTextIter paste_end = {0};
	GtkTextMark* mark_paste_start = NULL;
	ScratchWidgetsSourceView* _tmp7_;
	GtkTextBuffer* _tmp8_;
	GtkTextBuffer* _tmp9_;
	GtkTextMark* _tmp10_;
	GtkTextMark* _tmp11_;
	GtkTextMark* _tmp12_;
	ScratchWidgetsSourceView* _tmp13_;
	GtkTextBuffer* _tmp14_;
	GtkTextBuffer* _tmp15_;
	ScratchWidgetsSourceView* _tmp16_;
	GtkTextBuffer* _tmp17_;
	GtkTextBuffer* _tmp18_;
	GtkTextMark* _tmp19_;
	GtkTextIter _tmp20_ = {0};
	ScratchWidgetsSourceView* _tmp21_;
	GtkTextBuffer* _tmp22_;
	GtkTextBuffer* _tmp23_;
	ScratchWidgetsSourceView* _tmp24_;
	GtkTextBuffer* _tmp25_;
	GtkTextBuffer* _tmp26_;
	GtkTextMark* _tmp27_;
	GtkTextIter _tmp28_ = {0};
	gint indent_level = 0;
	ScratchWidgetsSourceView* _tmp29_;
	GtkTextIter _tmp30_;
	gint indent_diff = 0;
	ScratchWidgetsSourceView* _tmp37_;
	GtkTextBuffer* _tmp38_;
	GtkTextBuffer* _tmp39_;
	ScratchWidgetsSourceView* _tmp40_;
	GtkTextBuffer* _tmp41_;
	GtkTextBuffer* _tmp42_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->active_document;
	_tmp1_ = scratch_services_document_get_source_view (_tmp0_);
	_tmp2_ = _tmp1_;
	_tmp3_ = _g_object_ref0 (_tmp2_);
	view = _tmp3_;
	_tmp4_ = view;
	_tmp5_ = gtk_source_view_get_auto_indent ((GtkSourceView*) _tmp4_);
	_tmp6_ = _tmp5_;
	if (!_tmp6_) {
		_g_object_unref0 (view);
		return;
	}
	_tmp7_ = view;
	_tmp8_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp7_);
	_tmp9_ = _tmp8_;
	_tmp10_ = gtk_text_buffer_get_mark (_tmp9_, "paste_start");
	_tmp11_ = _g_object_ref0 (_tmp10_);
	mark_paste_start = _tmp11_;
	_tmp12_ = mark_paste_start;
	if (_tmp12_ == NULL) {
		_g_object_unref0 (mark_paste_start);
		_g_object_unref0 (view);
		return;
	}
	_tmp13_ = view;
	_tmp14_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp13_);
	_tmp15_ = _tmp14_;
	_tmp16_ = view;
	_tmp17_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp16_);
	_tmp18_ = _tmp17_;
	_tmp19_ = gtk_text_buffer_get_mark (_tmp18_, "paste_start");
	gtk_text_buffer_get_iter_at_mark (_tmp15_, &_tmp20_, _tmp19_);
	paste_begin = _tmp20_;
	_tmp21_ = view;
	_tmp22_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp21_);
	_tmp23_ = _tmp22_;
	_tmp24_ = view;
	_tmp25_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp24_);
	_tmp26_ = _tmp25_;
	_tmp27_ = gtk_text_buffer_get_insert (_tmp26_);
	gtk_text_buffer_get_iter_at_mark (_tmp23_, &_tmp28_, _tmp27_);
	paste_end = _tmp28_;
	_tmp29_ = view;
	_tmp30_ = paste_begin;
	indent_level = scratch_plugins_preserve_indent_measure_indent_at_iter (self, _tmp29_, &_tmp30_);
	indent_diff = indent_level - self->priv->last_clipboard_indent_level;
	gtk_text_iter_forward_line (&paste_begin);
	if (indent_diff > 0) {
		ScratchWidgetsSourceView* _tmp31_;
		GtkTextIter _tmp32_;
		GtkTextIter _tmp33_;
		_tmp31_ = view;
		_tmp32_ = paste_begin;
		_tmp33_ = paste_end;
		scratch_plugins_preserve_indent_increase_indent_in_region (self, _tmp31_, &_tmp32_, &_tmp33_, indent_diff);
	} else {
		if (indent_diff < 0) {
			ScratchWidgetsSourceView* _tmp34_;
			GtkTextIter _tmp35_;
			GtkTextIter _tmp36_;
			_tmp34_ = view;
			_tmp35_ = paste_begin;
			_tmp36_ = paste_end;
			scratch_plugins_preserve_indent_decrease_indent_in_region (self, _tmp34_, &_tmp35_, &_tmp36_, abs (indent_diff));
		}
	}
	_tmp37_ = view;
	_tmp38_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp37_);
	_tmp39_ = _tmp38_;
	gtk_text_buffer_delete_mark_by_name (_tmp39_, "paste_start");
	_tmp40_ = view;
	_tmp41_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp40_);
	_tmp42_ = _tmp41_;
	gtk_text_buffer_end_user_action (_tmp42_);
	self->priv->waiting_for_clipboard_text = FALSE;
	_g_object_unref0 (mark_paste_start);
	_g_object_unref0 (view);
}

static void
scratch_plugins_preserve_indent_increase_indent_in_region (ScratchPluginsPreserveIndent* self,
                                                           ScratchWidgetsSourceView* view,
                                                           GtkTextIter* region_begin,
                                                           GtkTextIter* region_end,
                                                           gint nchars)
{
	gint first_line = 0;
	gint last_line = 0;
	gint buf_last_line = 0;
	GtkTextBuffer* _tmp0_;
	GtkTextBuffer* _tmp1_;
	gint nlines = 0;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	gboolean _tmp4_ = FALSE;
	gboolean _tmp5_ = FALSE;
	gchar* indent_str = NULL;
	gboolean _tmp8_;
	gboolean _tmp9_;
	GtkTextIter itr = {0};
	g_return_if_fail (self != NULL);
	g_return_if_fail (view != NULL);
	g_return_if_fail (region_begin != NULL);
	g_return_if_fail (region_end != NULL);
	first_line = gtk_text_iter_get_line (region_begin);
	last_line = gtk_text_iter_get_line (region_end);
	_tmp0_ = gtk_text_view_get_buffer ((GtkTextView*) view);
	_tmp1_ = _tmp0_;
	buf_last_line = gtk_text_buffer_get_line_count (_tmp1_) - 1;
	nlines = abs (first_line - last_line) + 1;
	if (nlines < 1) {
		_tmp5_ = TRUE;
	} else {
		_tmp5_ = nchars < 1;
	}
	if (_tmp5_) {
		_tmp4_ = TRUE;
	} else {
		_tmp4_ = last_line < first_line;
	}
	if (_tmp4_) {
		_tmp3_ = TRUE;
	} else {
		gboolean _tmp6_;
		gboolean _tmp7_;
		_tmp6_ = gtk_text_view_get_editable ((GtkTextView*) view);
		_tmp7_ = _tmp6_;
		_tmp3_ = !_tmp7_;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = first_line == buf_last_line;
	}
	if (_tmp2_) {
		return;
	}
	_tmp8_ = gtk_source_view_get_insert_spaces_instead_of_tabs ((GtkSourceView*) view);
	_tmp9_ = _tmp8_;
	if (_tmp9_) {
		gchar* _tmp10_;
		_tmp10_ = g_strnfill ((gsize) nchars, ' ');
		_g_free0 (indent_str);
		indent_str = _tmp10_;
	} else {
		gint tabwidth = 0;
		GSettings* _tmp11_;
		gint tabs = 0;
		gint spaces = 0;
		gchar* _tmp12_;
		_tmp11_ = scratch_settings;
		tabwidth = g_settings_get_int (_tmp11_, "indent-width");
		tabs = nchars / tabwidth;
		spaces = nchars % tabwidth;
		_tmp12_ = g_strnfill ((gsize) tabs, '\t');
		_g_free0 (indent_str);
		indent_str = _tmp12_;
		if (spaces > 0) {
			const gchar* _tmp13_;
			gchar* _tmp14_;
			gchar* _tmp15_;
			gchar* _tmp16_;
			_tmp13_ = indent_str;
			_tmp14_ = g_strnfill ((gsize) spaces, ' ');
			_tmp15_ = _tmp14_;
			_tmp16_ = g_strconcat (_tmp13_, _tmp15_, NULL);
			_g_free0 (indent_str);
			indent_str = _tmp16_;
			_g_free0 (_tmp15_);
		}
	}
	{
		gint i = 0;
		i = first_line;
		{
			gboolean _tmp17_ = FALSE;
			_tmp17_ = TRUE;
			while (TRUE) {
				GtkTextBuffer* _tmp19_;
				GtkTextBuffer* _tmp20_;
				GtkTextIter _tmp21_ = {0};
				GtkTextBuffer* _tmp22_;
				GtkTextBuffer* _tmp23_;
				const gchar* _tmp24_;
				const gchar* _tmp25_;
				gint _tmp26_;
				gint _tmp27_;
				if (!_tmp17_) {
					gint _tmp18_;
					i = i + 1;
					_tmp18_ = i;
				}
				_tmp17_ = FALSE;
				if (!(i <= last_line)) {
					break;
				}
				_tmp19_ = gtk_text_view_get_buffer ((GtkTextView*) view);
				_tmp20_ = _tmp19_;
				gtk_text_buffer_get_iter_at_line (_tmp20_, &_tmp21_, i);
				itr = _tmp21_;
				_tmp22_ = gtk_text_view_get_buffer ((GtkTextView*) view);
				_tmp23_ = _tmp22_;
				_tmp24_ = indent_str;
				_tmp25_ = indent_str;
				_tmp26_ = strlen (_tmp25_);
				_tmp27_ = _tmp26_;
				gtk_text_buffer_insert (_tmp23_, &itr, _tmp24_, _tmp27_);
			}
		}
	}
	_g_free0 (indent_str);
}

static void
scratch_plugins_preserve_indent_decrease_indent_in_region (ScratchPluginsPreserveIndent* self,
                                                           ScratchWidgetsSourceView* view,
                                                           GtkTextIter* region_begin,
                                                           GtkTextIter* region_end,
                                                           gint nchars)
{
	gint first_line = 0;
	gint last_line = 0;
	gint nlines = 0;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	GtkTextBuffer* buffer = NULL;
	GtkTextBuffer* _tmp5_;
	GtkTextBuffer* _tmp6_;
	GtkTextBuffer* _tmp7_;
	gint tabwidth = 0;
	GSettings* _tmp8_;
	GtkTextIter del_begin = {0};
	GtkTextIter del_end = {0};
	GtkTextIter itr = {0};
	g_return_if_fail (self != NULL);
	g_return_if_fail (view != NULL);
	g_return_if_fail (region_begin != NULL);
	g_return_if_fail (region_end != NULL);
	first_line = gtk_text_iter_get_line (region_begin);
	last_line = gtk_text_iter_get_line (region_end);
	nlines = abs (first_line - last_line) + 1;
	if (nlines < 1) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = nchars < 1;
	}
	if (_tmp2_) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = last_line < first_line;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp3_;
		gboolean _tmp4_;
		_tmp3_ = gtk_text_view_get_editable ((GtkTextView*) view);
		_tmp4_ = _tmp3_;
		_tmp0_ = !_tmp4_;
	}
	if (_tmp0_) {
		return;
	}
	_tmp5_ = gtk_text_view_get_buffer ((GtkTextView*) view);
	_tmp6_ = _tmp5_;
	_tmp7_ = _g_object_ref0 (_tmp6_);
	buffer = _tmp7_;
	_tmp8_ = scratch_settings;
	tabwidth = g_settings_get_int (_tmp8_, "indent-width");
	{
		gint line = 0;
		line = first_line;
		{
			gboolean _tmp9_ = FALSE;
			_tmp9_ = TRUE;
			while (TRUE) {
				GtkTextBuffer* _tmp11_;
				GtkTextIter _tmp12_ = {0};
				gint chars_to_delete = 0;
				gint indent_chars_found = 0;
				gunichar ch = 0U;
				gboolean _tmp18_ = FALSE;
				GtkTextBuffer* _tmp19_;
				GtkTextIter _tmp20_ = {0};
				GtkTextBuffer* _tmp21_;
				GtkTextIter _tmp22_ = {0};
				GtkTextBuffer* _tmp23_;
				if (!_tmp9_) {
					gint _tmp10_;
					line = line + 1;
					_tmp10_ = line;
				}
				_tmp9_ = FALSE;
				if (!(line <= last_line)) {
					break;
				}
				_tmp11_ = buffer;
				gtk_text_buffer_get_iter_at_line (_tmp11_, &_tmp12_, line);
				itr = _tmp12_;
				chars_to_delete = 0;
				indent_chars_found = 0;
				ch = gtk_text_iter_get_char (&itr);
				while (TRUE) {
					gboolean _tmp13_ = FALSE;
					gboolean _tmp14_ = FALSE;
					if (ch != ((gunichar) '\n')) {
						_tmp14_ = !g_unichar_isgraph (ch);
					} else {
						_tmp14_ = FALSE;
					}
					if (_tmp14_) {
						_tmp13_ = indent_chars_found < nchars;
					} else {
						_tmp13_ = FALSE;
					}
					if (!_tmp13_) {
						break;
					}
					if (ch == ((gunichar) ' ')) {
						gint _tmp15_;
						gint _tmp16_;
						chars_to_delete = chars_to_delete + 1;
						_tmp15_ = chars_to_delete;
						indent_chars_found = indent_chars_found + 1;
						_tmp16_ = indent_chars_found;
					} else {
						if (ch == ((gunichar) '\t')) {
							gint _tmp17_;
							chars_to_delete = chars_to_delete + 1;
							_tmp17_ = chars_to_delete;
							indent_chars_found += tabwidth;
						}
					}
					gtk_text_iter_forward_char (&itr);
					ch = gtk_text_iter_get_char (&itr);
				}
				if (ch == ((gunichar) '\n')) {
					_tmp18_ = TRUE;
				} else {
					_tmp18_ = chars_to_delete < 1;
				}
				if (_tmp18_) {
					continue;
				}
				_tmp19_ = buffer;
				gtk_text_buffer_get_iter_at_line (_tmp19_, &_tmp20_, line);
				del_begin = _tmp20_;
				_tmp21_ = buffer;
				gtk_text_buffer_get_iter_at_line_offset (_tmp21_, &_tmp22_, line, chars_to_delete);
				del_end = _tmp22_;
				_tmp23_ = buffer;
				gtk_text_buffer_delete (_tmp23_, &del_begin, &del_end);
			}
		}
	}
	_g_object_unref0 (buffer);
}

ScratchPluginsPreserveIndent*
scratch_plugins_preserve_indent_construct (GType object_type)
{
	ScratchPluginsPreserveIndent * self = NULL;
	self = (ScratchPluginsPreserveIndent*) g_object_new (object_type, NULL);
	return self;
}

ScratchPluginsPreserveIndent*
scratch_plugins_preserve_indent_new (void)
{
	return scratch_plugins_preserve_indent_construct (SCRATCH_PLUGINS_TYPE_PRESERVE_INDENT);
}

static GObject*
scratch_plugins_preserve_indent_real_get_object (ScratchServicesActivatablePlugin* base)
{
	GObject* result;
	ScratchPluginsPreserveIndent* self;
	GObject* _tmp0_;
	GObject* _tmp1_;
	self = (ScratchPluginsPreserveIndent*) base;
	_tmp0_ = self->priv->_object;
	_tmp1_ = _g_object_ref0 (_tmp0_);
	result = _tmp1_;
	return result;
}

static void
scratch_plugins_preserve_indent_real_set_object (ScratchServicesActivatablePlugin* base,
                                                 GObject* value)
{
	ScratchPluginsPreserveIndent* self;
	GObject* old_value;
	self = (ScratchPluginsPreserveIndent*) base;
	old_value = scratch_plugins_preserve_indent_real_get_object (base);
	if (old_value != value) {
		GObject* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_object);
		self->priv->_object = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, scratch_plugins_preserve_indent_properties[SCRATCH_PLUGINS_PRESERVE_INDENT_OBJECT_PROPERTY]);
	}
	_g_object_unref0 (old_value);
}

static void
scratch_plugins_preserve_indent_class_init (ScratchPluginsPreserveIndentClass * klass,
                                            gpointer klass_data)
{
	scratch_plugins_preserve_indent_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &ScratchPluginsPreserveIndent_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_scratch_plugins_preserve_indent_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_scratch_plugins_preserve_indent_set_property;
	G_OBJECT_CLASS (klass)->finalize = scratch_plugins_preserve_indent_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), SCRATCH_PLUGINS_PRESERVE_INDENT_OBJECT_PROPERTY, scratch_plugins_preserve_indent_properties[SCRATCH_PLUGINS_PRESERVE_INDENT_OBJECT_PROPERTY] = g_param_spec_object ("object", "object", "object", G_TYPE_OBJECT, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
}

static void
scratch_plugins_preserve_indent_scratch_services_activatable_plugin_interface_init (ScratchServicesActivatablePluginIface * iface,
                                                                                    gpointer iface_data)
{
	scratch_plugins_preserve_indent_scratch_services_activatable_plugin_parent_iface = g_type_interface_peek_parent (iface);
	iface->activate = (void (*) (ScratchServicesActivatablePlugin*)) scratch_plugins_preserve_indent_real_activate;
	iface->deactivate = (void (*) (ScratchServicesActivatablePlugin*)) scratch_plugins_preserve_indent_real_deactivate;
	iface->update_state = (void (*) (ScratchServicesActivatablePlugin*)) scratch_plugins_preserve_indent_real_update_state;
	iface->get_object = scratch_plugins_preserve_indent_real_get_object;
	iface->set_object = scratch_plugins_preserve_indent_real_set_object;
}

static void
scratch_plugins_preserve_indent_instance_init (ScratchPluginsPreserveIndent * self,
                                               gpointer klass)
{
	self->priv = scratch_plugins_preserve_indent_get_instance_private (self);
	self->priv->last_clipboard_indent_level = 0;
	self->priv->waiting_for_clipboard_text = FALSE;
}

static void
scratch_plugins_preserve_indent_finalize (GObject * obj)
{
	ScratchPluginsPreserveIndent * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, SCRATCH_PLUGINS_TYPE_PRESERVE_INDENT, ScratchPluginsPreserveIndent);
	_g_object_unref0 (self->priv->plugins);
	_g_object_unref0 (self->priv->documents);
	_g_object_unref0 (self->priv->active_document);
	_g_object_unref0 (self->priv->_object);
	G_OBJECT_CLASS (scratch_plugins_preserve_indent_parent_class)->finalize (obj);
}

/***
  BEGIN LICENSE

  Copyright (C) 2015 James Morgan <james.harmonic@gmail.com>
  This program is free software: you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License version 3, as published
  by the Free Software Foundation.

  This program is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranties of
  MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
  PURPOSE.  See the GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program.  If not, see <http://www.gnu.org/licenses/>

  END LICENSE
***/
GType
scratch_plugins_preserve_indent_get_type (void)
{
	return scratch_plugins_preserve_indent_type_id;
}

GType
scratch_plugins_preserve_indent_register_type (GTypeModule * module)
{
	static const GTypeInfo g_define_type_info = { sizeof (ScratchPluginsPreserveIndentClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) scratch_plugins_preserve_indent_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (ScratchPluginsPreserveIndent), 0, (GInstanceInitFunc) scratch_plugins_preserve_indent_instance_init, NULL };
	static const GInterfaceInfo scratch_services_activatable_plugin_info = { (GInterfaceInitFunc) scratch_plugins_preserve_indent_scratch_services_activatable_plugin_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
	scratch_plugins_preserve_indent_type_id = g_type_module_register_type (module, peas_extension_base_get_type (), "ScratchPluginsPreserveIndent", &g_define_type_info, G_TYPE_FLAG_NONE);
	g_type_module_add_interface (module, scratch_plugins_preserve_indent_type_id, SCRATCH_SERVICES_TYPE_ACTIVATABLE_PLUGIN, &scratch_services_activatable_plugin_info);
	ScratchPluginsPreserveIndent_private_offset = sizeof (ScratchPluginsPreserveIndentPrivate);
	return scratch_plugins_preserve_indent_type_id;
}

static void
_vala_scratch_plugins_preserve_indent_get_property (GObject * object,
                                                    guint property_id,
                                                    GValue * value,
                                                    GParamSpec * pspec)
{
	ScratchPluginsPreserveIndent * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, SCRATCH_PLUGINS_TYPE_PRESERVE_INDENT, ScratchPluginsPreserveIndent);
	switch (property_id) {
		case SCRATCH_PLUGINS_PRESERVE_INDENT_OBJECT_PROPERTY:
		g_value_take_object (value, scratch_services_activatable_plugin_get_object ((ScratchServicesActivatablePlugin*) self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_scratch_plugins_preserve_indent_set_property (GObject * object,
                                                    guint property_id,
                                                    const GValue * value,
                                                    GParamSpec * pspec)
{
	ScratchPluginsPreserveIndent * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, SCRATCH_PLUGINS_TYPE_PRESERVE_INDENT, ScratchPluginsPreserveIndent);
	switch (property_id) {
		case SCRATCH_PLUGINS_PRESERVE_INDENT_OBJECT_PROPERTY:
		scratch_services_activatable_plugin_set_object ((ScratchServicesActivatablePlugin*) self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

void
peas_register_types (GTypeModule* module)
{
	PeasObjectModule* objmodule = NULL;
	PeasObjectModule* _tmp0_;
	g_return_if_fail (module != NULL);
	scratch_plugins_preserve_indent_register_type (module);
	_tmp0_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_TYPE (module, peas_object_module_get_type ()) ? ((PeasObjectModule*) module) : NULL);
	objmodule = _tmp0_;
	peas_object_module_register_extension_type (objmodule, SCRATCH_SERVICES_TYPE_ACTIVATABLE_PLUGIN, SCRATCH_PLUGINS_TYPE_PRESERVE_INDENT);
	_g_object_unref0 (objmodule);
}

