tNavigate over tab strings as one character - ve - a minimal text editor (work in progress)
 (HTM) git clone git://src.adamsgaard.dk/ve
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit bc2cd2c1479a6026fcef43418a6e4b9de93a7b3f
 (DIR) parent ec3976286cbc8ff16cf02429d735951bb80a29d4
 (HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
       Date:   Tue,  6 Aug 2019 13:57:33 +0200
       
       Navigate over tab strings as one character
       
       Diffstat:
         M byote.h                             |       2 +-
         M output.c                            |      29 ++++++++++++++++++++++++-----
         M terminal.c                          |       1 +
       
       3 files changed, 26 insertions(+), 6 deletions(-)
       ---
 (DIR) diff --git a/byote.h b/byote.h
       t@@ -17,7 +17,7 @@ typedef struct eRow {
        } eRow;
        
        struct editor_config {
       -        int cursor_x, cursor_y;
       +        int cursor_x, cursor_y, cursor_rx;
                int screen_rows, screen_columns;
                int num_rows;
                eRow *row;
 (DIR) diff --git a/output.c b/output.c
       t@@ -68,19 +68,38 @@ draw_status(struct abuf *ab)
                }
        }
        
       +/* navigate over tab-representative string as one character */
       +int
       +editor_row_cursor_x_to_rx(eRow *row, int cursor_x)
       +{
       +        int rx, j;
       +        rx = 0;
       +        for (j=0; j<cursor_x; ++j) {
       +                if (row->chars[j] == '\t')
       +                        rx += (TAB_WIDTH - 1) - (rx % TAB_WIDTH);
       +                rx++;
       +        }
       +        return rx;
       +}
       +
        /* set vertical offset between file and screen when hitting the boundaries */
        void
        editor_scroll()
        {
       +        E.cursor_rx = 0;
       +        if (E.cursor_y < E.num_rows)
       +                E.cursor_rx = editor_row_cursor_x_to_rx(&E.row[E.cursor_y],
       +                                                        E.cursor_x);
       +
                if (E.cursor_y < E.row_offset)
                        E.row_offset = E.cursor_y;
                else if (E.cursor_y >= E.row_offset + E.screen_rows - E.status_height)
                        E.row_offset = E.cursor_y - E.screen_rows + E.status_height + 1;
        
       -        if (E.cursor_x < E.column_offset)
       -                E.column_offset = E.cursor_x;
       -        else if (E.cursor_x >= E.column_offset + E.screen_columns)
       -                E.column_offset = E.cursor_x - E.screen_columns + 1;
       +        if (E.cursor_rx < E.column_offset)
       +                E.column_offset = E.cursor_rx;
       +        else if (E.cursor_rx >= E.column_offset + E.screen_columns)
       +                E.column_offset = E.cursor_rx - E.screen_columns + 1;
        }
        
        /* draw editor screen.
       t@@ -130,7 +149,7 @@ editor_refresh_screen()
                char buf[32];
                snprintf(buf, sizeof(buf), "\x1b[%d;%dH",
                        (E.cursor_y - E.row_offset)+1,
       -                (E.cursor_x - E.column_offset)+1);
       +                (E.cursor_rx - E.column_offset)+1);
                ab_append(&ab, buf, strlen(buf));
        
                ab_append(&ab, "\x1b[?25h", 6); /* show cursor */
 (DIR) diff --git a/terminal.c b/terminal.c
       t@@ -110,6 +110,7 @@ void
        init_editor() {
                E.cursor_x = 0;
                E.cursor_y = 0;
       +        E.cursor_rx = 0;
                E.mode = 0;
                E.num_rows = 0;
                E.row = NULL;