aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--src/core-commands.c42
-rw-r--r--tests/testsuite.at5
3 files changed, 47 insertions, 1 deletions
diff --git a/TODO b/TODO
index a62ee75..697dd10 100644
--- a/TODO
+++ b/TODO
@@ -346,7 +346,6 @@ Features:
The DEC behavior could be achieved by always searching till the end
of the buffer, but excluding all matches beyond the target range.
* ^A, :Gq, T, ^T and stdio in general
- * ^B as the current date. We should probably copy TECOC's behavior here.
* ^W was an immediate action command to repaint the screen.
This could be a regular command to allow refreshing in long loops.
Video TECO had ET for the same purpose.
diff --git a/src/core-commands.c b/src/core-commands.c
index b8918ef..819b1aa 100644
--- a/src/core-commands.c
+++ b/src/core-commands.c
@@ -18,6 +18,7 @@
#include "config.h"
#endif
+#include <time.h>
#include <string.h>
#include <glib.h>
@@ -1541,6 +1542,45 @@ teco_ranges_cleanup(void)
g_free(teco_ranges);
}
+/*$ ^B date time timestamp
+ * ^B -> (((year-1900)*16 + month)*32 + day) -- Retrieve date, time or timestamp
+ * :^B -> seconds
+ * ::^B -> timestamp
+ *
+ * By default returns the current date via the given equation.
+ *
+ * If colon-modified it returns the number of <seconds> since the Epoch,
+ * 1970-01-01 00:00:00 +0000 (UTC).
+ *
+ * If modified by two colons it returns the system's monotonic time in microseconds,
+ * which can be used as a <timestamp>.
+ */
+static void
+teco_state_control_date(teco_machine_main_t *ctx, GError **error)
+{
+ GDate date;
+
+ switch (teco_machine_main_eval_colon(ctx)) {
+ case 0:
+ g_date_clear(&date, 1);
+ g_date_set_time_t(&date, time(NULL));
+ teco_expressions_push(((g_date_get_year(&date)-1900)*16 + g_date_get_month(&date))*32 +
+ g_date_get_day(&date));
+ break;
+ case 1:
+ teco_expressions_push(time(NULL));
+ break;
+ case 2:
+ /*
+ * NOTE: Might not be reliable if TECO_INTEGER==32.
+ */
+ teco_expressions_push(g_get_monotonic_time());
+ break;
+ default:
+ g_assert_not_reached();
+ }
+}
+
static teco_state_t *
teco_state_control_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
{
@@ -1567,6 +1607,8 @@ teco_state_control_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
/*
* Commands
*/
+ ['B'] = {&teco_state_start, teco_state_control_date,
+ .modifier_colon = 2},
['O'] = {&teco_state_start, teco_state_control_octal},
['D'] = {&teco_state_start, teco_state_control_decimal},
['R'] = {&teco_state_start, teco_state_control_radix},
diff --git a/tests/testsuite.at b/tests/testsuite.at
index c50061a..a1b8ada 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -283,6 +283,11 @@ TE_CHECK([[@EC'dd if=/dev/zero bs=512 count=1' Z= Z-512"N(0/0)']], 0, ignore, ig
TE_CHECK([[0,128ED @EC'dd if=/dev/zero bs=512 count=1' Z= Z-512"N(0/0)']], 0, ignore, ignore)
AT_CLEANUP
+AT_SETUP([Timestamps])
+# TODO: Test the date (^B) and time (:^B) variants as well.
+TE_CHECK([[::^BUa ::^B-Qa"<(0/0)']], 0, ignore, ignore)
+AT_CLEANUP
+
#
# Command-line editing.
#