Added option to execute programs in the VTE instead of executing them in a terminal emulation window (closes #1594456).

git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1078 ea778897-0a13-0410-b9d1-a72fbfd435f5
This commit is contained in:
Enrico Tröger 2006-12-10 21:29:04 +00:00
parent a0da812c93
commit 33425f1a5d
8 changed files with 122 additions and 72 deletions

View File

@ -1,3 +1,11 @@
2006-12-10 Enrico Tröger <enrico.troeger@uvena.de>
* src/build.c, src/callbacks.c, src/document.c, src/keyfile.c,
src/prefs.c, src/vte.c, src/vte.h:
Added option to execute programs in the VTE instead of executing
them in a terminal emulation window (closes #1594456).
2006-12-09 Nick Treleaven <nick.treleaven@btinternet.com>
* src/build.c:
@ -29,7 +37,7 @@
Use ui_button_new_with_image() in dialogs_show_unsaved_file().
2006-12-08 Enrico Troeger <enrico.troeger@uvena.de>
2006-12-08 Enrico Tröger <enrico.troeger@uvena.de>
* src/build.c: Made the created run script for command execution a bit
more portable to other shells than bash (thanks to
@ -41,7 +49,6 @@
* src/msgwindow.c: Removed compiler warning.
* src/sci_cb.c, src/sci_cb.h:
Made sci_cb_get_indent and sci_Cb_auto_multiline static.
* src/sci_cb.c, src/sci_cb.h:
Improved auto completion of multi line comments and support
/+ +/ for D files.
* src/msgwindow.c: Fixed wrong check button state in view menu if

View File

@ -44,6 +44,7 @@
#include "msgwindow.h"
#include "document.h"
#include "keybindings.h"
#include "vte.h"
BuildInfo build_info = {GBO_COMPILE, 0, NULL, GEANY_FILETYPES_ALL, NULL};
@ -493,6 +494,7 @@ GPid build_run_cmd(gint idx)
gchar *executable = NULL;
gchar *script_name;
guint term_argv_len, i;
gboolean autoclose = FALSE;
struct stat st;
if (! DOC_IDX_VALID(idx) || doc_list[idx].file_name == NULL) return (GPid) 1;
@ -589,9 +591,14 @@ GPid build_run_cmd(gint idx)
g_free(tmp);
cmd = utils_str_replace(cmd, "%e", executable);
#ifdef HAVE_VTE
if (vte_info.load_vte && vc != NULL && vc->run_in_vte)
autoclose = TRUE; // don't wait for user input at the end of script when we are running in VTE
#endif
// write a little shellscript to call the executable (similar to anjuta_launcher but "internal")
// (script_name should be ok in UTF8 without converting in locale because it contains no umlauts)
if (! build_create_shellscript(idx, script_name, cmd, FALSE))
if (! build_create_shellscript(idx, script_name, cmd, autoclose))
{
utf8_check_executable = utils_remove_ext_from_filename(doc_list[idx].file_name);
msgwin_status_add(_("Failed to execute %s (start-script could not be created)"),
@ -600,39 +607,60 @@ GPid build_run_cmd(gint idx)
goto free_strings;
}
argv = g_new0(gchar *, term_argv_len + 3);
for (i = 0; i < term_argv_len; i++)
#ifdef HAVE_VTE
if (vte_info.load_vte && vc != NULL && vc->run_in_vte)
{
argv[i] = g_strdup(term_argv[i]);
gchar *cmd = g_strconcat(script_name, "\n", NULL);
// change into current directory if it is not done by default
if (! vc->follow_path) vte_cwd(doc_list[idx].file_name, TRUE);
vte_send_cmd(cmd);
// show the VTE
gtk_notebook_set_current_page(GTK_NOTEBOOK(msgwindow.notebook), MSG_VTE);
gtk_widget_grab_focus(vc->vte);
msgwin_show();
run_info.pid = 1;
g_free(cmd);
}
#ifdef G_OS_WIN32
// command line arguments for cmd.exe
argv[term_argv_len ] = g_strdup("/Q /C");
argv[term_argv_len + 1] = g_path_get_basename(script_name);
#else
argv[term_argv_len ] = g_strdup("-e");
argv[term_argv_len + 1] = g_strdup(script_name);
else
#endif
argv[term_argv_len + 2] = NULL;
if (! g_spawn_async_with_pipes(working_dir, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, &(run_info.pid), NULL, NULL, NULL, &error))
{
geany_debug("g_spawn_async_with_pipes() failed: %s", error->message);
msgwin_status_add(_("Process failed (%s)"), error->message);
unlink(script_name);
g_error_free(error);
error = NULL;
result_id = (GPid) 0;
goto free_strings;
}
argv = g_new0(gchar *, term_argv_len + 3);
for (i = 0; i < term_argv_len; i++)
{
argv[i] = g_strdup(term_argv[i]);
}
#ifdef G_OS_WIN32
// command line arguments for cmd.exe
argv[term_argv_len ] = g_strdup("/Q /C");
argv[term_argv_len + 1] = g_path_get_basename(script_name);
#else
argv[term_argv_len ] = g_strdup("-e");
argv[term_argv_len + 1] = g_strdup(script_name);
#endif
argv[term_argv_len + 2] = NULL;
if (! g_spawn_async_with_pipes(working_dir, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
NULL, NULL, &(run_info.pid), NULL, NULL, NULL, &error))
{
geany_debug("g_spawn_async_with_pipes() failed: %s", error->message);
msgwin_status_add(_("Process failed (%s)"), error->message);
unlink(script_name);
g_error_free(error);
error = NULL;
result_id = (GPid) 0;
goto free_strings;
}
if (run_info.pid > 0)
{
g_child_watch_add(run_info.pid, (GChildWatchFunc) run_exit_cb, NULL);
build_menu_update(idx);
}
}
result_id = run_info.pid; // g_spawn was successful, result is child process id
if (run_info.pid > 0)
{
g_child_watch_add(run_info.pid, (GChildWatchFunc) run_exit_cb, NULL);
build_menu_update(idx);
}
free_strings:
/* free all non-NULL strings */
@ -782,8 +810,8 @@ static gboolean build_create_shellscript(const gint idx, const gchar *fname, con
#else
str = g_strdup_printf(
"#!/bin/sh\n\n%s\n\necho \"\n\n------------------\n(program exited with code: $?)\" \
\n\necho \"Press return to continue\"\n%s\nunlink $0\n", cmd, (autoclose) ? "" :
"#to be more compatible with shells like dash\ndummy_var=\"\"\nread dummy_var");
\n\n%s\nunlink $0\n", cmd, (autoclose) ? "" :
"\necho \"Press return to continue\"\n#to be more compatible with shells like dash\ndummy_var=\"\"\nread dummy_var");
#endif
fputs(str, fp);

View File

@ -719,7 +719,7 @@ on_notebook1_switch_page_after (GtkNotebook *notebook,
utils_check_disk_status(idx);
#ifdef HAVE_VTE
vte_cwd(doc_list[idx].file_name);
vte_cwd(doc_list[idx].file_name, FALSE);
#endif
}
}

View File

@ -786,7 +786,7 @@ static gboolean document_update_timestamp(gint idx)
{
struct stat st;
gchar *locale_filename;
g_return_val_if_fail(DOC_IDX_VALID(idx), FALSE);
locale_filename = utils_get_locale_from_utf8(doc_list[idx].file_name);
@ -937,7 +937,7 @@ gboolean document_save_file(gint idx, gboolean force)
ui_update_statusbar(idx, -1);
g_free(basename);
#ifdef HAVE_VTE
vte_cwd(doc_list[idx].file_name);
vte_cwd(doc_list[idx].file_name, FALSE);
#endif
}

View File

@ -128,6 +128,7 @@ void configuration_save()
g_key_file_set_boolean(config, "VTE", "scroll_on_out", vc->scroll_on_out);
g_key_file_set_boolean(config, "VTE", "ignore_menu_bar_accel", vc->ignore_menu_bar_accel);
g_key_file_set_boolean(config, "VTE", "follow_path", vc->follow_path);
g_key_file_set_boolean(config, "VTE", "run_in_vte", vc->run_in_vte);
g_key_file_set_integer(config, "VTE", "scrollback_lines", vc->scrollback_lines);
g_key_file_set_string(config, "VTE", "font", vc->font);
g_key_file_set_string(config, "VTE", "shell", vc->shell);
@ -397,6 +398,7 @@ gboolean configuration_load()
vc->scroll_on_out = utils_get_setting_boolean(config, "VTE", "scroll_on_out", TRUE);
vc->ignore_menu_bar_accel = utils_get_setting_boolean(config, "VTE", "ignore_menu_bar_accel", FALSE);
vc->follow_path = utils_get_setting_boolean(config, "VTE", "follow_path", FALSE);
vc->run_in_vte = utils_get_setting_boolean(config, "VTE", "run_in_vte", FALSE);
vc->scrollback_lines = utils_get_setting_integer(config, "VTE", "scrollback_lines", 500);
vc->colour_fore = g_new0(GdkColor, 1);
vc->colour_back = g_new0(GdkColor, 1);

View File

@ -375,6 +375,9 @@ void prefs_init_dialog(void)
widget = lookup_widget(app->prefs_dialog, "check_follow_path");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->follow_path);
widget = lookup_widget(app->prefs_dialog, "check_run_in_vte");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->run_in_vte);
}
#endif
}
@ -628,6 +631,9 @@ void on_prefs_button_clicked(GtkDialog *dialog, gint response, gpointer user_dat
widget = lookup_widget(app->prefs_dialog, "check_follow_path");
vc->follow_path = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
widget = lookup_widget(app->prefs_dialog, "check_run_in_vte");
vc->run_in_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
vte_apply_user_settings();
}
#endif

View File

@ -390,48 +390,47 @@ void vte_send_cmd(const gchar *cmd)
* Determines the working directory using various OS-specific mechanisms. */
const gchar* vte_get_working_directory()
{
gchar buffer[4096 + 1];
gchar *file;
gchar *cwd;
gint length;
gchar buffer[4096 + 1];
gchar *file;
gchar *cwd;
gint length;
if (pid >= 0)
{
file = g_strdup_printf ("/proc/%d/cwd", pid);
length = readlink (file, buffer, sizeof (buffer));
if (pid >= 0)
{
file = g_strdup_printf("/proc/%d/cwd", pid);
length = readlink(file, buffer, sizeof (buffer));
if (length > 0 && *buffer == '/')
{
buffer[length] = '\0';
g_free(vte_info.dir);
vte_info.dir = g_strdup (buffer);
}
else if (length == 0)
{
cwd = g_get_current_dir ();
if (G_LIKELY (cwd != NULL))
{
if (chdir (file) == 0)
{
g_free(vte_info.dir);
vte_info.dir = g_get_current_dir ();
chdir (cwd);
}
if (length > 0 && *buffer == '/')
{
buffer[length] = '\0';
g_free(vte_info.dir);
vte_info.dir = g_strdup(buffer);
}
else if (length == 0)
{
cwd = g_get_current_dir();
if (G_LIKELY(cwd != NULL))
{
if (chdir(file) == 0)
{
g_free(vte_info.dir);
vte_info.dir = g_get_current_dir();
chdir(cwd);
}
g_free(cwd);
}
}
g_free(file);
}
g_free (cwd);
}
}
g_free (file);
}
return vte_info.dir;
return vte_info.dir;
}
void vte_cwd(const gchar *filename)
// if force is set to TRUE, it will always change the cwd
void vte_cwd(const gchar *filename, gboolean force)
{
if (vte_info.have_vte && vc->follow_path && filename != NULL)
if (vte_info.have_vte && (vc->follow_path || force) && filename != NULL)
{
gchar *path;
gchar *cmd;
@ -488,7 +487,7 @@ void vte_append_preferences_tab()
GtkWidget *notebook, *vbox, *label, *alignment, *table, *frame, *box;
GtkWidget *font_term, *color_fore, *color_back, *spin_scrollback, *entry_emulation;
GtkWidget *check_scroll_key, *check_scroll_out, *check_follow_path, *check_ignore_menu_key;
GtkWidget *entry_shell, *button_shell, *image_shell;
GtkWidget *check_run_in_vte, *entry_shell, *button_shell, *image_shell;
GtkTooltips *tooltips;
GtkObject *spin_scrollback_adj;
@ -622,6 +621,11 @@ void vte_append_preferences_tab()
gtk_button_set_focus_on_click(GTK_BUTTON(check_follow_path), FALSE);
gtk_container_add(GTK_CONTAINER(box), check_follow_path);
check_run_in_vte = gtk_check_button_new_with_mnemonic(_("Execute programs in VTE"));
gtk_tooltips_set_tip(tooltips, check_run_in_vte, _("Run programs in VTE instead of opening a terminal emulation window. Please note, programs executed in VTE cannot be stopped."), NULL);
gtk_button_set_focus_on_click(GTK_BUTTON(check_run_in_vte), FALSE);
gtk_container_add(GTK_CONTAINER(box), check_run_in_vte);
gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0);
g_object_set_data_full(G_OBJECT(app->prefs_dialog), "font_term",
@ -644,6 +648,8 @@ void vte_append_preferences_tab()
gtk_widget_ref(check_ignore_menu_key), (GDestroyNotify) gtk_widget_unref);
g_object_set_data_full(G_OBJECT(app->prefs_dialog), "check_follow_path",
gtk_widget_ref(check_follow_path), (GDestroyNotify) gtk_widget_unref);
g_object_set_data_full(G_OBJECT(app->prefs_dialog), "check_run_in_vte",
gtk_widget_ref(check_run_in_vte), (GDestroyNotify) gtk_widget_unref);
gtk_widget_show_all(frame);

View File

@ -52,6 +52,7 @@ typedef struct
gboolean scroll_on_out;
gboolean ignore_menu_bar_accel;
gboolean follow_path;
gboolean run_in_vte;
gint scrollback_lines;
gchar *emulation;
gchar *shell;
@ -72,7 +73,7 @@ void vte_send_cmd(const gchar *cmd);
const gchar* vte_get_working_directory(void);
void vte_cwd(const gchar *filename);
void vte_cwd(const gchar *filename, gboolean force);
void vte_append_preferences_tab();