aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core-commands.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/core-commands.c b/src/core-commands.c
index 6e39d9a..2f473ce 100644
--- a/src/core-commands.c
+++ b/src/core-commands.c
@@ -1672,6 +1672,9 @@ teco_state_control_negate(teco_machine_main_t *ctx, GError **error)
{
teco_int_t v;
+ if (!teco_expressions_eval(FALSE, error))
+ return;
+
if (!teco_expressions_args()) {
teco_error_argexpected_set(error, "^_");
return;
@@ -1788,6 +1791,67 @@ teco_state_control_radix(teco_machine_main_t *ctx, GError **error)
}
}
+/*$ ^Q lines2glyphs glyphs2lines
+ * [n]^Q -> glyphs -- Convert between lines and glyph lengths or positions
+ * [position]:^Q -> line
+ *
+ * Converts between line and glyph arguments.
+ * It returns the number of glyphs between dot and the <n>-th next
+ * line (or previous line if <n> is negative).
+ * Consequently \(lq^QC\(rq is equivalent to \(lqL\(rq, but less efficient.
+ *
+ * If colon-modified, an absolute buffer position is converted to the line that
+ * contains this position, beginning with 1.
+ * Without arguments, \(lq:^Q\(rq returns the current line.
+ */
+/*
+ * FIXME: Perhaps there should be a way to convert an absolute line to an
+ * absolute position.
+ */
+static void
+teco_state_control_lines2glyphs(teco_machine_main_t *ctx, GError **error)
+{
+ if (!teco_expressions_eval(FALSE, error))
+ return;
+
+ if (teco_machine_main_eval_colon(ctx)) {
+ gssize pos;
+
+ if (!teco_expressions_args()) {
+ pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
+ } else {
+ teco_int_t v;
+
+ if (!teco_expressions_pop_num_calc(&v, 0, error))
+ return;
+
+ pos = teco_interface_glyphs2bytes(v);
+ if (pos < 0) {
+ teco_error_range_set(error, "^Q");
+ return;
+ }
+ }
+
+ teco_expressions_push(teco_interface_ssm(SCI_LINEFROMPOSITION, pos, 0)+1);
+ } else {
+ teco_int_t v;
+
+ if (!teco_expressions_pop_num_calc(&v, teco_num_sign, error))
+ return;
+
+ sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0);
+ sptr_t line = teco_interface_ssm(SCI_LINEFROMPOSITION, pos, 0) + v;
+
+ if (!teco_validate_line(line)) {
+ teco_error_range_set(error, "^Q");
+ return;
+ }
+
+ sptr_t line_pos = teco_interface_ssm(SCI_POSITIONFROMLINE, line, 0);
+ teco_expressions_push(teco_interface_bytes2glyphs(line_pos) - teco_interface_bytes2glyphs(pos));
+ }
+}
+
/*$ ^E glyphs2bytes bytes2glyphs
* glyphs^E -> bytes -- Translate between glyph and byte indexes
* bytes:^E -> glyphs
@@ -1975,6 +2039,7 @@ teco_state_control_input(teco_machine_main_t *ctx, gunichar chr, GError **error)
['O'] = {&teco_state_start, teco_state_control_octal},
['D'] = {&teco_state_start, teco_state_control_decimal},
['R'] = {&teco_state_start, teco_state_control_radix},
+ ['Q'] = {&teco_state_start, teco_state_control_lines2glyphs},
['E'] = {&teco_state_start, teco_state_control_glyphs2bytes},
['X'] = {&teco_state_start, teco_state_control_search_mode},
['Y'] = {&teco_state_start, teco_state_control_last_range},