summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--mixgtk/mixgtk.c2
-rw-r--r--mixgtk/mixgtk_cmd_dispatcher.c37
-rw-r--r--mixgtk/mixgtk_cmd_dispatcher.h5
-rw-r--r--mixlib/mix_config.c70
-rw-r--r--mixlib/mix_config.h19
-rw-r--r--mixlib/mix_vm_command.c23
-rw-r--r--mixutils/mixvm_loop.c8
8 files changed, 146 insertions, 21 deletions
diff --git a/NEWS b/NEWS
index 3f5d9fe..185d5bd 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,9 @@ Please send mdk bug reports to bug-mdk@gnu.org.
statistics (both in gmixvm and mixvm). Its value is also stored as
a config param.
+** mixvm and gmixvm now save a history file so that they remember
+ commands typed in previous sessions.
+
** Bug fix: changes in the device format are now correctly stored (gmixvm).
---------------------------------------------------------------------------
diff --git a/mixgtk/mixgtk.c b/mixgtk/mixgtk.c
index 1198fb3..9c18703 100644
--- a/mixgtk/mixgtk.c
+++ b/mixgtk/mixgtk.c
@@ -136,6 +136,6 @@ void
mixgtk_release (void)
{
if (mixgtk_config_is_autosave ()) mixgtk_config_save ();
-
+ mix_vm_cmd_dispatcher_delete (mixgtk_cmd_dispatcher_get_mix_dispatcher ());
mix_release_lib ();
}
diff --git a/mixgtk/mixgtk_cmd_dispatcher.c b/mixgtk/mixgtk_cmd_dispatcher.c
index 2f47c64..8d2d0a7 100644
--- a/mixgtk/mixgtk_cmd_dispatcher.c
+++ b/mixgtk/mixgtk_cmd_dispatcher.c
@@ -219,10 +219,6 @@ 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)
@@ -230,13 +226,6 @@ read_config_ (void)
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};
@@ -328,6 +317,10 @@ mixgtk_cmd_dispatcher_init (mixgtk_dialog_id_t top)
if (!dis_data_.dispatcher)
{
+ static const gchar *HISTORY_FILE = "gmixvm.history";
+ static gint HISTORY_SIZE = 100;
+ mix_config_t *config = mixgtk_config_get_mix_config ();
+
int r = pipe (dis_data_.fildes);
g_return_val_if_fail (r == 0, FALSE);
/* connect stdout/stderr to the pipe's write end
@@ -341,10 +334,16 @@ mixgtk_cmd_dispatcher_init (mixgtk_dialog_id_t top)
r |= O_NONBLOCK;
r = fcntl(dis_data_.fildes[0], F_SETFL, r);
g_return_val_if_fail (r != -1, FALSE);
+
+ if (!mix_config_get_history_file (config))
+ mix_config_set_history_file (config, HISTORY_FILE);
+ if (mix_config_get_history_size (config) == 0)
+ mix_config_set_history_size (config, HISTORY_SIZE);
+
dis_data_.dispatcher =
mix_vm_cmd_dispatcher_new_with_config (dis_data_.out,
dis_data_.out,
- mixgtk_config_get_mix_config ());
+ config);
mix_vm_cmd_dispatcher_print_time (dis_data_.dispatcher, FALSE);
install_hooks_ ();
@@ -363,13 +362,6 @@ mixgtk_cmd_dispatcher_init (mixgtk_dialog_id_t top)
(GTK_WINDOW (mixgtk_widget_factory_get_dialog (MIXGTK_MAIN)),
dis_data_.last_file);
-#ifdef HAVE_LIBHISTORY
- if (!restart)
- {
- using_history ();
- stifle_history (MAX_HISTORY_);
- }
-#endif
restart = TRUE;
return TRUE;
@@ -414,6 +406,13 @@ mixgtk_cmd_dispatcher_get_src_path (void)
return mix_vm_cmd_dispatcher_get_src_file_path (dis_data_.dispatcher);
}
+/* get the mix cmd dispatcher */
+mix_vm_cmd_dispatcher_t *
+mixgtk_cmd_dispatcher_get_mix_dispatcher (void)
+{
+ return dis_data_.dispatcher;
+}
+
/* process commands */
void
complete_command_ (void)
diff --git a/mixgtk/mixgtk_cmd_dispatcher.h b/mixgtk/mixgtk_cmd_dispatcher.h
index a67ec26..6ea840c 100644
--- a/mixgtk/mixgtk_cmd_dispatcher.h
+++ b/mixgtk/mixgtk_cmd_dispatcher.h
@@ -26,6 +26,7 @@
#define MIXGTK_CMD_DISPATCHER_H
#include <mixlib/mix_vm.h>
+#include <mixlib/mix_vm_command.h>
#include "mixgtk_widgets.h"
/* initialise the command dispatcher */
@@ -48,6 +49,10 @@ mixgtk_cmd_dispatcher_get_vm (void);
extern const gchar *
mixgtk_cmd_dispatcher_get_src_path (void);
+/* get the mix cmd dispatcher */
+extern mix_vm_cmd_dispatcher_t *
+mixgtk_cmd_dispatcher_get_mix_dispatcher (void);
+
#endif /* MIXGTK_CMD_DISPATCHER_H */
diff --git a/mixlib/mix_config.c b/mixlib/mix_config.c
index 871af91..ba9ad19 100644
--- a/mixlib/mix_config.c
+++ b/mixlib/mix_config.c
@@ -34,7 +34,9 @@ static const gchar *DEF_DIR_ = ".mdk";
static const gchar *AUTOSAVE_KEY_ = "Autosave";
static const gchar *AUTOSAVE_YES_ = "True";
static const gchar *AUTOSAVE_NO_ = "False";
-static const gchar *DEVICES_KEY_ = "DevicesDir";
+static const gchar *DEVICES_KEY_ = "Devices.dir";
+static const gchar *HISTORY_KEY_ = "History.file";
+static const gchar *HISTORY_SIZE_KEY_ = "History.size";
/* the config type */
struct mix_config_t
@@ -126,6 +128,17 @@ mix_config_get (const mix_config_t *config, const gchar *key)
}
+gint
+mix_config_get_integer (const mix_config_t *config, const gchar *key)
+{
+ const gchar *val;
+ g_return_val_if_fail (config != NULL, 0);
+ g_return_val_if_fail (key != NULL, 0);
+ val = mix_config_get (config, key);
+ if (!val) return 0;
+ return atoi (val);
+}
+
/* update (or create if it does not exist) a new config item */
void
mix_config_update (mix_config_t *config, const gchar *key, const gchar *value)
@@ -150,6 +163,20 @@ mix_config_update (mix_config_t *config, const gchar *key, const gchar *value)
g_hash_table_insert (config->items, tmp, g_strdup (value));
}
+void
+mix_config_update_integer (mix_config_t *config, const gchar *key, gint value)
+{
+ gchar *val;
+
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (key != NULL);
+ g_return_if_fail (value != NULL);
+
+ val = g_strdup_printf ("%d", value);
+ mix_config_update (config, key, val);
+ g_free (val);
+}
+
/* save the current configuration */
static void
save_ (gpointer key, gpointer value, gpointer file)
@@ -209,3 +236,44 @@ mix_config_get_devices_dir (const mix_config_t *config)
return mix_config_get (config, DEVICES_KEY_);
}
+/* history file. if relative path, config dir taken as root */
+void
+mix_config_set_history_file (mix_config_t *config, const gchar *path)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (path != NULL);
+ if (g_path_is_absolute (path))
+ {
+ mix_config_update (config, HISTORY_KEY_, path);
+ }
+ else
+ {
+ gchar *base = g_dirname (config->filename);
+ gchar *hf = g_strconcat (base, G_DIR_SEPARATOR_S, path, NULL);
+ mix_config_update (config, HISTORY_KEY_, hf);
+ g_free (hf);
+ g_free (base);
+ }
+}
+
+const gchar *
+mix_config_get_history_file (const mix_config_t *config)
+{
+ g_return_val_if_fail (config != NULL, NULL);
+ return mix_config_get (config, HISTORY_KEY_);
+}
+
+void
+mix_config_set_history_size (mix_config_t *config, gint s)
+{
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (s >= 0);
+ mix_config_update_integer (config, HISTORY_SIZE_KEY_, s);
+}
+
+gint
+mix_config_get_history_size (const mix_config_t *config)
+{
+ g_return_val_if_fail (config != NULL, 0);
+ return mix_config_get_integer (config, HISTORY_SIZE_KEY_);
+}
diff --git a/mixlib/mix_config.h b/mixlib/mix_config.h
index e6e00b8..47932e1 100644
--- a/mixlib/mix_config.h
+++ b/mixlib/mix_config.h
@@ -46,10 +46,16 @@ mix_config_get_filename (const mix_config_t *config);
extern const gchar *
mix_config_get (const mix_config_t *config, const gchar *key);
+extern gint
+mix_config_get_integer (const mix_config_t *config, const gchar *key);
+
/* update (or create if it does not exist) a new config item */
extern void
mix_config_update (mix_config_t *config, const gchar *key, const gchar *value);
+extern void
+mix_config_update_integer (mix_config_t *config, const gchar *key, gint value);
+
/* save the current configuration */
extern void
mix_config_save (const mix_config_t *config);
@@ -70,6 +76,19 @@ mix_config_set_devices_dir (mix_config_t *config, const gchar *dirname);
extern const gchar *
mix_config_get_devices_dir (const mix_config_t *config);
+/* history file. if relative path, config dir taken as root */
+extern void
+mix_config_set_history_file (mix_config_t *config, const gchar *path);
+
+extern const gchar *
+mix_config_get_history_file (const mix_config_t *config);
+
+extern void
+mix_config_set_history_size (mix_config_t *config, gint s);
+
+extern gint
+mix_config_get_history_size (const mix_config_t *config);
+
#endif /* MIX_CONFIG_H */
diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c
index afabc55..bb4b67f 100644
--- a/mixlib/mix_vm_command.c
+++ b/mixlib/mix_vm_command.c
@@ -33,6 +33,11 @@
#include "mix_eval.h"
#include "mix_vm_command.h"
+#ifdef HAVE_LIBHISTORY
+# include <readline/history.h>
+#endif
+
+
/* hooks */
typedef struct
{
@@ -253,6 +258,7 @@ mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err,
mix_vm_cmd_dispatcher_t *result = mix_vm_cmd_dispatcher_new (out, err);
if (result != NULL && (result->config = config) != NULL)
{
+ gint hsize = 0;
const gchar *val = mix_config_get (result->config, TRACING_KEY_);
if (val) cmd_tracing_ (result, val);
val = mix_config_get (result->config, EDITOR_KEY_);
@@ -270,6 +276,17 @@ mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err,
}
else
cmd_devdir_ (result, val);
+#ifdef HAVE_LIBHISTORY
+ val = mix_config_get_history_file (result->config);
+ hsize = mix_config_get_history_size (result->config);
+ using_history ();
+ stifle_history (hsize);
+ if (val)
+ {
+ read_history ((char *)val);
+ history_set_pos (history_base + history_length - 1);
+ }
+#endif
}
return result;
}
@@ -279,12 +296,18 @@ mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err,
void
mix_vm_cmd_dispatcher_delete (mix_vm_cmd_dispatcher_t *dis)
{
+ const gchar *hfile = NULL;
g_return_if_fail (dis != NULL);
mix_eval_delete (dis->eval);
mix_dump_context_delete (dis->dump);
mix_vm_delete (dis->vm);
if (dis->editor) g_free (dis->editor);
if (dis->editor) g_free (dis->assembler);
+#ifdef HAVE_LIBHISTORY
+ if (dis->config && (hfile = mix_config_get_history_file
+ (dis->config)))
+ write_history ((char *)hfile);
+#endif
g_free (dis);
}
diff --git a/mixutils/mixvm_loop.c b/mixutils/mixvm_loop.c
index ad49829..f9672e8 100644
--- a/mixutils/mixvm_loop.c
+++ b/mixutils/mixvm_loop.c
@@ -81,8 +81,16 @@ rl_gets ()
void
mix_vmloop (const gchar *file, gboolean use_emacs)
{
+ static const gchar *HISTORY_FILE = "mixvm.history";
+ static gint HISTORY_SIZE = 100;
mix_config_t *config = mix_config_new (NULL, CONFIG_FILE_);
+
mix_config_set_autosave (config, TRUE);
+ if (!mix_config_get_history_file (config))
+ mix_config_set_history_file (config, HISTORY_FILE);
+ if (mix_config_get_history_size (config) == 0)
+ mix_config_set_history_size (config, HISTORY_SIZE);
+
mixvm_cmd_init (config, (char *)file, use_emacs);
while ( mixvm_cmd_exec (rl_gets ()) )
;