/* vtgoutputview.c generated by valac 0.12.1.1-323029-dirty, the Vala compiler
 * generated from vtgoutputview.vala, do not modify */

/*
 *  vtgoutputview.vala - Vala developer toys for GEdit
 *  
 *  Copyright (C) 2008 - Andrea Del Signore <sejerpz@tin.it>
 *  
 *  This program 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 2 of the License, or
 *  (at your option) any later version.
 *   
 *  This program 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 this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330,
 *  Boston, MA 02111-1307, USA.
 */

#include <glib.h>
#include <glib-object.h>
#include <valagee.h>
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
#include <gedit/gedit-window.h>
#include <gedit/gedit-panel.h>
#include <pango/pango.h>
#include <gdk/gdk.h>
#include <glib/gi18n-lib.h>
#include <gdk/gdkkeysyms.h>


#define VTG_TYPE_OUTPUT_TYPES (vtg_output_types_get_type ())

#define VTG_TYPE_OUTPUT_VIEW (vtg_output_view_get_type ())
#define VTG_OUTPUT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VTG_TYPE_OUTPUT_VIEW, VtgOutputView))
#define VTG_OUTPUT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VTG_TYPE_OUTPUT_VIEW, VtgOutputViewClass))
#define VTG_IS_OUTPUT_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VTG_TYPE_OUTPUT_VIEW))
#define VTG_IS_OUTPUT_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VTG_TYPE_OUTPUT_VIEW))
#define VTG_OUTPUT_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VTG_TYPE_OUTPUT_VIEW, VtgOutputViewClass))

typedef struct _VtgOutputView VtgOutputView;
typedef struct _VtgOutputViewClass VtgOutputViewClass;
typedef struct _VtgOutputViewPrivate VtgOutputViewPrivate;

#define VTG_TYPE_PLUGIN_INSTANCE (vtg_plugin_instance_get_type ())
#define VTG_PLUGIN_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VTG_TYPE_PLUGIN_INSTANCE, VtgPluginInstance))
#define VTG_PLUGIN_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VTG_TYPE_PLUGIN_INSTANCE, VtgPluginInstanceClass))
#define VTG_IS_PLUGIN_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VTG_TYPE_PLUGIN_INSTANCE))
#define VTG_IS_PLUGIN_INSTANCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VTG_TYPE_PLUGIN_INSTANCE))
#define VTG_PLUGIN_INSTANCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VTG_TYPE_PLUGIN_INSTANCE, VtgPluginInstanceClass))

typedef struct _VtgPluginInstance VtgPluginInstance;
typedef struct _VtgPluginInstanceClass VtgPluginInstanceClass;

#define VTG_TYPE_PROCESS_WATCH_INFO (vtg_process_watch_info_get_type ())
#define VTG_PROCESS_WATCH_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VTG_TYPE_PROCESS_WATCH_INFO, VtgProcessWatchInfo))
#define VTG_PROCESS_WATCH_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VTG_TYPE_PROCESS_WATCH_INFO, VtgProcessWatchInfoClass))
#define VTG_IS_PROCESS_WATCH_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VTG_TYPE_PROCESS_WATCH_INFO))
#define VTG_IS_PROCESS_WATCH_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VTG_TYPE_PROCESS_WATCH_INFO))
#define VTG_PROCESS_WATCH_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VTG_TYPE_PROCESS_WATCH_INFO, VtgProcessWatchInfoClass))

typedef struct _VtgProcessWatchInfo VtgProcessWatchInfo;
typedef struct _VtgProcessWatchInfoClass VtgProcessWatchInfoClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _vala_iterable_unref0(var) ((var == NULL) ? NULL : (var = (vala_iterable_unref (var), NULL)))
#define _g_string_free0(var) ((var == NULL) ? NULL : (var = (g_string_free (var, TRUE), NULL)))
#define _pango_font_description_free0(var) ((var == NULL) ? NULL : (var = (pango_font_description_free (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _VtgProcessWatchInfoPrivate VtgProcessWatchInfoPrivate;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))
#define _vtg_process_watch_info_unref0(var) ((var == NULL) ? NULL : (var = (vtg_process_watch_info_unref (var), NULL)))
#define _g_io_channel_unref0(var) ((var == NULL) ? NULL : (var = (g_io_channel_unref (var), NULL)))

typedef enum  {
	VTG_OUTPUT_TYPES_MESSAGE,
	VTG_OUTPUT_TYPES_ERROR,
	VTG_OUTPUT_TYPES_CHILD_PROCESS,
	VTG_OUTPUT_TYPES_BUILD,
	VTG_OUTPUT_TYPES_AUTO_BUILD,
	VTG_OUTPUT_TYPES_SEARCH
} VtgOutputTypes;

struct _VtgOutputView {
	GObject parent_instance;
	VtgOutputViewPrivate * priv;
	VtgPluginInstance* _plugin_instance;
};

struct _VtgOutputViewClass {
	GObjectClass parent_class;
	void (*start_watch) (VtgOutputView* self, VtgOutputTypes output_type, guint id, gint stdo, gint stde, gint stdi);
	void (*stop_watch) (VtgOutputView* self, guint id);
};

struct _VtgOutputViewPrivate {
	ValaList* _processes;
	GString* line;
	GtkTextBuffer* _messages;
	GtkTextView* _textview;
	GtkScrolledWindow* _ui;
	gchar** keywords;
	gint keywords_length1;
	gint _keywords_size_;
};

struct _VtgProcessWatchInfo {
	GTypeInstance parent_instance;
	volatile int ref_count;
	VtgProcessWatchInfoPrivate * priv;
	guint id;
	GIOChannel* stdin;
	GIOChannel* stdout;
	GIOChannel* stderr;
	guint stdout_watch_id;
	guint stderr_watch_id;
	VtgOutputTypes output_type;
};

struct _VtgProcessWatchInfoClass {
	GTypeClass parent_class;
	void (*finalize) (VtgProcessWatchInfo *self);
};


static gpointer vtg_output_view_parent_class = NULL;
static GType vtg_output_view_type_id = 0;

GType vtg_output_types_get_type (void) G_GNUC_CONST;
GType vtg_output_view_get_type (void) G_GNUC_CONST;
GType vtg_output_view_register_type (GTypeModule * module);
GType vtg_plugin_instance_get_type (void) G_GNUC_CONST;
GType vtg_plugin_instance_register_type (GTypeModule * module);
gpointer vtg_process_watch_info_ref (gpointer instance);
void vtg_process_watch_info_unref (gpointer instance);
GParamSpec* vtg_param_spec_process_watch_info (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags);
void vtg_value_set_process_watch_info (GValue* value, gpointer v_object);
void vtg_value_take_process_watch_info (GValue* value, gpointer v_object);
gpointer vtg_value_get_process_watch_info (const GValue* value);
GType vtg_process_watch_info_get_type (void) G_GNUC_CONST;
GType vtg_process_watch_info_register_type (GTypeModule * module);
#define VTG_OUTPUT_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VTG_TYPE_OUTPUT_VIEW, VtgOutputViewPrivate))
enum  {
	VTG_OUTPUT_VIEW_DUMMY_PROPERTY
};
GeditWindow* vtg_plugin_instance_get_window (VtgPluginInstance* self);
VtgOutputView* vtg_output_view_new (VtgPluginInstance* plugin_instance);
VtgOutputView* vtg_output_view_construct (GType object_type, VtgPluginInstance* plugin_instance);
static gboolean vtg_output_view_on_textview_key_press (VtgOutputView* self, GtkWidget* sender, GdkEventKey* evt);
static gboolean _vtg_output_view_on_textview_key_press_gtk_widget_key_press_event (GtkWidget* _sender, GdkEventKey* event, gpointer self);
static VtgProcessWatchInfo* vtg_output_view_find_process_by_id (VtgOutputView* self, guint id);
static VtgProcessWatchInfo* vtg_output_view_find_process_by_io_channel (VtgOutputView* self, GIOChannel* chan);
static VtgProcessWatchInfo* vtg_output_view_add_process_view (VtgOutputView* self, guint id);
VtgProcessWatchInfo* vtg_process_watch_info_new (guint id);
VtgProcessWatchInfo* vtg_process_watch_info_construct (GType object_type, guint id);
void vtg_output_view_start_watch (VtgOutputView* self, VtgOutputTypes output_type, guint id, gint stdo, gint stde, gint stdi);
static void vtg_output_view_real_start_watch (VtgOutputView* self, VtgOutputTypes output_type, guint id, gint stdo, gint stde, gint stdi);
void vtg_output_view_stop_watch (VtgOutputView* self, guint id);
static gboolean vtg_output_view_on_messages (VtgOutputView* self, GIOChannel* source, GIOCondition condition);
static gboolean _vtg_output_view_on_messages_gio_func (GIOChannel* source, GIOCondition condition, gpointer self);
static void vtg_output_view_real_stop_watch (VtgOutputView* self, guint id);
void vtg_process_watch_info_cleanup (VtgProcessWatchInfo* self);
void vtg_output_view_clean_output (VtgOutputView* self);
static void vtg_output_view_log_channel (VtgOutputView* self, GIOChannel* source, GError** error);
void vtg_output_view_log_message (VtgOutputView* self, VtgOutputTypes output_type, const gchar* message);
gboolean vtg_string_utils_is_null_or_empty (const gchar* data);
gchar* vtg_string_utils_replace (const gchar* data, const gchar* search, const gchar* replace);
void vtg_output_view_activate (VtgOutputView* self);
static void g_cclosure_user_marshal_VOID__ENUM_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data);
static void vtg_output_view_finalize (GObject* obj);
static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func);
static gint _vala_array_length (gpointer array);


GType vtg_output_types_get_type (void) {
	static volatile gsize vtg_output_types_type_id__volatile = 0;
	if (g_once_init_enter (&vtg_output_types_type_id__volatile)) {
		static const GEnumValue values[] = {{VTG_OUTPUT_TYPES_MESSAGE, "VTG_OUTPUT_TYPES_MESSAGE", "message"}, {VTG_OUTPUT_TYPES_ERROR, "VTG_OUTPUT_TYPES_ERROR", "error"}, {VTG_OUTPUT_TYPES_CHILD_PROCESS, "VTG_OUTPUT_TYPES_CHILD_PROCESS", "child-process"}, {VTG_OUTPUT_TYPES_BUILD, "VTG_OUTPUT_TYPES_BUILD", "build"}, {VTG_OUTPUT_TYPES_AUTO_BUILD, "VTG_OUTPUT_TYPES_AUTO_BUILD", "auto-build"}, {VTG_OUTPUT_TYPES_SEARCH, "VTG_OUTPUT_TYPES_SEARCH", "search"}, {0, NULL, NULL}};
		GType vtg_output_types_type_id;
		vtg_output_types_type_id = g_enum_register_static ("VtgOutputTypes", values);
		g_once_init_leave (&vtg_output_types_type_id__volatile, vtg_output_types_type_id);
	}
	return vtg_output_types_type_id__volatile;
}


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


static gboolean _vtg_output_view_on_textview_key_press_gtk_widget_key_press_event (GtkWidget* _sender, GdkEventKey* event, gpointer self) {
	gboolean result;
	result = vtg_output_view_on_textview_key_press (self, _sender, event);
	return result;
}


VtgOutputView* vtg_output_view_construct (GType object_type, VtgPluginInstance* plugin_instance) {
	VtgOutputView * self = NULL;
	GeditWindow* _tmp0_ = NULL;
	GeditPanel* _tmp1_ = NULL;
	GeditPanel* _tmp2_;
	GeditPanel* panel;
	GtkTextBuffer* _tmp3_ = NULL;
	GtkTextView* _tmp4_ = NULL;
	PangoFontDescription* _tmp5_ = NULL;
	PangoFontDescription* font_desc;
	GtkScrolledWindow* _tmp6_ = NULL;
	const gchar* _tmp7_ = NULL;
	g_return_val_if_fail (plugin_instance != NULL, NULL);
	self = (VtgOutputView*) g_object_new (object_type, NULL);
	self->_plugin_instance = plugin_instance;
	_tmp0_ = vtg_plugin_instance_get_window (self->_plugin_instance);
	_tmp1_ = gedit_window_get_bottom_panel (_tmp0_);
	_tmp2_ = _g_object_ref0 (_tmp1_);
	panel = _tmp2_;
	_tmp3_ = gtk_text_buffer_new (NULL);
	_g_object_unref0 (self->priv->_messages);
	self->priv->_messages = _tmp3_;
	gtk_text_buffer_create_tag (self->priv->_messages, "keyword", "weight", PANGO_WEIGHT_BOLD, NULL, NULL);
	_tmp4_ = (GtkTextView*) gtk_text_view_new_with_buffer (self->priv->_messages);
	_g_object_unref0 (self->priv->_textview);
	self->priv->_textview = g_object_ref_sink (_tmp4_);
	g_signal_connect_object ((GtkWidget*) self->priv->_textview, "key-press-event", (GCallback) _vtg_output_view_on_textview_key_press_gtk_widget_key_press_event, self, 0);
	_tmp5_ = pango_font_description_from_string ("Monospace");
	font_desc = _tmp5_;
	gtk_widget_modify_font ((GtkWidget*) self->priv->_textview, font_desc);
	gtk_text_view_set_wrap_mode (self->priv->_textview, GTK_WRAP_CHAR);
	_tmp6_ = (GtkScrolledWindow*) gtk_scrolled_window_new (NULL, NULL);
	_g_object_unref0 (self->priv->_ui);
	self->priv->_ui = g_object_ref_sink (_tmp6_);
	gtk_container_add ((GtkContainer*) self->priv->_ui, (GtkWidget*) self->priv->_textview);
	gtk_widget_show_all ((GtkWidget*) self->priv->_ui);
	_tmp7_ = _ ("Output");
	gedit_panel_add_item (panel, (GtkWidget*) self->priv->_ui, "Output", _tmp7_, NULL);
	_pango_font_description_free0 (font_desc);
	_g_object_unref0 (panel);
	return self;
}


VtgOutputView* vtg_output_view_new (VtgPluginInstance* plugin_instance) {
	return vtg_output_view_construct (VTG_TYPE_OUTPUT_VIEW, plugin_instance);
}


static gpointer _vala_iterable_ref0 (gpointer self) {
	return self ? vala_iterable_ref (self) : NULL;
}


static gboolean vtg_output_view_on_textview_key_press (VtgOutputView* self, GtkWidget* sender, GdkEventKey* evt) {
	gboolean result = FALSE;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (sender != NULL, FALSE);
	if ((*evt).keyval == GDK_KEY_Return) {
		gchar* buffer = NULL;
		if (self->priv->line->len == 0) {
			gchar* _tmp0_;
			_tmp0_ = g_strdup ("\n");
			_g_free0 (buffer);
			buffer = _tmp0_;
		} else {
			gchar* _tmp1_ = NULL;
			_tmp1_ = g_strdup_printf ("%s\n", self->priv->line->str);
			_g_free0 (buffer);
			buffer = _tmp1_;
		}
		{
			ValaList* _tmp2_;
			ValaList* _item_list;
			gint _tmp3_;
			gint _item_size;
			gint _item_index;
			_tmp2_ = _vala_iterable_ref0 (self->priv->_processes);
			_item_list = _tmp2_;
			_tmp3_ = vala_collection_get_size ((ValaCollection*) _item_list);
			_item_size = _tmp3_;
			_item_index = -1;
			while (TRUE) {
				gpointer _tmp4_ = NULL;
				VtgProcessWatchInfo* item;
				_item_index = _item_index + 1;
				if (!(_item_index < _item_size)) {
					break;
				}
				_tmp4_ = vala_list_get (_item_list, _item_index);
				item = (VtgProcessWatchInfo*) _tmp4_;
				if (item->stdin != NULL) {
					gsize bw = 0UL;
					gsize _tmp5_;
					g_io_channel_write_chars (item->stdin, (gchar*) buffer, -1, &_tmp5_, &_inner_error_);
					bw = _tmp5_;
					if (_inner_error_ != NULL) {
						goto __catch33_g_error;
					}
					g_io_channel_flush (item->stdin, &_inner_error_);
					if (_inner_error_ != NULL) {
						goto __catch33_g_error;
					}
					goto __finally33;
					__catch33_g_error:
					{
						GError * err;
						err = _inner_error_;
						_inner_error_ = NULL;
						g_warning ("vtgoutputview.vala:101: on_textview_key_press - error: %s", err->message);
						_g_error_free0 (err);
					}
					__finally33:
					if (_inner_error_ != NULL) {
						_vtg_process_watch_info_unref0 (item);
						_vala_iterable_unref0 (_item_list);
						_g_free0 (buffer);
						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 FALSE;
					}
				}
				_vtg_process_watch_info_unref0 (item);
			}
			_vala_iterable_unref0 (_item_list);
		}
		g_string_erase (self->priv->line, (gssize) 0, (gssize) (-1));
		_g_free0 (buffer);
	} else {
		guint32 _tmp6_;
		gunichar ch;
		_tmp6_ = gdk_keyval_to_unicode ((*evt).keyval);
		ch = (gunichar) _tmp6_;
		g_string_append_unichar (self->priv->line, ch);
	}
	result = FALSE;
	return result;
}


static VtgProcessWatchInfo* vtg_output_view_find_process_by_id (VtgOutputView* self, guint id) {
	VtgProcessWatchInfo* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	{
		ValaList* _tmp0_;
		ValaList* _target_list;
		gint _tmp1_;
		gint _target_size;
		gint _target_index;
		_tmp0_ = _vala_iterable_ref0 (self->priv->_processes);
		_target_list = _tmp0_;
		_tmp1_ = vala_collection_get_size ((ValaCollection*) _target_list);
		_target_size = _tmp1_;
		_target_index = -1;
		while (TRUE) {
			gpointer _tmp2_ = NULL;
			VtgProcessWatchInfo* target;
			_target_index = _target_index + 1;
			if (!(_target_index < _target_size)) {
				break;
			}
			_tmp2_ = vala_list_get (_target_list, _target_index);
			target = (VtgProcessWatchInfo*) _tmp2_;
			if (target->id == id) {
				result = target;
				_vala_iterable_unref0 (_target_list);
				return result;
			}
			_vtg_process_watch_info_unref0 (target);
		}
		_vala_iterable_unref0 (_target_list);
	}
	result = NULL;
	return result;
}


static VtgProcessWatchInfo* vtg_output_view_find_process_by_io_channel (VtgOutputView* self, GIOChannel* chan) {
	VtgProcessWatchInfo* result = NULL;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (chan != NULL, NULL);
	{
		ValaList* _tmp0_;
		ValaList* _target_list;
		gint _tmp1_;
		gint _target_size;
		gint _target_index;
		_tmp0_ = _vala_iterable_ref0 (self->priv->_processes);
		_target_list = _tmp0_;
		_tmp1_ = vala_collection_get_size ((ValaCollection*) _target_list);
		_target_size = _tmp1_;
		_target_index = -1;
		while (TRUE) {
			gpointer _tmp2_ = NULL;
			VtgProcessWatchInfo* target;
			gboolean _tmp3_ = FALSE;
			_target_index = _target_index + 1;
			if (!(_target_index < _target_size)) {
				break;
			}
			_tmp2_ = vala_list_get (_target_list, _target_index);
			target = (VtgProcessWatchInfo*) _tmp2_;
			if (target->stdout == chan) {
				_tmp3_ = TRUE;
			} else {
				_tmp3_ = target->stderr == chan;
			}
			if (_tmp3_) {
				result = target;
				_vala_iterable_unref0 (_target_list);
				return result;
			}
			_vtg_process_watch_info_unref0 (target);
		}
		_vala_iterable_unref0 (_target_list);
	}
	result = NULL;
	return result;
}


static VtgProcessWatchInfo* vtg_output_view_add_process_view (VtgOutputView* self, guint id) {
	VtgProcessWatchInfo* result = NULL;
	VtgProcessWatchInfo* _tmp0_ = NULL;
	VtgProcessWatchInfo* _result_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = vtg_process_watch_info_new (id);
	_result_ = _tmp0_;
	vala_collection_add ((ValaCollection*) self->priv->_processes, _result_);
	result = _result_;
	return result;
}


static gboolean _vtg_output_view_on_messages_gio_func (GIOChannel* source, GIOCondition condition, gpointer self) {
	gboolean result;
	result = vtg_output_view_on_messages (self, source, condition);
	return result;
}


static void vtg_output_view_real_start_watch (VtgOutputView* self, VtgOutputTypes output_type, guint id, gint stdo, gint stde, gint stdi) {
	VtgProcessWatchInfo* _tmp0_ = NULL;
	VtgProcessWatchInfo* target;
	VtgProcessWatchInfo* _tmp1_ = NULL;
	GIOChannel* _tmp3_ = NULL;
	guint _tmp4_;
	GIOFlags _tmp5_;
	GIOChannel* _tmp6_ = NULL;
	guint _tmp7_;
	GIOFlags _tmp8_;
	GeditWindow* _tmp9_ = NULL;
	GeditPanel* _tmp10_ = NULL;
	GeditPanel* _tmp11_;
	GeditPanel* panel;
	gboolean _tmp12_;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = vtg_output_view_find_process_by_id (self, id);
	target = _tmp0_;
	if (target != NULL) {
		vtg_output_view_stop_watch (self, id);
	}
	_tmp1_ = vtg_output_view_add_process_view (self, id);
	_vtg_process_watch_info_unref0 (target);
	target = _tmp1_;
	target->output_type = output_type;
	if (stdi != (-1)) {
		GIOChannel* _tmp2_ = NULL;
		_tmp2_ = g_io_channel_unix_new (stdi);
		_g_io_channel_unref0 (target->stdin);
		target->stdin = _tmp2_;
	}
	_tmp3_ = g_io_channel_unix_new (stdo);
	_g_io_channel_unref0 (target->stdout);
	target->stdout = _tmp3_;
	_tmp4_ = g_io_add_watch (target->stdout, G_IO_IN | G_IO_PRI, _vtg_output_view_on_messages_gio_func, self);
	target->stdout_watch_id = _tmp4_;
	_tmp5_ = g_io_channel_get_flags (target->stdout);
	g_io_channel_set_flags (target->stdout, _tmp5_ | G_IO_FLAG_NONBLOCK, &_inner_error_);
	if (_inner_error_ != NULL) {
		_vtg_process_watch_info_unref0 (target);
		goto __catch34_g_error;
	}
	_tmp6_ = g_io_channel_unix_new (stde);
	_g_io_channel_unref0 (target->stderr);
	target->stderr = _tmp6_;
	_tmp7_ = g_io_add_watch (target->stderr, G_IO_IN | G_IO_PRI, _vtg_output_view_on_messages_gio_func, self);
	target->stderr_watch_id = _tmp7_;
	_tmp8_ = g_io_channel_get_flags (target->stderr);
	g_io_channel_set_flags (target->stderr, _tmp8_ | G_IO_FLAG_NONBLOCK, &_inner_error_);
	if (_inner_error_ != NULL) {
		_vtg_process_watch_info_unref0 (target);
		goto __catch34_g_error;
	}
	g_string_erase (self->priv->line, (gssize) 0, (gssize) (-1));
	_tmp9_ = vtg_plugin_instance_get_window (self->_plugin_instance);
	_tmp10_ = gedit_window_get_bottom_panel (_tmp9_);
	_tmp11_ = _g_object_ref0 (_tmp10_);
	panel = _tmp11_;
	_tmp12_ = gtk_widget_get_visible ((GtkWidget*) panel);
	if (!_tmp12_) {
		gtk_widget_show_all ((GtkWidget*) panel);
	}
	_g_object_unref0 (panel);
	_vtg_process_watch_info_unref0 (target);
	goto __finally34;
	__catch34_g_error:
	{
		GError * err;
		err = _inner_error_;
		_inner_error_ = NULL;
		g_warning ("vtgoutputview.vala:175: error during watch setup: %s", err->message);
		_g_error_free0 (err);
	}
	__finally34:
	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;
	}
}


void vtg_output_view_start_watch (VtgOutputView* self, VtgOutputTypes output_type, guint id, gint stdo, gint stde, gint stdi) {
	VTG_OUTPUT_VIEW_GET_CLASS (self)->start_watch (self, output_type, id, stdo, stde, stdi);
}


static void vtg_output_view_real_stop_watch (VtgOutputView* self, guint id) {
	VtgProcessWatchInfo* _tmp0_ = NULL;
	VtgProcessWatchInfo* target;
	gint _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = vtg_output_view_find_process_by_id (self, id);
	target = _tmp0_;
	if (target == NULL) {
		g_warning ("vtgoutputview.vala:184: stop_watch: no target with id %u found", id);
		_vtg_process_watch_info_unref0 (target);
		return;
	}
	vtg_process_watch_info_cleanup (target);
	_tmp1_ = vala_list_index_of (self->priv->_processes, target);
	vala_list_remove_at (self->priv->_processes, _tmp1_);
	_vtg_process_watch_info_unref0 (target);
}


void vtg_output_view_stop_watch (VtgOutputView* self, guint id) {
	VTG_OUTPUT_VIEW_GET_CLASS (self)->stop_watch (self, id);
}


void vtg_output_view_clean_output (VtgOutputView* self) {
	g_return_if_fail (self != NULL);
	gtk_text_buffer_set_text (self->priv->_messages, "", 0);
}


static void vtg_output_view_log_channel (VtgOutputView* self, GIOChannel* source, GError** error) {
	GString* _tmp0_ = NULL;
	GString* message;
	gsize len;
	gchar* _tmp1_ = NULL;
	gchar* buff;
	gint buff_length1;
	gint _buff_size_;
	GIOStatus res;
	GError * _inner_error_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (source != NULL);
	_tmp0_ = g_string_new ("");
	message = _tmp0_;
	len = (gsize) 0;
	_tmp1_ = g_new0 (gchar, 4096);
	buff = _tmp1_;
	buff_length1 = 4096;
	_buff_size_ = 4096;
	res = G_IO_STATUS_NORMAL;
	while (TRUE) {
		gsize _tmp2_;
		GIOStatus _tmp3_;
		GIOStatus _tmp4_;
		if (!(res == G_IO_STATUS_NORMAL)) {
			break;
		}
		_tmp3_ = g_io_channel_read_chars (source, buff, buff_length1, &_tmp2_, &_inner_error_);
		len = _tmp2_;
		_tmp4_ = _tmp3_;
		if (_inner_error_ != NULL) {
			g_propagate_error (error, _inner_error_);
			buff = (g_free (buff), NULL);
			_g_string_free0 (message);
			return;
		}
		res = _tmp4_;
		if (len > 0) {
			g_string_append_len (message, (const gchar*) buff, (gssize) len);
		}
	}
	if (message->len > 0) {
		VtgProcessWatchInfo* _tmp5_ = NULL;
		VtgProcessWatchInfo* process;
		VtgOutputTypes output_type = 0;
		_tmp5_ = vtg_output_view_find_process_by_io_channel (self, source);
		process = _tmp5_;
		if (process != NULL) {
			output_type = process->output_type;
		} else {
			output_type = VTG_OUTPUT_TYPES_CHILD_PROCESS;
		}
		vtg_output_view_log_message (self, output_type, message->str);
		_vtg_process_watch_info_unref0 (process);
	}
	buff = (g_free (buff), NULL);
	_g_string_free0 (message);
}


static gboolean vtg_output_view_on_messages (VtgOutputView* self, GIOChannel* source, GIOCondition condition) {
	gboolean result = FALSE;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (source != NULL, FALSE);
	if ((condition & (G_IO_IN | G_IO_PRI)) != 0) {
		vtg_output_view_log_channel (self, source, &_inner_error_);
		if (_inner_error_ != NULL) {
			goto __catch35_g_error;
		}
	}
	result = TRUE;
	return result;
	goto __finally35;
	__catch35_g_error:
	{
		GError * err;
		err = _inner_error_;
		_inner_error_ = NULL;
		g_warning ("vtgoutputview.vala:230: Error reading from process %s", err->message);
		result = FALSE;
		_g_error_free0 (err);
		return result;
	}
	__finally35:
	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 FALSE;
}


static glong string_strnlen (gchar* str, glong maxlen) {
	glong result = 0L;
	gchar* _tmp0_ = NULL;
	gchar* end;
	_tmp0_ = memchr (str, 0, (gsize) maxlen);
	end = _tmp0_;
	if (end == NULL) {
		result = maxlen;
		return result;
	} else {
		result = (glong) (end - str);
		return result;
	}
}


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


void vtg_output_view_log_message (VtgOutputView* self, VtgOutputTypes output_type, const gchar* message) {
	gchar** _tmp0_;
	gchar** _tmp1_ = NULL;
	gchar** lines;
	gint lines_length1;
	gint _lines_size_;
	GtkTextIter iter = {0};
	GtkTextMark* _tmp2_ = NULL;
	GtkTextIter _tmp3_ = {0};
	GtkTextMark* _tmp18_ = NULL;
	g_return_if_fail (self != NULL);
	g_return_if_fail (message != NULL);
	_tmp1_ = _tmp0_ = g_strsplit (message, "\n", 0);
	lines = _tmp1_;
	lines_length1 = _vala_array_length (_tmp0_);
	_lines_size_ = _vala_array_length (_tmp0_);
	_tmp2_ = gtk_text_buffer_get_insert (self->priv->_messages);
	gtk_text_buffer_get_iter_at_mark (self->priv->_messages, &_tmp3_, _tmp2_);
	iter = _tmp3_;
	{
		gint count;
		count = 0;
		{
			gboolean _tmp4_;
			_tmp4_ = TRUE;
			while (TRUE) {
				gchar* _tmp5_;
				gchar* line;
				gboolean _tmp6_;
				gboolean _tmp17_;
				if (!_tmp4_) {
					count++;
				}
				_tmp4_ = FALSE;
				if (!(count < lines_length1)) {
					break;
				}
				_tmp5_ = g_strdup (lines[count]);
				line = _tmp5_;
				_tmp6_ = vtg_string_utils_is_null_or_empty (line);
				if (!_tmp6_) {
					gchar* _tmp11_ = NULL;
					gchar* _tmp12_ = NULL;
					gchar* _tmp13_ = NULL;
					{
						gchar** keyword_collection;
						int keyword_collection_length1;
						int keyword_it;
						keyword_collection = self->priv->keywords;
						keyword_collection_length1 = self->priv->keywords_length1;
						for (keyword_it = 0; keyword_it < self->priv->keywords_length1; keyword_it = keyword_it + 1) {
							gchar* _tmp7_;
							gchar* keyword;
							_tmp7_ = g_strdup (keyword_collection[keyword_it]);
							keyword = _tmp7_;
							{
								gboolean _tmp8_;
								_tmp8_ = g_str_has_prefix (line, keyword);
								if (_tmp8_) {
									gint _tmp9_;
									gchar* _tmp10_ = NULL;
									gtk_text_buffer_insert_with_tags_by_name (self->priv->_messages, &iter, keyword, -1, "keyword", NULL);
									_tmp9_ = strlen (keyword);
									_tmp10_ = string_substring (line, (glong) _tmp9_, (glong) (-1));
									_g_free0 (line);
									line = _tmp10_;
								}
								_g_free0 (keyword);
							}
						}
					}
					_tmp11_ = vtg_string_utils_replace (line, "[1m", "");
					_g_free0 (line);
					line = _tmp11_;
					_tmp12_ = vtg_string_utils_replace (line, "[m", "");
					_g_free0 (line);
					line = _tmp12_;
					_tmp13_ = vtg_string_utils_replace (line, "(B", "");
					_g_free0 (line);
					line = _tmp13_;
				}
				if (count < (lines_length1 - 1)) {
					if (line == NULL) {
						gchar* _tmp14_;
						_tmp14_ = g_strdup ("\n");
						_g_free0 (line);
						line = _tmp14_;
					} else {
						gboolean _tmp15_;
						_tmp15_ = g_str_has_suffix (line, "\n");
						if (!_tmp15_) {
							gchar* _tmp16_;
							_tmp16_ = g_strconcat (line, "\n", NULL);
							_g_free0 (line);
							line = _tmp16_;
						}
					}
				}
				_tmp17_ = vtg_string_utils_is_null_or_empty (line);
				if (!_tmp17_) {
					gtk_text_buffer_insert (self->priv->_messages, &iter, line, -1);
				}
				_g_free0 (line);
			}
		}
	}
	_tmp18_ = gtk_text_buffer_get_insert (self->priv->_messages);
	gtk_text_view_scroll_mark_onscreen (self->priv->_textview, _tmp18_);
	g_signal_emit_by_name (self, "message-added", output_type, message);
	lines = (_vala_array_free (lines, lines_length1, (GDestroyNotify) g_free), NULL);
}


void vtg_output_view_activate (VtgOutputView* self) {
	GeditWindow* _tmp0_ = NULL;
	GeditPanel* _tmp1_ = NULL;
	GeditPanel* _tmp2_;
	GeditPanel* panel;
	g_return_if_fail (self != NULL);
	_tmp0_ = vtg_plugin_instance_get_window (self->_plugin_instance);
	_tmp1_ = gedit_window_get_bottom_panel (_tmp0_);
	_tmp2_ = _g_object_ref0 (_tmp1_);
	panel = _tmp2_;
	gedit_panel_activate_item (panel, (GtkWidget*) self->priv->_ui);
	_g_object_unref0 (panel);
}


static void g_cclosure_user_marshal_VOID__ENUM_STRING (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) {
	typedef void (*GMarshalFunc_VOID__ENUM_STRING) (gpointer data1, gint arg_1, const char* arg_2, gpointer data2);
	register GMarshalFunc_VOID__ENUM_STRING callback;
	register GCClosure * cc;
	register gpointer data1, data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__ENUM_STRING) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_enum (param_values + 1), g_value_get_string (param_values + 2), data2);
}


static void vtg_output_view_class_init (VtgOutputViewClass * klass) {
	vtg_output_view_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (VtgOutputViewPrivate));
	VTG_OUTPUT_VIEW_CLASS (klass)->start_watch = vtg_output_view_real_start_watch;
	VTG_OUTPUT_VIEW_CLASS (klass)->stop_watch = vtg_output_view_real_stop_watch;
	G_OBJECT_CLASS (klass)->finalize = vtg_output_view_finalize;
	g_signal_new ("message_added", VTG_TYPE_OUTPUT_VIEW, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__ENUM_STRING, G_TYPE_NONE, 2, VTG_TYPE_OUTPUT_TYPES, G_TYPE_STRING);
}


static void vtg_output_view_instance_init (VtgOutputView * self) {
	ValaArrayList* _tmp0_ = NULL;
	GString* _tmp1_ = NULL;
	gchar* _tmp2_;
	gchar* _tmp3_;
	gchar* _tmp4_;
	gchar* _tmp5_;
	gchar** _tmp6_ = NULL;
	self->priv = VTG_OUTPUT_VIEW_GET_PRIVATE (self);
	self->_plugin_instance = NULL;
	_tmp0_ = vala_array_list_new (VTG_TYPE_PROCESS_WATCH_INFO, (GBoxedCopyFunc) vtg_process_watch_info_ref, vtg_process_watch_info_unref, g_direct_equal);
	self->priv->_processes = (ValaList*) _tmp0_;
	_tmp1_ = g_string_new ("");
	self->priv->line = _tmp1_;
	self->priv->_ui = NULL;
	_tmp2_ = g_strdup ("checking");
	_tmp3_ = g_strdup ("Checking");
	_tmp4_ = g_strdup ("Running");
	_tmp5_ = g_strdup ("  testing");
	_tmp6_ = g_new0 (gchar*, 4 + 1);
	_tmp6_[0] = _tmp2_;
	_tmp6_[1] = _tmp3_;
	_tmp6_[2] = _tmp4_;
	_tmp6_[3] = _tmp5_;
	self->priv->keywords = _tmp6_;
	self->priv->keywords_length1 = 4;
	self->priv->_keywords_size_ = self->priv->keywords_length1;
}


static void vtg_output_view_finalize (GObject* obj) {
	VtgOutputView * self;
	GeditWindow* _tmp0_ = NULL;
	GeditPanel* _tmp1_ = NULL;
	GeditPanel* _tmp2_;
	GeditPanel* panel;
	self = VTG_OUTPUT_VIEW (obj);
	_tmp0_ = vtg_plugin_instance_get_window (self->_plugin_instance);
	_tmp1_ = gedit_window_get_bottom_panel (_tmp0_);
	_tmp2_ = _g_object_ref0 (_tmp1_);
	panel = _tmp2_;
	gedit_panel_remove_item (panel, (GtkWidget*) self->priv->_ui);
	_g_object_unref0 (panel);
	_vala_iterable_unref0 (self->priv->_processes);
	_g_string_free0 (self->priv->line);
	_g_object_unref0 (self->priv->_messages);
	_g_object_unref0 (self->priv->_textview);
	_g_object_unref0 (self->priv->_ui);
	self->priv->keywords = (_vala_array_free (self->priv->keywords, self->priv->keywords_length1, (GDestroyNotify) g_free), NULL);
	G_OBJECT_CLASS (vtg_output_view_parent_class)->finalize (obj);
}


GType vtg_output_view_get_type (void) {
	return vtg_output_view_type_id;
}


GType vtg_output_view_register_type (GTypeModule * module) {
	static const GTypeInfo g_define_type_info = { sizeof (VtgOutputViewClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) vtg_output_view_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (VtgOutputView), 0, (GInstanceInitFunc) vtg_output_view_instance_init, NULL };
	vtg_output_view_type_id = g_type_module_register_type (module, G_TYPE_OBJECT, "VtgOutputView", &g_define_type_info, 0);
	return vtg_output_view_type_id;
}


static void _vala_array_destroy (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	if ((array != NULL) && (destroy_func != NULL)) {
		int i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}


static void _vala_array_free (gpointer array, gint array_length, GDestroyNotify destroy_func) {
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}


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



