summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJose Antonio Ortega Ruiz <jao@gnu.org>2001-06-06 22:49:25 +0000
committerJose Antonio Ortega Ruiz <jao@gnu.org>2001-06-06 22:49:25 +0000
commitcb2a285f50a6a0bf54a9d7e65579cb6edcda008b (patch)
tree9066b5f3327e5170530294e6e29b1a1476d725fe
parent4bc28027ccb359c6e3b469d4eb702a38c11792a6 (diff)
downloadmdk-cb2a285f50a6a0bf54a9d7e65579cb6edcda008b.tar.gz
mdk-cb2a285f50a6a0bf54a9d7e65579cb6edcda008b.tar.bz2
command history and tab completion added
-rw-r--r--NEWS15
-rw-r--r--mixgtk/mixgtk.glade33
-rw-r--r--mixgtk/mixgtk_cmd_dispatcher.c274
3 files changed, 144 insertions, 178 deletions
diff --git a/NEWS b/NEWS
index 2785fb6..775e4e5 100644
--- a/NEWS
+++ b/NEWS
@@ -17,13 +17,28 @@ Please send mdk bug reports to bug-mdk@gnu.org.
external programs used can be configured using the menu entry
Settings->External programs.
+** The commands 'edit' and 'compile' can be now executed without
+ argument (both in mixvm and gmixvm). When no argument is given, the
+ MIXAL source file corresponding to the currently loaded MIX program
+ is edited/compiled.
+
** Bug in CON fixed : 'CON wexpr' didn't compile correctly unless wexpr
represented a valid instruction; now, wexpr can evaluate to an
arbitrary value (Vasilij Ozmetelenko).
+** The completion key for the gmixvm command prompt is now TAB
+ (instead of RETURN).
+
+** The gmixvm command prompt maintains now a history of previously
+ typed commands, which can be visited using the arrow keys (UP for
+ previous commands, DOWN for next).
+
** When a file is reloaded by the virtual machine (both in mixvm and
gmixvm), the currently set breakpoints are conserved.
+** When compiling a source file which is not in the current directory, the
+ correct path is now stored in the compiled file.
+
---------------------------------------------------------------------------
* Version 0.3.2 (10/04/01)
diff --git a/mixgtk/mixgtk.glade b/mixgtk/mixgtk.glade
index a0dcfcf..5a74485 100644
--- a/mixgtk/mixgtk.glade
+++ b/mixgtk/mixgtk.glade
@@ -1220,7 +1220,7 @@
<widget>
<class>GtkScrolledWindow</class>
<name>mixlog_scrolledwindow</name>
- <hscrollbar_policy>GTK_POLICY_NEVER</hscrollbar_policy>
+ <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy>
<vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy>
<hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy>
<vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy>
@@ -1245,9 +1245,10 @@
<can_focus>True</can_focus>
<has_focus>True</has_focus>
<signal>
- <name>activate</name>
- <handler>on_mixvm_cmd_entry_activate</handler>
- <last_modification_time>Thu, 22 Feb 2001 23:26:28 GMT</last_modification_time>
+ <name>key_press_event</name>
+ <handler>on_command_prompt_key_press_event</handler>
+ <after>True</after>
+ <last_modification_time>Wed, 06 Jun 2001 06:46:05 GMT</last_modification_time>
</signal>
<editable>True</editable>
<text_visible>True</text_visible>
@@ -2519,7 +2520,7 @@
<widget>
<class>GtkDialog</class>
<name>external_dialog</name>
- <width>235</width>
+ <width>285</width>
<height>210</height>
<visible>False</visible>
<signal>
@@ -2636,23 +2637,23 @@
<name>editor_entry</name>
<x>48</x>
<y>40</y>
- <width>160</width>
+ <width>220</width>
<height>24</height>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
- <text>vi %s</text>
+ <text>xterm -e vi %s</text>
</widget>
<widget>
<class>GtkLabel</class>
<name>label234</name>
- <x>16</x>
+ <x>3</x>
<y>16</y>
- <width>176</width>
+ <width>223</width>
<height>16</height>
- <label>Editor command (e.g vi %s)</label>
+ <label>Editor command (e.g xterm -e vi %s)</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
@@ -2676,23 +2677,23 @@
<name>mixasm_entry</name>
<x>48</x>
<y>40</y>
- <width>158</width>
+ <width>220</width>
<height>22</height>
<can_focus>True</can_focus>
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
- <text>mixasm -g</text>
+ <text>mixasm -g %s</text>
</widget>
<widget>
<class>GtkLabel</class>
<name>label235</name>
- <x>11</x>
- <y>8</y>
- <width>168</width>
+ <x>0</x>
+ <y>16</y>
+ <width>278</width>
<height>16</height>
- <label>MIX sssembler command</label>
+ <label>MIX sssembler command (e.g. mixasm -g %s)</label>
<justify>GTK_JUSTIFY_LEFT</justify>
<wrap>False</wrap>
<xalign>0.5</xalign>
diff --git a/mixgtk/mixgtk_cmd_dispatcher.c b/mixgtk/mixgtk_cmd_dispatcher.c
index bb1d4db..5076727 100644
--- a/mixgtk/mixgtk_cmd_dispatcher.c
+++ b/mixgtk/mixgtk_cmd_dispatcher.c
@@ -29,6 +29,13 @@
#include <fcntl.h>
#include <errno.h>
+#include <mixlib/mix.h>
+
+#ifdef HAVE_LIBHISTORY
+# include <readline/history.h>
+#endif
+
+#include <gdk/gdkkeysyms.h>
#include <mixlib/mix_vm_command.h>
#include "mixgtk_mixvm.h"
#include "mixgtk_mixal.h"
@@ -51,21 +58,18 @@ typedef struct mixgtk_dispatch_
static struct mixgtk_dispatch_ dis_data_ = {NULL};
-/* local commands stuff */
-static const gchar *EDITOR_ = NULL;
-static const gchar *MIXASM_ = NULL;
-static const gchar *EDITOR_KEY_ = "Editor";
-static const gchar *MIXASM_KEY_ = "Mixasm";
-
-typedef gboolean (*local_handler_t) (mixgtk_dispatch_data_t *,
- const gchar *);
-
static void
log_command_ (mixgtk_dispatch_data_t *dis, const gchar *cmd)
{
gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL,"MIX> ", -1);
gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL, cmd, -1);
gtk_text_insert (GTK_TEXT (dis->log), NULL, NULL, NULL, "\n", -1);
+
+#ifdef HAVE_LIBHISTORY
+ add_history ((char *)cmd);
+/* history_search ((char *)cmd, 0); */
+ history_set_pos (history_base + history_length - 1);
+#endif
}
static void
@@ -85,90 +89,6 @@ flush_log_ (mixgtk_dispatch_data_t *dis)
}
}
-static gboolean
-exec_ (mixgtk_dispatch_data_t *dis, const gchar *cmd, const gchar *arg)
-{
- gchar *fullcmd = NULL;
- gboolean r = FALSE;
- fullcmd = g_strdup_printf (cmd, arg);
- r = !system (fullcmd);
- flush_log_ (dis);
- g_free (fullcmd);
- return r;
-}
-
-static const gchar *
-get_src_file_path_ (mixgtk_dispatch_data_t *dis)
-{
- static gchar *PATH = NULL;
-
- const mix_vm_t *vm = mix_vm_cmd_dispatcher_get_vm (dis->dispatcher);
- const mix_src_file_t *f = mix_vm_get_src_file (vm);
-
- if (PATH)
- {
- g_free (PATH);
- PATH = NULL;
- }
-
- if (f)
- PATH = mix_file_complete_name (mix_src_file_get_path (f), MIX_SRC_DEFEXT);
-
- return PATH;
-}
-
-static gboolean
-edit_handler_ (mixgtk_dispatch_data_t *dis, const gchar *arg)
-{
- if (!arg) arg = get_src_file_path_ (dis);
- if (!arg) return FALSE;
- return exec_ (dis, EDITOR_, arg);
-}
-
-static gboolean
-compile_handler_ (mixgtk_dispatch_data_t *dis, const gchar *arg)
-{
- if (!arg) arg = get_src_file_path_ (dis);
- if (!arg) return FALSE;
- return exec_ (dis, MIXASM_, arg);
-}
-
-static const gchar* local_cmds_[] = {
- "edit", "compile"
-};
-
-static const local_handler_t handlers_[] = {
- edit_handler_, compile_handler_
-};
-
-#define LOCAL_NO_ (sizeof (local_cmds_) / sizeof (local_cmds_[0]))
-
-static gboolean
-dispatch_local_command_ (mixgtk_dispatch_data_t *dis, const gchar *cmd)
-{
- int k = 0;
-
- g_return_val_if_fail (dis != NULL, FALSE);
- g_return_val_if_fail (cmd != NULL, FALSE);
-
- for (k = 0; k < LOCAL_NO_; ++k)
- {
- if (!strncmp (local_cmds_[k], cmd, strlen (local_cmds_[k])))
- {
- int j = 0;
- const gchar *arg = NULL;
- while (cmd[j] && !isspace (cmd[j])) ++j;
- if (cmd[j]) arg = cmd + j;
- log_command_ (dis, cmd);
- handlers_[k](dis, arg);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-
/* completions */
static void
init_completions_ (void)
@@ -179,37 +99,9 @@ init_completions_ (void)
dis_data_.completions = g_completion_new (NULL);
for (k = 0; k < MIX_CMD_INVALID; ++k)
cmds = g_list_append (cmds, (gpointer) mix_vm_command_to_string (k));
- for (k = 0; k < sizeof (local_cmds_) / sizeof (local_cmds_[0]); ++k)
- cmds = g_list_append (cmds, (gpointer)local_cmds_[k]);
g_completion_add_items (dis_data_.completions, cmds);
}
-/* global hooks for the command dispatcher
-static void
-global_pre_hook_ (mix_vm_cmd_dispatcher_t *dis,
- mix_vm_command_t cmd, const gchar *arg, gpointer data)
-{
- if (cmd < MIX_CMD_INVALID)
- {
- gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL,
- "MIX> ", -1);
- gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL,
- mix_vm_command_to_string (cmd), -1);
- gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL,
- " ", -1);
- gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL,
- arg, -1);
- gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL,
- "\n", -1);
- }
- else
- {
- gtk_text_insert (GTK_TEXT (dis_data_.log), NULL, NULL, NULL,
- _("\n*** Invalid command ***\n"), -1);
- }
-}
-*/
-
static void
global_post_hook_ (mix_vm_cmd_dispatcher_t *dis,
mix_vm_command_t cmd, const gchar *arg, gpointer data)
@@ -309,19 +201,44 @@ install_hooks_ (void)
}
/* configuration stuff */
+static const gchar *EDITOR_KEY_ = "Editor";
+static const gchar *MIXASM_KEY_ = "Mixasm";
+static const gchar *HISTORY_FILE_KEY_ = "History.file";
+static const gchar *MAX_HISTORY_KEY_ = "History.size";
+static const gchar *HISTORY_FILE_ = NULL;
+static int MAX_HISTORY_ = 50;
+
static void
read_config_ (void)
{
- EDITOR_ = mixgtk_config_get (EDITOR_KEY_);
- if (!EDITOR_)
+ const gchar *editor = mixgtk_config_get (EDITOR_KEY_);
+ const gchar *assem = mixgtk_config_get (MIXASM_KEY_);
+
+#ifdef HAVE_LIBHISTORY
+ const gchar *mh = mixgtk_config_get (MAX_HISTORY_KEY_);
+ if (mh) MAX_HISTORY_ = atoi (mh);
+ if (MAX_HISTORY_ <= 0) MAX_HISTORY_ = 50;
+ HISTORY_FILE_ = mixgtk_config_get (HISTORY_FILE_KEY_);
+#endif
+
+ if (!editor)
{
static const gchar *ENV[] = {"MDK_EDITOR", "X_EDITOR", NULL};
+ gchar *edit = NULL;
int k = 0;
- while (!EDITOR_ && ENV[k]) EDITOR_ = getenv (ENV[k++]);
- if (EDITOR_) EDITOR_ = g_strconcat (EDITOR_, " %s", NULL);
+ while (!edit && ENV[k]) edit = getenv (ENV[k++]);
+ if (edit) edit = g_strconcat (edit, " %s", NULL);
+ else edit = g_strdup ("xterm -e vi %s");
+ mix_vm_cmd_dispatcher_set_editor (dis_data_.dispatcher, edit);
+ g_free (edit);
}
- MIXASM_ = mixgtk_config_get (MIXASM_KEY_);
- if (!MIXASM_) MIXASM_ = "mixasm -g %s";
+ else
+ {
+ mix_vm_cmd_dispatcher_set_editor (dis_data_.dispatcher, editor);
+ }
+ if (!assem) assem = "mixasm -g %s";
+ mix_vm_cmd_dispatcher_set_assembler (dis_data_.dispatcher, assem);
+
}
static GtkWidget *ext_dlg_ = NULL;
@@ -345,8 +262,11 @@ on_external_programs_activate ()
(MIXGTK_EXTERNPROG_DIALOG, ASM_NAME_);
g_assert (asm_entry_);
}
- gtk_entry_set_text (GTK_ENTRY (ed_entry_), EDITOR_);
- gtk_entry_set_text (GTK_ENTRY (asm_entry_), MIXASM_);
+ gtk_entry_set_text (GTK_ENTRY (ed_entry_),
+ mix_vm_cmd_dispatcher_get_editor (dis_data_.dispatcher));
+ gtk_entry_set_text (GTK_ENTRY (asm_entry_),
+ mix_vm_cmd_dispatcher_get_assembler
+ (dis_data_.dispatcher));
gtk_widget_show (ext_dlg_);
}
@@ -359,10 +279,12 @@ on_extern_cancel_button_clicked ()
void
on_extern_ok_button_clicked ()
{
- EDITOR_ = gtk_entry_get_text (GTK_ENTRY (ed_entry_));
- MIXASM_ = gtk_entry_get_text (GTK_ENTRY (asm_entry_));
- mixgtk_config_update (EDITOR_KEY_, EDITOR_);
- mixgtk_config_update (MIXASM_KEY_, MIXASM_);
+ const gchar *value = gtk_entry_get_text (GTK_ENTRY (ed_entry_));
+ mix_vm_cmd_dispatcher_set_editor (dis_data_.dispatcher, value);
+ mixgtk_config_update (EDITOR_KEY_, value);
+ value = gtk_entry_get_text (GTK_ENTRY (asm_entry_));
+ mix_vm_cmd_dispatcher_set_assembler (dis_data_.dispatcher, value);
+ mixgtk_config_update (MIXASM_KEY_, value);
gtk_widget_hide (ext_dlg_);
}
@@ -411,6 +333,11 @@ mixgtk_cmd_dispatcher_init (void)
if (!dis_data_.completions) init_completions_ ();
read_config_ ();
+
+#ifdef HAVE_LIBHISTORY
+ using_history ();
+ stifle_history (MAX_HISTORY_);
+#endif
return TRUE;
}
@@ -423,7 +350,9 @@ mixgtk_cmd_dispatcher_dispatch (const gchar *command)
g_return_if_fail (command != NULL);
g_assert (entry != NULL);
gtk_entry_set_text (GTK_ENTRY (entry), command);
- on_mixvm_cmd_entry_activate (entry, NULL);
+ log_command_ (&dis_data_, command);
+ mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, command);
+ gtk_entry_set_text (GTK_ENTRY (entry), "");
}
/* get times */
@@ -445,34 +374,18 @@ mixgtk_cmd_dispatcher_get_vm (void)
return (mix_vm_t *) mix_vm_cmd_dispatcher_get_vm (dis_data_.dispatcher);
}
-/* process new command */
+/* process commands */
void
-on_mixvm_cmd_entry_activate (GtkWidget *w, gpointer e)
+complete_command_ (void)
{
- gchar *text;
- GList *cmds = NULL;
+ GtkEntry *entry = GTK_ENTRY (dis_data_.prompt);
gchar *prefix = NULL;
-
- text = g_strchomp (gtk_entry_get_text (GTK_ENTRY (w)));
-
- if (mix_vm_command_from_string (text) != MIX_CMD_INVALID)
- {
- mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text);
- gtk_entry_set_text (GTK_ENTRY (w), "");
- return;
- }
-
- if (dispatch_local_command_ (&dis_data_, text))
- {
- gtk_entry_set_text (GTK_ENTRY (w), "");
- return;
- }
-
- cmds = g_completion_complete (dis_data_.completions, text, &prefix);
+ gchar *text = g_strchomp (gtk_entry_get_text (entry));
+ GList *cmds = g_completion_complete (dis_data_.completions, text, &prefix);
if (prefix != NULL)
{
- gtk_entry_set_text (GTK_ENTRY (w), prefix);
+ gtk_entry_set_text (entry, prefix);
g_free (prefix);
if (g_list_length (cmds) > 1)
{
@@ -498,14 +411,51 @@ on_mixvm_cmd_entry_activate (GtkWidget *w, gpointer e)
NULL, NULL, NULL, "\n", -1);
}
else
- gtk_entry_append_text (GTK_ENTRY (w), " ");
+ gtk_entry_append_text (entry, " ");
}
- else
+}
+
+
+int
+on_command_prompt_key_press_event (GtkEntry *w, GdkEventKey *e, gpointer d)
+{
+ guint key = e->keyval;
+
+#ifdef HAVE_LIBHISTORY
+ HIST_ENTRY *entry = NULL;
+ if (key == GDK_Up)
{
- log_command_ (&dis_data_, text);
- mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text);
- gtk_entry_set_text (GTK_ENTRY (w), "");
+ entry = previous_history ();
+ if (entry && entry->line)
+ gtk_entry_set_text (w, entry->line);
+ return TRUE;
}
-}
+ if (key == GDK_Down)
+ {
+ entry = next_history ();
+ if (entry && entry->line)
+ gtk_entry_set_text (w, entry->line);
+ return TRUE;
+ }
+#endif
+ if (key == GDK_Tab)
+ {
+ complete_command_ ();
+ return TRUE;
+ }
+ if (key == GDK_Return)
+ {
+ gchar *text = gtk_entry_get_text (w);
+ if (text && *text)
+ {
+ log_command_ (&dis_data_, text);
+ mix_vm_cmd_dispatcher_dispatch_text (dis_data_.dispatcher, text);
+ gtk_entry_set_text (w, "");
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}