aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/qreg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/qreg.c')
-rw-r--r--src/qreg.c116
1 files changed, 68 insertions, 48 deletions
diff --git a/src/qreg.c b/src/qreg.c
index d0f3e6b..7d9a83b 100644
--- a/src/qreg.c
+++ b/src/qreg.c
@@ -58,6 +58,12 @@ teco_qreg_t *teco_qreg_current = NULL;
*/
teco_qreg_table_t teco_qreg_table_globals;
+typedef struct teco_qreg_flags_t teco_qreg_flags_t;
+TECO_DEFINE_UNDO_SCALAR(teco_qreg_flags_t);
+
+#define teco_undo_qreg_flags(VAR) \
+ (*teco_undo_object_teco_qreg_flags_t_push(&(VAR)))
+
/** @private @static @memberof teco_qreg_t */
static teco_qreg_t *
teco_qreg_new(teco_qreg_vtable_t *vtable, const gchar *name, gsize len)
@@ -103,7 +109,7 @@ teco_qreg_execute(teco_qreg_t *qreg, teco_qreg_table_t *qreg_table_locals, GErro
void
teco_qreg_undo_set_eol_mode(teco_qreg_t *qreg)
{
- if (!qreg->must_undo)
+ if (!qreg->flags.must_undo)
return;
/*
@@ -112,7 +118,7 @@ teco_qreg_undo_set_eol_mode(teco_qreg_t *qreg)
*/
teco_doc_update(&qreg->string, teco_qreg_view);
- if (teco_qreg_current && teco_qreg_current->must_undo) // FIXME
+ if (teco_qreg_current && teco_qreg_current->flags.must_undo) // FIXME
teco_doc_undo_edit(&teco_qreg_current->string);
undo__teco_view_ssm(teco_qreg_view, SCI_SETEOLMODE,
@@ -136,18 +142,23 @@ teco_qreg_set_eol_mode(teco_qreg_t *qreg, gint mode)
}
static gboolean
-teco_qreg_plain_set_integer(teco_qreg_t *qreg, teco_int_t value, GError **error)
+teco_qreg_plain_set_number(teco_qreg_t *qreg, teco_number_t value, gboolean is_float, GError **error)
{
- if (qreg->must_undo) // FIXME
- teco_undo_int(qreg->integer);
- qreg->integer = value;
+ if (qreg->flags.must_undo) { // FIXME
+ teco_undo_number(qreg->number);
+ teco_undo_qreg_flags(qreg->flags);
+ }
+ qreg->number = value;
+ qreg->flags.is_float = is_float;
return TRUE;
}
static gboolean
-teco_qreg_plain_get_integer(teco_qreg_t *qreg, teco_int_t *ret, GError **error)
+teco_qreg_plain_get_number(teco_qreg_t *qreg, teco_number_t *ret,
+ gboolean *is_float, GError **error)
{
- *ret = qreg->integer;
+ *ret = qreg->number;
+ *is_float = qreg->flags.is_float;
return TRUE;
}
@@ -162,7 +173,7 @@ teco_qreg_plain_set_string(teco_qreg_t *qreg, const gchar *str, gsize len,
static gboolean
teco_qreg_plain_undo_set_string(teco_qreg_t *qreg, GError **error)
{
- if (qreg->must_undo) // FIXME
+ if (qreg->flags.must_undo) // FIXME
teco_doc_undo_set_string(&qreg->string);
return TRUE;
}
@@ -177,14 +188,14 @@ teco_qreg_plain_append_string(teco_qreg_t *qreg, const gchar *str, gsize len, GE
if (!len)
return TRUE;
- if (qreg->must_undo) { // FIXME
+ if (qreg->flags.must_undo) { // FIXME
/*
* Necessary, so that upon rubout the
* string's parameters are restored.
*/
teco_doc_update(&qreg->string, teco_qreg_view);
- if (teco_qreg_current && teco_qreg_current->must_undo) // FIXME
+ if (teco_qreg_current && teco_qreg_current->flags.must_undo) // FIXME
teco_doc_undo_edit(&teco_qreg_current->string);
teco_doc_undo_reset(&qreg->string);
@@ -208,7 +219,7 @@ teco_qreg_plain_append_string(teco_qreg_t *qreg, const gchar *str, gsize len, GE
* so that teco_doc_edit() always initializes the document and
* the default codepage.
*/
- if (qreg->must_undo) // FIXME
+ if (qreg->flags.must_undo) // FIXME
teco_doc_undo_edit(&qreg->string);
return TRUE;
@@ -273,7 +284,7 @@ teco_qreg_plain_exchange_string(teco_qreg_t *qreg, teco_doc_t *src, GError **err
static gboolean
teco_qreg_plain_undo_exchange_string(teco_qreg_t *qreg, teco_doc_t *src, GError **error)
{
- if (qreg->must_undo) // FIXME
+ if (qreg->flags.must_undo) // FIXME
teco_doc_undo_exchange(&qreg->string);
teco_doc_undo_exchange(src);
return TRUE;
@@ -301,7 +312,7 @@ teco_qreg_plain_undo_edit(teco_qreg_t *qreg, GError **error)
*/
teco_doc_update(&qreg->string, teco_qreg_view);
- if (!qreg->must_undo) // FIXME
+ if (!qreg->flags.must_undo) // FIXME
return TRUE;
undo__teco_interface_info_update_qreg(qreg);
@@ -363,8 +374,8 @@ teco_qreg_plain_save(teco_qreg_t *qreg, const gchar *filename, GError **error)
* These store their string part as teco_docs.
*/
#define TECO_INIT_QREG(...) { \
- .set_integer = teco_qreg_plain_set_integer, \
- .get_integer = teco_qreg_plain_get_integer, \
+ .set_number = teco_qreg_plain_set_number, \
+ .get_number = teco_qreg_plain_get_number, \
.set_string = teco_qreg_plain_set_string, \
.undo_set_string = teco_qreg_plain_undo_set_string, \
.append_string = teco_qreg_plain_append_string, \
@@ -391,9 +402,12 @@ teco_qreg_plain_new(const gchar *name, gsize len)
/* see also teco_state_start_jump() */
static gboolean
-teco_qreg_dot_set_integer(teco_qreg_t *qreg, teco_int_t value, GError **error)
+teco_qreg_dot_set_number(teco_qreg_t *qreg, teco_number_t value, gboolean is_float, GError **error)
{
- gssize pos = teco_interface_glyphs2bytes_absdot(value);
+ if (is_float)
+ value.i = value.f;
+
+ gssize pos = teco_interface_glyphs2bytes_absdot(value.i);
if (pos < 0) {
g_set_error_literal(error, TECO_ERROR, TECO_ERROR_MOVE,
"Attempt to move pointer off page when setting Q-Register \":\"");
@@ -405,16 +419,17 @@ teco_qreg_dot_set_integer(teco_qreg_t *qreg, teco_int_t value, GError **error)
teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0);
teco_interface_ssm(SCI_GOTOPOS, pos, 0);
- teco_current_doc_set_dot(value);
+ teco_current_doc_set_dot(value.i);
return TRUE;
}
-/* see also teco_state_start_dot() */
static gboolean
-teco_qreg_dot_get_integer(teco_qreg_t *qreg, teco_int_t *ret, GError **error)
+teco_qreg_dot_get_number(teco_qreg_t *qreg, teco_number_t *ret,
+ gboolean *is_float, GError **error)
{
- *ret = teco_current_doc_get_dot();
+ ret->i = teco_current_doc_get_dot();
+ *is_float = FALSE;
return TRUE;
}
@@ -423,8 +438,8 @@ teco_qreg_t *
teco_qreg_dot_new(void)
{
static teco_qreg_vtable_t vtable = TECO_INIT_QREG(
- .set_integer = teco_qreg_dot_set_integer,
- .get_integer = teco_qreg_dot_get_integer
+ .set_number = teco_qreg_dot_set_number,
+ .get_number = teco_qreg_dot_get_number
);
/*
@@ -435,18 +450,18 @@ teco_qreg_dot_new(void)
}
static gboolean
-teco_qreg_radix_set_integer(teco_qreg_t *qreg, teco_int_t value, GError **error)
+teco_qreg_radix_set_number(teco_qreg_t *qreg, teco_number_t value, gboolean is_float, GError **error)
{
- if (value < 2) {
- g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED,
- "Invalid radix");
+ if (is_float)
+ value.i = value.f;
+
+ if (value.i < 2) {
+ g_set_error(error, TECO_ERROR, TECO_ERROR_FAILED,
+ "Invalid radix %" TECO_INT_FORMAT, value.i);
return FALSE;
}
- if (qreg->must_undo) // FIXME
- teco_undo_int(qreg->integer);
- qreg->integer = value;
- return TRUE;
+ return teco_qreg_plain_set_number(qreg, value, FALSE, error);
}
/** @static @memberof teco_qreg_t */
@@ -454,11 +469,11 @@ static teco_qreg_t *
teco_qreg_radix_new(void)
{
static teco_qreg_vtable_t vtable = TECO_INIT_QREG(
- .set_integer = teco_qreg_radix_set_integer
+ .set_number = teco_qreg_radix_set_number
);
teco_qreg_t *qreg = teco_qreg_new(&vtable, "\x12", 1); /* ^R */
- qreg->integer = 10;
+ qreg->number.i = 10;
return qreg;
}
@@ -514,7 +529,7 @@ teco_qreg_external_undo_exchange_string(teco_qreg_t *qreg, teco_doc_t *src, GErr
{
if (!qreg->vtable->undo_set_string(qreg, error))
return FALSE;
- if (qreg->must_undo) // FIXME
+ if (qreg->flags.must_undo) // FIXME
teco_doc_undo_set_string(src);
return TRUE;
}
@@ -537,7 +552,7 @@ teco_qreg_external_get_character(teco_qreg_t *qreg, teco_int_t position,
/*
* Make sure that the -1/-2 error values are preserved.
* The sign bit in UCS-4/UTF-32 is unused, so this will even
- * suffice if TECO_INTEGER == 32.
+ * suffice if TECO_NUMBER == 32.
*/
*chr = *p ? (gint32)g_utf8_get_char_validated(p, -1) : 0;
return TRUE;
@@ -622,16 +637,18 @@ teco_qreg_external_save(teco_qreg_t *qreg, const gchar *filename, GError **error
* NOTE: The integer-component is currently unused on the "*" special register.
*/
static gboolean
-teco_qreg_bufferinfo_set_integer(teco_qreg_t *qreg, teco_int_t value, GError **error)
+teco_qreg_bufferinfo_set_number(teco_qreg_t *qreg, teco_number_t value, gboolean is_float, GError **error)
{
return teco_current_doc_undo_edit(error) &&
- teco_ring_edit(value, error);
+ teco_ring_edit(is_float ? (teco_int_t)value.f : value.i, error);
}
static gboolean
-teco_qreg_bufferinfo_get_integer(teco_qreg_t *qreg, teco_int_t *ret, GError **error)
+teco_qreg_bufferinfo_get_number(teco_qreg_t *qreg, teco_number_t *ret,
+ gboolean *is_float, GError **error)
{
- *ret = teco_ring_get_id(teco_ring_current);
+ ret->i = teco_ring_get_id(teco_ring_current);
+ *is_float = FALSE;
return TRUE;
}
@@ -690,8 +707,8 @@ teco_qreg_t *
teco_qreg_bufferinfo_new(void)
{
static teco_qreg_vtable_t vtable = TECO_INIT_QREG_EXTERNAL(
- .set_integer = teco_qreg_bufferinfo_set_integer,
- .get_integer = teco_qreg_bufferinfo_get_integer,
+ .set_number = teco_qreg_bufferinfo_set_number,
+ .get_number = teco_qreg_bufferinfo_get_number,
.set_string = teco_qreg_bufferinfo_set_string,
.undo_set_string = teco_qreg_bufferinfo_undo_set_string,
.append_string = teco_qreg_bufferinfo_append_string,
@@ -944,7 +961,7 @@ teco_qreg_clipboard_new(const gchar *name)
* This is configurable via the integer cell.
*/
if (qreg->head.name.len == 1)
- qreg->integer = 'C';
+ qreg->number.i = 'C';
return qreg;
}
@@ -987,7 +1004,7 @@ TECO_DEFINE_UNDO_CALL(teco_qreg_table_remove, teco_qreg_t *);
static inline void
teco_qreg_table_undo_remove(teco_qreg_t *qreg)
{
- if (qreg->must_undo)
+ if (qreg->flags.must_undo)
undo__teco_qreg_table_remove(qreg);
}
@@ -1169,8 +1186,11 @@ teco_qreg_table_clear(teco_qreg_table_t *table)
}
typedef struct {
- teco_int_t integer;
+ teco_number_t number;
teco_doc_t string;
+
+ /** whether the number cell is an integer or float */
+ gboolean is_float;
} teco_qreg_stack_entry_t;
static inline void
@@ -1199,11 +1219,11 @@ TECO_DEFINE_UNDO_CALL(teco_qreg_stack_remove_last);
gboolean
teco_qreg_stack_push(teco_qreg_t *qreg, GError **error)
{
- teco_qreg_stack_entry_t entry;
+ teco_qreg_stack_entry_t entry = {0};
g_auto(teco_string_t) string = {NULL, 0};
guint codepage;
- if (!qreg->vtable->get_integer(qreg, &entry.integer, error) ||
+ if (!qreg->vtable->get_number(qreg, &entry.number, &entry.is_float, error) ||
!qreg->vtable->get_string(qreg, &string.data, &string.len, &codepage, error))
return FALSE;
teco_doc_init(&entry.string);
@@ -1247,7 +1267,7 @@ teco_qreg_stack_pop(teco_qreg_t *qreg, GError **error)
teco_qreg_stack_entry_t *entry;
entry = &g_array_index(teco_qreg_stack, teco_qreg_stack_entry_t, teco_qreg_stack->len-1);
- if (!qreg->vtable->set_integer(qreg, entry->integer, error))
+ if (!qreg->vtable->set_number(qreg, entry->number, entry->is_float, error))
return FALSE;
/* exchange document ownership between stack entry and Q-Register */