Added MooCmdView - widget for running commands and printing output
parent
365dc2cf6a
commit
4eb2fdf219
26
moo.kdevelop
26
moo.kdevelop
|
@ -36,7 +36,7 @@
|
|||
<useconfiguration>debug</useconfiguration>
|
||||
</general>
|
||||
<run>
|
||||
<mainprogram>tests/editor</mainprogram>
|
||||
<mainprogram>tests/medit</mainprogram>
|
||||
<directoryradio>executable</directoryradio>
|
||||
<customdirectory>/</customdirectory>
|
||||
<programargs></programargs>
|
||||
|
@ -46,7 +46,7 @@
|
|||
</run>
|
||||
<configurations>
|
||||
<debug>
|
||||
<configargs>--enable-debug=full --enable-all-gcc-warnings=fatal --enable-developer-mode --disable-moo-module --without-python --without-mooterm --without-mooui</configargs>
|
||||
<configargs>--enable-debug=full --enable-all-gcc-warnings=fatal --enable-developer-mode --disable-moo-module --without-python --without-mooterm --without-mooui --without-mooapp</configargs>
|
||||
<builddir>build/debug</builddir>
|
||||
<ccompiler>kdevgccoptions</ccompiler>
|
||||
<cxxcompiler>kdevgppoptions</cxxcompiler>
|
||||
|
@ -54,13 +54,13 @@
|
|||
<cflags>-O0 -g3 -pg</cflags>
|
||||
<cxxflags>-O0 -g3 -pg</cxxflags>
|
||||
<envvars/>
|
||||
<topsourcedir></topsourcedir>
|
||||
<cppflags></cppflags>
|
||||
<ldflags></ldflags>
|
||||
<ccompilerbinary></ccompilerbinary>
|
||||
<cxxcompilerbinary></cxxcompilerbinary>
|
||||
<f77compilerbinary></f77compilerbinary>
|
||||
<f77flags></f77flags>
|
||||
<topsourcedir/>
|
||||
<cppflags/>
|
||||
<ldflags/>
|
||||
<ccompilerbinary/>
|
||||
<cxxcompilerbinary/>
|
||||
<f77compilerbinary/>
|
||||
<f77flags/>
|
||||
</debug>
|
||||
<optimized>
|
||||
<configargs>--enable-all-gcc-warnings=fatal --enable-developer-mode --without-mooapp --without-mooterm --without-python</configargs>
|
||||
|
@ -251,16 +251,16 @@
|
|||
</kdevdoctreeview>
|
||||
<kdevfilecreate>
|
||||
<filetypes>
|
||||
<type icon="source" ext="g" create="template" name="GAP source" >
|
||||
<type icon="source" ext="g" name="GAP source" create="template" >
|
||||
<descr>A new empty GAP source file</descr>
|
||||
</type>
|
||||
<type icon="source_cpp" ext="cpp" create="template" name="C++ Source" >
|
||||
<type icon="source_cpp" ext="cpp" name="C++ Source" create="template" >
|
||||
<descr>A new empty C++ file.</descr>
|
||||
</type>
|
||||
<type icon="source_h" ext="h" create="template" name="C/C++ Header" >
|
||||
<type icon="source_h" ext="h" name="C/C++ Header" create="template" >
|
||||
<descr>A new empty header file for C/C++.</descr>
|
||||
</type>
|
||||
<type icon="source_c" ext="c" create="template" name="C Source" >
|
||||
<type icon="source_c" ext="c" name="C Source" create="template" >
|
||||
<descr>A new empty C file.</descr>
|
||||
</type>
|
||||
</filetypes>
|
||||
|
|
|
@ -717,7 +717,7 @@ static gboolean moo_app_init_real (MooApp *app)
|
|||
G_CALLBACK (all_editors_closed),
|
||||
app);
|
||||
|
||||
moo_grep_init ();
|
||||
moo_find_init ();
|
||||
moo_file_selector_init ();
|
||||
|
||||
moo_plugin_read_dir (plugin_dir);
|
||||
|
|
|
@ -35,6 +35,8 @@ libmooedit_la_LIBADD = \
|
|||
libmooedit_la_SOURCES = \
|
||||
moobigpaned.c \
|
||||
moobigpaned.h \
|
||||
moocmdview.c \
|
||||
moocmdview.h \
|
||||
mooedit.c \
|
||||
mooedit.h \
|
||||
mooedit-private.h \
|
||||
|
|
|
@ -0,0 +1,579 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
* moopaneview.c
|
||||
*
|
||||
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#include "mooedit/moocmdview.h"
|
||||
#include "mooutils/moomarshals.h"
|
||||
#include <sys/wait.h>
|
||||
|
||||
|
||||
struct _MooCmdViewPrivate {
|
||||
gboolean running;
|
||||
char *cmd;
|
||||
int exit_status;
|
||||
GPid pid;
|
||||
int stdout;
|
||||
int stderr;
|
||||
GIOChannel *stdout_io;
|
||||
GIOChannel *stderr_io;
|
||||
guint child_watch;
|
||||
guint stdout_watch;
|
||||
guint stderr_watch;
|
||||
|
||||
GtkTextTag *error_tag;
|
||||
GtkTextTag *message_tag;
|
||||
GtkTextTag *stdout_tag;
|
||||
GtkTextTag *stderr_tag;
|
||||
};
|
||||
|
||||
static void moo_cmd_view_finalize (GObject *object);
|
||||
static void moo_cmd_view_destroy (GtkObject *object);
|
||||
static GObject *moo_cmd_view_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
GObjectConstructParam *construct_param);
|
||||
|
||||
static void moo_cmd_view_check_stop (MooCmdView *view);
|
||||
static void moo_cmd_view_cleanup (MooCmdView *view);
|
||||
|
||||
static gboolean moo_cmd_view_abort_real (MooCmdView *view);
|
||||
static gboolean moo_cmd_view_cmd_exit (MooCmdView *view,
|
||||
int status);
|
||||
static gboolean moo_cmd_view_stdout_line (MooCmdView *view,
|
||||
const char *line);
|
||||
static gboolean moo_cmd_view_stderr_line (MooCmdView *view,
|
||||
const char *line);
|
||||
|
||||
|
||||
|
||||
enum {
|
||||
ABORT,
|
||||
CMD_EXIT,
|
||||
OUTPUT_LINE,
|
||||
STDOUT_LINE,
|
||||
STDERR_LINE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
};
|
||||
|
||||
|
||||
/* MOO_TYPE_CMD_VIEW */
|
||||
G_DEFINE_TYPE (MooCmdView, moo_cmd_view, MOO_TYPE_PANE_VIEW)
|
||||
|
||||
|
||||
static void
|
||||
moo_cmd_view_class_init (MooCmdViewClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->finalize = moo_cmd_view_finalize;
|
||||
gobject_class->constructor = moo_cmd_view_constructor;
|
||||
|
||||
gtkobject_class->destroy = moo_cmd_view_destroy;
|
||||
|
||||
klass->abort = moo_cmd_view_abort_real;
|
||||
klass->cmd_exit = moo_cmd_view_cmd_exit;
|
||||
klass->output_line = NULL;
|
||||
klass->stdout_line = moo_cmd_view_stdout_line;
|
||||
klass->stderr_line = moo_cmd_view_stderr_line;
|
||||
|
||||
signals[ABORT] =
|
||||
g_signal_new ("abort",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_STRUCT_OFFSET (MooCmdViewClass, abort),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
_moo_marshal_BOOL__VOID,
|
||||
G_TYPE_BOOLEAN, 0);
|
||||
|
||||
signals[CMD_EXIT] =
|
||||
g_signal_new ("cmd-exit",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MooCmdViewClass, cmd_exit),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
_moo_marshal_BOOL__INT,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
G_TYPE_INT);
|
||||
|
||||
signals[OUTPUT_LINE] =
|
||||
g_signal_new ("output-line",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MooCmdViewClass, output_line),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
_moo_marshal_BOOL__STRING_BOOL,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
G_TYPE_STRING, G_TYPE_BOOLEAN);
|
||||
|
||||
signals[STDOUT_LINE] =
|
||||
g_signal_new ("stdout-line",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MooCmdViewClass, stdout_line),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
_moo_marshal_BOOL__STRING,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
signals[STDERR_LINE] =
|
||||
g_signal_new ("stderr-line",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MooCmdViewClass, stderr_line),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
_moo_marshal_BOOL__STRING,
|
||||
G_TYPE_BOOLEAN, 1,
|
||||
G_TYPE_STRING);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_cmd_view_init (MooCmdView *view)
|
||||
{
|
||||
view->priv = g_new0 (MooCmdViewPrivate, 1);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_cmd_view_finalize (GObject *object)
|
||||
{
|
||||
MooCmdView *view = MOO_CMD_VIEW (object);
|
||||
|
||||
g_free (view->priv);
|
||||
|
||||
G_OBJECT_CLASS (moo_cmd_view_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
||||
static GObject*
|
||||
moo_cmd_view_constructor (GType type,
|
||||
guint n_props,
|
||||
GObjectConstructParam *props)
|
||||
{
|
||||
GObject *object;
|
||||
MooCmdView *view;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
object = G_OBJECT_CLASS(moo_cmd_view_parent_class)->constructor (type, n_props, props);
|
||||
view = MOO_CMD_VIEW (object);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
|
||||
view->priv->message_tag = gtk_text_buffer_create_tag (buffer, "message", NULL);
|
||||
view->priv->error_tag = gtk_text_buffer_create_tag (buffer, "error", NULL);
|
||||
view->priv->stdout_tag = gtk_text_buffer_create_tag (buffer, "stdout", NULL);
|
||||
view->priv->stderr_tag = gtk_text_buffer_create_tag (buffer, "stderr", NULL);
|
||||
|
||||
g_object_set (view->priv->error_tag, "foreground", "red", NULL);
|
||||
g_object_set (view->priv->stderr_tag, "foreground", "red", NULL);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_cmd_view_destroy (GtkObject *object)
|
||||
{
|
||||
MooCmdView *view = MOO_CMD_VIEW (object);
|
||||
|
||||
moo_cmd_view_abort (view);
|
||||
|
||||
if (GTK_OBJECT_CLASS (moo_cmd_view_parent_class)->destroy)
|
||||
GTK_OBJECT_CLASS (moo_cmd_view_parent_class)->destroy (object);
|
||||
}
|
||||
|
||||
|
||||
GtkWidget*
|
||||
moo_cmd_view_new (void)
|
||||
{
|
||||
return g_object_new (MOO_TYPE_CMD_VIEW, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
command_exit (GPid pid,
|
||||
gint status,
|
||||
MooCmdView *view)
|
||||
{
|
||||
g_return_if_fail (pid == view->priv->pid);
|
||||
|
||||
view->priv->child_watch = 0;
|
||||
view->priv->exit_status = status;
|
||||
|
||||
g_spawn_close_pid (view->priv->pid);
|
||||
view->priv->pid = 0;
|
||||
|
||||
moo_cmd_view_check_stop (view);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
process_line (MooCmdView *view,
|
||||
const char *line,
|
||||
gboolean stderr)
|
||||
{
|
||||
gboolean handled = FALSE;
|
||||
|
||||
g_signal_emit (view, signals[OUTPUT_LINE], 0, line, stderr, &handled);
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
if (stderr)
|
||||
g_signal_emit (view, signals[STDERR_LINE], 0, line, &handled);
|
||||
else
|
||||
g_signal_emit (view, signals[STDOUT_LINE], 0, line, &handled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
command_out_or_err (MooCmdView *view,
|
||||
GIOChannel *channel,
|
||||
GIOCondition condition,
|
||||
gboolean stdout)
|
||||
{
|
||||
char *line;
|
||||
GError *error = NULL;
|
||||
GIOStatus status;
|
||||
|
||||
status = g_io_channel_read_line (channel, &line, NULL, NULL, &error);
|
||||
|
||||
if (line)
|
||||
{
|
||||
process_line (view, line, !stdout);
|
||||
g_free (line);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (condition & (G_IO_ERR | G_IO_HUP))
|
||||
return FALSE;
|
||||
|
||||
if (status == G_IO_STATUS_EOF)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
command_out (GIOChannel *channel,
|
||||
GIOCondition condition,
|
||||
MooCmdView *view)
|
||||
{
|
||||
return command_out_or_err (view, channel, condition, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
command_err (GIOChannel *channel,
|
||||
GIOCondition condition,
|
||||
MooCmdView *view)
|
||||
{
|
||||
return command_out_or_err (view, channel, condition, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
try_channel_leftover (MooCmdView *view,
|
||||
GIOChannel *channel,
|
||||
gboolean stdout)
|
||||
{
|
||||
char *text;
|
||||
|
||||
g_io_channel_read_to_end (channel, &text, NULL, NULL);
|
||||
|
||||
if (text)
|
||||
{
|
||||
char **lines, **p;
|
||||
g_strdelimit (text, "\r", '\n');
|
||||
lines = g_strsplit (text, "\n", 0);
|
||||
|
||||
if (lines)
|
||||
{
|
||||
for (p = lines; *p != NULL; p++)
|
||||
if (**p)
|
||||
process_line (view, *p, !stdout);
|
||||
}
|
||||
|
||||
g_strfreev (lines);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
stdout_watch_removed (MooCmdView *view)
|
||||
{
|
||||
if (view->priv->stdout_io)
|
||||
{
|
||||
try_channel_leftover (view, view->priv->stdout_io, TRUE);
|
||||
g_io_channel_unref (view->priv->stdout_io);
|
||||
}
|
||||
|
||||
view->priv->stdout_io = NULL;
|
||||
view->priv->stdout_watch = 0;
|
||||
moo_cmd_view_check_stop (view);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
stderr_watch_removed (MooCmdView *view)
|
||||
{
|
||||
if (view->priv->stderr_io)
|
||||
{
|
||||
try_channel_leftover (view, view->priv->stderr_io, TRUE);
|
||||
g_io_channel_unref (view->priv->stderr_io);
|
||||
}
|
||||
|
||||
view->priv->stderr_io = NULL;
|
||||
view->priv->stderr_watch = 0;
|
||||
moo_cmd_view_check_stop (view);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
moo_cmd_view_run_command (MooCmdView *view,
|
||||
const char *cmd)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char **argv = NULL;
|
||||
gboolean result = TRUE;
|
||||
|
||||
g_return_val_if_fail (MOO_IS_CMD_VIEW (view), FALSE);
|
||||
g_return_val_if_fail (cmd && cmd[0], FALSE);
|
||||
|
||||
g_return_val_if_fail (!view->priv->running, FALSE);
|
||||
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view), cmd, -1,
|
||||
view->priv->message_tag);
|
||||
|
||||
argv = g_new (char*, 4);
|
||||
argv[0] = g_strdup ("/bin/sh");
|
||||
argv[1] = g_strdup ("-c");
|
||||
argv[2] = g_strdup (cmd);
|
||||
argv[3] = NULL;
|
||||
|
||||
g_spawn_async_with_pipes (NULL,
|
||||
argv, NULL,
|
||||
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL, NULL,
|
||||
&view->priv->pid,
|
||||
NULL,
|
||||
&view->priv->stdout,
|
||||
&view->priv->stderr,
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view),
|
||||
error->message, -1,
|
||||
view->priv->error_tag);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
view->priv->running = TRUE;
|
||||
view->priv->cmd = g_strdup (cmd);
|
||||
|
||||
view->priv->child_watch =
|
||||
g_child_watch_add (view->priv->pid,
|
||||
(GChildWatchFunc) command_exit,
|
||||
view);
|
||||
|
||||
view->priv->stdout_io = g_io_channel_unix_new (view->priv->stdout);
|
||||
g_io_channel_set_encoding (view->priv->stdout_io, NULL, NULL);
|
||||
g_io_channel_set_buffered (view->priv->stdout_io, TRUE);
|
||||
g_io_channel_set_flags (view->priv->stdout_io, G_IO_FLAG_NONBLOCK, NULL);
|
||||
g_io_channel_set_close_on_unref (view->priv->stdout_io, TRUE);
|
||||
view->priv->stdout_watch =
|
||||
g_io_add_watch_full (view->priv->stdout_io,
|
||||
G_PRIORITY_DEFAULT_IDLE,
|
||||
G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
|
||||
(GIOFunc) command_out, view,
|
||||
(GDestroyNotify) stdout_watch_removed);
|
||||
|
||||
view->priv->stderr_io = g_io_channel_unix_new (view->priv->stderr);
|
||||
g_io_channel_set_encoding (view->priv->stderr_io, NULL, NULL);
|
||||
g_io_channel_set_buffered (view->priv->stderr_io, TRUE);
|
||||
g_io_channel_set_flags (view->priv->stderr_io, G_IO_FLAG_NONBLOCK, NULL);
|
||||
g_io_channel_set_close_on_unref (view->priv->stderr_io, TRUE);
|
||||
view->priv->stderr_watch =
|
||||
g_io_add_watch_full (view->priv->stderr_io,
|
||||
G_PRIORITY_DEFAULT_IDLE,
|
||||
G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
|
||||
(GIOFunc) command_err, view,
|
||||
(GDestroyNotify) stderr_watch_removed);
|
||||
|
||||
out:
|
||||
g_strfreev (argv);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_cmd_view_check_stop (MooCmdView *view)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
if (!view->priv->running)
|
||||
return;
|
||||
|
||||
if (!view->priv->child_watch && !view->priv->stdout_watch && !view->priv->stderr_watch)
|
||||
{
|
||||
g_signal_emit (view, signals[CMD_EXIT], 0, view->priv->exit_status, &result);
|
||||
moo_cmd_view_cleanup (view);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
moo_cmd_view_cmd_exit (MooCmdView *view,
|
||||
int status)
|
||||
{
|
||||
if (WIFEXITED (status))
|
||||
{
|
||||
guint8 exit_code = WEXITSTATUS (status);
|
||||
|
||||
if (!exit_code)
|
||||
{
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view),
|
||||
"*** Done ***", -1,
|
||||
view->priv->message_tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *msg = g_strdup_printf ("*** Failed with code %d ***",
|
||||
exit_code);
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view),
|
||||
msg, -1,
|
||||
view->priv->error_tag);
|
||||
g_free (msg);
|
||||
}
|
||||
}
|
||||
#ifdef WCOREDUMP
|
||||
else if (WCOREDUMP (status))
|
||||
{
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view),
|
||||
"*** Dumped core ***", -1,
|
||||
view->priv->error_tag);
|
||||
}
|
||||
#endif
|
||||
else if (WIFSIGNALED (status))
|
||||
{
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view),
|
||||
"*** Killed ***", -1,
|
||||
view->priv->error_tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view),
|
||||
"*** ??? ***", -1,
|
||||
view->priv->error_tag);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_cmd_view_cleanup (MooCmdView *view)
|
||||
{
|
||||
if (!view->priv->running)
|
||||
return;
|
||||
|
||||
view->priv->running = FALSE;
|
||||
|
||||
if (view->priv->child_watch)
|
||||
g_source_remove (view->priv->child_watch);
|
||||
if (view->priv->stdout_watch)
|
||||
g_source_remove (view->priv->stdout_watch);
|
||||
if (view->priv->stderr_watch)
|
||||
g_source_remove (view->priv->stderr_watch);
|
||||
|
||||
if (view->priv->stdout_io)
|
||||
g_io_channel_unref (view->priv->stdout_io);
|
||||
if (view->priv->stderr_io)
|
||||
g_io_channel_unref (view->priv->stderr_io);
|
||||
|
||||
if (view->priv->pid)
|
||||
{
|
||||
kill (view->priv->pid, SIGTERM);
|
||||
g_spawn_close_pid (view->priv->pid);
|
||||
}
|
||||
|
||||
g_free (view->priv->cmd);
|
||||
view->priv->cmd = NULL;
|
||||
view->priv->pid = 0;
|
||||
view->priv->stdout = -1;
|
||||
view->priv->stderr = -1;
|
||||
view->priv->child_watch = 0;
|
||||
view->priv->stdout_watch = 0;
|
||||
view->priv->stderr_watch = 0;
|
||||
view->priv->stdout_io = NULL;
|
||||
view->priv->stderr_io = NULL;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
moo_cmd_view_abort_real (MooCmdView *view)
|
||||
{
|
||||
if (!view->priv->running)
|
||||
return TRUE;
|
||||
|
||||
g_return_val_if_fail (view->priv->pid != 0, TRUE);
|
||||
|
||||
kill (view->priv->pid, SIGTERM);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
moo_cmd_view_abort (MooCmdView *view)
|
||||
{
|
||||
gboolean handled;
|
||||
g_return_if_fail (MOO_IS_CMD_VIEW (view));
|
||||
g_signal_emit (view, signals[ABORT], 0, &handled);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
moo_cmd_view_stdout_line (MooCmdView *view,
|
||||
const char *line)
|
||||
{
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view), line, -1,
|
||||
view->priv->stdout_tag);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
moo_cmd_view_stderr_line (MooCmdView *view,
|
||||
const char *line)
|
||||
{
|
||||
moo_pane_view_write_line (MOO_PANE_VIEW (view), line, -1,
|
||||
view->priv->stderr_tag);
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
* moocmdview.h
|
||||
*
|
||||
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* See COPYING file that comes with this distribution.
|
||||
*/
|
||||
|
||||
#ifndef __MOO_CMD_VIEW__
|
||||
#define __MOO_CMD_VIEW__
|
||||
|
||||
#include "mooedit/moopaneview.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define MOO_TYPE_CMD_VIEW (moo_cmd_view_get_type ())
|
||||
#define MOO_CMD_VIEW(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), MOO_TYPE_CMD_VIEW, MooCmdView))
|
||||
#define MOO_CMD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOO_TYPE_CMD_VIEW, MooCmdViewClass))
|
||||
#define MOO_IS_CMD_VIEW(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), MOO_TYPE_CMD_VIEW))
|
||||
#define MOO_IS_CMD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOO_TYPE_CMD_VIEW))
|
||||
#define MOO_CMD_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOO_TYPE_CMD_VIEW, MooCmdViewClass))
|
||||
|
||||
|
||||
typedef struct _MooCmdView MooCmdView;
|
||||
typedef struct _MooCmdViewPrivate MooCmdViewPrivate;
|
||||
typedef struct _MooCmdViewClass MooCmdViewClass;
|
||||
|
||||
struct _MooCmdView
|
||||
{
|
||||
MooPaneView parent;
|
||||
MooCmdViewPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MooCmdViewClass
|
||||
{
|
||||
MooPaneViewClass parent_class;
|
||||
|
||||
/* action signal */
|
||||
gboolean (*abort) (MooCmdView *view);
|
||||
|
||||
gboolean (*cmd_exit) (MooCmdView *view,
|
||||
int status);
|
||||
gboolean (*output_line) (MooCmdView *view,
|
||||
const char *line,
|
||||
gboolean std_err);
|
||||
gboolean (*stdout_line) (MooCmdView *view,
|
||||
const char *line);
|
||||
gboolean (*stderr_line) (MooCmdView *view,
|
||||
const char *line);
|
||||
};
|
||||
|
||||
|
||||
GType moo_cmd_view_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget *moo_cmd_view_new (void);
|
||||
|
||||
gboolean moo_cmd_view_run_command (MooCmdView *view,
|
||||
const char *cmd);
|
||||
void moo_cmd_view_abort (MooCmdView *view);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __MOO_CMD_VIEW__ */
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#include "mooedit/moopaneview.h"
|
||||
#include "mooutils/moomarshals.h"
|
||||
#include "mooutils/moosignal.h"
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
|
||||
struct _MooPaneViewPrivate {
|
||||
|
@ -47,12 +49,23 @@ static void moo_pane_view_realize (GtkWidget *widget);
|
|||
static gboolean moo_pane_view_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
|
||||
static void moo_pane_view_move_cursor (GtkTextView *text_view,
|
||||
GtkMovementStep step,
|
||||
gint count,
|
||||
gboolean extend_selection);
|
||||
|
||||
static gboolean activate (MooPaneView *view,
|
||||
int line);
|
||||
static void activate_current_line (MooPaneView *view);
|
||||
|
||||
|
||||
static GtkTextBuffer *get_buffer (MooPaneView *view);
|
||||
static GHashTable *get_hash_table (MooPaneView *view);
|
||||
|
||||
|
||||
enum {
|
||||
CLICK,
|
||||
ACTIVATE,
|
||||
ACTIVATE_CURRENT_LINE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
@ -72,6 +85,8 @@ static void moo_pane_view_class_init (MooPaneViewClass *klass)
|
|||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
GtkTextViewClass *textview_class = GTK_TEXT_VIEW_CLASS (klass);
|
||||
GtkBindingSet *binding_set;
|
||||
|
||||
// gobject_class->set_property = moo_pane_view_set_property;
|
||||
// gobject_class->get_property = moo_pane_view_get_property;
|
||||
|
@ -80,15 +95,31 @@ static void moo_pane_view_class_init (MooPaneViewClass *klass)
|
|||
widget_class->realize = moo_pane_view_realize;
|
||||
widget_class->button_press_event = moo_pane_view_button_press;
|
||||
|
||||
signals[CLICK] =
|
||||
g_signal_new ("click",
|
||||
textview_class->move_cursor = moo_pane_view_move_cursor;
|
||||
|
||||
signals[ACTIVATE] =
|
||||
g_signal_new ("activate",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MooPaneViewClass, click),
|
||||
G_STRUCT_OFFSET (MooPaneViewClass, activate),
|
||||
g_signal_accumulator_true_handled, NULL,
|
||||
_moo_marshal_BOOL__POINTER_INT,
|
||||
G_TYPE_BOOLEAN, 2,
|
||||
G_TYPE_POINTER, G_TYPE_INT);
|
||||
|
||||
signals[ACTIVATE_CURRENT_LINE] =
|
||||
moo_signal_new_cb ("activate-current-line",
|
||||
G_OBJECT_CLASS_TYPE (klass),
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||
G_CALLBACK (activate_current_line),
|
||||
NULL, NULL,
|
||||
_moo_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
binding_set = gtk_binding_set_by_class (klass);
|
||||
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
|
||||
"activate-current-line", 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,9 +228,8 @@ moo_pane_view_button_press (GtkWidget *widget,
|
|||
{
|
||||
GtkTextView *textview = GTK_TEXT_VIEW (widget);
|
||||
MooPaneView *view = MOO_PANE_VIEW (widget);
|
||||
int buffer_x, buffer_y, line;
|
||||
int buffer_x, buffer_y;
|
||||
GtkTextIter iter;
|
||||
gpointer data;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
if (gtk_text_view_get_window_type (textview, event->window) == GTK_TEXT_WINDOW_TEXT)
|
||||
|
@ -211,10 +241,7 @@ moo_pane_view_button_press (GtkWidget *widget,
|
|||
/* XXX */
|
||||
gtk_text_view_get_line_at_y (textview, &iter, buffer_y, NULL);
|
||||
|
||||
line = gtk_text_iter_get_line (&iter);
|
||||
data = moo_pane_view_get_line_data (view, line);
|
||||
|
||||
g_signal_emit (view, signals[CLICK], 0, data, line, &handled);
|
||||
handled = activate (view, gtk_text_iter_get_line (&iter));
|
||||
|
||||
if (handled)
|
||||
gtk_text_buffer_place_cursor (get_buffer (view), &iter);
|
||||
|
@ -227,6 +254,134 @@ moo_pane_view_button_press (GtkWidget *widget,
|
|||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
activate (MooPaneView *view,
|
||||
int line)
|
||||
{
|
||||
gboolean handled = FALSE;
|
||||
gpointer data = moo_pane_view_get_line_data (view, line);
|
||||
|
||||
g_signal_emit (view, signals[ACTIVATE], 0, data, line, &handled);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_current_line (MooPaneView *view)
|
||||
{
|
||||
GtkTextIter iter;
|
||||
GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
|
||||
return gtk_text_iter_get_line (&iter);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
activate_current_line (MooPaneView *view)
|
||||
{
|
||||
activate (view, get_current_line (view));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
get_visible_height (GtkTextView *text_view)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GtkTextIter iter;
|
||||
int start, end;
|
||||
|
||||
gtk_text_view_get_visible_rect (text_view, &rect);
|
||||
gtk_text_view_get_line_at_y (text_view, &iter, rect.y, NULL);
|
||||
start = gtk_text_iter_get_line (&iter);
|
||||
gtk_text_view_get_line_at_y (text_view, &iter, rect.y + rect.height - 1, NULL);
|
||||
end = gtk_text_iter_get_line (&iter);
|
||||
|
||||
return end - start + 1;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
moo_pane_view_move_cursor (GtkTextView *text_view,
|
||||
GtkMovementStep step,
|
||||
gint count,
|
||||
gboolean extend_selection)
|
||||
{
|
||||
gboolean handle;
|
||||
MooPaneView *view;
|
||||
GtkTextBuffer *buffer;
|
||||
int current_line, new_line, height, total;
|
||||
GtkTextIter iter;
|
||||
|
||||
switch (step)
|
||||
{
|
||||
case GTK_MOVEMENT_LOGICAL_POSITIONS:
|
||||
case GTK_MOVEMENT_VISUAL_POSITIONS:
|
||||
case GTK_MOVEMENT_WORDS:
|
||||
case GTK_MOVEMENT_PARAGRAPH_ENDS:
|
||||
case GTK_MOVEMENT_HORIZONTAL_PAGES:
|
||||
handle = FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
handle = TRUE;
|
||||
}
|
||||
|
||||
if (extend_selection)
|
||||
handle = FALSE;
|
||||
|
||||
if (!handle)
|
||||
return GTK_TEXT_VIEW_CLASS(moo_pane_view_parent_class)->move_cursor (text_view, step, count, extend_selection);
|
||||
|
||||
view = MOO_PANE_VIEW (text_view);
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
|
||||
current_line = get_current_line (view);
|
||||
|
||||
height = get_visible_height (text_view);
|
||||
total = gtk_text_buffer_get_line_count (buffer);
|
||||
|
||||
switch (step)
|
||||
{
|
||||
case GTK_MOVEMENT_DISPLAY_LINES:
|
||||
case GTK_MOVEMENT_PARAGRAPHS:
|
||||
new_line = current_line + count;
|
||||
break;
|
||||
|
||||
case GTK_MOVEMENT_PAGES:
|
||||
new_line = current_line + count * (height - 1);
|
||||
break;
|
||||
|
||||
case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
|
||||
case GTK_MOVEMENT_BUFFER_ENDS:
|
||||
if (count < 0)
|
||||
new_line = 0;
|
||||
else
|
||||
new_line = total - 1;
|
||||
break;
|
||||
|
||||
case GTK_MOVEMENT_LOGICAL_POSITIONS:
|
||||
case GTK_MOVEMENT_VISUAL_POSITIONS:
|
||||
case GTK_MOVEMENT_WORDS:
|
||||
case GTK_MOVEMENT_PARAGRAPH_ENDS:
|
||||
case GTK_MOVEMENT_HORIZONTAL_PAGES:
|
||||
g_return_if_reached ();
|
||||
}
|
||||
|
||||
new_line = CLAMP (new_line, 0, total - 1);
|
||||
gtk_text_buffer_get_iter_at_line (buffer, &iter, new_line);
|
||||
gtk_text_buffer_place_cursor (buffer, &iter);
|
||||
gtk_text_view_scroll_to_mark (text_view,
|
||||
gtk_text_buffer_get_insert (buffer),
|
||||
0, FALSE, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
static gboolean activate (MooPaneView *view,
|
||||
int line);
|
||||
|
||||
|
||||
static void
|
||||
moo_pane_view_realize (GtkWidget *widget)
|
||||
{
|
||||
|
|
|
@ -42,7 +42,7 @@ struct _MooPaneViewClass
|
|||
{
|
||||
MooTextViewClass parent_class;
|
||||
|
||||
gboolean (*click) (MooPaneView *view,
|
||||
gboolean (*activate) (MooPaneView *view,
|
||||
gpointer line_data,
|
||||
int line);
|
||||
};
|
||||
|
|
|
@ -1042,3 +1042,20 @@ moo_text_view_set_show_tabs (MooTextView *view,
|
|||
if (GTK_WIDGET_DRAWABLE (view))
|
||||
gtk_widget_queue_draw (GTK_WIDGET (view));
|
||||
}
|
||||
|
||||
|
||||
GtkTextTag*
|
||||
moo_text_view_lookup_tag (MooTextView *view,
|
||||
const char *name)
|
||||
{
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextTagTable *table;
|
||||
|
||||
g_return_val_if_fail (MOO_IS_TEXT_VIEW (view), NULL);
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
buffer = get_buffer (view);
|
||||
table = gtk_text_buffer_get_tag_table (buffer);
|
||||
|
||||
return gtk_text_tag_table_lookup (table, name);
|
||||
}
|
||||
|
|
|
@ -130,6 +130,9 @@ void moo_text_view_set_current_line_color (MooTextView *view,
|
|||
void moo_text_view_set_show_tabs (MooTextView *view,
|
||||
gboolean show);
|
||||
|
||||
GtkTextTag *moo_text_view_lookup_tag (MooTextView *view,
|
||||
const char *name);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -31,12 +31,12 @@ noinst_LTLIBRARIES = libplugins.la
|
|||
libplugins_la_SOURCES = \
|
||||
mooeditplugins.h \
|
||||
fileselector.c \
|
||||
moogrep.c \
|
||||
moogrep-glade.h
|
||||
moofind.c \
|
||||
moofind-glade.h
|
||||
|
||||
BUILT_SOURCES = moogrep-glade.h
|
||||
EXTRA_DIST = moogrep.glade
|
||||
BUILT_SOURCES = moofind-glade.h
|
||||
EXTRA_DIST = moofind.glade
|
||||
|
||||
moogrep-glade.h: moogrep.glade
|
||||
sh $(srcdir)/../../mooutils/xml2h.sh MOO_GREP_GLADE_XML $(srcdir)/moogrep.glade > \
|
||||
moogrep-glade.h
|
||||
moofind-glade.h: moofind.glade
|
||||
sh $(srcdir)/../../mooutils/xml2h.sh MOO_FIND_GLADE_XML $(srcdir)/moofind.glade > \
|
||||
moofind-glade.h
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
gboolean moo_grep_init (void);
|
||||
gboolean moo_find_init (void);
|
||||
gboolean moo_file_selector_init (void);
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4; coding: utf-8 -*-
|
||||
*
|
||||
* moogrep.c
|
||||
* moofind.c
|
||||
*
|
||||
* Copyright (C) 2004-2005 by Yevgen Muntyan <muntyan@math.tamu.edu>
|
||||
*
|
||||
|
@ -20,10 +20,10 @@
|
|||
#endif
|
||||
|
||||
#include "mooedit/mooplugin.h"
|
||||
#include "mooedit/plugins/moogrep-glade.h"
|
||||
#include "mooedit/plugins/moofind-glade.h"
|
||||
#include "mooedit/plugins/mooeditplugins.h"
|
||||
#include "mooedit/moofileview/moofileentry.h"
|
||||
#include "mooedit/moopaneview.h"
|
||||
#include "mooedit/moocmdview.h"
|
||||
#include "mooui/moouiobject.h"
|
||||
#include "mooutils/moostock.h"
|
||||
#include "mooutils/mooglade.h"
|
||||
|
@ -32,7 +32,7 @@
|
|||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define GREP_PLUGIN_ID "grep"
|
||||
#define FIND_PLUGIN_ID "find"
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -40,22 +40,14 @@ typedef struct {
|
|||
MooGladeXML *xml;
|
||||
MooFileEntryCompletion *completion;
|
||||
MooEditWindow *window;
|
||||
MooPaneView *output;
|
||||
MooCmdView *output;
|
||||
GtkTextTag *line_number_tag;
|
||||
GtkTextTag *match_tag;
|
||||
GtkTextTag *file_tag;
|
||||
GtkTextTag *error_tag;
|
||||
GtkTextTag *message_tag;
|
||||
char *current_file;
|
||||
gboolean running;
|
||||
int exit_status;
|
||||
GPid pid;
|
||||
int stdout;
|
||||
int stderr;
|
||||
GIOChannel *stdout_io;
|
||||
GIOChannel *stderr_io;
|
||||
guint child_watch;
|
||||
guint stdout_watch;
|
||||
guint stderr_watch;
|
||||
guint match_count;
|
||||
} WindowStuff;
|
||||
|
||||
typedef struct {
|
||||
|
@ -66,8 +58,8 @@ typedef struct {
|
|||
static WindowStuff *window_stuff_new (MooEditWindow *window);
|
||||
static void window_stuff_free (WindowStuff *stuff);
|
||||
|
||||
static void grep_plugin_attach (MooEditWindow *window);
|
||||
static void grep_plugin_detach (MooEditWindow *window);
|
||||
static void find_plugin_attach (MooEditWindow *window);
|
||||
static void find_plugin_detach (MooEditWindow *window);
|
||||
|
||||
static void do_find (MooEditWindow *window,
|
||||
WindowStuff *stuff);
|
||||
|
@ -81,10 +73,15 @@ static void execute_find (const char *pattern,
|
|||
const char *skip_files,
|
||||
gboolean case_sensitive,
|
||||
WindowStuff *stuff);
|
||||
static void stop_find (WindowStuff *stuff);
|
||||
static gboolean output_click (WindowStuff *stuff,
|
||||
static gboolean output_activate (WindowStuff *stuff,
|
||||
FileLinePair *line_data);
|
||||
static void check_find_stop (WindowStuff *stuff);
|
||||
|
||||
static gboolean command_exit (MooPaneView *view,
|
||||
int status,
|
||||
WindowStuff *stuff);
|
||||
static gboolean process_line (MooPaneView *view,
|
||||
const char *line,
|
||||
WindowStuff *stuff);
|
||||
|
||||
|
||||
static void
|
||||
|
@ -93,7 +90,7 @@ find_in_files_cb (MooEditWindow *window)
|
|||
WindowStuff *stuff;
|
||||
int response;
|
||||
|
||||
stuff = moo_plugin_get_window_data (GREP_PLUGIN_ID, window);
|
||||
stuff = moo_plugin_get_window_data (FIND_PLUGIN_ID, window);
|
||||
g_return_if_fail (stuff != NULL);
|
||||
|
||||
if (!stuff->dialog)
|
||||
|
@ -113,32 +110,38 @@ find_in_files_cb (MooEditWindow *window)
|
|||
|
||||
|
||||
static void
|
||||
grep_plugin_attach (MooEditWindow *window)
|
||||
find_plugin_attach (MooEditWindow *window)
|
||||
{
|
||||
GtkWidget *swin;
|
||||
MooPaneLabel *label;
|
||||
WindowStuff *stuff = window_stuff_new (window);
|
||||
|
||||
label = moo_pane_label_new (MOO_STOCK_GREP, NULL, NULL, "Find in Files");
|
||||
stuff->output = g_object_new (MOO_TYPE_PANE_VIEW,
|
||||
label = moo_pane_label_new (MOO_STOCK_FIND_IN_FILES, NULL, NULL, "Find");
|
||||
stuff->output = g_object_new (MOO_TYPE_CMD_VIEW,
|
||||
"highlight-current-line", TRUE,
|
||||
NULL);
|
||||
|
||||
g_signal_connect_swapped (stuff->output, "click",
|
||||
G_CALLBACK (output_click), stuff);
|
||||
g_signal_connect_swapped (stuff->output, "activate",
|
||||
G_CALLBACK (output_activate), stuff);
|
||||
|
||||
stuff->line_number_tag = moo_pane_view_create_tag (stuff->output, NULL,
|
||||
"weight", PANGO_WEIGHT_BOLD,
|
||||
NULL);
|
||||
stuff->match_tag = moo_pane_view_create_tag (stuff->output, NULL,
|
||||
"foreground", "blue",
|
||||
NULL);
|
||||
stuff->file_tag = moo_pane_view_create_tag (stuff->output, NULL,
|
||||
"foreground", "green",
|
||||
NULL);
|
||||
stuff->error_tag = moo_pane_view_create_tag (stuff->output, NULL,
|
||||
"foreground", "red",
|
||||
NULL);
|
||||
stuff->line_number_tag =
|
||||
moo_pane_view_create_tag (MOO_PANE_VIEW (stuff->output),
|
||||
NULL, "weight", PANGO_WEIGHT_BOLD, NULL);
|
||||
stuff->match_tag =
|
||||
moo_pane_view_create_tag (MOO_PANE_VIEW (stuff->output), NULL,
|
||||
"foreground", "blue", NULL);
|
||||
stuff->file_tag =
|
||||
moo_pane_view_create_tag (MOO_PANE_VIEW (stuff->output), NULL,
|
||||
"foreground", "green", NULL);
|
||||
stuff->error_tag =
|
||||
moo_text_view_lookup_tag (MOO_TEXT_VIEW (stuff->output), "error");
|
||||
stuff->message_tag =
|
||||
moo_text_view_lookup_tag (MOO_TEXT_VIEW (stuff->output), "message");
|
||||
|
||||
g_signal_connect (stuff->output, "cmd-exit",
|
||||
G_CALLBACK (command_exit), stuff);
|
||||
g_signal_connect (stuff->output, "stdout-line",
|
||||
G_CALLBACK (process_line), stuff);
|
||||
|
||||
swin = gtk_scrolled_window_new (NULL, NULL);
|
||||
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin),
|
||||
|
@ -149,10 +152,10 @@ grep_plugin_attach (MooEditWindow *window)
|
|||
gtk_container_add (GTK_CONTAINER (swin), GTK_WIDGET (stuff->output));
|
||||
gtk_widget_show_all (swin);
|
||||
|
||||
moo_edit_window_add_pane (window, GREP_PLUGIN_ID,
|
||||
moo_edit_window_add_pane (window, FIND_PLUGIN_ID,
|
||||
swin, label, MOO_PANE_POS_BOTTOM);
|
||||
|
||||
moo_plugin_set_window_data (GREP_PLUGIN_ID, window, stuff,
|
||||
moo_plugin_set_window_data (FIND_PLUGIN_ID, window, stuff,
|
||||
(GDestroyNotify) window_stuff_free);
|
||||
}
|
||||
|
||||
|
@ -184,7 +187,7 @@ window_stuff_free (WindowStuff *stuff)
|
|||
|
||||
|
||||
static gboolean
|
||||
grep_plugin_init (void)
|
||||
find_plugin_init (void)
|
||||
{
|
||||
GObjectClass *klass = g_type_class_ref (MOO_TYPE_EDIT_WINDOW);
|
||||
g_return_val_if_fail (klass != NULL, FALSE);
|
||||
|
@ -194,7 +197,7 @@ grep_plugin_init (void)
|
|||
"name", "Find In Files",
|
||||
"label", "Find In Files",
|
||||
"tooltip", "Find In Files",
|
||||
"icon-stock-id", MOO_STOCK_GREP,
|
||||
"icon-stock-id", MOO_STOCK_FIND_IN_FILES,
|
||||
"closure::callback", find_in_files_cb,
|
||||
NULL);
|
||||
|
||||
|
@ -204,14 +207,14 @@ grep_plugin_init (void)
|
|||
|
||||
|
||||
static void
|
||||
grep_plugin_deinit (void)
|
||||
find_plugin_deinit (void)
|
||||
{
|
||||
/* XXX remove action */
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
moo_grep_init (void)
|
||||
moo_find_init (void)
|
||||
{
|
||||
MooPluginParams params = { TRUE };
|
||||
MooPluginPrefsParams prefs_params;
|
||||
|
@ -219,16 +222,16 @@ moo_grep_init (void)
|
|||
MooPluginInfo info = {
|
||||
MOO_PLUGIN_CURRENT_VERSION,
|
||||
|
||||
GREP_PLUGIN_ID,
|
||||
GREP_PLUGIN_ID,
|
||||
GREP_PLUGIN_ID,
|
||||
FIND_PLUGIN_ID,
|
||||
FIND_PLUGIN_ID,
|
||||
FIND_PLUGIN_ID,
|
||||
"Yevgen Muntyan <muntyan@tamu.edu>",
|
||||
MOO_VERSION,
|
||||
|
||||
(MooPluginInitFunc) grep_plugin_init,
|
||||
(MooPluginDeinitFunc) grep_plugin_deinit,
|
||||
(MooPluginWindowAttachFunc) grep_plugin_attach,
|
||||
(MooPluginWindowDetachFunc) grep_plugin_detach,
|
||||
(MooPluginInitFunc) find_plugin_init,
|
||||
(MooPluginDeinitFunc) find_plugin_deinit,
|
||||
(MooPluginWindowAttachFunc) find_plugin_attach,
|
||||
(MooPluginWindowDetachFunc) find_plugin_detach,
|
||||
|
||||
¶ms,
|
||||
&prefs_params
|
||||
|
@ -252,9 +255,9 @@ static void
|
|||
create_dialog (MooEditWindow *window,
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
GtkWidget *dir_entry, *pattern_entry;
|
||||
GtkWidget *dir_entry, *pattern_entry, *glob_entry, *skip_entry;
|
||||
|
||||
stuff->xml = moo_glade_xml_new_from_buf (MOO_GREP_GLADE_XML, -1, NULL, NULL);
|
||||
stuff->xml = moo_glade_xml_new_from_buf (MOO_FIND_GLADE_XML, -1, "dialog", NULL);
|
||||
g_return_if_fail (stuff->xml != NULL);
|
||||
|
||||
stuff->dialog = moo_glade_xml_get_widget (stuff->xml, "dialog");
|
||||
|
@ -283,6 +286,17 @@ create_dialog (MooEditWindow *window,
|
|||
"show-hidden", FALSE,
|
||||
NULL);
|
||||
moo_file_entry_completion_set_entry (stuff->completion, GTK_ENTRY (dir_entry));
|
||||
|
||||
glob_entry = moo_glade_xml_get_widget (stuff->xml, "glob_combo");
|
||||
glob_entry = GTK_BIN(glob_entry)->child;
|
||||
|
||||
skip_entry = moo_glade_xml_get_widget (stuff->xml, "skip_combo");
|
||||
skip_entry = GTK_BIN(skip_entry)->child;
|
||||
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (pattern_entry), TRUE);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (dir_entry), TRUE);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (glob_entry), TRUE);
|
||||
gtk_entry_set_activates_default (GTK_ENTRY (skip_entry), TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -339,7 +353,7 @@ do_find (MooEditWindow *window,
|
|||
gboolean case_sensitive;
|
||||
char *dir;
|
||||
|
||||
pane = moo_edit_window_get_pane (window, GREP_PLUGIN_ID);
|
||||
pane = moo_edit_window_get_pane (window, FIND_PLUGIN_ID);
|
||||
g_return_if_fail (pane != NULL);
|
||||
|
||||
dir_entry = GTK_BIN (moo_glade_xml_get_widget (stuff->xml, "dir_combo"))->child;
|
||||
|
@ -357,7 +371,7 @@ do_find (MooEditWindow *window,
|
|||
skip = gtk_entry_get_text (GTK_ENTRY (skip_entry));
|
||||
case_sensitive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (case_sensitive_button));
|
||||
|
||||
moo_pane_view_clear (stuff->output);
|
||||
moo_pane_view_clear (MOO_PANE_VIEW (stuff->output));
|
||||
moo_big_paned_present_pane (window->paned, pane);
|
||||
|
||||
execute_find (pattern, glob, dir, skip,
|
||||
|
@ -365,23 +379,6 @@ do_find (MooEditWindow *window,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
command_exit (GPid pid,
|
||||
gint status,
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
g_return_if_fail (pid == stuff->pid);
|
||||
|
||||
stuff->child_watch = 0;
|
||||
stuff->exit_status = status;
|
||||
|
||||
g_spawn_close_pid (stuff->pid);
|
||||
stuff->pid = 0;
|
||||
|
||||
check_find_stop (stuff);
|
||||
}
|
||||
|
||||
|
||||
static FileLinePair*
|
||||
file_line_pair_new (const char *filename,
|
||||
int line)
|
||||
|
@ -404,10 +401,10 @@ file_line_pair_free (FileLinePair *pair)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
process_line (WindowStuff *stuff,
|
||||
static gboolean
|
||||
process_line (MooPaneView *view,
|
||||
const char *line,
|
||||
gboolean stderr)
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
char *filename = NULL;
|
||||
char *number = NULL;
|
||||
|
@ -416,19 +413,9 @@ process_line (WindowStuff *stuff,
|
|||
int line_no;
|
||||
guint64 line_no_64;
|
||||
|
||||
if (stderr)
|
||||
{
|
||||
moo_pane_view_write_line (stuff->output, line, -1,
|
||||
stuff->error_tag);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Binary file blah matches */
|
||||
/* 'Binary file blah matches' */
|
||||
if (g_str_has_prefix (line, "Binary file "))
|
||||
{
|
||||
moo_pane_view_write_line (stuff->output, line, -1, NULL);
|
||||
return;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
p = line;
|
||||
if (!(colon = strchr (p, ':')) || !colon[1])
|
||||
|
@ -447,10 +434,9 @@ process_line (WindowStuff *stuff,
|
|||
{
|
||||
g_free (stuff->current_file);
|
||||
stuff->current_file = filename;
|
||||
view_line = moo_pane_view_write_line (stuff->output,
|
||||
filename, -1,
|
||||
view_line = moo_pane_view_write_line (view, filename, -1,
|
||||
stuff->file_tag);
|
||||
moo_pane_view_set_line_data (stuff->output, view_line,
|
||||
moo_pane_view_set_line_data (view, view_line,
|
||||
file_line_pair_new (filename, -1),
|
||||
(GDestroyNotify) file_line_pair_free);
|
||||
}
|
||||
|
@ -485,135 +471,28 @@ process_line (WindowStuff *stuff,
|
|||
line_no = line_no_64 - 1;
|
||||
}
|
||||
|
||||
view_line = moo_pane_view_start_line (stuff->output);
|
||||
moo_pane_view_write (stuff->output, number, -1,
|
||||
stuff->line_number_tag);
|
||||
moo_pane_view_write (stuff->output, ": ", -1, NULL);
|
||||
moo_pane_view_write (stuff->output, p, -1, stuff->match_tag);
|
||||
moo_pane_view_end_line (stuff->output);
|
||||
view_line = moo_pane_view_start_line (view);
|
||||
moo_pane_view_write (view, number, -1, stuff->line_number_tag);
|
||||
moo_pane_view_write (view, ": ", -1, NULL);
|
||||
moo_pane_view_write (view, p, -1, stuff->match_tag);
|
||||
moo_pane_view_end_line (view);
|
||||
|
||||
moo_pane_view_set_line_data (stuff->output, view_line,
|
||||
moo_pane_view_set_line_data (view, view_line,
|
||||
file_line_pair_new (stuff->current_file, line_no),
|
||||
(GDestroyNotify) file_line_pair_free);
|
||||
stuff->match_count++;
|
||||
|
||||
g_free (number);
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
parse_error:
|
||||
g_warning ("%s: could not parse line '%s'",
|
||||
G_STRLOC, line);
|
||||
moo_pane_view_write_line (stuff->output, line, -1, NULL);
|
||||
g_free (filename);
|
||||
g_free (number);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
command_out_or_err (GIOChannel *channel,
|
||||
GIOCondition condition,
|
||||
gboolean stdout,
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
char *line;
|
||||
GError *error = NULL;
|
||||
GIOStatus status;
|
||||
|
||||
status = g_io_channel_read_line (channel, &line, NULL, NULL, &error);
|
||||
|
||||
if (line)
|
||||
{
|
||||
process_line (stuff, line, !stdout);
|
||||
g_free (line);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_warning ("%s: %s", G_STRLOC, error->message);
|
||||
g_error_free (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (condition & (G_IO_ERR | G_IO_HUP))
|
||||
return FALSE;
|
||||
|
||||
if (status == G_IO_STATUS_EOF)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
command_out (GIOChannel *channel,
|
||||
GIOCondition condition,
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
return command_out_or_err (channel, condition, TRUE, stuff);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
command_err (GIOChannel *channel,
|
||||
GIOCondition condition,
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
return command_out_or_err (channel, condition, FALSE, stuff);
|
||||
}
|
||||
|
||||
static void
|
||||
try_channel_leftover (WindowStuff *stuff,
|
||||
GIOChannel *channel,
|
||||
gboolean stdout)
|
||||
{
|
||||
char *text;
|
||||
|
||||
g_io_channel_read_to_end (channel, &text, NULL, NULL);
|
||||
|
||||
if (text)
|
||||
{
|
||||
char **lines, **p;
|
||||
g_strdelimit (text, "\r", '\n');
|
||||
lines = g_strsplit (text, "\n", 0);
|
||||
|
||||
if (lines)
|
||||
{
|
||||
for (p = lines; *p != NULL; p++)
|
||||
if (**p)
|
||||
process_line (stuff, *p, !stdout);
|
||||
}
|
||||
|
||||
g_strfreev (lines);
|
||||
g_free (text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
stdout_watch_removed (WindowStuff *stuff)
|
||||
{
|
||||
if (stuff->stdout_io)
|
||||
{
|
||||
try_channel_leftover (stuff, stuff->stdout_io, TRUE);
|
||||
g_io_channel_unref (stuff->stdout_io);
|
||||
}
|
||||
|
||||
stuff->stdout_io = NULL;
|
||||
stuff->stdout_watch = 0;
|
||||
check_find_stop (stuff);
|
||||
}
|
||||
|
||||
static void
|
||||
stderr_watch_removed (WindowStuff *stuff)
|
||||
{
|
||||
if (stuff->stderr_io)
|
||||
{
|
||||
try_channel_leftover (stuff, stuff->stderr_io, FALSE);
|
||||
g_io_channel_unref (stuff->stderr_io);
|
||||
}
|
||||
|
||||
stuff->stderr_io = NULL;
|
||||
stuff->stderr_watch = 0;
|
||||
check_find_stop (stuff);
|
||||
}
|
||||
|
||||
static void
|
||||
execute_find (const char *pattern,
|
||||
|
@ -623,19 +502,15 @@ execute_find (const char *pattern,
|
|||
gboolean case_sensitive,
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
GError *error = NULL;
|
||||
char **argv = NULL;
|
||||
GString *command = NULL;
|
||||
char **globs = NULL;
|
||||
|
||||
g_return_if_fail (stuff->output != NULL);
|
||||
g_return_if_fail (pattern && pattern[0]);
|
||||
|
||||
if (stuff->running)
|
||||
return;
|
||||
|
||||
g_free (stuff->current_file);
|
||||
stuff->current_file = NULL;
|
||||
stuff->match_count = 0;
|
||||
|
||||
command = g_string_new ("");
|
||||
g_string_printf (command, "find '%s'", dir);
|
||||
|
@ -687,182 +562,54 @@ execute_find (const char *pattern,
|
|||
g_string_append_printf (command, " | xargs egrep -H -n %s-e '%s'",
|
||||
!case_sensitive ? "-i " : "", pattern);
|
||||
|
||||
moo_pane_view_write_line (stuff->output, command->str, -1, NULL);
|
||||
|
||||
argv = g_new (char*, 4);
|
||||
argv[0] = g_strdup ("/bin/sh");
|
||||
argv[1] = g_strdup ("-c");
|
||||
argv[2] = g_string_free (command, FALSE);
|
||||
argv[3] = NULL;
|
||||
|
||||
g_spawn_async_with_pipes (NULL,
|
||||
argv, NULL,
|
||||
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL, NULL,
|
||||
&stuff->pid,
|
||||
NULL,
|
||||
&stuff->stdout,
|
||||
&stuff->stderr,
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
{
|
||||
moo_pane_view_write_line (stuff->output, error->message, -1,
|
||||
stuff->error_tag);
|
||||
g_error_free (error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
stuff->running = TRUE;
|
||||
|
||||
stuff->child_watch =
|
||||
g_child_watch_add (stuff->pid,
|
||||
(GChildWatchFunc) command_exit,
|
||||
stuff);
|
||||
|
||||
stuff->stdout_io = g_io_channel_unix_new (stuff->stdout);
|
||||
g_io_channel_set_encoding (stuff->stdout_io, NULL, NULL);
|
||||
g_io_channel_set_buffered (stuff->stdout_io, TRUE);
|
||||
g_io_channel_set_flags (stuff->stdout_io, G_IO_FLAG_NONBLOCK, NULL);
|
||||
g_io_channel_set_close_on_unref (stuff->stdout_io, TRUE);
|
||||
stuff->stdout_watch =
|
||||
g_io_add_watch_full (stuff->stdout_io,
|
||||
G_PRIORITY_DEFAULT_IDLE,
|
||||
G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
|
||||
(GIOFunc) command_out, stuff,
|
||||
(GDestroyNotify) stdout_watch_removed);
|
||||
|
||||
stuff->stderr_io = g_io_channel_unix_new (stuff->stderr);
|
||||
g_io_channel_set_encoding (stuff->stderr_io, NULL, NULL);
|
||||
g_io_channel_set_buffered (stuff->stderr_io, TRUE);
|
||||
g_io_channel_set_flags (stuff->stderr_io, G_IO_FLAG_NONBLOCK, NULL);
|
||||
g_io_channel_set_close_on_unref (stuff->stderr_io, TRUE);
|
||||
stuff->stderr_watch =
|
||||
g_io_add_watch_full (stuff->stderr_io,
|
||||
G_PRIORITY_DEFAULT_IDLE,
|
||||
G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
|
||||
(GIOFunc) command_err, stuff,
|
||||
(GDestroyNotify) stderr_watch_removed);
|
||||
|
||||
out:
|
||||
g_strfreev (argv);
|
||||
moo_cmd_view_run_command (stuff->output, command->str);
|
||||
g_string_free (command, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
grep_plugin_detach (MooEditWindow *window)
|
||||
find_plugin_detach (MooEditWindow *window)
|
||||
{
|
||||
WindowStuff *stuff = moo_plugin_get_window_data (GREP_PLUGIN_ID, window);
|
||||
WindowStuff *stuff = moo_plugin_get_window_data (FIND_PLUGIN_ID, window);
|
||||
g_return_if_fail (stuff != NULL);
|
||||
stop_find (stuff);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
stop_find (WindowStuff *stuff)
|
||||
{
|
||||
if (!stuff->running)
|
||||
return;
|
||||
|
||||
stuff->running = FALSE;
|
||||
|
||||
if (stuff->child_watch)
|
||||
g_source_remove (stuff->child_watch);
|
||||
if (stuff->stdout_watch)
|
||||
g_source_remove (stuff->stdout_watch);
|
||||
if (stuff->stderr_watch)
|
||||
g_source_remove (stuff->stderr_watch);
|
||||
|
||||
if (stuff->stdout_io)
|
||||
g_io_channel_unref (stuff->stdout_io);
|
||||
if (stuff->stderr_io)
|
||||
g_io_channel_unref (stuff->stderr_io);
|
||||
|
||||
if (stuff->pid)
|
||||
{
|
||||
kill (stuff->pid, SIGTERM);
|
||||
g_spawn_close_pid (stuff->pid);
|
||||
}
|
||||
|
||||
g_free (stuff->current_file);
|
||||
stuff->current_file = NULL;
|
||||
stuff->pid = 0;
|
||||
stuff->stdout = -1;
|
||||
stuff->stderr = -1;
|
||||
stuff->child_watch = 0;
|
||||
stuff->stdout_watch = 0;
|
||||
stuff->stderr_watch = 0;
|
||||
stuff->stdout_io = NULL;
|
||||
stuff->stderr_io = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
check_find_stop (WindowStuff *stuff)
|
||||
{
|
||||
if (!stuff->running)
|
||||
return;
|
||||
|
||||
if (!stuff->child_watch && !stuff->stdout_watch && !stuff->stderr_watch)
|
||||
{
|
||||
if (WIFEXITED (stuff->exit_status))
|
||||
{
|
||||
guint8 exit_code = WEXITSTATUS (stuff->exit_status);
|
||||
|
||||
/*
|
||||
xargs exits with the following status:
|
||||
0 if it succeeds
|
||||
123 if any invocation of the command exited with status 1-125
|
||||
124 if the command exited with status 255
|
||||
125 if the command is killed by a signal
|
||||
126 if the command cannot be run
|
||||
127 if the command is not found
|
||||
1 if some other error occurred.
|
||||
*/
|
||||
|
||||
if (!exit_code || exit_code == 123)
|
||||
{
|
||||
moo_pane_view_write_line (stuff->output,
|
||||
"*** Done ***", -1,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *msg = g_strdup_printf ("Command failed with status %d",
|
||||
exit_code);
|
||||
moo_pane_view_write_line (stuff->output,
|
||||
msg, -1, stuff->error_tag);
|
||||
g_free (msg);
|
||||
}
|
||||
}
|
||||
#ifdef WCOREDUMP
|
||||
else if (WCOREDUMP (stuff->exit_status))
|
||||
{
|
||||
moo_pane_view_write_line (stuff->output,
|
||||
"*** Dumped core ***", -1,
|
||||
NULL);
|
||||
}
|
||||
#endif
|
||||
else if (WIFSIGNALED (stuff->exit_status))
|
||||
{
|
||||
moo_pane_view_write_line (stuff->output,
|
||||
"*** Killed ***", -1,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
moo_pane_view_write_line (stuff->output,
|
||||
"*** ??? ***", -1,
|
||||
NULL);
|
||||
}
|
||||
|
||||
stop_find (stuff);
|
||||
}
|
||||
g_signal_handlers_disconnect_by_func (stuff->output,
|
||||
(gpointer) command_exit,
|
||||
stuff);
|
||||
g_signal_handlers_disconnect_by_func (stuff->output,
|
||||
(gpointer) process_line,
|
||||
stuff);
|
||||
moo_cmd_view_abort (stuff->output);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
output_click (WindowStuff *stuff,
|
||||
command_exit (MooPaneView *view,
|
||||
int status,
|
||||
WindowStuff *stuff)
|
||||
{
|
||||
if (WIFEXITED (status))
|
||||
{
|
||||
guint8 exit_code = WEXITSTATUS (status);
|
||||
|
||||
/* xargs exits with code 123 if it's command exited with status 1-125*/
|
||||
if (!exit_code || exit_code == 123)
|
||||
{
|
||||
char *msg = g_strdup_printf ("*** %d matches found ***",
|
||||
stuff->match_count);
|
||||
moo_pane_view_write_line (view, msg, -1,
|
||||
stuff->message_tag);
|
||||
g_free (msg);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
output_activate (WindowStuff *stuff,
|
||||
FileLinePair *line_data)
|
||||
{
|
||||
MooEditor *editor;
|
|
@ -332,291 +332,4 @@
|
|||
</child>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkWindow" id="window1">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes">window1</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment3">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0.5</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xscale">1</property>
|
||||
<property name="yscale">1</property>
|
||||
<property name="top_padding">6</property>
|
||||
<property name="bottom_padding">6</property>
|
||||
<property name="left_padding">6</property>
|
||||
<property name="right_padding">6</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="search_vbox">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTable" id="table2">
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">0</property>
|
||||
<property name="column_spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkComboBoxEntry" id="comboboxentry1">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkComboBoxEntry" id="comboboxentry2">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkComboBoxEntry" id="comboboxentry3">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkComboBoxEntry" id="comboboxentry4">
|
||||
<property name="visible">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options">fill</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="eventbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">This entry content will be passed to grep</property>
|
||||
<property name="visible_window">True</property>
|
||||
<property name="above_child">False</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Pattern:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="eventbox6">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Enter semicolon-separated list of globs</property>
|
||||
<property name="visible_window">True</property>
|
||||
<property name="above_child">False</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label7">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Fi_les:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="eventbox7">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">You can use Tab completion in this entry. Try also Ctrl-L</property>
|
||||
<property name="visible_window">True</property>
|
||||
<property name="above_child">False</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Directory:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEventBox" id="eventbox8">
|
||||
<property name="visible">True</property>
|
||||
<property name="tooltip" translatable="yes">Enter semicolon-separated list of globs</property>
|
||||
<property name="visible_window">True</property>
|
||||
<property name="above_child">False</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label9">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Skip files:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">1</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="checkbutton1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">_Case sensitive</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="active">True</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="button3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-find</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">False</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">6</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
|
||||
</glade-interface>
|
|
@ -1,9 +1,11 @@
|
|||
BOOL:ENUM,INT
|
||||
BOOL:ENUM,INT,BOOL
|
||||
BOOL:INT
|
||||
BOOL:OBJECT,OBJECT
|
||||
BOOL:POINTER
|
||||
BOOL:POINTER,INT
|
||||
BOOL:STRING
|
||||
BOOL:STRING,BOOL
|
||||
BOOL:STRING,POINTER
|
||||
BOOL:STRING,STRING
|
||||
BOOL:STRING,STRING,POINTER
|
||||
|
|
|
@ -202,7 +202,8 @@ void moo_create_stock_items (void)
|
|||
register_stock_icon_alias (factory, GTK_STOCK_GO_DOWN, MOO_STOCK_COMPILE);
|
||||
register_stock_icon_alias (factory, GTK_STOCK_EXECUTE, MOO_STOCK_EXECUTE);
|
||||
|
||||
register_stock_icon_alias (factory, GTK_STOCK_FIND, MOO_STOCK_GREP);
|
||||
register_stock_icon_alias (factory, GTK_STOCK_FIND, MOO_STOCK_FIND_IN_FILES);
|
||||
register_stock_icon_alias (factory, GTK_STOCK_FIND, MOO_STOCK_FIND_FILE);
|
||||
|
||||
g_object_unref (G_OBJECT (factory));
|
||||
}
|
||||
|
|
|
@ -49,7 +49,8 @@ G_BEGIN_DECLS
|
|||
#define MOO_STOCK_COMPILE "moo-compile"
|
||||
#define MOO_STOCK_EXECUTE "moo-execute"
|
||||
|
||||
#define MOO_STOCK_GREP "moo-grep"
|
||||
#define MOO_STOCK_FIND_IN_FILES "moo-find-in-files"
|
||||
#define MOO_STOCK_FIND_FILE "moo-find-file"
|
||||
|
||||
|
||||
void moo_create_stock_items (void);
|
||||
|
|
|
@ -44,7 +44,7 @@ int main (int argc, char **argv)
|
|||
moo_plugin_read_dir (plugin_dir);
|
||||
g_free (plugin_dir);
|
||||
|
||||
moo_grep_init ();
|
||||
moo_find_init ();
|
||||
moo_file_selector_init ();
|
||||
|
||||
editor = moo_editor_new ();
|
||||
|
|
Loading…
Reference in New Issue