/* completion.c generated by valac 0.12.1, the Vala compiler
 * generated from completion.vala, do not modify */

/*
 * This file is part of LaTeXila.
 *
 * Copyright © 2010-2011 Sébastien Wilmet
 *
 * LaTeXila is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * LaTeXila is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY 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 LaTeXila.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glib.h>
#include <glib-object.h>
#include <gtksourceview/gtksourceview.h>
#include <gtksourceview/gtksourcecompletionitem.h>
#include <gee.h>
#include <stdlib.h>
#include <string.h>
#include <gio/gio.h>
#include <gdk-pixbuf/gdk-pixdata.h>
#include <gtk/gtk.h>
#include <config.h>
#include <glib/gi18n-lib.h>


#define TYPE_COMPLETION_PROVIDER (completion_provider_get_type ())
#define COMPLETION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_COMPLETION_PROVIDER, CompletionProvider))
#define COMPLETION_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_COMPLETION_PROVIDER, CompletionProviderClass))
#define IS_COMPLETION_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_COMPLETION_PROVIDER))
#define IS_COMPLETION_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_COMPLETION_PROVIDER))
#define COMPLETION_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_COMPLETION_PROVIDER, CompletionProviderClass))

typedef struct _CompletionProvider CompletionProvider;
typedef struct _CompletionProviderClass CompletionProviderClass;
typedef struct _CompletionProviderPrivate CompletionProviderPrivate;

#define COMPLETION_PROVIDER_TYPE_COMPLETION_COMMAND (completion_provider_completion_command_get_type ())

#define COMPLETION_PROVIDER_TYPE_COMPLETION_ARGUMENT (completion_provider_completion_argument_get_type ())

#define COMPLETION_PROVIDER_TYPE_COMPLETION_CHOICE (completion_provider_completion_choice_get_type ())
typedef struct _CompletionProviderCompletionChoice CompletionProviderCompletionChoice;
typedef struct _CompletionProviderCompletionArgument CompletionProviderCompletionArgument;
typedef struct _CompletionProviderCompletionCommand CompletionProviderCompletionCommand;
#define __g_list_free__g_object_unref0_0(var) ((var == NULL) ? NULL : (var = (_g_list_free__g_object_unref0_ (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_markup_parse_context_free0(var) ((var == NULL) ? NULL : (var = (g_markup_parse_context_free (var), NULL)))
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _completion_provider_completion_command_free0(var) ((var == NULL) ? NULL : (var = (completion_provider_completion_command_free (var), NULL)))

#define TYPE_DOCUMENT (document_get_type ())
#define DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DOCUMENT, Document))
#define DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DOCUMENT, DocumentClass))
#define IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DOCUMENT))
#define IS_DOCUMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DOCUMENT))
#define DOCUMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DOCUMENT, DocumentClass))

typedef struct _Document Document;
typedef struct _DocumentClass DocumentClass;
typedef struct _DocumentPrivate DocumentPrivate;

#define TYPE_DOCUMENT_TAB (document_tab_get_type ())
#define DOCUMENT_TAB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DOCUMENT_TAB, DocumentTab))
#define DOCUMENT_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DOCUMENT_TAB, DocumentTabClass))
#define IS_DOCUMENT_TAB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DOCUMENT_TAB))
#define IS_DOCUMENT_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DOCUMENT_TAB))
#define DOCUMENT_TAB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DOCUMENT_TAB, DocumentTabClass))

typedef struct _DocumentTab DocumentTab;
typedef struct _DocumentTabClass DocumentTabClass;

#define TYPE_DOCUMENT_VIEW (document_view_get_type ())
#define DOCUMENT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_DOCUMENT_VIEW, DocumentView))
#define DOCUMENT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_DOCUMENT_VIEW, DocumentViewClass))
#define IS_DOCUMENT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_DOCUMENT_VIEW))
#define IS_DOCUMENT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_DOCUMENT_VIEW))
#define DOCUMENT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_DOCUMENT_VIEW, DocumentViewClass))

typedef struct _DocumentView DocumentView;
typedef struct _DocumentViewClass DocumentViewClass;
#define _completion_provider_completion_choice_free0(var) ((var == NULL) ? NULL : (var = (completion_provider_completion_choice_free (var), NULL)))

#define TYPE_APPLICATION (application_get_type ())
#define APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_APPLICATION, Application))
#define APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_APPLICATION, ApplicationClass))
#define IS_APPLICATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_APPLICATION))
#define IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_APPLICATION))
#define APPLICATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_APPLICATION, ApplicationClass))

typedef struct _Application Application;
typedef struct _ApplicationClass ApplicationClass;

#define TYPE_MAIN_WINDOW (main_window_get_type ())
#define MAIN_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_MAIN_WINDOW, MainWindow))
#define MAIN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_MAIN_WINDOW, MainWindowClass))
#define IS_MAIN_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_MAIN_WINDOW))
#define IS_MAIN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_MAIN_WINDOW))
#define MAIN_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_MAIN_WINDOW, MainWindowClass))

typedef struct _MainWindow MainWindow;
typedef struct _MainWindowClass MainWindowClass;

struct _CompletionProvider {
	GObject parent_instance;
	CompletionProviderPrivate * priv;
};

struct _CompletionProviderClass {
	GObjectClass parent_class;
};

struct _CompletionProviderCompletionChoice {
	gchar* name;
	gchar* package;
	gchar* insert;
	gchar* insert_after;
};

struct _CompletionProviderCompletionArgument {
	gchar* label;
	gboolean optional;
	CompletionProviderCompletionChoice* choices;
	gint choices_length1;
	gint _choices_size_;
};

struct _CompletionProviderCompletionCommand {
	gchar* name;
	gchar* package;
	CompletionProviderCompletionArgument* args;
	gint args_length1;
	gint _args_size_;
};

struct _CompletionProviderPrivate {
	GList* proposals;
	GeeHashMap* commands;
	GeeHashMap* environments;
	GSettings* settings;
	CompletionProviderCompletionCommand current_command;
	CompletionProviderCompletionArgument current_arg;
	CompletionProviderCompletionChoice current_choice;
	gboolean show_all_proposals;
	GdkPixbuf* icon_normal_cmd;
	GdkPixbuf* icon_normal_choice;
	GdkPixbuf* icon_package_required;
	GtkSourceCompletionInfo* calltip_window;
	GtkLabel* calltip_window_label;
	gboolean first_populate;
};

struct _Document {
	GtkSourceBuffer parent_instance;
	DocumentPrivate * priv;
	DocumentTab* tab;
	guint _unsaved_doc_num;
};

struct _DocumentClass {
	GtkSourceBufferClass parent_class;
};


static gpointer completion_provider_parent_class = NULL;
static CompletionProvider* completion_provider_instance;
static CompletionProvider* completion_provider_instance = NULL;
static GtkSourceCompletionProviderIface* completion_provider_gtk_source_completion_provider_parent_iface = NULL;

GType completion_provider_get_type (void) G_GNUC_CONST;
static GType completion_provider_completion_command_get_type (void) G_GNUC_CONST G_GNUC_UNUSED;
static GType completion_provider_completion_argument_get_type (void) G_GNUC_CONST G_GNUC_UNUSED;
static GType completion_provider_completion_choice_get_type (void) G_GNUC_CONST G_GNUC_UNUSED;
static CompletionProviderCompletionChoice* completion_provider_completion_choice_dup (const CompletionProviderCompletionChoice* self);
static void completion_provider_completion_choice_free (CompletionProviderCompletionChoice* self);
static void completion_provider_completion_choice_copy (const CompletionProviderCompletionChoice* self, CompletionProviderCompletionChoice* dest);
static void completion_provider_completion_choice_destroy (CompletionProviderCompletionChoice* self);
static CompletionProviderCompletionArgument* completion_provider_completion_argument_dup (const CompletionProviderCompletionArgument* self);
static void completion_provider_completion_argument_free (CompletionProviderCompletionArgument* self);
static void completion_provider_completion_argument_copy (const CompletionProviderCompletionArgument* self, CompletionProviderCompletionArgument* dest);
static void completion_provider_completion_argument_destroy (CompletionProviderCompletionArgument* self);
static CompletionProviderCompletionCommand* completion_provider_completion_command_dup (const CompletionProviderCompletionCommand* self);
static void completion_provider_completion_command_free (CompletionProviderCompletionCommand* self);
static void completion_provider_completion_command_copy (const CompletionProviderCompletionCommand* self, CompletionProviderCompletionCommand* dest);
static void completion_provider_completion_command_destroy (CompletionProviderCompletionCommand* self);
#define COMPLETION_PROVIDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_COMPLETION_PROVIDER, CompletionProviderPrivate))
enum  {
	COMPLETION_PROVIDER_DUMMY_PROPERTY
};
static void _g_object_unref0_ (gpointer var);
static void _g_list_free__g_object_unref0_ (GList* self);
static CompletionProvider* completion_provider_new (void);
static CompletionProvider* completion_provider_construct (GType object_type);
GdkPixbuf* utils_get_pixbuf_from_stock (const gchar* stock_id, GtkIconSize size);
static void completion_provider_parser_start (CompletionProvider* self, GMarkupParseContext* context, const gchar* name, gchar** attr_names, int attr_names_length1, gchar** attr_values, int attr_values_length1, GError** error);
static void _completion_provider_parser_start_gmarkup_parser_start_element_func (GMarkupParseContext* context, const gchar* element_name, gchar** attribute_names, gchar** attribute_values, gpointer self, GError** error);
static void completion_provider_parser_end (CompletionProvider* self, GMarkupParseContext* context, const gchar* name, GError** error);
static void _completion_provider_parser_end_gmarkup_parser_end_element_func (GMarkupParseContext* context, const gchar* element_name, gpointer self, GError** error);
static void completion_provider_parser_text (CompletionProvider* self, GMarkupParseContext* context, const gchar* text, gsize text_len, GError** error);
static void _completion_provider_parser_text_gmarkup_parser_text_func (GMarkupParseContext* context, const gchar* text, gsize text_len, gpointer self, GError** error);
static gint completion_provider_compare_proposals (GtkSourceCompletionItem* a, GtkSourceCompletionItem* b);
CompletionProvider* completion_provider_get_default (void);
static gchar* completion_provider_real_get_name (GtkSourceCompletionProvider* base);
static GtkSourceCompletionActivation completion_provider_real_get_activation (GtkSourceCompletionProvider* base);
static gboolean completion_provider_real_match (GtkSourceCompletionProvider* base, GtkSourceCompletionContext* context);
static gchar* completion_provider_get_latex_command_at_iter (CompletionProvider* self, GtkTextIter* iter);
static gboolean completion_provider_in_latex_command_argument (CompletionProvider* self, GtkTextIter* iter, gchar** cmd_name, GeeArrayList** arguments, gchar** argument_contents, gboolean* valid_arg_contents);
static void completion_provider_real_populate (GtkSourceCompletionProvider* base, GtkSourceCompletionContext* context);
static void completion_provider_clear_context (CompletionProvider* self, GtkSourceCompletionContext* context);
static GList* completion_provider_get_argument_proposals (CompletionProvider* self, CompletionProviderCompletionCommand* cmd, GeeArrayList* arguments);
void completion_provider_hide_calltip_window (CompletionProvider* self);
static gint completion_provider_get_argument_num (CompletionProvider* self, CompletionProviderCompletionArgument* all_args, int all_args_length1, GeeArrayList* args);
static gchar* completion_provider_get_command_info (CompletionProvider* self, CompletionProviderCompletionCommand* cmd, gint num);
static void completion_provider_show_calltip_info (CompletionProvider* self, const gchar* markup);
static gboolean completion_provider_real_activate_proposal (GtkSourceCompletionProvider* base, GtkSourceCompletionProposal* proposal, GtkTextIter* iter);
static void completion_provider_activate_proposal_argument_choice (CompletionProvider* self, GtkSourceCompletionProposal* proposal, GtkTextIter* iter, const gchar* cmd_name, const gchar* argument_contents);
static void completion_provider_activate_proposal_command_name (CompletionProvider* self, GtkSourceCompletionProposal* proposal, GtkTextIter* iter, const gchar* cmd);
static void completion_provider_close_environment (CompletionProvider* self, const gchar* env_name, GtkTextIter* iter);
GType document_get_type (void) G_GNUC_CONST;
void document_insert (Document* self, GtkTextIter* iter, const gchar* text, gint len);
gchar* document_get_current_indentation (Document* self, gint line);
GType document_tab_get_type (void) G_GNUC_CONST;
GType document_view_get_type (void) G_GNUC_CONST;
DocumentView* document_tab_get_view (DocumentTab* self);
gchar* document_view_get_indentation_style (DocumentView* self);
static void completion_provider_init_calltip_window (CompletionProvider* self);
GType application_get_type (void) G_GNUC_CONST;
Application* application_get_default (void);
GType main_window_get_type (void) G_GNUC_CONST;
MainWindow* application_get_active_window (Application* self);
DocumentView* main_window_get_active_view (MainWindow* self);
static gchar* completion_provider_get_text_line_at_iter (CompletionProvider* self, GtkTextIter* iter);
gboolean utils_char_is_escaped (const gchar* text, glong char_index);
static gchar* completion_provider_get_command_text (CompletionProvider* self, CompletionProviderCompletionCommand* cmd);
static void _vala_array_add10 (CompletionProviderCompletionArgument** array, int* length, int* size, const CompletionProviderCompletionArgument* value);
static void _vala_array_add11 (CompletionProviderCompletionChoice** array, int* length, int* size, const CompletionProviderCompletionChoice* value);
static gchar* completion_provider_get_latex_command_at_index (CompletionProvider* self, const gchar* text, glong index);
static void _vala_CompletionProviderCompletionArgument_array_free (CompletionProviderCompletionArgument* array, gint array_length);
static CompletionProviderCompletionArgument* _vala_array_dup1 (CompletionProviderCompletionArgument* self, int length);
static void _vala_CompletionProviderCompletionChoice_array_free (CompletionProviderCompletionChoice* array, gint array_length);
static CompletionProviderCompletionChoice* _vala_array_dup2 (CompletionProviderCompletionChoice* self, int length);
static void completion_provider_finalize (GObject* obj);
static gint _vala_array_length (gpointer array);


static void _g_object_unref0_ (gpointer var) {
	(var == NULL) ? NULL : (var = (g_object_unref (var), NULL));
}


static void _g_list_free__g_object_unref0_ (GList* self) {
	g_list_foreach (self, (GFunc) _g_object_unref0_, NULL);
	g_list_free (self);
}


static void _completion_provider_parser_start_gmarkup_parser_start_element_func (GMarkupParseContext* context, const gchar* element_name, gchar** attribute_names, gchar** attribute_values, gpointer self, GError** error) {
	completion_provider_parser_start (self, context, element_name, attribute_names, _vala_array_length (attribute_names), attribute_values, _vala_array_length (attribute_values), error);
}


static void _completion_provider_parser_end_gmarkup_parser_end_element_func (GMarkupParseContext* context, const gchar* element_name, gpointer self, GError** error) {
	completion_provider_parser_end (self, context, element_name, error);
}


static void _completion_provider_parser_text_gmarkup_parser_text_func (GMarkupParseContext* context, const gchar* text, gsize text_len, gpointer self, GError** error) {
	completion_provider_parser_text (self, context, text, text_len, error);
}


static CompletionProvider* completion_provider_construct (GType object_type) {
	CompletionProvider * self = NULL;
	GSettings* _tmp0_ = NULL;
	GeeHashMap* _tmp1_ = NULL;
	GeeHashMap* _tmp2_ = NULL;
	GdkPixbuf* _tmp3_ = NULL;
	GdkPixbuf* _tmp4_ = NULL;
	GdkPixbuf* _tmp5_ = NULL;
	GFile* _tmp6_ = NULL;
	GFile* file;
	gchar* contents = NULL;
	gchar* _tmp7_ = NULL;
	GMarkupParser _tmp8_ = {0};
	GMarkupParser parser;
	GMarkupParseContext* _tmp9_ = NULL;
	GMarkupParseContext* context;
	GError * _inner_error_ = NULL;
	self = (CompletionProvider*) g_object_new (object_type, NULL);
	_tmp0_ = g_settings_new ("org.gnome.latexila.preferences.latex");
	_g_object_unref0 (self->priv->settings);
	self->priv->settings = _tmp0_;
	_tmp1_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, COMPLETION_PROVIDER_TYPE_COMPLETION_COMMAND, (GBoxedCopyFunc) completion_provider_completion_command_dup, completion_provider_completion_command_free, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->commands);
	self->priv->commands = _tmp1_;
	_tmp2_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, g_free, COMPLETION_PROVIDER_TYPE_COMPLETION_CHOICE, (GBoxedCopyFunc) completion_provider_completion_choice_dup, completion_provider_completion_choice_free, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->environments);
	self->priv->environments = _tmp2_;
	_tmp3_ = utils_get_pixbuf_from_stock ("completion_cmd", GTK_ICON_SIZE_MENU);
	_g_object_unref0 (self->priv->icon_normal_cmd);
	self->priv->icon_normal_cmd = _tmp3_;
	_tmp4_ = utils_get_pixbuf_from_stock ("completion_choice", GTK_ICON_SIZE_MENU);
	_g_object_unref0 (self->priv->icon_normal_choice);
	self->priv->icon_normal_choice = _tmp4_;
	_tmp5_ = utils_get_pixbuf_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU);
	_g_object_unref0 (self->priv->icon_package_required);
	self->priv->icon_package_required = _tmp5_;
	_tmp6_ = g_file_new_for_path (DATA_DIR "/completion.xml");
	file = _tmp6_;
	g_file_load_contents (file, NULL, &_tmp7_, NULL, NULL, &_inner_error_);
	_g_free0 (contents);
	contents = _tmp7_;
	if (_inner_error_ != NULL) {
		_g_free0 (contents);
		_g_object_unref0 (file);
		goto __catch42_g_error;
	}
	_tmp8_.start_element = _completion_provider_parser_start_gmarkup_parser_start_element_func;
	_tmp8_.end_element = _completion_provider_parser_end_gmarkup_parser_end_element_func;
	_tmp8_.text = _completion_provider_parser_text_gmarkup_parser_text_func;
	_tmp8_.passthrough = NULL;
	_tmp8_.error = NULL;
	parser = _tmp8_;
	_tmp9_ = g_markup_parse_context_new (&parser, 0, self, NULL);
	context = _tmp9_;
	g_markup_parse_context_parse (context, contents, (gssize) (-1), &_inner_error_);
	if (_inner_error_ != NULL) {
		_g_markup_parse_context_free0 (context);
		_g_free0 (contents);
		_g_object_unref0 (file);
		goto __catch42_g_error;
	}
	self->priv->proposals = g_list_sort (self->priv->proposals, (GCompareFunc) completion_provider_compare_proposals);
	_g_markup_parse_context_free0 (context);
	_g_free0 (contents);
	_g_object_unref0 (file);
	goto __finally42;
	__catch42_g_error:
	{
		GError * e;
		e = _inner_error_;
		_inner_error_ = NULL;
		g_warning ("completion.vala:100: Impossible to load completion data: %s", e->message);
		_g_error_free0 (e);
	}
	__finally42:
	if (_inner_error_ != NULL) {
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
		g_clear_error (&_inner_error_);
		return NULL;
	}
	return self;
}


static CompletionProvider* completion_provider_new (void) {
	return completion_provider_construct (TYPE_COMPLETION_PROVIDER);
}


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


CompletionProvider* completion_provider_get_default (void) {
	CompletionProvider* result = NULL;
	CompletionProvider* _tmp1_;
	if (completion_provider_instance == NULL) {
		CompletionProvider* _tmp0_ = NULL;
		_tmp0_ = completion_provider_new ();
		_g_object_unref0 (completion_provider_instance);
		completion_provider_instance = _tmp0_;
	}
	_tmp1_ = _g_object_ref0 (completion_provider_instance);
	result = _tmp1_;
	return result;
}


static gchar* completion_provider_real_get_name (GtkSourceCompletionProvider* base) {
	CompletionProvider * self;
	gchar* result = NULL;
	gchar* _tmp0_;
	self = (CompletionProvider*) base;
	_tmp0_ = g_strdup ("LaTeX");
	result = _tmp0_;
	return result;
}


static GtkSourceCompletionActivation completion_provider_real_get_activation (GtkSourceCompletionProvider* base) {
	CompletionProvider * self;
	GtkSourceCompletionActivation result = 0;
	GtkSourceCompletionActivation ret;
	gboolean _tmp0_;
	self = (CompletionProvider*) base;
	ret = GTK_SOURCE_COMPLETION_ACTIVATION_USER_REQUESTED;
	_tmp0_ = g_settings_get_boolean (self->priv->settings, "interactive-completion");
	if (_tmp0_) {
		ret = ret | GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE;
	}
	result = ret;
	return result;
}


static gboolean completion_provider_real_match (GtkSourceCompletionProvider* base, GtkSourceCompletionContext* context) {
	CompletionProvider * self;
	gboolean result = FALSE;
	gboolean in_argument;
	gboolean valid_arg_contents;
	GtkTextIter _tmp0_ = {0};
	GtkTextIter iter;
	GtkTextBuffer* _tmp1_ = NULL;
	GtkTextBuffer* _tmp2_;
	GtkTextBuffer* buf;
	gboolean _tmp3_;
	gchar* _tmp4_ = NULL;
	gchar* cmd;
	GtkSourceCompletionActivation _tmp7_;
	gboolean _tmp9_ = FALSE;
	gboolean _tmp10_;
	gboolean _tmp12_ = FALSE;
	guint min_nb_chars = 0U;
	gboolean _tmp13_ = FALSE;
	self = (CompletionProvider*) base;
	g_return_val_if_fail (context != NULL, FALSE);
	self->priv->first_populate = TRUE;
	in_argument = FALSE;
	valid_arg_contents = FALSE;
	self->priv->show_all_proposals = FALSE;
	iter = _tmp0_;
	gtk_source_completion_context_get_iter (context, &iter);
	_tmp1_ = gtk_text_iter_get_buffer (&iter);
	_tmp2_ = _g_object_ref0 (_tmp1_);
	buf = _tmp2_;
	_tmp3_ = gtk_text_buffer_get_has_selection (buf);
	if (_tmp3_) {
		result = FALSE;
		_g_object_unref0 (buf);
		return result;
	}
	_tmp4_ = completion_provider_get_latex_command_at_iter (self, &iter);
	cmd = _tmp4_;
	if (cmd == NULL) {
		gboolean _tmp5_;
		gboolean _tmp6_;
		_tmp6_ = completion_provider_in_latex_command_argument (self, &iter, NULL, NULL, NULL, &_tmp5_);
		valid_arg_contents = _tmp5_;
		in_argument = _tmp6_;
	}
	g_object_get (context, "activation", &_tmp7_, NULL);
	if (_tmp7_ == GTK_SOURCE_COMPLETION_ACTIVATION_USER_REQUESTED) {
		gboolean _tmp8_ = FALSE;
		if (cmd == NULL) {
			_tmp8_ = !in_argument;
		} else {
			_tmp8_ = FALSE;
		}
		self->priv->show_all_proposals = _tmp8_;
		result = TRUE;
		_g_free0 (cmd);
		_g_object_unref0 (buf);
		return result;
	}
	_tmp10_ = g_settings_get_boolean (self->priv->settings, "interactive-completion");
	if (!_tmp10_) {
		_tmp9_ = TRUE;
	} else {
		gboolean _tmp11_ = FALSE;
		if (in_argument) {
			_tmp11_ = !valid_arg_contents;
		} else {
			_tmp11_ = FALSE;
		}
		_tmp9_ = _tmp11_;
	}
	if (_tmp9_) {
		result = FALSE;
		_g_free0 (cmd);
		_g_object_unref0 (buf);
		return result;
	}
	if (in_argument) {
		_tmp12_ = valid_arg_contents;
	} else {
		_tmp12_ = FALSE;
	}
	if (_tmp12_) {
		result = TRUE;
		_g_free0 (cmd);
		_g_object_unref0 (buf);
		return result;
	}
	g_settings_get (self->priv->settings, "interactive-completion-num", "u", &min_nb_chars);
	if (cmd != NULL) {
		gint _tmp14_;
		_tmp14_ = strlen (cmd);
		_tmp13_ = _tmp14_ > min_nb_chars;
	} else {
		_tmp13_ = FALSE;
	}
	result = _tmp13_;
	_g_free0 (cmd);
	_g_object_unref0 (buf);
	return result;
}


static void completion_provider_real_populate (GtkSourceCompletionProvider* base, GtkSourceCompletionContext* context) {
	CompletionProvider * self;
	GtkTextIter _tmp0_ = {0};
	GtkTextIter iter;
	gchar* _tmp1_ = NULL;
	gchar* cmd;
	gboolean in_argument;
	gchar* cmd_name;
	GeeArrayList* _tmp2_ = NULL;
	GeeArrayList* arguments;
	gchar* argument_contents;
	gboolean valid_arg_contents;
	gboolean _tmp8_ = FALSE;
	gboolean _tmp9_ = FALSE;
	gboolean _tmp10_ = FALSE;
	gboolean _tmp11_ = FALSE;
	gboolean _tmp17_ = FALSE;
	GList* proposals_to_filter;
	gchar* prefix;
	gboolean _tmp28_ = FALSE;
	GList* filtered_proposals;
	self = (CompletionProvider*) base;
	g_return_if_fail (context != NULL);
	iter = _tmp0_;
	gtk_source_completion_context_get_iter (context, &iter);
	_tmp1_ = completion_provider_get_latex_command_at_iter (self, &iter);
	cmd = _tmp1_;
	in_argument = FALSE;
	cmd_name = NULL;
	_tmp2_ = gee_array_list_new (G_TYPE_BOOLEAN, NULL, NULL, NULL);
	arguments = _tmp2_;
	argument_contents = NULL;
	valid_arg_contents = FALSE;
	if (cmd == NULL) {
		gchar* _tmp3_ = NULL;
		GeeArrayList* _tmp4_ = NULL;
		gchar* _tmp5_ = NULL;
		gboolean _tmp6_;
		gboolean _tmp7_;
		_tmp7_ = completion_provider_in_latex_command_argument (self, &iter, &_tmp3_, &_tmp4_, &_tmp5_, &_tmp6_);
		_g_free0 (cmd_name);
		cmd_name = _tmp3_;
		_g_object_unref0 (arguments);
		arguments = _tmp4_;
		_g_free0 (argument_contents);
		argument_contents = _tmp5_;
		valid_arg_contents = _tmp6_;
		in_argument = _tmp7_;
	}
	if (!self->priv->show_all_proposals) {
		_tmp11_ = cmd == NULL;
	} else {
		_tmp11_ = FALSE;
	}
	if (_tmp11_) {
		_tmp10_ = !in_argument;
	} else {
		_tmp10_ = FALSE;
	}
	if (_tmp10_) {
		_tmp9_ = TRUE;
	} else {
		gboolean _tmp12_ = FALSE;
		GtkSourceCompletionActivation _tmp13_;
		g_object_get (context, "activation", &_tmp13_, NULL);
		if (_tmp13_ == GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE) {
			gboolean _tmp14_;
			_tmp14_ = g_settings_get_boolean (self->priv->settings, "interactive-completion");
			_tmp12_ = !_tmp14_;
		} else {
			_tmp12_ = FALSE;
		}
		_tmp9_ = _tmp12_;
	}
	if (_tmp9_) {
		_tmp8_ = TRUE;
	} else {
		gboolean _tmp15_ = FALSE;
		if (in_argument) {
			gboolean _tmp16_;
			_tmp16_ = gee_abstract_map_has_key ((GeeAbstractMap*) self->priv->commands, cmd_name);
			_tmp15_ = !_tmp16_;
		} else {
			_tmp15_ = FALSE;
		}
		_tmp8_ = _tmp15_;
	}
	if (_tmp8_) {
		completion_provider_clear_context (self, context);
		self->priv->first_populate = FALSE;
		_g_free0 (argument_contents);
		_g_object_unref0 (arguments);
		_g_free0 (cmd_name);
		_g_free0 (cmd);
		return;
	}
	if (self->priv->show_all_proposals) {
		_tmp17_ = TRUE;
	} else {
		_tmp17_ = g_strcmp0 (cmd, "\\") == 0;
	}
	if (_tmp17_) {
		self->priv->show_all_proposals = FALSE;
		gtk_source_completion_context_add_proposals (context, GTK_SOURCE_COMPLETION_PROVIDER (self), self->priv->proposals, TRUE);
		self->priv->first_populate = FALSE;
		_g_free0 (argument_contents);
		_g_object_unref0 (arguments);
		_g_free0 (cmd_name);
		_g_free0 (cmd);
		return;
	}
	proposals_to_filter = NULL;
	prefix = NULL;
	if (!in_argument) {
		gchar* _tmp18_;
		proposals_to_filter = self->priv->proposals;
		_tmp18_ = g_strdup (cmd);
		_g_free0 (prefix);
		prefix = _tmp18_;
	} else {
		gboolean _tmp19_ = FALSE;
		if (valid_arg_contents) {
			gboolean _tmp20_;
			_tmp20_ = gee_abstract_map_has_key ((GeeAbstractMap*) self->priv->commands, cmd_name);
			_tmp19_ = _tmp20_;
		} else {
			_tmp19_ = FALSE;
		}
		if (_tmp19_) {
			gpointer _tmp21_ = NULL;
			CompletionProviderCompletionCommand* _tmp22_;
			GList* _tmp23_ = NULL;
			gchar* _tmp24_;
			gchar* _tmp25_;
			gchar* _tmp27_;
			_tmp21_ = gee_abstract_map_get ((GeeAbstractMap*) self->priv->commands, cmd_name);
			_tmp22_ = (CompletionProviderCompletionCommand*) _tmp21_;
			_tmp23_ = completion_provider_get_argument_proposals (self, _tmp22_, arguments);
			proposals_to_filter = _tmp23_;
			_completion_provider_completion_command_free0 (_tmp22_);
			_tmp24_ = g_strdup (argument_contents);
			_tmp25_ = _tmp24_;
			if (_tmp25_ == NULL) {
				gchar* _tmp26_;
				_tmp26_ = g_strdup ("");
				_g_free0 (_tmp25_);
				_tmp25_ = _tmp26_;
			}
			_tmp27_ = g_strdup (_tmp25_);
			_g_free0 (prefix);
			prefix = _tmp27_;
			_g_free0 (_tmp25_);
		}
	}
	if (in_argument) {
		_tmp28_ = proposals_to_filter == NULL;
	} else {
		_tmp28_ = FALSE;
	}
	if (_tmp28_) {
		GtkSourceCompletionActivation _tmp29_;
		g_object_get (context, "activation", &_tmp29_, NULL);
		if (_tmp29_ == GTK_SOURCE_COMPLETION_ACTIVATION_INTERACTIVE) {
			completion_provider_clear_context (self, context);
			completion_provider_hide_calltip_window (self);
			_g_free0 (prefix);
			_g_free0 (argument_contents);
			_g_object_unref0 (arguments);
			_g_free0 (cmd_name);
			_g_free0 (cmd);
			return;
		}
		if (self->priv->first_populate) {
			gpointer _tmp30_ = NULL;
			CompletionProviderCompletionCommand* _tmp31_;
			CompletionProviderCompletionCommand _tmp32_;
			CompletionProviderCompletionCommand _tmp33_ = {0};
			CompletionProviderCompletionCommand _tmp34_;
			CompletionProviderCompletionCommand command;
			gint _tmp35_;
			gint num;
			_tmp30_ = gee_abstract_map_get ((GeeAbstractMap*) self->priv->commands, cmd_name);
			_tmp31_ = (CompletionProviderCompletionCommand*) _tmp30_;
			completion_provider_completion_command_copy (_tmp31_, &_tmp33_);
			_tmp32_ = _tmp33_;
			_tmp34_ = _tmp32_;
			_completion_provider_completion_command_free0 (_tmp31_);
			command = _tmp34_;
			_tmp35_ = completion_provider_get_argument_num (self, command.args, command.args_length1, arguments);
			num = _tmp35_;
			if (num != (-1)) {
				gchar* _tmp36_ = NULL;
				gchar* info;
				_tmp36_ = completion_provider_get_command_info (self, &command, num);
				info = _tmp36_;
				completion_provider_show_calltip_info (self, info);
				_g_free0 (info);
			}
			completion_provider_completion_command_destroy (&command);
			_g_free0 (prefix);
			_g_free0 (argument_contents);
			_g_object_unref0 (arguments);
			_g_free0 (cmd_name);
			_g_free0 (cmd);
			return;
		}
	}
	completion_provider_hide_calltip_window (self);
	filtered_proposals = NULL;
	{
		GList* item_collection;
		GList* item_it;
		item_collection = proposals_to_filter;
		for (item_it = item_collection; item_it != NULL; item_it = item_it->next) {
			GtkSourceCompletionItem* _tmp37_;
			GtkSourceCompletionItem* item;
			_tmp37_ = _g_object_ref0 ((GtkSourceCompletionItem*) item_it->data);
			item = _tmp37_;
			{
				gchar* _tmp38_ = NULL;
				gchar* _tmp39_;
				gboolean _tmp40_;
				gboolean _tmp41_;
				g_object_get (item, "text", &_tmp38_, NULL);
				_tmp39_ = _tmp38_;
				_tmp40_ = g_str_has_prefix (_tmp39_, prefix);
				_tmp41_ = _tmp40_;
				_g_free0 (_tmp39_);
				if (_tmp41_) {
					GtkSourceCompletionItem* _tmp42_;
					_tmp42_ = _g_object_ref0 (item);
					filtered_proposals = g_list_prepend (filtered_proposals, _tmp42_);
				}
				_g_object_unref0 (item);
			}
		}
	}
	if (filtered_proposals == NULL) {
		const gchar* _tmp43_ = NULL;
		GtkSourceCompletionItem* _tmp44_ = NULL;
		GtkSourceCompletionItem* dummy_proposal;
		GtkSourceCompletionItem* _tmp45_;
		_tmp43_ = _ ("No matching proposal");
		_tmp44_ = gtk_source_completion_item_new (_tmp43_, "", NULL, NULL);
		dummy_proposal = _tmp44_;
		_tmp45_ = _g_object_ref0 (dummy_proposal);
		filtered_proposals = g_list_prepend (filtered_proposals, _tmp45_);
		_g_object_unref0 (dummy_proposal);
	} else {
		filtered_proposals = g_list_reverse (filtered_proposals);
	}
	gtk_source_completion_context_add_proposals (context, GTK_SOURCE_COMPLETION_PROVIDER (self), filtered_proposals, TRUE);
	self->priv->first_populate = FALSE;
	__g_list_free__g_object_unref0_0 (filtered_proposals);
	_g_free0 (prefix);
	_g_free0 (argument_contents);
	_g_object_unref0 (arguments);
	_g_free0 (cmd_name);
	_g_free0 (cmd);
}


static gchar string_get (const gchar* self, glong index) {
	gchar result = '\0';
	g_return_val_if_fail (self != NULL, '\0');
	result = ((gchar*) self)[index];
	return result;
}


static gboolean completion_provider_real_activate_proposal (GtkSourceCompletionProvider* base, GtkSourceCompletionProposal* proposal, GtkTextIter* iter) {
	CompletionProvider * self;
	gboolean result = FALSE;
	gchar* _tmp0_ = NULL;
	gchar* text;
	gboolean _tmp1_ = FALSE;
	gchar* _tmp2_ = NULL;
	gchar* cmd;
	gboolean _tmp3_ = FALSE;
	self = (CompletionProvider*) base;
	g_return_val_if_fail (proposal != NULL, FALSE);
	_tmp0_ = gtk_source_completion_proposal_get_text (proposal);
	text = _tmp0_;
	if (text == NULL) {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = g_strcmp0 (text, "") == 0;
	}
	if (_tmp1_) {
		result = TRUE;
		_g_free0 (text);
		return result;
	}
	_tmp2_ = completion_provider_get_latex_command_at_iter (self, iter);
	cmd = _tmp2_;
	if (cmd == NULL) {
		gchar _tmp4_;
		_tmp4_ = string_get (text, (glong) 0);
		_tmp3_ = _tmp4_ != '\\';
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		gchar* cmd_name;
		gchar* argument_contents;
		gchar* _tmp5_ = NULL;
		gchar* _tmp6_ = NULL;
		gboolean _tmp7_;
		gboolean in_argument;
		cmd_name = NULL;
		argument_contents = NULL;
		_tmp7_ = completion_provider_in_latex_command_argument (self, iter, &_tmp5_, NULL, &_tmp6_, NULL);
		_g_free0 (cmd_name);
		cmd_name = _tmp5_;
		_g_free0 (argument_contents);
		argument_contents = _tmp6_;
		in_argument = _tmp7_;
		if (in_argument) {
			completion_provider_activate_proposal_argument_choice (self, proposal, iter, cmd_name, argument_contents);
			result = TRUE;
			_g_free0 (argument_contents);
			_g_free0 (cmd_name);
			_g_free0 (cmd);
			_g_free0 (text);
			return result;
		}
		_g_free0 (argument_contents);
		_g_free0 (cmd_name);
	}
	completion_provider_activate_proposal_command_name (self, proposal, iter, cmd);
	result = TRUE;
	_g_free0 (cmd);
	_g_free0 (text);
	return result;
}


static gchar* string_slice (const gchar* self, glong start, glong end) {
	gchar* result = NULL;
	gint _tmp0_;
	glong string_length;
	gboolean _tmp1_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gchar* _tmp3_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = strlen (self);
	string_length = (glong) _tmp0_;
	if (start < 0) {
		start = string_length + start;
	}
	if (end < 0) {
		end = string_length + end;
	}
	if (start >= 0) {
		_tmp1_ = start <= string_length;
	} else {
		_tmp1_ = FALSE;
	}
	g_return_val_if_fail (_tmp1_, NULL);
	if (end >= 0) {
		_tmp2_ = end <= string_length;
	} else {
		_tmp2_ = FALSE;
	}
	g_return_val_if_fail (_tmp2_, NULL);
	g_return_val_if_fail (start <= end, NULL);
	_tmp3_ = g_strndup (((gchar*) self) + start, (gsize) (end - start));
	result = _tmp3_;
	return result;
}


static void completion_provider_activate_proposal_command_name (CompletionProvider* self, GtkSourceCompletionProposal* proposal, GtkTextIter* iter, const gchar* cmd) {
	gchar* _tmp0_ = NULL;
	gchar* text;
	gint _tmp1_ = 0;
	glong index_start;
	gint _tmp3_;
	gchar* _tmp4_ = NULL;
	gchar* text_to_insert;
	GtkTextBuffer* _tmp5_ = NULL;
	GtkTextBuffer* _tmp6_;
	GtkTextBuffer* doc;
	gint i = 0;
	gint _tmp10_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (proposal != NULL);
	_tmp0_ = gtk_source_completion_proposal_get_text (proposal);
	text = _tmp0_;
	if (cmd != NULL) {
		gint _tmp2_;
		_tmp2_ = strlen (cmd);
		_tmp1_ = _tmp2_;
	} else {
		_tmp1_ = 0;
	}
	index_start = (glong) _tmp1_;
	_tmp3_ = strlen (text);
	_tmp4_ = string_slice (text, index_start, (glong) _tmp3_);
	text_to_insert = _tmp4_;
	_tmp5_ = gtk_text_iter_get_buffer (iter);
	_tmp6_ = _g_object_ref0 (_tmp5_);
	doc = _tmp6_;
	gtk_text_buffer_begin_user_action (doc);
	gtk_text_buffer_insert (doc, iter, text_to_insert, -1);
	gtk_text_buffer_end_user_action (doc);
	{
		gboolean _tmp7_;
		i = 0;
		_tmp7_ = TRUE;
		while (TRUE) {
			gint _tmp8_;
			gchar _tmp9_;
			if (!_tmp7_) {
				i++;
			}
			_tmp7_ = FALSE;
			_tmp8_ = strlen (text_to_insert);
			if (!(i < _tmp8_)) {
				break;
			}
			_tmp9_ = string_get (text_to_insert, (glong) i);
			if (_tmp9_ == '{') {
				break;
			}
		}
	}
	_tmp10_ = strlen (text_to_insert);
	if (i < _tmp10_) {
		gint _tmp11_;
		gboolean _tmp12_;
		_tmp11_ = strlen (text_to_insert);
		_tmp12_ = gtk_text_iter_backward_chars (iter, (((gint) _tmp11_) - i) - 1);
		if (_tmp12_) {
			gtk_text_buffer_place_cursor (doc, iter);
		}
	}
	_g_object_unref0 (doc);
	_g_free0 (text_to_insert);
	_g_free0 (text);
}


static void completion_provider_activate_proposal_argument_choice (CompletionProvider* self, GtkSourceCompletionProposal* proposal, GtkTextIter* iter, const gchar* cmd_name, const gchar* argument_contents) {
	gchar* _tmp0_ = NULL;
	gchar* text;
	gint _tmp1_ = 0;
	glong index_start;
	gint _tmp3_;
	gchar* _tmp4_ = NULL;
	gchar* text_to_insert;
	GtkTextBuffer* _tmp5_ = NULL;
	GtkTextBuffer* _tmp6_;
	GtkTextBuffer* doc;
	g_return_if_fail (self != NULL);
	g_return_if_fail (proposal != NULL);
	g_return_if_fail (cmd_name != NULL);
	_tmp0_ = gtk_source_completion_proposal_get_text (proposal);
	text = _tmp0_;
	if (argument_contents != NULL) {
		gint _tmp2_;
		_tmp2_ = strlen (argument_contents);
		_tmp1_ = _tmp2_;
	} else {
		_tmp1_ = 0;
	}
	index_start = (glong) _tmp1_;
	_tmp3_ = strlen (text);
	_tmp4_ = string_slice (text, index_start, (glong) _tmp3_);
	text_to_insert = _tmp4_;
	_tmp5_ = gtk_text_iter_get_buffer (iter);
	_tmp6_ = _g_object_ref0 (_tmp5_);
	doc = _tmp6_;
	gtk_text_buffer_begin_user_action (doc);
	gtk_text_buffer_insert (doc, iter, text_to_insert, -1);
	if (g_strcmp0 (cmd_name, "\\begin") == 0) {
		completion_provider_close_environment (self, text, iter);
	} else {
	}
	gtk_text_buffer_end_user_action (doc);
	_g_object_unref0 (doc);
	_g_free0 (text_to_insert);
	_g_free0 (text);
}


static const gchar* string_to_string (const gchar* self) {
	const gchar* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	result = self;
	return result;
}


static void completion_provider_close_environment (CompletionProvider* self, const gchar* env_name, GtkTextIter* iter) {
	gint _tmp0_;
	gint line;
	GtkTextBuffer* _tmp1_ = NULL;
	Document* _tmp2_;
	Document* doc;
	GtkTextIter end_iter = {0};
	GtkTextIter _tmp3_ = {0};
	gchar* _tmp4_ = NULL;
	gchar* text;
	gboolean found;
	glong i = 0L;
	gchar* _tmp10_ = NULL;
	gchar* current_indent;
	gpointer _tmp11_ = NULL;
	CompletionProviderCompletionChoice* environment;
	Document* _tmp12_;
	Document* document;
	DocumentView* _tmp13_ = NULL;
	gchar* _tmp14_ = NULL;
	gchar* indent;
	const gchar* _tmp15_ = NULL;
	const gchar* _tmp16_ = NULL;
	gchar* _tmp17_ = NULL;
	gchar* _tmp18_;
	gboolean _tmp19_ = FALSE;
	GtkTextMark* _tmp20_ = NULL;
	GtkTextMark* _tmp21_;
	GtkTextMark* cursor_pos;
	gboolean _tmp22_ = FALSE;
	const gchar* _tmp23_ = NULL;
	gchar* _tmp24_ = NULL;
	gchar* _tmp25_;
	gchar* _tmp26_;
	gchar* _tmp27_;
	gchar* _tmp28_;
	gchar* _tmp29_;
	GtkTextIter _tmp30_ = {0};
	g_return_if_fail (self != NULL);
	g_return_if_fail (env_name != NULL);
	_tmp0_ = gtk_text_iter_get_line (iter);
	line = _tmp0_;
	_tmp1_ = gtk_text_iter_get_buffer (iter);
	_tmp2_ = _g_object_ref0 (DOCUMENT (_tmp1_));
	doc = _tmp2_;
	gtk_text_buffer_get_iter_at_line ((GtkTextBuffer*) doc, &_tmp3_, line + 1);
	end_iter = _tmp3_;
	_tmp4_ = gtk_text_buffer_get_text ((GtkTextBuffer*) doc, iter, &end_iter, FALSE);
	text = _tmp4_;
	found = FALSE;
	{
		gboolean _tmp5_;
		i = (glong) 0;
		_tmp5_ = TRUE;
		while (TRUE) {
			gint _tmp6_;
			gchar _tmp7_;
			gchar _tmp8_;
			gboolean _tmp9_;
			if (!_tmp5_) {
				i++;
			}
			_tmp5_ = FALSE;
			_tmp6_ = strlen (text);
			if (!(i < _tmp6_)) {
				break;
			}
			_tmp7_ = string_get (text, i);
			if (_tmp7_ == '}') {
				found = TRUE;
				break;
			}
			_tmp8_ = string_get (text, i);
			_tmp9_ = g_ascii_isspace (_tmp8_);
			if (_tmp9_) {
				continue;
			}
			break;
		}
	}
	if (!found) {
		document_insert (doc, iter, "}", -1);
	} else {
		gtk_text_iter_forward_chars (iter, ((gint) i) + 1);
	}
	_tmp10_ = document_get_current_indentation (doc, line);
	current_indent = _tmp10_;
	_tmp11_ = gee_abstract_map_get ((GeeAbstractMap*) self->priv->environments, env_name);
	environment = (CompletionProviderCompletionChoice*) _tmp11_;
	_tmp12_ = _g_object_ref0 (DOCUMENT (doc));
	document = _tmp12_;
	_tmp13_ = document_tab_get_view (document->tab);
	_tmp14_ = document_view_get_indentation_style (_tmp13_);
	indent = _tmp14_;
	_tmp15_ = string_to_string (current_indent);
	_tmp16_ = string_to_string (indent);
	_tmp17_ = g_strconcat ("\n", _tmp15_, _tmp16_, NULL);
	_tmp18_ = _tmp17_;
	document_insert (doc, iter, _tmp18_, -1);
	_g_free0 (_tmp18_);
	if (environment != NULL) {
		_tmp19_ = (*environment).insert != NULL;
	} else {
		_tmp19_ = FALSE;
	}
	if (_tmp19_) {
		document_insert (doc, iter, (*environment).insert, -1);
	}
	_tmp20_ = gtk_text_buffer_create_mark ((GtkTextBuffer*) doc, NULL, iter, TRUE);
	_tmp21_ = _g_object_ref0 (_tmp20_);
	cursor_pos = _tmp21_;
	if (environment != NULL) {
		_tmp22_ = (*environment).insert_after != NULL;
	} else {
		_tmp22_ = FALSE;
	}
	if (_tmp22_) {
		document_insert (doc, iter, (*environment).insert_after, -1);
	}
	_tmp23_ = string_to_string (current_indent);
	_tmp24_ = g_strconcat ("\n", _tmp23_, "\\end{", NULL);
	_tmp25_ = _tmp24_;
	_tmp26_ = g_strconcat (_tmp25_, env_name, NULL);
	_tmp27_ = _tmp26_;
	_tmp28_ = g_strconcat (_tmp27_, "}", NULL);
	_tmp29_ = _tmp28_;
	document_insert (doc, iter, _tmp29_, -1);
	_g_free0 (_tmp29_);
	_g_free0 (_tmp27_);
	_g_free0 (_tmp25_);
	gtk_text_buffer_get_iter_at_mark ((GtkTextBuffer*) doc, &_tmp30_, cursor_pos);
	*iter = _tmp30_;
	gtk_text_buffer_place_cursor ((GtkTextBuffer*) doc, iter);
	_g_object_unref0 (cursor_pos);
	_g_free0 (indent);
	_g_object_unref0 (document);
	_completion_provider_completion_choice_free0 (environment);
	_g_free0 (current_indent);
	_g_free0 (text);
	_g_object_unref0 (doc);
}


static void completion_provider_init_calltip_window (CompletionProvider* self) {
	Application* _tmp0_ = NULL;
	Application* app;
	GtkSourceCompletionInfo* _tmp1_ = NULL;
	MainWindow* _tmp2_ = NULL;
	GtkLabel* _tmp3_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = application_get_default ();
	app = _tmp0_;
	_tmp1_ = gtk_source_completion_info_new ();
	_g_object_unref0 (self->priv->calltip_window);
	self->priv->calltip_window = g_object_ref_sink (_tmp1_);
	_tmp2_ = application_get_active_window (app);
	gtk_window_set_transient_for ((GtkWindow*) self->priv->calltip_window, (GtkWindow*) _tmp2_);
	gtk_source_completion_info_set_sizing (self->priv->calltip_window, 800, 200, TRUE, TRUE);
	_tmp3_ = (GtkLabel*) gtk_label_new (NULL);
	_g_object_unref0 (self->priv->calltip_window_label);
	self->priv->calltip_window_label = g_object_ref_sink (_tmp3_);
	gtk_source_completion_info_set_widget (self->priv->calltip_window, (GtkWidget*) self->priv->calltip_window_label);
	_g_object_unref0 (app);
}


static void completion_provider_show_calltip_info (CompletionProvider* self, const gchar* markup) {
	Application* _tmp0_ = NULL;
	Application* _tmp1_;
	MainWindow* _tmp2_ = NULL;
	MainWindow* _tmp3_;
	MainWindow* _tmp4_;
	MainWindow* win;
	GtkTextIter pos = {0};
	DocumentView* _tmp5_ = NULL;
	GtkTextBuffer* _tmp6_ = NULL;
	GtkTextBuffer* _tmp7_;
	GtkTextBuffer* buffer;
	GtkTextMark* _tmp8_ = NULL;
	GtkTextIter _tmp9_ = {0};
	gchar* _tmp10_ = NULL;
	gchar* text;
	DocumentView* _tmp18_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (markup != NULL);
	if (self->priv->calltip_window == NULL) {
		completion_provider_init_calltip_window (self);
	}
	_tmp0_ = application_get_default ();
	_tmp1_ = _tmp0_;
	_tmp2_ = application_get_active_window (_tmp1_);
	_tmp3_ = _g_object_ref0 (_tmp2_);
	_tmp4_ = _tmp3_;
	_g_object_unref0 (_tmp1_);
	win = _tmp4_;
	_tmp5_ = main_window_get_active_view (win);
	_tmp6_ = gtk_text_view_get_buffer ((GtkTextView*) _tmp5_);
	_tmp7_ = _g_object_ref0 (_tmp6_);
	buffer = _tmp7_;
	_tmp8_ = gtk_text_buffer_get_insert (buffer);
	gtk_text_buffer_get_iter_at_mark (buffer, &_tmp9_, _tmp8_);
	pos = _tmp9_;
	_tmp10_ = completion_provider_get_text_line_at_iter (self, &pos);
	text = _tmp10_;
	{
		gint _tmp11_;
		glong i;
		_tmp11_ = strlen (text);
		i = (glong) (_tmp11_ - 1);
		{
			gboolean _tmp12_;
			_tmp12_ = TRUE;
			while (TRUE) {
				gboolean _tmp13_ = FALSE;
				gchar _tmp14_;
				if (!_tmp12_) {
					i--;
				}
				_tmp12_ = FALSE;
				if (!(i >= 0)) {
					break;
				}
				_tmp14_ = string_get (text, i);
				if (_tmp14_ == '[') {
					_tmp13_ = TRUE;
				} else {
					gchar _tmp15_;
					_tmp15_ = string_get (text, i);
					_tmp13_ = _tmp15_ == '{';
				}
				if (_tmp13_) {
					gboolean _tmp16_;
					gint _tmp17_;
					_tmp16_ = utils_char_is_escaped (text, i);
					if (_tmp16_) {
						continue;
					}
					_tmp17_ = strlen (text);
					gtk_text_iter_backward_chars (&pos, (gint) ((_tmp17_ - 1) - i));
					break;
				}
			}
		}
	}
	gtk_label_set_markup (self->priv->calltip_window_label, markup);
	gtk_window_set_transient_for ((GtkWindow*) self->priv->calltip_window, (GtkWindow*) win);
	_tmp18_ = main_window_get_active_view (win);
	gtk_source_completion_info_move_to_iter (self->priv->calltip_window, (GtkTextView*) _tmp18_, &pos);
	gtk_widget_show_all ((GtkWidget*) self->priv->calltip_window);
	_g_free0 (text);
	_g_object_unref0 (buffer);
	_g_object_unref0 (win);
}


void completion_provider_hide_calltip_window (CompletionProvider* self) {
	g_return_if_fail (self != NULL);
	if (self->priv->calltip_window == NULL) {
		return;
	}
	gtk_widget_hide ((GtkWidget*) self->priv->calltip_window);
}


static void completion_provider_parser_start (CompletionProvider* self, GMarkupParseContext* context, const gchar* name, gchar** attr_names, int attr_names_length1, gchar** attr_values, int attr_values_length1, GError** error) {
	const gchar* _tmp0_;
	GQuark _tmp1_;
	static GQuark _tmp1__label0 = 0;
	static GQuark _tmp1__label1 = 0;
	static GQuark _tmp1__label2 = 0;
	static GQuark _tmp1__label3 = 0;
	static GQuark _tmp1__label4 = 0;
	static GQuark _tmp1__label5 = 0;
	static GQuark _tmp1__label6 = 0;
	static GQuark _tmp1__label7 = 0;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (context != NULL);
	g_return_if_fail (name != NULL);
	_tmp0_ = name;
	_tmp1_ = (NULL == _tmp0_) ? 0 : g_quark_from_string (_tmp0_);
	if (_tmp1_ == ((0 != _tmp1__label0) ? _tmp1__label0 : (_tmp1__label0 = g_quark_from_static_string ("commands")))) {
		switch (0) {
			default:
			{
				break;
			}
		}
	} else if (_tmp1_ == ((0 != _tmp1__label1) ? _tmp1__label1 : (_tmp1__label1 = g_quark_from_static_string ("command")))) {
		switch (0) {
			default:
			{
				CompletionProviderCompletionCommand _tmp2_ = {0};
				CompletionProviderCompletionCommand _tmp3_ = {0};
				memset (&_tmp2_, 0, sizeof (CompletionProviderCompletionCommand));
				_tmp3_ = _tmp2_;
				completion_provider_completion_command_destroy (&self->priv->current_command);
				self->priv->current_command = _tmp3_;
				{
					gint i;
					i = 0;
					{
						gboolean _tmp4_;
						_tmp4_ = TRUE;
						while (TRUE) {
							const gchar* _tmp5_;
							GQuark _tmp6_;
							static GQuark _tmp6__label0 = 0;
							static GQuark _tmp6__label1 = 0;
							static GQuark _tmp6__label2 = 0;
							if (!_tmp4_) {
								i++;
							}
							_tmp4_ = FALSE;
							if (!(i < attr_names_length1)) {
								break;
							}
							_tmp5_ = attr_names[i];
							_tmp6_ = (NULL == _tmp5_) ? 0 : g_quark_from_string (_tmp5_);
							if (_tmp6_ == ((0 != _tmp6__label0) ? _tmp6__label0 : (_tmp6__label0 = g_quark_from_static_string ("name")))) {
								switch (0) {
									default:
									{
										gchar* _tmp7_;
										_tmp7_ = g_strconcat ("\\", attr_values[i], NULL);
										_g_free0 (self->priv->current_command.name);
										self->priv->current_command.name = _tmp7_;
										break;
									}
								}
							} else if (_tmp6_ == ((0 != _tmp6__label1) ? _tmp6__label1 : (_tmp6__label1 = g_quark_from_static_string ("package")))) {
								switch (0) {
									default:
									{
										gchar* _tmp8_;
										_tmp8_ = g_strdup (attr_values[i]);
										_g_free0 (self->priv->current_command.package);
										self->priv->current_command.package = _tmp8_;
										break;
									}
								}
							} else if (_tmp6_ == ((0 != _tmp6__label2) ? _tmp6__label2 : (_tmp6__label2 = g_quark_from_static_string ("environment")))) {
								switch (0) {
									default:
									{
										break;
									}
								}
							} else {
								switch (0) {
									default:
									{
										gchar* _tmp9_;
										gchar* _tmp10_;
										gchar* _tmp11_;
										gchar* _tmp12_;
										GError* _tmp13_ = NULL;
										GError* _tmp14_;
										_tmp9_ = g_strconcat ("unknown command attribute \"", attr_names[i], NULL);
										_tmp10_ = _tmp9_;
										_tmp11_ = g_strconcat (_tmp10_, "\"", NULL);
										_tmp12_ = _tmp11_;
										_tmp13_ = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, _tmp12_);
										_tmp14_ = _tmp13_;
										_g_free0 (_tmp12_);
										_g_free0 (_tmp10_);
										_inner_error_ = _tmp14_;
										if (_inner_error_->domain == G_MARKUP_ERROR) {
											g_propagate_error (error, _inner_error_);
											return;
										} else {
											g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
											g_clear_error (&_inner_error_);
											return;
										}
									}
								}
							}
						}
					}
				}
				break;
			}
		}
	} else if (_tmp1_ == ((0 != _tmp1__label2) ? _tmp1__label2 : (_tmp1__label2 = g_quark_from_static_string ("argument")))) {
		switch (0) {
			default:
			{
				CompletionProviderCompletionArgument _tmp15_ = {0};
				CompletionProviderCompletionArgument _tmp16_ = {0};
				memset (&_tmp15_, 0, sizeof (CompletionProviderCompletionArgument));
				_tmp16_ = _tmp15_;
				completion_provider_completion_argument_destroy (&self->priv->current_arg);
				self->priv->current_arg = _tmp16_;
				self->priv->current_arg.optional = FALSE;
				{
					gint i;
					i = 0;
					{
						gboolean _tmp17_;
						_tmp17_ = TRUE;
						while (TRUE) {
							const gchar* _tmp18_;
							GQuark _tmp19_;
							static GQuark _tmp19__label0 = 0;
							static GQuark _tmp19__label1 = 0;
							if (!_tmp17_) {
								i++;
							}
							_tmp17_ = FALSE;
							if (!(i < attr_names_length1)) {
								break;
							}
							_tmp18_ = attr_names[i];
							_tmp19_ = (NULL == _tmp18_) ? 0 : g_quark_from_string (_tmp18_);
							if (_tmp19_ == ((0 != _tmp19__label0) ? _tmp19__label0 : (_tmp19__label0 = g_quark_from_static_string ("label")))) {
								switch (0) {
									default:
									{
										gchar* _tmp20_;
										_tmp20_ = g_strdup (attr_values[i]);
										_g_free0 (self->priv->current_arg.label);
										self->priv->current_arg.label = _tmp20_;
										break;
									}
								}
							} else if (_tmp19_ == ((0 != _tmp19__label1) ? _tmp19__label1 : (_tmp19__label1 = g_quark_from_static_string ("type")))) {
								switch (0) {
									default:
									{
										self->priv->current_arg.optional = g_strcmp0 (attr_values[i], "optional") == 0;
										break;
									}
								}
							} else {
								switch (0) {
									default:
									{
										gchar* _tmp21_;
										gchar* _tmp22_;
										gchar* _tmp23_;
										gchar* _tmp24_;
										GError* _tmp25_ = NULL;
										GError* _tmp26_;
										_tmp21_ = g_strconcat ("unknown argument attribute \"", attr_names[i], NULL);
										_tmp22_ = _tmp21_;
										_tmp23_ = g_strconcat (_tmp22_, "\"", NULL);
										_tmp24_ = _tmp23_;
										_tmp25_ = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, _tmp24_);
										_tmp26_ = _tmp25_;
										_g_free0 (_tmp24_);
										_g_free0 (_tmp22_);
										_inner_error_ = _tmp26_;
										if (_inner_error_->domain == G_MARKUP_ERROR) {
											g_propagate_error (error, _inner_error_);
											return;
										} else {
											g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
											g_clear_error (&_inner_error_);
											return;
										}
									}
								}
							}
						}
					}
				}
				break;
			}
		}
	} else if (_tmp1_ == ((0 != _tmp1__label3) ? _tmp1__label3 : (_tmp1__label3 = g_quark_from_static_string ("choice")))) {
		switch (0) {
			default:
			{
				CompletionProviderCompletionChoice _tmp27_ = {0};
				CompletionProviderCompletionChoice _tmp28_ = {0};
				memset (&_tmp27_, 0, sizeof (CompletionProviderCompletionChoice));
				_tmp28_ = _tmp27_;
				completion_provider_completion_choice_destroy (&self->priv->current_choice);
				self->priv->current_choice = _tmp28_;
				{
					gint i;
					i = 0;
					{
						gboolean _tmp29_;
						_tmp29_ = TRUE;
						while (TRUE) {
							const gchar* _tmp30_;
							GQuark _tmp31_;
							static GQuark _tmp31__label0 = 0;
							static GQuark _tmp31__label1 = 0;
							if (!_tmp29_) {
								i++;
							}
							_tmp29_ = FALSE;
							if (!(i < attr_names_length1)) {
								break;
							}
							_tmp30_ = attr_names[i];
							_tmp31_ = (NULL == _tmp30_) ? 0 : g_quark_from_string (_tmp30_);
							if (_tmp31_ == ((0 != _tmp31__label0) ? _tmp31__label0 : (_tmp31__label0 = g_quark_from_static_string ("name")))) {
								switch (0) {
									default:
									{
										gchar* _tmp32_;
										_tmp32_ = g_strdup (attr_values[i]);
										_g_free0 (self->priv->current_choice.name);
										self->priv->current_choice.name = _tmp32_;
										break;
									}
								}
							} else if (_tmp31_ == ((0 != _tmp31__label1) ? _tmp31__label1 : (_tmp31__label1 = g_quark_from_static_string ("package")))) {
								switch (0) {
									default:
									{
										gchar* _tmp33_;
										_tmp33_ = g_strdup (attr_values[i]);
										_g_free0 (self->priv->current_choice.package);
										self->priv->current_choice.package = _tmp33_;
										break;
									}
								}
							} else {
								switch (0) {
									default:
									{
										gchar* _tmp34_;
										gchar* _tmp35_;
										gchar* _tmp36_;
										gchar* _tmp37_;
										GError* _tmp38_ = NULL;
										GError* _tmp39_;
										_tmp34_ = g_strconcat ("unknown choice attribute \"", attr_names[i], NULL);
										_tmp35_ = _tmp34_;
										_tmp36_ = g_strconcat (_tmp35_, "\"", NULL);
										_tmp37_ = _tmp36_;
										_tmp38_ = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, _tmp37_);
										_tmp39_ = _tmp38_;
										_g_free0 (_tmp37_);
										_g_free0 (_tmp35_);
										_inner_error_ = _tmp39_;
										if (_inner_error_->domain == G_MARKUP_ERROR) {
											g_propagate_error (error, _inner_error_);
											return;
										} else {
											g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
											g_clear_error (&_inner_error_);
											return;
										}
									}
								}
							}
						}
					}
				}
				break;
			}
		}
	} else if ((_tmp1_ == ((0 != _tmp1__label4) ? _tmp1__label4 : (_tmp1__label4 = g_quark_from_static_string ("insert")))) || (_tmp1_ == ((0 != _tmp1__label5) ? _tmp1__label5 : (_tmp1__label5 = g_quark_from_static_string ("insert_after"))))) {
		switch (0) {
			default:
			{
				break;
			}
		}
	} else if ((_tmp1_ == ((0 != _tmp1__label6) ? _tmp1__label6 : (_tmp1__label6 = g_quark_from_static_string ("placeholder")))) || (_tmp1_ == ((0 != _tmp1__label7) ? _tmp1__label7 : (_tmp1__label7 = g_quark_from_static_string ("component"))))) {
		switch (0) {
			default:
			{
				break;
			}
		}
	} else {
		switch (0) {
			default:
			{
				gchar* _tmp40_;
				gchar* _tmp41_;
				gchar* _tmp42_;
				gchar* _tmp43_;
				GError* _tmp44_ = NULL;
				GError* _tmp45_;
				_tmp40_ = g_strconcat ("unknown element \"", name, NULL);
				_tmp41_ = _tmp40_;
				_tmp42_ = g_strconcat (_tmp41_, "\"", NULL);
				_tmp43_ = _tmp42_;
				_tmp44_ = g_error_new_literal (G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, _tmp43_);
				_tmp45_ = _tmp44_;
				_g_free0 (_tmp43_);
				_g_free0 (_tmp41_);
				_inner_error_ = _tmp45_;
				if (_inner_error_->domain == G_MARKUP_ERROR) {
					g_propagate_error (error, _inner_error_);
					return;
				} else {
					g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code);
					g_clear_error (&_inner_error_);
					return;
				}
			}
		}
	}
}


static void _vala_array_add10 (CompletionProviderCompletionArgument** array, int* length, int* size, const CompletionProviderCompletionArgument* value) {
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (CompletionProviderCompletionArgument, *array, *size);
	}
	(*array)[(*length)++] = *value;
}


static void _vala_array_add11 (CompletionProviderCompletionChoice** array, int* length, int* size, const CompletionProviderCompletionChoice* value) {
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (CompletionProviderCompletionChoice, *array, *size);
	}
	(*array)[(*length)++] = *value;
}


static void completion_provider_parser_end (CompletionProvider* self, GMarkupParseContext* context, const gchar* name, GError** error) {
	const gchar* _tmp0_;
	GQuark _tmp1_;
	static GQuark _tmp1__label0 = 0;
	static GQuark _tmp1__label1 = 0;
	static GQuark _tmp1__label2 = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (context != NULL);
	g_return_if_fail (name != NULL);
	_tmp0_ = name;
	_tmp1_ = (NULL == _tmp0_) ? 0 : g_quark_from_string (_tmp0_);
	if (_tmp1_ == ((0 != _tmp1__label0) ? _tmp1__label0 : (_tmp1__label0 = g_quark_from_static_string ("command")))) {
		switch (0) {
			default:
			{
				GdkPixbuf* _tmp2_ = NULL;
				GdkPixbuf* _tmp3_;
				GdkPixbuf* pixbuf;
				gchar* _tmp4_ = NULL;
				gchar* _tmp5_;
				gchar* _tmp6_ = NULL;
				gchar* _tmp7_;
				GtkSourceCompletionItem* _tmp8_ = NULL;
				GtkSourceCompletionItem* _tmp9_;
				GtkSourceCompletionItem* item;
				GtkSourceCompletionItem* _tmp10_;
				if (self->priv->current_command.package != NULL) {
					_tmp2_ = self->priv->icon_package_required;
				} else {
					_tmp2_ = self->priv->icon_normal_cmd;
				}
				_tmp3_ = _g_object_ref0 (_tmp2_);
				pixbuf = _tmp3_;
				_tmp4_ = completion_provider_get_command_text (self, &self->priv->current_command);
				_tmp5_ = _tmp4_;
				_tmp6_ = completion_provider_get_command_info (self, &self->priv->current_command, -1);
				_tmp7_ = _tmp6_;
				_tmp8_ = gtk_source_completion_item_new (self->priv->current_command.name, _tmp5_, pixbuf, _tmp7_);
				_tmp9_ = _tmp8_;
				_g_free0 (_tmp7_);
				_g_free0 (_tmp5_);
				item = _tmp9_;
				_tmp10_ = _g_object_ref0 (item);
				self->priv->proposals = g_list_append (self->priv->proposals, _tmp10_);
				if (self->priv->current_command.args_length1 > 0) {
					gee_abstract_map_set ((GeeAbstractMap*) self->priv->commands, self->priv->current_command.name, &self->priv->current_command);
				}
				_g_object_unref0 (item);
				_g_object_unref0 (pixbuf);
				break;
			}
		}
	} else if (_tmp1_ == ((0 != _tmp1__label1) ? _tmp1__label1 : (_tmp1__label1 = g_quark_from_static_string ("argument")))) {
		switch (0) {
			default:
			{
				CompletionProviderCompletionArgument _tmp11_;
				CompletionProviderCompletionArgument _tmp12_ = {0};
				completion_provider_completion_argument_copy (&self->priv->current_arg, &_tmp12_);
				_tmp11_ = _tmp12_;
				_vala_array_add10 (&self->priv->current_command.args, &self->priv->current_command.args_length1, &self->priv->current_command._args_size_, &_tmp11_);
				break;
			}
		}
	} else if (_tmp1_ == ((0 != _tmp1__label2) ? _tmp1__label2 : (_tmp1__label2 = g_quark_from_static_string ("choice")))) {
		switch (0) {
			default:
			{
				CompletionProviderCompletionChoice _tmp13_;
				CompletionProviderCompletionChoice _tmp14_ = {0};
				gboolean _tmp15_ = FALSE;
				completion_provider_completion_choice_copy (&self->priv->current_choice, &_tmp14_);
				_tmp13_ = _tmp14_;
				_vala_array_add11 (&self->priv->current_arg.choices, &self->priv->current_arg.choices_length1, &self->priv->current_arg._choices_size_, &_tmp13_);
				if (self->priv->current_choice.insert != NULL) {
					_tmp15_ = TRUE;
				} else {
					_tmp15_ = self->priv->current_choice.insert_after != NULL;
				}
				if (_tmp15_) {
					gee_abstract_map_set ((GeeAbstractMap*) self->priv->environments, self->priv->current_choice.name, &self->priv->current_choice);
				}
				break;
			}
		}
	}
}


static void completion_provider_parser_text (CompletionProvider* self, GMarkupParseContext* context, const gchar* text, gsize text_len, GError** error) {
	const gchar* _tmp0_ = NULL;
	const gchar* _tmp1_;
	GQuark _tmp2_;
	static GQuark _tmp2__label0 = 0;
	static GQuark _tmp2__label1 = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (context != NULL);
	g_return_if_fail (text != NULL);
	_tmp0_ = g_markup_parse_context_get_element (context);
	_tmp1_ = _tmp0_;
	_tmp2_ = (NULL == _tmp1_) ? 0 : g_quark_from_string (_tmp1_);
	if (_tmp2_ == ((0 != _tmp2__label0) ? _tmp2__label0 : (_tmp2__label0 = g_quark_from_static_string ("insert")))) {
		switch (0) {
			default:
			{
				gchar* _tmp3_;
				_tmp3_ = g_strdup (text);
				_g_free0 (self->priv->current_choice.insert);
				self->priv->current_choice.insert = _tmp3_;
				break;
			}
		}
	} else if (_tmp2_ == ((0 != _tmp2__label1) ? _tmp2__label1 : (_tmp2__label1 = g_quark_from_static_string ("insert_after")))) {
		switch (0) {
			default:
			{
				gchar* _tmp4_;
				_tmp4_ = g_strdup (text);
				_g_free0 (self->priv->current_choice.insert_after);
				self->priv->current_choice.insert_after = _tmp4_;
				break;
			}
		}
	}
}


static GList* completion_provider_get_argument_proposals (CompletionProvider* self, CompletionProviderCompletionCommand* cmd, GeeArrayList* arguments) {
	GList* result = NULL;
	gchar* _tmp0_ = NULL;
	gchar* info;
	gint _tmp1_;
	gint num;
	CompletionProviderCompletionArgument _tmp2_;
	CompletionProviderCompletionArgument _tmp3_ = {0};
	CompletionProviderCompletionArgument arg;
	GList* items;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (arguments != NULL, NULL);
	if ((*cmd).args_length1 == 0) {
		result = NULL;
		return result;
	}
	_tmp0_ = completion_provider_get_command_info (self, cmd, -1);
	info = _tmp0_;
	_tmp1_ = completion_provider_get_argument_num (self, (*cmd).args, (*cmd).args_length1, arguments);
	num = _tmp1_;
	if (num == (-1)) {
		result = NULL;
		_g_free0 (info);
		return result;
	}
	completion_provider_completion_argument_copy (&(*cmd).args[num - 1], &_tmp3_);
	_tmp2_ = _tmp3_;
	arg = _tmp2_;
	items = NULL;
	{
		CompletionProviderCompletionChoice* choice_collection;
		int choice_collection_length1;
		int choice_it;
		choice_collection = arg.choices;
		choice_collection_length1 = arg.choices_length1;
		for (choice_it = 0; choice_it < arg.choices_length1; choice_it = choice_it + 1) {
			CompletionProviderCompletionChoice _tmp4_;
			CompletionProviderCompletionChoice _tmp5_ = {0};
			CompletionProviderCompletionChoice choice;
			completion_provider_completion_choice_copy (&choice_collection[choice_it], &_tmp5_);
			_tmp4_ = _tmp5_;
			choice = _tmp4_;
			{
				gchar* info2;
				GdkPixbuf* pixbuf = NULL;
				gchar* _tmp11_;
				gchar* _tmp12_;
				GtkSourceCompletionItem* _tmp14_ = NULL;
				GtkSourceCompletionItem* item;
				GtkSourceCompletionItem* _tmp15_;
				info2 = NULL;
				if (choice.package != NULL) {
					gchar* _tmp6_;
					gchar* _tmp7_;
					gchar* _tmp8_;
					GdkPixbuf* _tmp9_;
					_tmp6_ = g_strconcat (info, "\nPackage: ", NULL);
					_tmp7_ = _tmp6_;
					_tmp8_ = g_strconcat (_tmp7_, choice.package, NULL);
					_g_free0 (info2);
					info2 = _tmp8_;
					_g_free0 (_tmp7_);
					_tmp9_ = _g_object_ref0 (self->priv->icon_package_required);
					_g_object_unref0 (pixbuf);
					pixbuf = _tmp9_;
				} else {
					GdkPixbuf* _tmp10_;
					_tmp10_ = _g_object_ref0 (self->priv->icon_normal_choice);
					_g_object_unref0 (pixbuf);
					pixbuf = _tmp10_;
				}
				_tmp11_ = g_strdup (info2);
				_tmp12_ = _tmp11_;
				if (_tmp12_ == NULL) {
					gchar* _tmp13_;
					_tmp13_ = g_strdup (info);
					_g_free0 (_tmp12_);
					_tmp12_ = _tmp13_;
				}
				_tmp14_ = gtk_source_completion_item_new (choice.name, choice.name, pixbuf, _tmp12_);
				item = _tmp14_;
				_tmp15_ = _g_object_ref0 (item);
				items = g_list_prepend (items, _tmp15_);
				_g_object_unref0 (item);
				_g_free0 (_tmp12_);
				_g_object_unref0 (pixbuf);
				_g_free0 (info2);
				completion_provider_completion_choice_destroy (&choice);
			}
		}
	}
	if (items == NULL) {
		result = NULL;
		completion_provider_completion_argument_destroy (&arg);
		_g_free0 (info);
		return result;
	}
	items = g_list_sort (items, (GCompareFunc) completion_provider_compare_proposals);
	result = items;
	completion_provider_completion_argument_destroy (&arg);
	_g_free0 (info);
	return result;
}


static gint completion_provider_get_argument_num (CompletionProvider* self, CompletionProviderCompletionArgument* all_args, int all_args_length1, GeeArrayList* args) {
	gint result = 0;
	gint _tmp0_;
	gint num;
	g_return_val_if_fail (self != NULL, 0);
	g_return_val_if_fail (args != NULL, 0);
	_tmp0_ = gee_collection_get_size ((GeeCollection*) args);
	g_return_val_if_fail (_tmp0_ <= all_args_length1, -1);
	num = 0;
	{
		GeeArrayList* _tmp1_;
		GeeArrayList* _arg_list;
		gint _tmp2_;
		gint _arg_size;
		gint _arg_index;
		_tmp1_ = _g_object_ref0 (args);
		_arg_list = _tmp1_;
		_tmp2_ = gee_collection_get_size ((GeeCollection*) _arg_list);
		_arg_size = _tmp2_;
		_arg_index = -1;
		while (TRUE) {
			gpointer _tmp3_ = NULL;
			gboolean arg;
			_arg_index = _arg_index + 1;
			if (!(_arg_index < _arg_size)) {
				break;
			}
			_tmp3_ = gee_abstract_list_get ((GeeAbstractList*) _arg_list, _arg_index);
			arg = GPOINTER_TO_INT (_tmp3_);
			while (TRUE) {
				if (num >= all_args_length1) {
					result = -1;
					_g_object_unref0 (_arg_list);
					return result;
				}
				if (all_args[num].optional == arg) {
					break;
				} else {
					if (!all_args[num].optional) {
						result = -1;
						_g_object_unref0 (_arg_list);
						return result;
					}
				}
				num++;
			}
			num++;
		}
		_g_object_unref0 (_arg_list);
	}
	result = num;
	return result;
}


static gchar* completion_provider_get_command_text (CompletionProvider* self, CompletionProviderCompletionCommand* cmd) {
	gchar* result = NULL;
	gchar* _tmp0_;
	gchar* text_to_insert;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup ((*cmd).name);
	text_to_insert = _tmp0_;
	{
		CompletionProviderCompletionArgument* arg_collection;
		int arg_collection_length1;
		int arg_it;
		arg_collection = (*cmd).args;
		arg_collection_length1 = (*cmd).args_length1;
		for (arg_it = 0; arg_it < (*cmd).args_length1; arg_it = arg_it + 1) {
			CompletionProviderCompletionArgument _tmp1_;
			CompletionProviderCompletionArgument _tmp2_ = {0};
			CompletionProviderCompletionArgument arg;
			completion_provider_completion_argument_copy (&arg_collection[arg_it], &_tmp2_);
			_tmp1_ = _tmp2_;
			arg = _tmp1_;
			{
				if (!arg.optional) {
					gchar* _tmp3_;
					_tmp3_ = g_strconcat (text_to_insert, "{}", NULL);
					_g_free0 (text_to_insert);
					text_to_insert = _tmp3_;
				}
				completion_provider_completion_argument_destroy (&arg);
			}
		}
	}
	result = text_to_insert;
	return result;
}


static gchar* completion_provider_get_command_info (CompletionProvider* self, CompletionProviderCompletionCommand* cmd, gint num) {
	gchar* result = NULL;
	gchar* _tmp0_;
	gchar* info;
	gint i;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = g_strdup ((*cmd).name);
	info = _tmp0_;
	i = 1;
	{
		CompletionProviderCompletionArgument* arg_collection;
		int arg_collection_length1;
		int arg_it;
		arg_collection = (*cmd).args;
		arg_collection_length1 = (*cmd).args_length1;
		for (arg_it = 0; arg_it < (*cmd).args_length1; arg_it = arg_it + 1) {
			CompletionProviderCompletionArgument _tmp1_;
			CompletionProviderCompletionArgument _tmp2_ = {0};
			CompletionProviderCompletionArgument arg;
			completion_provider_completion_argument_copy (&arg_collection[arg_it], &_tmp2_);
			_tmp1_ = _tmp2_;
			arg = _tmp1_;
			{
				if (num == i) {
					gchar* _tmp3_;
					_tmp3_ = g_strconcat (info, "<b>", NULL);
					_g_free0 (info);
					info = _tmp3_;
				}
				if (arg.optional) {
					gchar* _tmp4_;
					gchar* _tmp5_;
					gchar* _tmp6_;
					gchar* _tmp7_;
					gchar* _tmp8_;
					_tmp4_ = g_strconcat ("[", arg.label, NULL);
					_tmp5_ = _tmp4_;
					_tmp6_ = g_strconcat (_tmp5_, "]", NULL);
					_tmp7_ = _tmp6_;
					_tmp8_ = g_strconcat (info, _tmp7_, NULL);
					_g_free0 (info);
					info = _tmp8_;
					_g_free0 (_tmp7_);
					_g_free0 (_tmp5_);
				} else {
					gchar* _tmp9_;
					gchar* _tmp10_;
					gchar* _tmp11_;
					gchar* _tmp12_;
					gchar* _tmp13_;
					_tmp9_ = g_strconcat ("{", arg.label, NULL);
					_tmp10_ = _tmp9_;
					_tmp11_ = g_strconcat (_tmp10_, "}", NULL);
					_tmp12_ = _tmp11_;
					_tmp13_ = g_strconcat (info, _tmp12_, NULL);
					_g_free0 (info);
					info = _tmp13_;
					_g_free0 (_tmp12_);
					_g_free0 (_tmp10_);
				}
				if (num == i) {
					gchar* _tmp14_;
					_tmp14_ = g_strconcat (info, "</b>", NULL);
					_g_free0 (info);
					info = _tmp14_;
				}
				i++;
				completion_provider_completion_argument_destroy (&arg);
			}
		}
	}
	if ((*cmd).package != NULL) {
		gchar* _tmp15_;
		gchar* _tmp16_;
		gchar* _tmp17_;
		_tmp15_ = g_strconcat ("\nPackage: ", (*cmd).package, NULL);
		_tmp16_ = _tmp15_;
		_tmp17_ = g_strconcat (info, _tmp16_, NULL);
		_g_free0 (info);
		info = _tmp17_;
		_g_free0 (_tmp16_);
	}
	result = info;
	return result;
}


static gchar* completion_provider_get_latex_command_at_iter (CompletionProvider* self, GtkTextIter* iter) {
	gchar* result = NULL;
	gchar* _tmp0_ = NULL;
	gchar* text;
	gint _tmp1_;
	gchar* _tmp2_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = completion_provider_get_text_line_at_iter (self, iter);
	text = _tmp0_;
	_tmp1_ = strlen (text);
	_tmp2_ = completion_provider_get_latex_command_at_index (self, text, (glong) (_tmp1_ - 1));
	result = _tmp2_;
	_g_free0 (text);
	return result;
}


static gchar* completion_provider_get_text_line_at_iter (CompletionProvider* self, GtkTextIter* iter) {
	gchar* result = NULL;
	gint _tmp0_;
	gint line;
	GtkTextBuffer* _tmp1_ = NULL;
	GtkTextBuffer* _tmp2_;
	GtkTextBuffer* doc;
	GtkTextIter iter_start = {0};
	GtkTextIter _tmp3_ = {0};
	gchar* _tmp4_ = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = gtk_text_iter_get_line (iter);
	line = _tmp0_;
	_tmp1_ = gtk_text_iter_get_buffer (iter);
	_tmp2_ = _g_object_ref0 (_tmp1_);
	doc = _tmp2_;
	gtk_text_buffer_get_iter_at_line (doc, &_tmp3_, line);
	iter_start = _tmp3_;
	_tmp4_ = gtk_text_buffer_get_text (doc, &iter_start, iter, FALSE);
	result = _tmp4_;
	_g_object_unref0 (doc);
	return result;
}


static gchar* completion_provider_get_latex_command_at_index (CompletionProvider* self, const gchar* text, glong index) {
	gchar* result = NULL;
	gint _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (text != NULL, NULL);
	_tmp0_ = strlen (text);
	g_return_val_if_fail (_tmp0_ > index, NULL);
	{
		glong i;
		i = index;
		{
			gboolean _tmp1_;
			_tmp1_ = TRUE;
			while (TRUE) {
				gchar _tmp2_;
				gboolean _tmp5_ = FALSE;
				gchar _tmp6_;
				gboolean _tmp7_;
				if (!_tmp1_) {
					i--;
				}
				_tmp1_ = FALSE;
				if (!(i >= 0)) {
					break;
				}
				_tmp2_ = string_get (text, i);
				if (_tmp2_ == '\\') {
					gboolean _tmp3_;
					gchar* _tmp4_ = NULL;
					_tmp3_ = utils_char_is_escaped (text, i);
					if (_tmp3_) {
						break;
					}
					_tmp4_ = string_slice (text, i, index + 1);
					result = _tmp4_;
					return result;
				}
				_tmp6_ = string_get (text, i);
				_tmp7_ = g_ascii_isalpha (_tmp6_);
				if (!_tmp7_) {
					gchar _tmp8_;
					_tmp8_ = string_get (text, i);
					_tmp5_ = _tmp8_ != '*';
				} else {
					_tmp5_ = FALSE;
				}
				if (_tmp5_) {
					break;
				}
			}
		}
	}
	result = NULL;
	return result;
}


static gboolean completion_provider_in_latex_command_argument (CompletionProvider* self, GtkTextIter* iter, gchar** cmd_name, GeeArrayList** arguments, gchar** argument_contents, gboolean* valid_arg_contents) {
	gchar* _cmd_name = NULL;
	GeeArrayList* _arguments = NULL;
	gchar* _argument_contents = NULL;
	gboolean _valid_arg_contents = FALSE;
	gboolean result = FALSE;
	gchar* _tmp0_ = NULL;
	gchar* text;
	gboolean fetch_argument_contents;
	glong index_start_argument_contents;
	gboolean in_other_argument;
	gchar other_argument_opening_bracket;
	GeeArrayList* _tmp1_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = completion_provider_get_text_line_at_iter (self, iter);
	text = _tmp0_;
	fetch_argument_contents = TRUE;
	index_start_argument_contents = (glong) (-1);
	in_other_argument = FALSE;
	other_argument_opening_bracket = '{';
	_tmp1_ = gee_array_list_new (G_TYPE_BOOLEAN, NULL, NULL, NULL);
	_g_object_unref0 (_arguments);
	_arguments = _tmp1_;
	_valid_arg_contents = TRUE;
	{
		gint _tmp2_;
		glong i;
		_tmp2_ = strlen (text);
		i = (glong) (_tmp2_ - 1);
		{
			gboolean _tmp3_;
			_tmp3_ = TRUE;
			while (TRUE) {
				if (!_tmp3_) {
					i--;
				}
				_tmp3_ = FALSE;
				if (!(i >= 0)) {
					break;
				}
				if (fetch_argument_contents) {
					gboolean _tmp4_ = FALSE;
					gboolean _tmp5_ = FALSE;
					gchar _tmp6_;
					gboolean _tmp12_ = FALSE;
					gchar _tmp13_;
					gboolean _tmp14_;
					_tmp6_ = string_get (text, i);
					if (_tmp6_ == '{') {
						_tmp5_ = TRUE;
					} else {
						gchar _tmp7_;
						_tmp7_ = string_get (text, i);
						_tmp5_ = _tmp7_ == '[';
					}
					if (_tmp5_) {
						gboolean _tmp8_;
						_tmp8_ = utils_char_is_escaped (text, i);
						_tmp4_ = !_tmp8_;
					} else {
						_tmp4_ = FALSE;
					}
					if (_tmp4_) {
						gchar _tmp9_;
						_tmp9_ = string_get (text, i);
						gee_abstract_list_insert ((GeeAbstractList*) _arguments, 0, GINT_TO_POINTER (_tmp9_ == '['));
						if (index_start_argument_contents != (-1)) {
							gint _tmp10_;
							gchar* _tmp11_ = NULL;
							_tmp10_ = strlen (text);
							_tmp11_ = string_slice (text, index_start_argument_contents, (glong) _tmp10_);
							_g_free0 (_argument_contents);
							_argument_contents = _tmp11_;
						}
						fetch_argument_contents = FALSE;
						continue;
					}
					_tmp13_ = string_get (text, i);
					_tmp14_ = g_ascii_isalpha (_tmp13_);
					if (!_tmp14_) {
						gchar _tmp15_;
						_tmp15_ = string_get (text, i);
						_tmp12_ = _tmp15_ != '*';
					} else {
						_tmp12_ = FALSE;
					}
					if (_tmp12_) {
						_valid_arg_contents = FALSE;
					}
					index_start_argument_contents = i;
				} else {
					if (in_other_argument) {
						gchar _tmp16_;
						_tmp16_ = string_get (text, i);
						if (_tmp16_ == other_argument_opening_bracket) {
							gboolean _tmp17_;
							_tmp17_ = utils_char_is_escaped (text, i);
							in_other_argument = _tmp17_;
						}
						continue;
					} else {
						gchar _tmp18_;
						gboolean _tmp19_;
						gboolean _tmp20_ = FALSE;
						gchar _tmp21_;
						gboolean _tmp22_;
						gboolean _tmp25_ = FALSE;
						gchar _tmp26_;
						_tmp18_ = string_get (text, i);
						_tmp19_ = g_ascii_isspace (_tmp18_);
						if (_tmp19_) {
							continue;
						}
						_tmp21_ = string_get (text, i);
						_tmp22_ = g_ascii_isalpha (_tmp21_);
						if (_tmp22_) {
							_tmp20_ = TRUE;
						} else {
							gchar _tmp23_;
							_tmp23_ = string_get (text, i);
							_tmp20_ = _tmp23_ == '*';
						}
						if (_tmp20_) {
							gchar* _tmp24_ = NULL;
							_tmp24_ = completion_provider_get_latex_command_at_index (self, text, i);
							_g_free0 (_cmd_name);
							_cmd_name = _tmp24_;
							result = _cmd_name != NULL;
							_g_free0 (text);
							if (cmd_name) {
								*cmd_name = _cmd_name;
							} else {
								_g_free0 (_cmd_name);
							}
							if (arguments) {
								*arguments = _arguments;
							} else {
								_g_object_unref0 (_arguments);
							}
							if (argument_contents) {
								*argument_contents = _argument_contents;
							} else {
								_g_free0 (_argument_contents);
							}
							if (valid_arg_contents) {
								*valid_arg_contents = _valid_arg_contents;
							}
							return result;
						}
						_tmp26_ = string_get (text, i);
						if (_tmp26_ == '}') {
							_tmp25_ = TRUE;
						} else {
							gchar _tmp27_;
							_tmp27_ = string_get (text, i);
							_tmp25_ = _tmp27_ == ']';
						}
						if (_tmp25_) {
							gboolean _tmp28_;
							gchar _tmp29_ = '\0';
							gchar _tmp30_;
							gchar _tmp31_;
							_tmp28_ = utils_char_is_escaped (text, i);
							if (_tmp28_) {
								result = FALSE;
								_g_free0 (text);
								if (cmd_name) {
									*cmd_name = _cmd_name;
								} else {
									_g_free0 (_cmd_name);
								}
								if (arguments) {
									*arguments = _arguments;
								} else {
									_g_object_unref0 (_arguments);
								}
								if (argument_contents) {
									*argument_contents = _argument_contents;
								} else {
									_g_free0 (_argument_contents);
								}
								if (valid_arg_contents) {
									*valid_arg_contents = _valid_arg_contents;
								}
								return result;
							}
							in_other_argument = TRUE;
							_tmp30_ = string_get (text, i);
							if (_tmp30_ == '}') {
								_tmp29_ = '{';
							} else {
								_tmp29_ = '[';
							}
							other_argument_opening_bracket = _tmp29_;
							_tmp31_ = string_get (text, i);
							gee_abstract_list_insert ((GeeAbstractList*) _arguments, 0, GINT_TO_POINTER (_tmp31_ == ']'));
							continue;
						}
						result = FALSE;
						_g_free0 (text);
						if (cmd_name) {
							*cmd_name = _cmd_name;
						} else {
							_g_free0 (_cmd_name);
						}
						if (arguments) {
							*arguments = _arguments;
						} else {
							_g_object_unref0 (_arguments);
						}
						if (argument_contents) {
							*argument_contents = _argument_contents;
						} else {
							_g_free0 (_argument_contents);
						}
						if (valid_arg_contents) {
							*valid_arg_contents = _valid_arg_contents;
						}
						return result;
					}
				}
			}
		}
	}
	result = FALSE;
	_g_free0 (text);
	if (cmd_name) {
		*cmd_name = _cmd_name;
	} else {
		_g_free0 (_cmd_name);
	}
	if (arguments) {
		*arguments = _arguments;
	} else {
		_g_object_unref0 (_arguments);
	}
	if (argument_contents) {
		*argument_contents = _argument_contents;
	} else {
		_g_free0 (_argument_contents);
	}
	if (valid_arg_contents) {
		*valid_arg_contents = _valid_arg_contents;
	}
	return result;
}


static gint completion_provider_compare_proposals (GtkSourceCompletionItem* a, GtkSourceCompletionItem* b) {
	gint result = 0;
	gchar* _tmp0_ = NULL;
	gchar* _tmp1_;
	gchar* _tmp2_ = NULL;
	gchar* _tmp3_;
	gint _tmp4_;
	gint _tmp5_;
	g_return_val_if_fail (a != NULL, 0);
	g_return_val_if_fail (b != NULL, 0);
	g_object_get (a, "text", &_tmp0_, NULL);
	_tmp1_ = _tmp0_;
	g_object_get (b, "text", &_tmp2_, NULL);
	_tmp3_ = _tmp2_;
	_tmp4_ = g_utf8_collate (_tmp1_, _tmp3_);
	_tmp5_ = _tmp4_;
	_g_free0 (_tmp3_);
	_g_free0 (_tmp1_);
	result = _tmp5_;
	return result;
}


static void completion_provider_clear_context (CompletionProvider* self, GtkSourceCompletionContext* context) {
	GList* empty_proposals;
	g_return_if_fail (self != NULL);
	g_return_if_fail (context != NULL);
	empty_proposals = NULL;
	gtk_source_completion_context_add_proposals (context, GTK_SOURCE_COMPLETION_PROVIDER (self), empty_proposals, TRUE);
	__g_list_free__g_object_unref0_0 (empty_proposals);
}


static void _vala_CompletionProviderCompletionArgument_array_free (CompletionProviderCompletionArgument* array, gint array_length) {
	if (array != NULL) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			completion_provider_completion_argument_destroy (&array[i]);
		}
	}
	g_free (array);
}


static CompletionProviderCompletionArgument* _vala_array_dup1 (CompletionProviderCompletionArgument* self, int length) {
	CompletionProviderCompletionArgument* result;
	int i;
	result = g_new0 (CompletionProviderCompletionArgument, length);
	for (i = 0; i < length; i++) {
		CompletionProviderCompletionArgument _tmp0_ = {0};
		completion_provider_completion_argument_copy (&self[i], &_tmp0_);
		result[i] = _tmp0_;
	}
	return result;
}


static void completion_provider_completion_command_copy (const CompletionProviderCompletionCommand* self, CompletionProviderCompletionCommand* dest) {
	CompletionProviderCompletionArgument* _tmp0_;
	dest->name = g_strdup (self->name);
	dest->package = g_strdup (self->package);
	dest->args = (_tmp0_ = self->args, (_tmp0_ == NULL) ? ((gpointer) _tmp0_) : _vala_array_dup1 (_tmp0_, (*self).args_length1));
	dest->args_length1 = self->args_length1;
}


static void completion_provider_completion_command_destroy (CompletionProviderCompletionCommand* self) {
	_g_free0 ((*self).name);
	_g_free0 ((*self).package);
	(*self).args = (_vala_CompletionProviderCompletionArgument_array_free ((*self).args, (*self).args_length1), NULL);
}


static CompletionProviderCompletionCommand* completion_provider_completion_command_dup (const CompletionProviderCompletionCommand* self) {
	CompletionProviderCompletionCommand* dup;
	dup = g_new0 (CompletionProviderCompletionCommand, 1);
	completion_provider_completion_command_copy (self, dup);
	return dup;
}


static void completion_provider_completion_command_free (CompletionProviderCompletionCommand* self) {
	completion_provider_completion_command_destroy (self);
	g_free (self);
}


static GType completion_provider_completion_command_get_type (void) {
	static volatile gsize completion_provider_completion_command_type_id__volatile = 0;
	if (g_once_init_enter (&completion_provider_completion_command_type_id__volatile)) {
		GType completion_provider_completion_command_type_id;
		completion_provider_completion_command_type_id = g_boxed_type_register_static ("CompletionProviderCompletionCommand", (GBoxedCopyFunc) completion_provider_completion_command_dup, (GBoxedFreeFunc) completion_provider_completion_command_free);
		g_once_init_leave (&completion_provider_completion_command_type_id__volatile, completion_provider_completion_command_type_id);
	}
	return completion_provider_completion_command_type_id__volatile;
}


static void _vala_CompletionProviderCompletionChoice_array_free (CompletionProviderCompletionChoice* array, gint array_length) {
	if (array != NULL) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			completion_provider_completion_choice_destroy (&array[i]);
		}
	}
	g_free (array);
}


static CompletionProviderCompletionChoice* _vala_array_dup2 (CompletionProviderCompletionChoice* self, int length) {
	CompletionProviderCompletionChoice* result;
	int i;
	result = g_new0 (CompletionProviderCompletionChoice, length);
	for (i = 0; i < length; i++) {
		CompletionProviderCompletionChoice _tmp0_ = {0};
		completion_provider_completion_choice_copy (&self[i], &_tmp0_);
		result[i] = _tmp0_;
	}
	return result;
}


static void completion_provider_completion_argument_copy (const CompletionProviderCompletionArgument* self, CompletionProviderCompletionArgument* dest) {
	CompletionProviderCompletionChoice* _tmp0_;
	dest->label = g_strdup (self->label);
	dest->optional = self->optional;
	dest->choices = (_tmp0_ = self->choices, (_tmp0_ == NULL) ? ((gpointer) _tmp0_) : _vala_array_dup2 (_tmp0_, (*self).choices_length1));
	dest->choices_length1 = self->choices_length1;
}


static void completion_provider_completion_argument_destroy (CompletionProviderCompletionArgument* self) {
	_g_free0 ((*self).label);
	(*self).choices = (_vala_CompletionProviderCompletionChoice_array_free ((*self).choices, (*self).choices_length1), NULL);
}


static CompletionProviderCompletionArgument* completion_provider_completion_argument_dup (const CompletionProviderCompletionArgument* self) {
	CompletionProviderCompletionArgument* dup;
	dup = g_new0 (CompletionProviderCompletionArgument, 1);
	completion_provider_completion_argument_copy (self, dup);
	return dup;
}


static void completion_provider_completion_argument_free (CompletionProviderCompletionArgument* self) {
	completion_provider_completion_argument_destroy (self);
	g_free (self);
}


static GType completion_provider_completion_argument_get_type (void) {
	static volatile gsize completion_provider_completion_argument_type_id__volatile = 0;
	if (g_once_init_enter (&completion_provider_completion_argument_type_id__volatile)) {
		GType completion_provider_completion_argument_type_id;
		completion_provider_completion_argument_type_id = g_boxed_type_register_static ("CompletionProviderCompletionArgument", (GBoxedCopyFunc) completion_provider_completion_argument_dup, (GBoxedFreeFunc) completion_provider_completion_argument_free);
		g_once_init_leave (&completion_provider_completion_argument_type_id__volatile, completion_provider_completion_argument_type_id);
	}
	return completion_provider_completion_argument_type_id__volatile;
}


static void completion_provider_completion_choice_copy (const CompletionProviderCompletionChoice* self, CompletionProviderCompletionChoice* dest) {
	dest->name = g_strdup (self->name);
	dest->package = g_strdup (self->package);
	dest->insert = g_strdup (self->insert);
	dest->insert_after = g_strdup (self->insert_after);
}


static void completion_provider_completion_choice_destroy (CompletionProviderCompletionChoice* self) {
	_g_free0 ((*self).name);
	_g_free0 ((*self).package);
	_g_free0 ((*self).insert);
	_g_free0 ((*self).insert_after);
}


static CompletionProviderCompletionChoice* completion_provider_completion_choice_dup (const CompletionProviderCompletionChoice* self) {
	CompletionProviderCompletionChoice* dup;
	dup = g_new0 (CompletionProviderCompletionChoice, 1);
	completion_provider_completion_choice_copy (self, dup);
	return dup;
}


static void completion_provider_completion_choice_free (CompletionProviderCompletionChoice* self) {
	completion_provider_completion_choice_destroy (self);
	g_free (self);
}


static GType completion_provider_completion_choice_get_type (void) {
	static volatile gsize completion_provider_completion_choice_type_id__volatile = 0;
	if (g_once_init_enter (&completion_provider_completion_choice_type_id__volatile)) {
		GType completion_provider_completion_choice_type_id;
		completion_provider_completion_choice_type_id = g_boxed_type_register_static ("CompletionProviderCompletionChoice", (GBoxedCopyFunc) completion_provider_completion_choice_dup, (GBoxedFreeFunc) completion_provider_completion_choice_free);
		g_once_init_leave (&completion_provider_completion_choice_type_id__volatile, completion_provider_completion_choice_type_id);
	}
	return completion_provider_completion_choice_type_id__volatile;
}


static void completion_provider_class_init (CompletionProviderClass * klass) {
	completion_provider_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (CompletionProviderPrivate));
	G_OBJECT_CLASS (klass)->finalize = completion_provider_finalize;
}


static void completion_provider_gtk_source_completion_provider_interface_init (GtkSourceCompletionProviderIface * iface) {
	completion_provider_gtk_source_completion_provider_parent_iface = g_type_interface_peek_parent (iface);
	iface->get_name = (gchar* (*)(GtkSourceCompletionProvider*)) completion_provider_real_get_name;
	iface->get_activation = (GtkSourceCompletionActivation (*)(GtkSourceCompletionProvider*)) completion_provider_real_get_activation;
	iface->match = (gboolean (*)(GtkSourceCompletionProvider* ,GtkSourceCompletionContext*)) completion_provider_real_match;
	iface->populate = (void (*)(GtkSourceCompletionProvider* ,GtkSourceCompletionContext*)) completion_provider_real_populate;
	iface->activate_proposal = (gboolean (*)(GtkSourceCompletionProvider* ,GtkSourceCompletionProposal* ,GtkTextIter*)) completion_provider_real_activate_proposal;
}


static void completion_provider_instance_init (CompletionProvider * self) {
	self->priv = COMPLETION_PROVIDER_GET_PRIVATE (self);
	self->priv->show_all_proposals = FALSE;
	self->priv->calltip_window = NULL;
	self->priv->calltip_window_label = NULL;
	self->priv->first_populate = TRUE;
}


static void completion_provider_finalize (GObject* obj) {
	CompletionProvider * self;
	self = COMPLETION_PROVIDER (obj);
	__g_list_free__g_object_unref0_0 (self->priv->proposals);
	_g_object_unref0 (self->priv->commands);
	_g_object_unref0 (self->priv->environments);
	_g_object_unref0 (self->priv->settings);
	completion_provider_completion_command_destroy (&self->priv->current_command);
	completion_provider_completion_argument_destroy (&self->priv->current_arg);
	completion_provider_completion_choice_destroy (&self->priv->current_choice);
	_g_object_unref0 (self->priv->icon_normal_cmd);
	_g_object_unref0 (self->priv->icon_normal_choice);
	_g_object_unref0 (self->priv->icon_package_required);
	_g_object_unref0 (self->priv->calltip_window);
	_g_object_unref0 (self->priv->calltip_window_label);
	G_OBJECT_CLASS (completion_provider_parent_class)->finalize (obj);
}


GType completion_provider_get_type (void) {
	static volatile gsize completion_provider_type_id__volatile = 0;
	if (g_once_init_enter (&completion_provider_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (CompletionProviderClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) completion_provider_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (CompletionProvider), 0, (GInstanceInitFunc) completion_provider_instance_init, NULL };
		static const GInterfaceInfo gtk_source_completion_provider_info = { (GInterfaceInitFunc) completion_provider_gtk_source_completion_provider_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
		GType completion_provider_type_id;
		completion_provider_type_id = g_type_register_static (G_TYPE_OBJECT, "CompletionProvider", &g_define_type_info, 0);
		g_type_add_interface_static (completion_provider_type_id, GTK_TYPE_SOURCE_COMPLETION_PROVIDER, &gtk_source_completion_provider_info);
		g_once_init_leave (&completion_provider_type_id__volatile, completion_provider_type_id);
	}
	return completion_provider_type_id__volatile;
}


static gint _vala_array_length (gpointer array) {
	int length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}



