Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/editors/vi.c


Ignore:
Timestamp:
Jan 1, 2014, 12:47:38 AM (10 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.21.1
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.2/mindi-busybox/editors/vi.c

    r2725 r3232  
    1515 *  :map macros
    1616 *  if mark[] values were line numbers rather than pointers
    17  *     it would be easier to change the mark when add/delete lines
     17 *      it would be easier to change the mark when add/delete lines
    1818 *  More intelligence in refresh()
    1919 *  ":r !cmd"  and  "!cmd"  to filter text through an external command
     
    2222 */
    2323
     24//config:config VI
     25//config:   bool "vi"
     26//config:   default y
     27//config:   help
     28//config:     'vi' is a text editor. More specifically, it is the One True
     29//config:     text editor <grin>. It does, however, have a rather steep
     30//config:     learning curve. If you are not already comfortable with 'vi'
     31//config:     you may wish to use something else.
     32//config:
     33//config:config FEATURE_VI_MAX_LEN
     34//config:   int "Maximum screen width in vi"
     35//config:   range 256 16384
     36//config:   default 4096
     37//config:   depends on VI
     38//config:   help
     39//config:     Contrary to what you may think, this is not eating much.
     40//config:     Make it smaller than 4k only if you are very limited on memory.
     41//config:
     42//config:config FEATURE_VI_8BIT
     43//config:   bool "Allow vi to display 8-bit chars (otherwise shows dots)"
     44//config:   default n
     45//config:   depends on VI
     46//config:   help
     47//config:     If your terminal can display characters with high bit set,
     48//config:     you may want to enable this. Note: vi is not Unicode-capable.
     49//config:     If your terminal combines several 8-bit bytes into one character
     50//config:     (as in Unicode mode), this will not work properly.
     51//config:
     52//config:config FEATURE_VI_COLON
     53//config:   bool "Enable \":\" colon commands (no \"ex\" mode)"
     54//config:   default y
     55//config:   depends on VI
     56//config:   help
     57//config:     Enable a limited set of colon commands for vi. This does not
     58//config:     provide an "ex" mode.
     59//config:
     60//config:config FEATURE_VI_YANKMARK
     61//config:   bool "Enable yank/put commands and mark cmds"
     62//config:   default y
     63//config:   depends on VI
     64//config:   help
     65//config:     This will enable you to use yank and put, as well as mark in
     66//config:     busybox vi.
     67//config:
     68//config:config FEATURE_VI_SEARCH
     69//config:   bool "Enable search and replace cmds"
     70//config:   default y
     71//config:   depends on VI
     72//config:   help
     73//config:     Select this if you wish to be able to do search and replace in
     74//config:     busybox vi.
     75//config:
     76//config:config FEATURE_VI_REGEX_SEARCH
     77//config:   bool "Enable regex in search and replace"
     78//config:   default n   # Uses GNU regex, which may be unavailable. FIXME
     79//config:   depends on FEATURE_VI_SEARCH
     80//config:   help
     81//config:     Use extended regex search.
     82//config:
     83//config:config FEATURE_VI_USE_SIGNALS
     84//config:   bool "Catch signals"
     85//config:   default y
     86//config:   depends on VI
     87//config:   help
     88//config:     Selecting this option will make busybox vi signal aware. This will
     89//config:     make busybox vi support SIGWINCH to deal with Window Changes, catch
     90//config:     Ctrl-Z and Ctrl-C and alarms.
     91//config:
     92//config:config FEATURE_VI_DOT_CMD
     93//config:   bool "Remember previous cmd and \".\" cmd"
     94//config:   default y
     95//config:   depends on VI
     96//config:   help
     97//config:     Make busybox vi remember the last command and be able to repeat it.
     98//config:
     99//config:config FEATURE_VI_READONLY
     100//config:   bool "Enable -R option and \"view\" mode"
     101//config:   default y
     102//config:   depends on VI
     103//config:   help
     104//config:     Enable the read-only command line option, which allows the user to
     105//config:     open a file in read-only mode.
     106//config:
     107//config:config FEATURE_VI_SETOPTS
     108//config:   bool "Enable set-able options, ai ic showmatch"
     109//config:   default y
     110//config:   depends on VI
     111//config:   help
     112//config:     Enable the editor to set some (ai, ic, showmatch) options.
     113//config:
     114//config:config FEATURE_VI_SET
     115//config:   bool "Support for :set"
     116//config:   default y
     117//config:   depends on VI
     118//config:   help
     119//config:     Support for ":set".
     120//config:
     121//config:config FEATURE_VI_WIN_RESIZE
     122//config:   bool "Handle window resize"
     123//config:   default y
     124//config:   depends on VI
     125//config:   help
     126//config:     Make busybox vi behave nicely with terminals that get resized.
     127//config:
     128//config:config FEATURE_VI_ASK_TERMINAL
     129//config:   bool "Use 'tell me cursor position' ESC sequence to measure window"
     130//config:   default y
     131//config:   depends on VI
     132//config:   help
     133//config:     If terminal size can't be retrieved and $LINES/$COLUMNS are not set,
     134//config:     this option makes vi perform a last-ditch effort to find it:
     135//config:     position cursor to 999,999 and ask terminal to report real
     136//config:     cursor position using "ESC [ 6 n" escape sequence, then read stdin.
     137//config:
     138//config:     This is not clean but helps a lot on serial lines and such.
     139
     140//applet:IF_VI(APPLET(vi, BB_DIR_BIN, BB_SUID_DROP))
     141
     142//kbuild:lib-$(CONFIG_VI) += vi.o
     143
     144//usage:#define vi_trivial_usage
     145//usage:       "[OPTIONS] [FILE]..."
     146//usage:#define vi_full_usage "\n\n"
     147//usage:       "Edit FILE\n"
     148//usage:    IF_FEATURE_VI_COLON(
     149//usage:     "\n    -c CMD  Initial command to run ($EXINIT also available)"
     150//usage:    )
     151//usage:    IF_FEATURE_VI_READONLY(
     152//usage:     "\n    -R  Read-only"
     153//usage:    )
     154//usage:     "\n    -H  List available features"
     155
    24156#include "libbb.h"
     157/* Should be after libbb.h: on some systems regex.h needs sys/types.h: */
     158#if ENABLE_FEATURE_VI_REGEX_SEARCH
     159# include <regex.h>
     160#endif
    25161
    26162/* the CRASHME code is unmaintained, and doesn't currently build */
     
    41177/* 0x9b is Meta-ESC */
    42178#if ENABLE_FEATURE_VI_8BIT
    43 #define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b)
     179# define Isprint(c) ((unsigned char)(c) >= ' ' && (c) != 0x7f && (unsigned char)(c) != 0x9b)
    44180#else
    45 #define Isprint(c) ((unsigned char)(c) >= ' ' && (unsigned char)(c) < 0x7f)
     181# define Isprint(c) ((unsigned char)(c) >= ' ' && (unsigned char)(c) < 0x7f)
    46182#endif
    47183
     
    59195};
    60196
    61 /* vt102 typical ESC sequence */
    62 /* terminal standout start/normal ESC sequence */
    63 #define SOs "\033[7m"
    64 #define SOn "\033[0m"
    65 /* terminal bell sequence */
    66 #define bell "\007"
    67 /* Clear-end-of-line and Clear-end-of-screen ESC sequence */
    68 #define Ceol "\033[K"
    69 #define Ceos "\033[J"
    70 /* Cursor motion arbitrary destination ESC sequence */
    71 #define CMrc "\033[%u;%uH"
    72 /* Cursor motion up and down ESC sequence */
    73 #define CMup "\033[A"
    74 #define CMdown "\n"
     197/* VT102 ESC sequences.
     198 * See "Xterm Control Sequences"
     199 * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
     200 */
     201/* Inverse/Normal text */
     202#define ESC_BOLD_TEXT "\033[7m"
     203#define ESC_NORM_TEXT "\033[0m"
     204/* Bell */
     205#define ESC_BELL "\007"
     206/* Clear-to-end-of-line */
     207#define ESC_CLEAR2EOL "\033[K"
     208/* Clear-to-end-of-screen.
     209 * (We use default param here.
     210 * Full sequence is "ESC [ <num> J",
     211 * <num> is 0/1/2 = "erase below/above/all".)
     212 */
     213#define ESC_CLEAR2EOS "\033[J"
     214/* Cursor to given coordinate (1,1: top left) */
     215#define ESC_SET_CURSOR_POS "\033[%u;%uH"
     216//UNUSED
     217///* Cursor up and down */
     218//#define ESC_CURSOR_UP "\033[A"
     219//#define ESC_CURSOR_DOWN "\n"
    75220
    76221#if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK
     
    135280    int file_modified;       // buffer contents changed (counter, not flag!)
    136281    int last_file_modified;  // = -1;
    137     int fn_start;            // index of first cmd line file name
    138282    int save_argc;           // how many file names on cmd line
    139283    int cmdcnt;              // repetition count
     
    161305    char *ioq, *ioq_start;   // pointer to string for get_one_char to "read"
    162306#endif
    163 #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    164     int last_row;        // where the cursor was last moved to
    165 #endif
    166307#if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME
    167308    int my_pid;
     
    220361#define file_modified           (G.file_modified      )
    221362#define last_file_modified      (G.last_file_modified )
    222 #define fn_start                (G.fn_start           )
    223363#define save_argc               (G.save_argc          )
    224364#define cmdcnt                  (G.cmdcnt             )
     
    248388#define ioq                     (G.ioq                )
    249389#define ioq_start               (G.ioq_start          )
    250 #define last_row                (G.last_row           )
    251390#define my_pid                  (G.my_pid             )
    252391#define last_search_pattern     (G.last_search_pattern)
     
    329468static int file_insert(const char *, char *, int);
    330469static int file_write(char *, char *, char *);
    331 #if !ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    332 #define place_cursor(a, b, optimize) place_cursor(a, b)
    333 #endif
    334 static void place_cursor(int, int, int);
     470static void place_cursor(int, int);
    335471static void screen_erase(void);
    336472static void clear_to_eol(void);
     
    355491#if ENABLE_FEATURE_VI_SEARCH
    356492static char *char_search(char *, const char *, int, int);   // search for pattern starting at p
    357 static int mycmp(const char *, const char *, int);  // string cmp based in "ignorecase"
    358493#endif
    359494#if ENABLE_FEATURE_VI_COLON
     
    418553#endif
    419554
    420     vi_setops = VI_AUTOINDENT | VI_SHOWMATCH | VI_IGNORECASE;
     555    // autoindent is not default in vim 7.3
     556    vi_setops = /*VI_AUTOINDENT |*/ VI_SHOWMATCH | VI_IGNORECASE;
    421557    //  1-  process $HOME/.exrc file (not inplemented yet)
    422558    //  2-  process EXINIT variable from environment
     
    444580        case 'c':       // cmd line vi command
    445581            if (*optarg)
    446                 initial_cmds[initial_cmds[0] != 0] = xstrndup(optarg, MAX_INPUT_LEN);
     582                initial_cmds[initial_cmds[0] != NULL] = xstrndup(optarg, MAX_INPUT_LEN);
    447583            break;
    448584#endif
     
    457593
    458594    // The argv array can be used by the ":next"  and ":rewind" commands
    459     // save optind.
    460     fn_start = optind;  // remember first file name for :next and :rew
     595    argv += optind;
     596    argc -= optind;
     597
     598    //----- This is the main file handling loop --------------
    461599    save_argc = argc;
    462 
    463     //----- This is the main file handling loop --------------
     600    optind = 0;
     601    // "Save cursor, use alternate screen buffer, clear screen"
     602    write1("\033[?1049h");
    464603    while (1) {
    465604        edit_file(argv[optind]); /* param might be NULL */
     
    467606            break;
    468607    }
     608    // "Use normal screen buffer, restore cursor"
     609    write1("\033[?1049l");
    469610    //-----------------------------------------------------------
    470611
     
    524665#endif
    525666    int c;
    526     int size;
    527667#if ENABLE_FEATURE_VI_USE_SIGNALS
    528668    int sig;
     
    533673    rows = 24;
    534674    columns = 80;
    535     size = 0;
    536675    IF_FEATURE_VI_ASK_TERMINAL(G.get_rowcol_error =) query_screen_dimensions();
    537676#if ENABLE_FEATURE_VI_ASK_TERMINAL
     
    8811020        // don't edit, if the current file has been modified
    8821021        if (file_modified && !useforce) {
    883             status_line_bold("No write since last change (:edit! overrides)");
     1022            status_line_bold("No write since last change (:%s! overrides)", cmd);
    8841023            goto ret;
    8851024        }
     
    9001039
    9011040#if ENABLE_FEATURE_VI_YANKMARK
    902         if (Ureg >= 0 && Ureg < 28 && reg[Ureg] != 0) {
     1041        if (Ureg >= 0 && Ureg < 28) {
    9031042            free(reg[Ureg]);    //   free orig line reg- for 'U'
    904             reg[Ureg]= 0;
    905         }
    906         if (YDreg >= 0 && YDreg < 28 && reg[YDreg] != 0) {
     1043            reg[Ureg] = NULL;
     1044        }
     1045        if (YDreg >= 0 && YDreg < 28) {
    9071046            free(reg[YDreg]);   //   free default yank/delete register
    908             reg[YDreg]= 0;
     1047            reg[YDreg] = NULL;
    9091048        }
    9101049#endif
     
    9711110    } else if (strncmp(cmd, "quit", i) == 0 // quit
    9721111            || strncmp(cmd, "next", i) == 0 // edit next file
     1112            || strncmp(cmd, "prev", i) == 0 // edit previous file
    9731113    ) {
    9741114        int n;
    9751115        if (useforce) {
    976             // force end of argv list
    9771116            if (*cmd == 'q') {
     1117                // force end of argv list
    9781118                optind = save_argc;
    9791119            }
     
    9831123        // don't exit if the file been modified
    9841124        if (file_modified) {
    985             status_line_bold("No write since last change (:%s! overrides)",
    986                  (*cmd == 'q' ? "quit" : "next"));
     1125            status_line_bold("No write since last change (:%s! overrides)", cmd);
    9871126            goto ret;
    9881127        }
     
    9961135            status_line_bold("No more files to edit");
    9971136            goto ret;
     1137        }
     1138        if (*cmd == 'p') {
     1139            // are there previous files to edit
     1140            if (optind < 1) {
     1141                status_line_bold("No previous files to edit");
     1142                goto ret;
     1143            }
     1144            optind -= 2;
    9981145        }
    9991146        editing = 0;
     
    10321179    } else if (strncmp(cmd, "rewind", i) == 0) {    // rewind cmd line args
    10331180        if (file_modified && !useforce) {
    1034             status_line_bold("No write since last change (:rewind! overrides)");
     1181            status_line_bold("No write since last change (:%s! overrides)", cmd);
    10351182        } else {
    10361183            // reset the filenames to edit
    1037             optind = fn_start - 1;
     1184            optind = -1; /* start from 0th file */
    10381185            editing = 0;
    10391186        }
     
    10441191#endif
    10451192        i = 0;          // offset into args
    1046         // only blank is regarded as args delmiter. What about tab '\t' ?
     1193        // only blank is regarded as args delimiter. What about tab '\t'?
    10471194        if (!args[0] || strcasecmp(args, "all") == 0) {
    10481195            // print out values of all options
     
    10851232#if ENABLE_FEATURE_VI_SEARCH
    10861233    } else if (cmd[0] == 's') { // substitute a pattern with a replacement pattern
    1087         char *ls, *F, *R;
    1088         int gflag;
     1234        char *F, *R, *flags;
     1235        size_t len_F, len_R;
     1236        int gflag;      // global replace flag
    10891237
    10901238        // F points to the "find" pattern
    10911239        // R points to the "replace" pattern
    1092         // replace the cmd line delimiters "/" with NULLs
    1093         gflag = 0;      // global replace flag
     1240        // replace the cmd line delimiters "/" with NULs
    10941241        c = orig_buf[1];    // what is the delimiter
    10951242        F = orig_buf + 2;   // start of "find"
     
    10971244        if (!R)
    10981245            goto colon_s_fail;
     1246        len_F = R - F;
    10991247        *R++ = '\0';    // terminate "find"
    1100         buf1 = strchr(R, c);
    1101         if (!buf1)
     1248        flags = strchr(R, c);
     1249        if (!flags)
    11021250            goto colon_s_fail;
    1103         *buf1++ = '\0'; // terminate "replace"
    1104         if (*buf1 == 'g') { // :s/foo/bar/g
    1105             buf1++;
    1106             gflag++;    // turn on gflag
    1107         }
     1251        len_R = flags - R;
     1252        *flags++ = '\0';    // terminate "replace"
     1253        gflag = *flags;
     1254
    11081255        q = begin_line(q);
    11091256        if (b < 0) {    // maybe :s/foo/bar/
    1110             q = begin_line(dot);    // start with cur line
    1111             b = count_lines(text, q);   // cur line number
     1257            q = begin_line(dot);      // start with cur line
     1258            b = count_lines(text, q); // cur line number
    11121259        }
    11131260        if (e < 0)
    11141261            e = b;      // maybe :.s/foo/bar/
     1262
    11151263        for (i = b; i <= e; i++) {  // so, :20,23 s \0 find \0 replace \0
    1116             ls = q;     // orig line start
     1264            char *ls = q;       // orig line start
     1265            char *found;
    11171266 vc4:
    1118             buf1 = char_search(q, F, FORWARD, LIMITED); // search cur line only for "find"
    1119             if (buf1) {
     1267            found = char_search(q, F, FORWARD, LIMITED);    // search cur line only for "find"
     1268            if (found) {
    11201269                uintptr_t bias;
    11211270                // we found the "find" pattern - delete it
    1122                 text_hole_delete(buf1, buf1 + strlen(F) - 1);
     1271                text_hole_delete(found, found + len_F - 1);
    11231272                // inset the "replace" patern
    1124                 bias = string_insert(buf1, R);  // insert the string
    1125                 buf1 += bias;
     1273                bias = string_insert(found, R); // insert the string
     1274                found += bias;
    11261275                ls += bias;
    11271276                /*q += bias; - recalculated anyway */
    11281277                // check for "global"  :s/foo/bar/g
    1129                 if (gflag == 1) {
    1130                     if ((buf1 + strlen(R)) < end_line(ls)) {
    1131                         q = buf1 + strlen(R);
     1278                if (gflag == 'g') {
     1279                    if ((found + len_R) < end_line(ls)) {
     1280                        q = found + len_R;
    11321281                        goto vc4;   // don't let q move past cur line
    11331282                    }
     
    15521701
    15531702#if ENABLE_FEATURE_VI_SEARCH
    1554 static int mycmp(const char *s1, const char *s2, int len)
    1555 {
    1556     if (ENABLE_FEATURE_VI_SETOPTS && ignorecase) {
    1557         return strncasecmp(s1, s2, len);
    1558     }
    1559     return strncmp(s1, s2, len);
    1560 }
     1703
     1704# if ENABLE_FEATURE_VI_REGEX_SEARCH
    15611705
    15621706// search for pattern starting at p
    15631707static char *char_search(char *p, const char *pat, int dir, int range)
    15641708{
    1565 #ifndef REGEX_SEARCH
    1566     char *start, *stop;
    1567     int len;
    1568 
    1569     len = strlen(pat);
    1570     if (dir == FORWARD) {
    1571         stop = end - 1; // assume range is p - end-1
    1572         if (range == LIMITED)
    1573             stop = next_line(p);    // range is to next line
    1574         for (start = p; start < stop; start++) {
    1575             if (mycmp(start, pat, len) == 0) {
    1576                 return start;
    1577             }
    1578         }
    1579     } else if (dir == BACK) {
    1580         stop = text;    // assume range is text - p
    1581         if (range == LIMITED)
    1582             stop = prev_line(p);    // range is to prev line
    1583         for (start = p - len; start >= stop; start--) {
    1584             if (mycmp(start, pat, len) == 0) {
    1585                 return start;
    1586             }
    1587         }
    1588     }
    1589     // pattern not found
    1590     return NULL;
    1591 #else /* REGEX_SEARCH */
    15921709    char *q;
    15931710    struct re_pattern_buffer preg;
    15941711    int i;
    1595     int size, range;
     1712    int size;
    15961713
    15971714    re_syntax_options = RE_SYNTAX_POSIX_EXTENDED;
     
    16161733    range = q - p;
    16171734
    1618     q = re_compile_pattern(pat, strlen(pat), &preg);
     1735    q = (char *)re_compile_pattern(pat, strlen(pat), (struct re_pattern_buffer *)&preg);
    16191736    if (q != 0) {
    16201737        // The pattern was not compiled
     
    16501767    }
    16511768    return p;
    1652 #endif /* REGEX_SEARCH */
    1653 }
     1769}
     1770
     1771# else
     1772
     1773#  if ENABLE_FEATURE_VI_SETOPTS
     1774static int mycmp(const char *s1, const char *s2, int len)
     1775{
     1776    if (ignorecase) {
     1777        return strncasecmp(s1, s2, len);
     1778    }
     1779    return strncmp(s1, s2, len);
     1780}
     1781#  else
     1782#   define mycmp strncmp
     1783#  endif
     1784
     1785static char *char_search(char *p, const char *pat, int dir, int range)
     1786{
     1787    char *start, *stop;
     1788    int len;
     1789
     1790    len = strlen(pat);
     1791    if (dir == FORWARD) {
     1792        stop = end - 1; // assume range is p - end-1
     1793        if (range == LIMITED)
     1794            stop = next_line(p);    // range is to next line
     1795        for (start = p; start < stop; start++) {
     1796            if (mycmp(start, pat, len) == 0) {
     1797                return start;
     1798            }
     1799        }
     1800    } else if (dir == BACK) {
     1801        stop = text;    // assume range is text - p
     1802        if (range == LIMITED)
     1803            stop = prev_line(p);    // range is to prev line
     1804        for (start = p - len; start >= stop; start--) {
     1805            if (mycmp(start, pat, len) == 0) {
     1806                return start;
     1807            }
     1808        }
     1809    }
     1810    // pattern not found
     1811    return NULL;
     1812}
     1813
     1814# endif
     1815
    16541816#endif /* FEATURE_VI_SEARCH */
    16551817
     
    16781840        }
    16791841    } else {
     1842#if ENABLE_FEATURE_VI_SETOPTS
    16801843        // insert a char into text[]
    16811844        char *sp;       // "save p"
     1845#endif
    16821846
    16831847        if (c == 13)
    16841848            c = '\n';   // translate \r to \n
     1849#if ENABLE_FEATURE_VI_SETOPTS
    16851850        sp = p;         // remember addr of insert
     1851#endif
    16861852        p += 1 + stupid_insert(p, c);   // insert the char
    16871853#if ENABLE_FEATURE_VI_SETOPTS
     
    17641930        q = dot;
    17651931    } else {
    1766         // nothing -- this causes any other values of c to
    1767         // represent the one-character range under the
    1768         // cursor.  this is correct for ' ' and 'l', but
    1769         // perhaps no others.
    1770         //
     1932        // nothing -- this causes any other values of c to
     1933        // represent the one-character range under the
     1934        // cursor.  this is correct for ' ' and 'l', but
     1935        // perhaps no others.
     1936        //
    17711937    }
    17721938    if (q < p) {
     
    19162082        end         += bias;
    19172083        p           += bias;
     2084#if ENABLE_FEATURE_VI_YANKMARK
     2085        {
     2086            int i;
     2087            for (i = 0; i < ARRAY_SIZE(mark); i++)
     2088                if (mark[i])
     2089                    mark[i] += bias;
     2090        }
     2091#endif
    19182092        text = new_text;
    19192093    }
     
    20022176#endif
    20032177#if ENABLE_FEATURE_VI_DOT_CMD
    2004     "\n\tLast command repeat with \'.\'"
     2178    "\n\tLast command repeat with ."
    20052179#endif
    20062180#if ENABLE_FEATURE_VI_YANKMARK
     
    20092183#endif
    20102184#if ENABLE_FEATURE_VI_READONLY
    2011     "\n\tReadonly if vi is called as \"view\""
    2012     "\n\tReadonly with -R command line arg"
     2185    //not implemented: "\n\tReadonly if vi is called as \"view\""
     2186    //redundant: usage text says this too: "\n\tReadonly with -R command line arg"
    20132187#endif
    20142188#if ENABLE_FEATURE_VI_SET
    2015     "\n\tSome colon mode commands with \':\'"
     2189    "\n\tSome colon mode commands with :"
    20162190#endif
    20172191#if ENABLE_FEATURE_VI_SETOPTS
     
    21472321    tcgetattr(0, &term_orig);
    21482322    term_vi = term_orig;
    2149     term_vi.c_lflag &= (~ICANON & ~ECHO);   // leave ISIG ON- allow intr's
     2323    term_vi.c_lflag &= (~ICANON & ~ECHO);   // leave ISIG on - allow intr's
    21502324    term_vi.c_iflag &= (~IXON & ~ICRNL);
    21512325    term_vi.c_oflag &= (~ONLCR);
     
    24182592
    24192593//----- Move the cursor to row x col (count from 0, not 1) -------
    2420 static void place_cursor(int row, int col, int optimize)
    2421 {
    2422     char cm1[sizeof(CMrc) + sizeof(int)*3 * 2];
    2423 #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    2424     enum {
    2425         SZ_UP = sizeof(CMup),
    2426         SZ_DN = sizeof(CMdown),
    2427         SEQ_SIZE = SZ_UP > SZ_DN ? SZ_UP : SZ_DN,
    2428     };
    2429     char cm2[SEQ_SIZE * 5 + 32]; // bigger than worst case size
    2430 #endif
    2431     char *cm;
     2594static void place_cursor(int row, int col)
     2595{
     2596    char cm1[sizeof(ESC_SET_CURSOR_POS) + sizeof(int)*3 * 2];
    24322597
    24332598    if (row < 0) row = 0;
     
    24362601    if (col >= columns) col = columns - 1;
    24372602
    2438     //----- 1.  Try the standard terminal ESC sequence
    2439     sprintf(cm1, CMrc, row + 1, col + 1);
    2440     cm = cm1;
    2441 
    2442 #if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR
    2443     if (optimize && col < 16) {
    2444         char *screenp;
    2445         int Rrow = last_row;
    2446         int diff = Rrow - row;
    2447 
    2448         if (diff < -5 || diff > 5)
    2449             goto skip;
    2450 
    2451         //----- find the minimum # of chars to move cursor -------------
    2452         //----- 2.  Try moving with discreet chars (Newline, [back]space, ...)
    2453         cm2[0] = '\0';
    2454 
    2455         // move to the correct row
    2456         while (row < Rrow) {
    2457             // the cursor has to move up
    2458             strcat(cm2, CMup);
    2459             Rrow--;
    2460         }
    2461         while (row > Rrow) {
    2462             // the cursor has to move down
    2463             strcat(cm2, CMdown);
    2464             Rrow++;
    2465         }
    2466 
    2467         // now move to the correct column
    2468         strcat(cm2, "\r");          // start at col 0
    2469         // just send out orignal source char to get to correct place
    2470         screenp = &screen[row * columns];   // start of screen line
    2471         strncat(cm2, screenp, col);
    2472 
    2473         // pick the shortest cursor motion to send out
    2474         if (strlen(cm2) < strlen(cm)) {
    2475             cm = cm2;
    2476         }
    2477  skip: ;
    2478     }
    2479     last_row = row;
    2480 #endif /* FEATURE_VI_OPTIMIZE_CURSOR */
    2481     write1(cm);
     2603    sprintf(cm1, ESC_SET_CURSOR_POS, row + 1, col + 1);
     2604    write1(cm1);
    24822605}
    24832606
     
    24852608static void clear_to_eol(void)
    24862609{
    2487     write1(Ceol);   // Erase from cursor to end of line
     2610    write1(ESC_CLEAR2EOL);
    24882611}
    24892612
    24902613static void go_bottom_and_clear_to_eol(void)
    24912614{
    2492     place_cursor(rows - 1, 0, FALSE); // go to bottom of screen
    2493     clear_to_eol(); // erase to end of line
     2615    place_cursor(rows - 1, 0);
     2616    clear_to_eol();
    24942617}
    24952618
     
    24972620static void clear_to_eos(void)
    24982621{
    2499     write1(Ceos);   // Erase from cursor to end of screen
     2622    write1(ESC_CLEAR2EOS);
    25002623}
    25012624
    25022625//----- Start standout mode ------------------------------------
    2503 static void standout_start(void) // send "start reverse video" sequence
    2504 {
    2505     write1(SOs);     // Start reverse video mode
     2626static void standout_start(void)
     2627{
     2628    write1(ESC_BOLD_TEXT);
    25062629}
    25072630
    25082631//----- End standout mode --------------------------------------
    2509 static void standout_end(void) // send "end reverse video" sequence
    2510 {
    2511     write1(SOn);     // End reverse video mode
     2632static void standout_end(void)
     2633{
     2634    write1(ESC_NORM_TEXT);
    25122635}
    25132636
     
    25152638static void flash(int h)
    25162639{
    2517     standout_start();   // send "start reverse video" sequence
     2640    standout_start();
    25182641    redraw(TRUE);
    25192642    mysleep(h);
    2520     standout_end();     // send "end reverse video" sequence
     2643    standout_end();
    25212644    redraw(TRUE);
    25222645}
     
    25292652#endif
    25302653    if (!err_method) {
    2531         write1(bell);   // send out a bell character
     2654        write1(ESC_BELL);
    25322655    } else {
    25332656        flash(10);
     
    25752698            have_status_msg = 0;
    25762699        }
    2577         place_cursor(crow, ccol, FALSE);    // put cursor back in correct place
     2700        place_cursor(crow, ccol);  // put cursor back in correct place
    25782701    }
    25792702    fflush_all();
     
    25872710
    25882711    va_start(args, format);
    2589     strcpy(status_buffer, SOs); // Terminal standout mode on
    2590     vsprintf(status_buffer + sizeof(SOs)-1, format, args);
    2591     strcat(status_buffer, SOn); // Terminal standout mode off
     2712    strcpy(status_buffer, ESC_BOLD_TEXT);
     2713    vsprintf(status_buffer + sizeof(ESC_BOLD_TEXT)-1, format, args);
     2714    strcat(status_buffer, ESC_NORM_TEXT);
    25922715    va_end(args);
    25932716
    2594     have_status_msg = 1 + sizeof(SOs) + sizeof(SOn) - 2;
     2717    have_status_msg = 1 + sizeof(ESC_BOLD_TEXT) + sizeof(ESC_NORM_TEXT) - 2;
    25952718}
    25962719
     
    26242747        c_is_no_print = (c & 0x80) && !Isprint(c);
    26252748        if (c_is_no_print) {
    2626             strcpy(d, SOn);
    2627             d += sizeof(SOn)-1;
     2749            strcpy(d, ESC_NORM_TEXT);
     2750            d += sizeof(ESC_NORM_TEXT)-1;
    26282751            c = '.';
    26292752        }
     
    26372760        *d = '\0';
    26382761        if (c_is_no_print) {
    2639             strcpy(d, SOs);
    2640             d += sizeof(SOs)-1;
     2762            strcpy(d, ESC_BOLD_TEXT);
     2763            d += sizeof(ESC_BOLD_TEXT)-1;
    26412764        }
    26422765        if (*s == '\n') {
     
    27202843static void redraw(int full_screen)
    27212844{
    2722     place_cursor(0, 0, FALSE);  // put cursor in correct place
    2723     clear_to_eos();     // tell terminal to erase display
     2845    place_cursor(0, 0);
     2846    clear_to_eos();
    27242847    screen_erase();     // erase the internal screen buffer
    27252848    last_status_cksum = 0;  // force status update
     
    28612984            // copy changed part of buffer to virtual screen
    28622985            memcpy(sp+cs, out_buf+cs, ce-cs+1);
    2863 
    2864             // move cursor to column of first change
    2865             //if (offset != old_offset) {
    2866             //  // place_cursor is still too stupid
    2867             //  // to handle offsets correctly
    2868             //  place_cursor(li, cs, FALSE);
    2869             //} else {
    2870                 place_cursor(li, cs, TRUE);
    2871             //}
    2872 
     2986            place_cursor(li, cs);
    28732987            // write line out to terminal
    28742988            fwrite(&sp[cs], ce - cs + 1, 1, stdout);
     
    28762990    }
    28772991
    2878     place_cursor(crow, ccol, TRUE);
     2992    place_cursor(crow, ccol);
    28792993
    28802994    old_offset = offset;
     
    29063020static void do_cmd(int c)
    29073021{
    2908     const char *msg = msg; // for compiler
    29093022    char *p, *q, *save_dot;
    29103023    char buf[12];
     
    29153028//  c1 = c; // quiet the compiler
    29163029//  cnt = yf = 0; // quiet the compiler
    2917 //  msg = p = q = save_dot = buf; // quiet the compiler
    2918     memset(buf, '\0', 12);
     3030//  p = q = save_dot = buf; // quiet the compiler
     3031    memset(buf, '\0', sizeof(buf));
    29193032
    29203033    show_status_line();
     
    30323145    case 8:     // ctrl-H- move left    (This may be ERASE char)
    30333146    case 0x7f:  // DEL- move left   (This may be ERASE char)
    3034         if (--cmdcnt > 0) {
    3035             do_cmd(c);
    3036         }
    3037         dot_left();
     3147        do {
     3148            dot_left();
     3149        } while (--cmdcnt > 0);
    30383150        break;
    30393151    case 10:            // Newline ^J
    30403152    case 'j':           // j- goto next line, same col
    30413153    case KEYCODE_DOWN:  // cursor key Down
    3042         if (--cmdcnt > 0) {
    3043             do_cmd(c);
    3044         }
    3045         dot_next();     // go to next B-o-l
    3046         dot = move_to_col(dot, ccol + offset);  // try stay in same col
     3154        do {
     3155            dot_next();     // go to next B-o-l
     3156            // try stay in same col
     3157            dot = move_to_col(dot, ccol + offset);
     3158        } while (--cmdcnt > 0);
    30473159        break;
    30483160    case 12:            // ctrl-L  force redraw whole screen
    30493161    case 18:            // ctrl-R  force redraw
    3050         place_cursor(0, 0, FALSE);  // put cursor in correct place
    3051         clear_to_eos(); // tel terminal to erase display
    3052         mysleep(10);
     3162        place_cursor(0, 0);
     3163        clear_to_eos();
     3164        //mysleep(10); // why???
    30533165        screen_erase(); // erase the internal screen buffer
    30543166        last_status_cksum = 0;  // force status update
     
    30573169    case 13:            // Carriage Return ^M
    30583170    case '+':           // +- goto next line
    3059         if (--cmdcnt > 0) {
    3060             do_cmd(c);
    3061         }
    3062         dot_next();
    3063         dot_skip_over_ws();
     3171        do {
     3172            dot_next();
     3173            dot_skip_over_ws();
     3174        } while (--cmdcnt > 0);
    30643175        break;
    30653176    case 21:            // ctrl-U  scroll up   half screen
     
    30793190    case 'l':           // move right
    30803191    case KEYCODE_RIGHT: // Cursor Key Right
    3081         if (--cmdcnt > 0) {
    3082             do_cmd(c);
    3083         }
    3084         dot_right();
     3192        do {
     3193            dot_right();
     3194        } while (--cmdcnt > 0);
    30853195        break;
    30863196#if ENABLE_FEATURE_VI_YANKMARK
     
    31523262        break;
    31533263    case 'U':           // U- Undo; replace current line with original version
    3154         if (reg[Ureg] != 0) {
     3264        if (reg[Ureg] != NULL) {
    31553265            p = begin_line(dot);
    31563266            q = end_line(dot);
     
    31643274    case '$':           // $- goto end of line
    31653275    case KEYCODE_END:       // Cursor Key End
    3166         if (--cmdcnt > 0) {
     3276        for (;;) {
     3277            dot = end_line(dot);
     3278            if (--cmdcnt <= 0)
     3279                break;
    31673280            dot_next();
    3168             do_cmd(c);
    3169         }
    3170         dot = end_line(dot);
     3281        }
    31713282        break;
    31723283    case '%':           // %- find matching char of pair () [] {}
     
    31933304        //**** fall through to ... ';'
    31943305    case ';':           // ;- look at rest of line for last forward char
    3195         if (--cmdcnt > 0) {
    3196             do_cmd(';');
    3197         }
     3306        do {
     3307            if (last_forward_char == 0)
     3308                break;
     3309            q = dot + 1;
     3310            while (q < end - 1 && *q != '\n' && *q != last_forward_char) {
     3311                q++;
     3312            }
     3313            if (*q == last_forward_char)
     3314                dot = q;
     3315        } while (--cmdcnt > 0);
     3316        break;
     3317    case ',':           // repeat latest 'f' in opposite direction
    31983318        if (last_forward_char == 0)
    31993319            break;
    3200         q = dot + 1;
    3201         while (q < end - 1 && *q != '\n' && *q != last_forward_char) {
    3202             q++;
    3203         }
    3204         if (*q == last_forward_char)
    3205             dot = q;
    3206         break;
    3207     case ',':           // repeat latest 'f' in opposite direction
    3208         if (--cmdcnt > 0) {
    3209             do_cmd(',');
    3210         }
    3211         if (last_forward_char == 0)
    3212             break;
    3213         q = dot - 1;
    3214         while (q >= text && *q != '\n' && *q != last_forward_char) {
    3215             q--;
    3216         }
    3217         if (q >= text && *q == last_forward_char)
    3218             dot = q;
     3320        do {
     3321            q = dot - 1;
     3322            while (q >= text && *q != '\n' && *q != last_forward_char) {
     3323                q--;
     3324            }
     3325            if (q >= text && *q == last_forward_char)
     3326                dot = q;
     3327        } while (--cmdcnt > 0);
    32193328        break;
    32203329
    32213330    case '-':           // -- goto prev line
    3222         if (--cmdcnt > 0) {
    3223             do_cmd(c);
    3224         }
    3225         dot_prev();
    3226         dot_skip_over_ws();
     3331        do {
     3332            dot_prev();
     3333            dot_skip_over_ws();
     3334        } while (--cmdcnt > 0);
    32273335        break;
    32283336#if ENABLE_FEATURE_VI_DOT_CMD
     
    32563364        break;
    32573365    case 'N':           // N- backward search for last pattern
    3258         if (--cmdcnt > 0) {
    3259             do_cmd(c);
    3260         }
    32613366        dir = BACK;     // assume BACKWARD search
    32623367        p = dot - 1;
     
    32703375        // search rest of text[] starting at next char
    32713376        // if search fails return orignal "p" not the "p+1" address
    3272         if (--cmdcnt > 0) {
    3273             do_cmd(c);
    3274         }
     3377        do {
     3378            const char *msg;
    32753379 dc3:
    3276         dir = FORWARD;  // assume FORWARD search
    3277         p = dot + 1;
    3278         if (last_search_pattern[0] == '?') {
    3279             dir = BACK;
    3280             p = dot - 1;
    3281         }
     3380            dir = FORWARD;  // assume FORWARD search
     3381            p = dot + 1;
     3382            if (last_search_pattern[0] == '?') {
     3383                dir = BACK;
     3384                p = dot - 1;
     3385            }
    32823386 dc4:
    3283         q = char_search(p, last_search_pattern + 1, dir, FULL);
    3284         if (q != NULL) {
    3285             dot = q;    // good search, update "dot"
    3286             msg = "";
    3287             goto dc2;
    3288         }
    3289         // no pattern found between "dot" and "end"- continue at top
    3290         p = text;
    3291         if (dir == BACK) {
    3292             p = end - 1;
    3293         }
    3294         q = char_search(p, last_search_pattern + 1, dir, FULL);
    3295         if (q != NULL) {    // found something
    3296             dot = q;    // found new pattern- goto it
    3297             msg = "search hit BOTTOM, continuing at TOP";
     3387            q = char_search(p, last_search_pattern + 1, dir, FULL);
     3388            if (q != NULL) {
     3389                dot = q;    // good search, update "dot"
     3390                msg = NULL;
     3391                goto dc2;
     3392            }
     3393            // no pattern found between "dot" and "end"- continue at top
     3394            p = text;
    32983395            if (dir == BACK) {
    3299                 msg = "search hit TOP, continuing at BOTTOM";
    3300             }
    3301         } else {
    3302             msg = "Pattern not found";
    3303         }
     3396                p = end - 1;
     3397            }
     3398            q = char_search(p, last_search_pattern + 1, dir, FULL);
     3399            if (q != NULL) {    // found something
     3400                dot = q;    // found new pattern- goto it
     3401                msg = "search hit BOTTOM, continuing at TOP";
     3402                if (dir == BACK) {
     3403                    msg = "search hit TOP, continuing at BOTTOM";
     3404                }
     3405            } else {
     3406                msg = "Pattern not found";
     3407            }
    33043408 dc2:
    3305         if (*msg)
    3306             status_line_bold("%s", msg);
     3409            if (msg)
     3410                status_line_bold("%s", msg);
     3411        } while (--cmdcnt > 0);
    33073412        break;
    33083413    case '{':           // {- move backward paragraph
     
    33493454        ) {
    33503455            if (file_modified && p[1] != '!') {
    3351                 status_line_bold("No write since last change (:quit! overrides)");
     3456                status_line_bold("No write since last change (:%s! overrides)", p);
    33523457            } else {
    33533458                editing = 0;
     
    34233528    case 'E':           // E- end of a blank-delimited word
    34243529    case 'W':           // W- forward a blank-delimited word
    3425         if (--cmdcnt > 0) {
    3426             do_cmd(c);
    3427         }
    34283530        dir = FORWARD;
    34293531        if (c == 'B')
    34303532            dir = BACK;
    3431         if (c == 'W' || isspace(dot[dir])) {
    3432             dot = skip_thing(dot, 1, dir, S_TO_WS);
    3433             dot = skip_thing(dot, 2, dir, S_OVER_WS);
    3434         }
    3435         if (c != 'W')
    3436             dot = skip_thing(dot, 1, dir, S_BEFORE_WS);
     3533        do {
     3534            if (c == 'W' || isspace(dot[dir])) {
     3535                dot = skip_thing(dot, 1, dir, S_TO_WS);
     3536                dot = skip_thing(dot, 2, dir, S_OVER_WS);
     3537            }
     3538            if (c != 'W')
     3539                dot = skip_thing(dot, 1, dir, S_BEFORE_WS);
     3540        } while (--cmdcnt > 0);
    34373541        break;
    34383542    case 'C':           // C- Change to e-o-l
     
    34853589    case KEYCODE_INSERT:    // Cursor Key Insert
    34863590 dc_i:
    3487         cmd_mode = 1;   // start insrting
     3591        cmd_mode = 1;   // start inserting
    34883592        break;
    34893593    case 'J':           // J- join current and next lines together
    3490         if (--cmdcnt > 1) {
    3491             do_cmd(c);
    3492         }
    3493         dot_end();      // move to NL
    3494         if (dot < end - 1) {    // make sure not last char in text[]
    3495             *dot++ = ' ';   // replace NL with space
    3496             file_modified++;
    3497             while (isblank(*dot)) { // delete leading WS
    3498                 dot_delete();
    3499             }
    3500         }
     3594        do {
     3595            dot_end();      // move to NL
     3596            if (dot < end - 1) {    // make sure not last char in text[]
     3597                *dot++ = ' ';   // replace NL with space
     3598                file_modified++;
     3599                while (isblank(*dot)) { // delete leading WS
     3600                    dot_delete();
     3601                }
     3602            }
     3603        } while (--cmdcnt > 0);
    35013604        end_cmd_q();    // stop adding to q
    35023605        break;
     
    35423645    case 'x':           // x- delete the current char
    35433646    case 's':           // s- substitute the current char
    3544         if (--cmdcnt > 0) {
    3545             do_cmd(c);
    3546         }
    35473647        dir = 0;
    35483648        if (c == 'X')
    35493649            dir = -1;
    3550         if (dot[dir] != '\n') {
    3551             if (c == 'X')
    3552                 dot--;  // delete prev char
    3553             dot = yank_delete(dot, dot, 0, YANKDEL);    // delete char
    3554         }
     3650        do {
     3651            if (dot[dir] != '\n') {
     3652                if (c == 'X')
     3653                    dot--;  // delete prev char
     3654                dot = yank_delete(dot, dot, 0, YANKDEL);    // delete char
     3655            }
     3656        } while (--cmdcnt > 0);
     3657        end_cmd_q();    // stop adding to q
    35553658        if (c == 's')
    3556             goto dc_i;  // start insrting
    3557         end_cmd_q();    // stop adding to q
     3659            goto dc_i;  // start inserting
    35583660        break;
    35593661    case 'Z':           // Z- if modified, {write}; exit
     
    35863688    case 'b':           // b- back a word
    35873689    case 'e':           // e- end of word
    3588         if (--cmdcnt > 0) {
    3589             do_cmd(c);
    3590         }
    35913690        dir = FORWARD;
    35923691        if (c == 'b')
    35933692            dir = BACK;
    3594         if ((dot + dir) < text || (dot + dir) > end - 1)
    3595             break;
    3596         dot += dir;
    3597         if (isspace(*dot)) {
    3598             dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS);
    3599         }
    3600         if (isalnum(*dot) || *dot == '_') {
    3601             dot = skip_thing(dot, 1, dir, S_END_ALNUM);
    3602         } else if (ispunct(*dot)) {
    3603             dot = skip_thing(dot, 1, dir, S_END_PUNCT);
    3604         }
     3693        do {
     3694            if ((dot + dir) < text || (dot + dir) > end - 1)
     3695                break;
     3696            dot += dir;
     3697            if (isspace(*dot)) {
     3698                dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS);
     3699            }
     3700            if (isalnum(*dot) || *dot == '_') {
     3701                dot = skip_thing(dot, 1, dir, S_END_ALNUM);
     3702            } else if (ispunct(*dot)) {
     3703                dot = skip_thing(dot, 1, dir, S_END_PUNCT);
     3704            }
     3705        } while (--cmdcnt > 0);
    36053706        break;
    36063707    case 'c':           // c- change something
     
    36873788    case 'k':           // k- goto prev line, same col
    36883789    case KEYCODE_UP:        // cursor key Up
    3689         if (--cmdcnt > 0) {
    3690             do_cmd(c);
    3691         }
    3692         dot_prev();
    3693         dot = move_to_col(dot, ccol + offset);  // try stay in same col
     3790        do {
     3791            dot_prev();
     3792            dot = move_to_col(dot, ccol + offset);  // try stay in same col
     3793        } while (--cmdcnt > 0);
    36943794        break;
    36953795    case 'r':           // r- replace the current char with user input
     
    37093809        break;
    37103810    case 'w':           // w- forward a word
    3711         if (--cmdcnt > 0) {
    3712             do_cmd(c);
    3713         }
    3714         if (isalnum(*dot) || *dot == '_') { // we are on ALNUM
    3715             dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM);
    3716         } else if (ispunct(*dot)) { // we are on PUNCT
    3717             dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT);
    3718         }
    3719         if (dot < end - 1)
    3720             dot++;      // move over word
    3721         if (isspace(*dot)) {
    3722             dot = skip_thing(dot, 2, FORWARD, S_OVER_WS);
    3723         }
     3811        do {
     3812            if (isalnum(*dot) || *dot == '_') { // we are on ALNUM
     3813                dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM);
     3814            } else if (ispunct(*dot)) { // we are on PUNCT
     3815                dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT);
     3816            }
     3817            if (dot < end - 1)
     3818                dot++;      // move over word
     3819            if (isspace(*dot)) {
     3820                dot = skip_thing(dot, 2, FORWARD, S_OVER_WS);
     3821            }
     3822        } while (--cmdcnt > 0);
    37243823        break;
    37253824    case 'z':           // z-
     
    37373836        break;
    37383837    case '~':           // ~- flip the case of letters   a-z -> A-Z
    3739         if (--cmdcnt > 0) {
    3740             do_cmd(c);
    3741         }
    3742         if (islower(*dot)) {
    3743             *dot = toupper(*dot);
    3744             file_modified++;
    3745         } else if (isupper(*dot)) {
    3746             *dot = tolower(*dot);
    3747             file_modified++;
    3748         }
    3749         dot_right();
     3838        do {
     3839            if (islower(*dot)) {
     3840                *dot = toupper(*dot);
     3841                file_modified++;
     3842            } else if (isupper(*dot)) {
     3843                *dot = tolower(*dot);
     3844                file_modified++;
     3845            }
     3846            dot_right();
     3847        } while (--cmdcnt > 0);
    37503848        end_cmd_q();    // stop adding to q
    37513849        break;
     
    39834081    if (msg[0]) {
    39844082        printf("\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s",
    3985             totalcmds, last_input_char, msg, SOs, SOn);
     4083            totalcmds, last_input_char, msg, ESC_BOLD_TEXT, ESC_NORM_TEXT);
    39864084        fflush_all();
    39874085        while (safe_read(STDIN_FILENO, d, 1) > 0) {
Note: See TracChangeset for help on using the changeset viewer.