diff options
Diffstat (limited to 'src/move-commands.c')
| -rw-r--r-- | src/move-commands.c | 72 |
1 files changed, 57 insertions, 15 deletions
diff --git a/src/move-commands.c b/src/move-commands.c index 45afc4e..9ef893e 100644 --- a/src/move-commands.c +++ b/src/move-commands.c @@ -58,12 +58,13 @@ teco_state_start_jump(teco_machine_main_t *ctx, GError **error) if (!teco_expressions_pop_num_calc(&v, 0, error)) return; - gssize pos = teco_interface_glyphs2bytes(v); - if (pos >= 0) { + gssize next_pos = teco_interface_glyphs2bytes_absdot(v); + if (next_pos >= 0) { if (teco_current_doc_must_undo()) undo__teco_interface_ssm(SCI_GOTOPOS, teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0); - teco_interface_ssm(SCI_GOTOPOS, pos, 0); + teco_interface_ssm(SCI_GOTOPOS, next_pos, 0); + teco_current_doc_set_dot(v); if (teco_machine_main_eval_colon(ctx) > 0) teco_expressions_push(TECO_SUCCESS); @@ -78,14 +79,15 @@ teco_state_start_jump(teco_machine_main_t *ctx, GError **error) static teco_bool_t teco_move_chars(teco_int_t n) { - sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); - gssize next_pos = teco_interface_glyphs2bytes_relative(pos, n); + gssize next_pos = teco_interface_glyphs2bytes_reldot(n); if (next_pos < 0) return TECO_FAILURE; - teco_interface_ssm(SCI_GOTOPOS, next_pos, 0); if (teco_current_doc_must_undo()) - undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + undo__teco_interface_ssm(SCI_GOTOPOS, teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0), 0); + + teco_interface_ssm(SCI_GOTOPOS, next_pos, 0); + teco_current_doc_set_dot(teco_current_doc_get_dot() + n); return TECO_SUCCESS; } @@ -151,7 +153,15 @@ teco_move_lines(teco_int_t n) if (!teco_validate_line(line)) return TECO_FAILURE; - teco_interface_ssm(SCI_GOTOLINE, line, 0); + sptr_t next_pos = teco_interface_ssm(SCI_POSITIONFROMLINE, line, 0); + /* + * FIXME: Perhaps it would be more efficient to fall back to the + * line index cache via teco_view_bytes2glyphs_unicode() since next_pos + * is guaranteed to fall on line starts. + */ + teco_current_doc_set_dot(teco_interface_bytes2glyphs_absdot(next_pos)); + teco_interface_ssm(SCI_GOTOPOS, next_pos, 0); + if (teco_current_doc_must_undo()) undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); @@ -388,6 +398,8 @@ teco_state_start_words(teco_machine_main_t *ctx, const gchar *cmd, gint factor, if (rc) { if (teco_current_doc_must_undo()) undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); + + teco_current_doc_set_dot(teco_interface_bytes2glyphs_absdot(word_pos)); teco_interface_ssm(SCI_GOTOPOS, word_pos, 0); } @@ -457,6 +469,9 @@ teco_state_start_delete_words(teco_machine_main_t *ctx, const gchar *cmd, gint f if (rc && start_pos != end_pos) { g_assert(start_pos < end_pos); + if (start_pos < pos) + teco_current_doc_set_dot(teco_interface_bytes2glyphs_absdot(start_pos)); + teco_interface_ssm(SCI_BEGINUNDOACTION, 0, 0); teco_interface_ssm(SCI_DELETERANGE, start_pos, end_pos-start_pos); teco_interface_ssm(SCI_ENDUNDOACTION, 0, 0); @@ -487,8 +502,10 @@ teco_state_start_kill(teco_machine_main_t *ctx, const gchar *cmd, gboolean by_li if (!teco_expressions_eval(FALSE, error)) return FALSE; + sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); + if (teco_expressions_args() <= 1) { - from = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); + from = pos; if (by_lines) { teco_int_t line; if (!teco_expressions_pop_num_calc(&line, teco_num_sign, error)) @@ -496,13 +513,24 @@ teco_state_start_kill(teco_machine_main_t *ctx, const gchar *cmd, gboolean by_li line += teco_interface_ssm(SCI_LINEFROMPOSITION, from, 0); len = teco_interface_ssm(SCI_POSITIONFROMLINE, line, 0) - from; rc = teco_bool(teco_validate_line(line)); + + /* + * FIXME: Perhaps it would be more efficient to fall back to the + * line index cache via teco_view_bytes2glyphs_unicode() since from+len + * is guaranteed to fall on line starts. + */ + if (teco_is_success(rc) && len < 0) + teco_current_doc_set_dot(teco_interface_bytes2glyphs_reldot(len)); } else { teco_int_t len_glyphs; if (!teco_expressions_pop_num_calc(&len_glyphs, teco_num_sign, error)) return FALSE; - gssize to = teco_interface_glyphs2bytes_relative(from, len_glyphs); + gssize to = teco_interface_glyphs2bytes_reldot(len_glyphs); rc = teco_bool(to >= 0); len = to-from; + + if (teco_is_success(rc) && len_glyphs < 0) + teco_current_doc_set_dot(teco_current_doc_get_dot() + len_glyphs); } if (len < 0) { len *= -1; @@ -510,11 +538,18 @@ teco_state_start_kill(teco_machine_main_t *ctx, const gchar *cmd, gboolean by_li } } else { teco_int_t to_glyphs = teco_expressions_pop_num(0); - gssize to = teco_interface_glyphs2bytes(to_glyphs); + gssize to = teco_interface_glyphs2bytes_absdot(to_glyphs); teco_int_t from_glyphs = teco_expressions_pop_num(0); - from = teco_interface_glyphs2bytes(from_glyphs); + from = teco_interface_glyphs2bytes_absdot(from_glyphs); len = to - from; rc = teco_bool(len >= 0 && from >= 0 && to >= 0); + + if (teco_is_success(rc)) { + if (to < pos) + teco_current_doc_set_dot(teco_current_doc_get_dot() - (to_glyphs-from_glyphs)); + else if (from < pos) + teco_current_doc_set_dot(from_glyphs); + } } if (teco_machine_main_eval_colon(ctx) > 0) { @@ -528,7 +563,6 @@ teco_state_start_kill(teco_machine_main_t *ctx, const gchar *cmd, gboolean by_li return TRUE; if (teco_current_doc_must_undo()) { - sptr_t pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); undo__teco_interface_ssm(SCI_GOTOPOS, pos, 0); undo__teco_interface_ssm(SCI_UNDO, 0, 0); } @@ -629,7 +663,11 @@ teco_state_control_lines2glyphs(teco_machine_main_t *ctx, GError **error) if (!teco_expressions_args()) { pos = teco_interface_ssm(SCI_GETCURRENTPOS, 0, 0); } else { - pos = teco_interface_glyphs2bytes(teco_expressions_pop_num(0)); + /* + * FIXME: Could be optimized by directly calling + * SCI_LINEFROMINDEXPOSITION. + */ + pos = teco_interface_glyphs2bytes_absdot(teco_expressions_pop_num(0)); if (pos < 0) { teco_error_range_set(error, "^Q"); return; @@ -652,6 +690,10 @@ teco_state_control_lines2glyphs(teco_machine_main_t *ctx, GError **error) } sptr_t line_pos = teco_interface_ssm(SCI_POSITIONFROMLINE, line, 0); - teco_expressions_push(teco_interface_bytes2glyphs(line_pos) - teco_interface_bytes2glyphs(pos)); + /* + * FIXME: Could be optimized with SCI_INDEXPOSITIONFROMLINE. + */ + teco_expressions_push(teco_interface_bytes2glyphs_absdot(line_pos) - + teco_current_doc_get_dot()); } } |
