tvi: r command - neatvi - [fork] simple vi-type editor with UTF-8 support
 (HTM) git clone git://src.adamsgaard.dk/neatvi
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit a64cb496ec7b0bed834969f1cf845e7d3c0b6d31
 (DIR) parent 6ec7a51894148a1051971d3b7628094f70cf2c9e
 (HTM) Author: Ali Gholami Rudi <ali@rudi.ir>
       Date:   Thu, 14 May 2015 18:08:38 +0430
       
       vi: r command
       
       Diffstat:
         M led.c                               |       8 +++-----
         M vi.c                                |      49 +++++++++++++++++++++++++++----
         M vi.h                                |       1 +
       
       3 files changed, 48 insertions(+), 10 deletions(-)
       ---
 (DIR) diff --git a/led.c b/led.c
       t@@ -5,8 +5,6 @@
        #include "vi.h"
        #include "kmap.h"
        
       -#define TK_STOP(c)                ((c) < 0 || (c) == TK_ESC || (c) == TK_CTL('c'))
       -
        static char **led_kmap = kmap_def;
        
        static char *keymap(char **kmap, int c)
       t@@ -150,11 +148,11 @@ static char *led_line(char *pref, char *post, int *key, char ***kmap)
                                        sbuf_cut(sb, led_lastword(sbuf_buf(sb)));
                                break;
                        default:
       -                        if (c == '\n' || TK_STOP(c))
       +                        if (c == '\n' || TK_INT(c))
                                        break;
                                sbuf_str(sb, keymap(*kmap, c));
                        }
       -                if (c == '\n' || TK_STOP(c))
       +                if (c == '\n' || TK_INT(c))
                                break;
                }
                *key = c;
       t@@ -193,7 +191,7 @@ char *led_input(char *pref, char *post)
                        if (key != '\n')
                                break;
                }
       -        if (TK_STOP(key))
       +        if (TK_INT(key))
                        return sbuf_done(sb);
                sbuf_free(sb);
                return NULL;
 (DIR) diff --git a/vi.c b/vi.c
       t@@ -55,7 +55,8 @@ static void vi_back(int c)
        
        static char *vi_char(void)
        {
       -        return led_keymap(vi_read());
       +        int key = vi_read();
       +        return TK_INT(key) ? NULL : led_keymap(key);
        }
        
        static int vi_prefix(void)
       t@@ -796,6 +797,40 @@ static void vi_status(void)
                led_print(stat, xrows);
        }
        
       +static int vc_replace(int arg)
       +{
       +        int cnt = MAX(1, arg);
       +        char *cs = vi_char();
       +        char *ln = lbuf_get(xb, xrow);
       +        struct sbuf *sb;
       +        char *pref, *post;
       +        char *s;
       +        int off, i;
       +        if (!ln || !cs)
       +                return 1;
       +        off = ren_off(ln, xcol);
       +        s = uc_chr(ln, off);
       +        for (i = 0; s[0] != '\n' && i < cnt; i++)
       +                s = uc_next(s);
       +        if (i < cnt)
       +                return 1;
       +        pref = uc_sub(ln, 0, off);
       +        post = uc_sub(ln, off + cnt, -1);
       +        sb = sbuf_make();
       +        sbuf_str(sb, pref);
       +        for (i = 0; i < cnt; i++)
       +                sbuf_str(sb, cs);
       +        sbuf_str(sb, post);
       +        lbuf_rm(xb, xrow, xrow + 1);
       +        lbuf_put(xb, xrow, sbuf_buf(sb));
       +        off += cnt - 1;
       +        xcol = ren_pos(sbuf_buf(sb), off);
       +        sbuf_free(sb);
       +        free(pref);
       +        free(post);
       +        return 0;
       +}
       +
        static void vi(void)
        {
                int mark;
       t@@ -829,10 +864,6 @@ static void vi(void)
                                if (c <= 0)
                                        continue;
                                switch (c) {
       -                        case 'u':
       -                                lbuf_undo(xb);
       -                                redraw = 1;
       -                                break;
                                case TK_CTL('b'):
                                        if (vi_scrollbackward((pre1 ? pre1 : 1) * (xrows - 1)))
                                                break;
       t@@ -855,6 +886,10 @@ static void vi(void)
                                                break;
                                        redraw = 1;
                                        break;
       +                        case 'u':
       +                                lbuf_undo(xb);
       +                                redraw = 1;
       +                                break;
                                case TK_CTL('r'):
                                        lbuf_redo(xb);
                                        redraw = 1;
       t@@ -947,6 +982,10 @@ static void vi(void)
                                        vc_motion('d', pre1);
                                        redraw = 1;
                                        break;
       +                        case 'r':
       +                                vc_replace(pre1);
       +                                redraw = 1;
       +                                break;
                                case 's':
                                        vi_back(' ');
                                        vc_motion('c', pre1);
 (DIR) diff --git a/vi.h b/vi.h
       t@@ -105,6 +105,7 @@ void term_record(void);
        void term_commit(void);
        
        #define TK_CTL(x)        ((x) & 037)
       +#define TK_INT(c)        ((c) < 0 || (c) == TK_ESC || (c) == TK_CTL('c'))
        #define TK_ESC                (TK_CTL('['))
        
        /* line-oriented input and output */