mg is a fine little editor, but it just seems so emacs-centric.
This little diff fixes that. Please test and get back to me.

Maybe *now* we'll get some users.

-kj

Index: Makefile
===================================================================
RCS file: /cvs/src/usr.bin/mg/Makefile,v
retrieving revision 1.19
diff -u -r1.19 Makefile
--- Makefile    16 Dec 2006 17:00:03 -0000      1.19
+++ Makefile    1 Apr 2007 18:33:37 -0000
@@ -13,14 +13,15 @@
 #                              XKEYS and bsmap mode do _not_ get along.
 #      REGEX           -- create regular expression functions
 #
-CFLAGS+=-Wall -DXKEYS -DFKEYS -DREGEX
+#      VI              -- the one true way
+CFLAGS+=-Wall -DXKEYS -DFKEYS -DREGEX -DVI
 
 SRCS=  cinfo.c fileio.c spawn.c ttyio.c tty.c ttykbd.c \
        basic.c dir.c dired.c file.c line.c match.c paragraph.c \
        random.c region.c search.c version.c window.c word.c \
        buffer.c display.c echo.c extend.c help.c kbd.c keymap.c \
        macro.c main.c modes.c re_search.c funmap.c undo.c autoexec.c \
-       yank.c
+       yank.c vi.c
 
 #
 # More or less standalone extensions.
Index: basic.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/basic.c,v
retrieving revision 1.28
diff -u -r1.28 basic.c
--- basic.c     20 Dec 2006 21:21:09 -0000      1.28
+++ basic.c     1 Apr 2007 18:33:37 -0000
@@ -64,6 +64,10 @@
 int
 gotoeol(int f, int n)
 {
+       while (n > 1) {
+               forwline(FFRAND, 1);
+               n--;
+       }
        curwp->w_doto = llength(curwp->w_dotp);
        return (TRUE);
 }
Index: def.h
===================================================================
RCS file: /cvs/src/usr.bin/mg/def.h,v
retrieving revision 1.99
diff -u -r1.99 def.h
--- def.h       21 Feb 2007 23:33:12 -0000      1.99
+++ def.h       1 Apr 2007 18:33:37 -0000
@@ -109,6 +109,17 @@
 #define KBACK  2
 
 /*
+ * Search codes
+ */
+#define SRCH_BEGIN     (0)
+#define SRCH_FORW      (-1)
+#define SRCH_BACK      (-2)
+#define SRCH_NOPR      (-3)
+#define SRCH_ACCM      (-4)
+#define SRCH_MARK      (-5)
+
+
+/*
  * This structure holds the starting position
  * (as a line/offset pair) and the number of characters in a
  * region of a buffer. This makes passing the specification
@@ -272,7 +283,10 @@
 #endif
 #define BFOVERWRITE 0x08               /* overwrite mode                */
 #define BFREADONLY  0x10               /* read only mode                */
-
+#ifdef VI
+#define BFVICMD                0x20            /* VI command mode              
 */
+#define BFVIINS                0x40            /* VI insert mode               
 */
+#endif
 /*
  * This structure holds information about recent actions for the Undo command.
  */
@@ -573,6 +587,7 @@
 #endif /* !NO_MACRO */
 
 /* modes.c X */
+int             changemode(int, int, char *);
 int             indentmode(int, int);
 int             fillmode(int, int);
 int             blinkparen(int, int);
Index: extend.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/extend.c,v
retrieving revision 1.50
diff -u -r1.50 extend.c
--- extend.c    30 Dec 2006 14:11:06 -0000      1.50
+++ extend.c    1 Apr 2007 18:33:38 -0000
@@ -555,11 +555,16 @@
 {
        PF       funct;
        char     xname[NXNAME], *bufp;
+       char    *pref = "M-x ";
 
+#ifdef VI
+       if (curbp->b_flag & BFVICMD)
+               pref = ":";
+#endif
        if (!(f & FFARG))
-               bufp = eread("M-x ", xname, NXNAME, EFNEW | EFFUNC);
+               bufp = eread("%s", xname, NXNAME, EFNEW | EFFUNC, pref);
        else
-               bufp = eread("%d M-x ", xname, NXNAME, EFNEW | EFFUNC, n);
+               bufp = eread("%d %s", xname, NXNAME, EFNEW | EFFUNC, n, pref);
        if (bufp == NULL)
                return (ABORT);
        else if (bufp[0] == '\0')
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/main.c,v
retrieving revision 1.56
diff -u -r1.56 main.c
--- main.c      20 Feb 2007 04:39:45 -0000      1.56
+++ main.c      1 Apr 2007 18:33:38 -0000
@@ -76,7 +76,11 @@
                extern void theo_init(void);
                extern void mail_init(void);
                extern void dired_init(void);
+#ifdef VI
+               extern void vi_init(void);
 
+               vi_init();
+#endif
                dired_init();
                grep_init();
                theo_init();
Index: modes.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/modes.c,v
retrieving revision 1.16
diff -u -r1.16 modes.c
--- modes.c     13 Dec 2005 07:20:13 -0000      1.16
+++ modes.c     1 Apr 2007 18:33:38 -0000
@@ -11,13 +11,13 @@
 #include "def.h"
 #include "kbd.h"
 
-static int     changemode(int, int, char *);
+int    changemode(int, int, char *);
 
 int     defb_nmodes = 0;
 struct maps_s  *defb_modes[PBMODES] = { &fundamental_mode };
 int     defb_flag = 0;
 
-static int
+int
 changemode(int f, int n, char *mode)
 {
        int      i;
Index: search.c
===================================================================
RCS file: /cvs/src/usr.bin/mg/search.c,v
retrieving revision 1.35
diff -u -r1.35 search.c
--- search.c    13 Feb 2007 17:50:26 -0000      1.35
+++ search.c    1 Apr 2007 18:33:38 -0000
@@ -18,13 +18,6 @@
 #include "macro.h"
 #endif /* !NO_MACRO */
 
-#define SRCH_BEGIN     (0)     /* Search sub-codes.     */
-#define SRCH_FORW      (-1)
-#define SRCH_BACK      (-2)
-#define SRCH_NOPR      (-3)
-#define SRCH_ACCM      (-4)
-#define SRCH_MARK      (-5)
-
 struct srchcom {
        int              s_code;
        struct line     *s_dotp;
Index: search.c
===================================================================
--- /dev/null   Thu Mar 15 02:19:17 2007
+++ vi.c        Thu Mar 15 02:13:37 2007
@@ -0,0 +1,391 @@
+/*     $OpenBSD$       */
+
+/* This file is in the public domain. */
+
+/* vi-mode for mg. By Kjell Wooding.
+ */
+
+#ifdef VI
+#include "def.h"
+#include "funmap.h"
+#include "kbd.h"
+
+/* last search direction */
+extern int      srch_lastdir;
+
+void            vi_init(void);
+static int      vi(int, int);
+int             vi_toggle(int, int);
+int             vi_append(int, int);
+int             vi_search(int, int);
+int             vi_rsearch(int, int);
+int             vi_open(int, int);
+int             vi_Open(int, int);
+int             vi_paste(int, int);
+
+extern struct keymap_s helpmap, cXmap, metamap;
+
+static PF vicmd_cc[] = {
+       rescan,                 /* ^@ */
+       rescan,                 /* ^A */
+       backpage,               /* ^B */
+       rescan,                 /* ^C */
+       rescan,                 /* ^D */
+       rescan,                 /* ^E */
+       forwpage,               /* ^F */
+       rescan,                 /* ^G */
+       backchar,               /* ^H */
+       rescan,                 /* ^I */
+       forwline,               /* ^J */
+       rescan,                 /* ^K */
+       reposition,             /* ^L */
+       rescan,                 /* ^M */
+       forwline,               /* ^N */
+       rescan,                 /* ^O */
+       backline,               /* ^P */
+       rescan,                 /* ^Q */
+       reposition,             /* ^R */
+       rescan,                 /* ^S */
+       rescan,                 /* ^T */
+       rescan,                 /* ^U */
+       rescan,                 /* ^V */
+       nextwind,               /* ^W */
+       rescan,                 /* ^X */
+       rescan,                 /* ^Y */
+       rescan,                 /* ^Z */
+};
+
+static PF vicmd_s0[] = {
+       rescan,         /* ! */
+       rescan,         /* " */
+       rescan,         /* # */
+       gotoeol,        /* $ */
+       rescan,         /* % */
+       rescan,         /* & */
+       rescan,         /* ' */
+       rescan,         /* ( */
+       rescan,         /* ) */
+       rescan,         /* * */
+       rescan,         /* + */
+       rescan,         /* , */
+       rescan,         /* - */
+       rescan,         /* . */
+       vi_search,      /* / */
+};
+
+static PF vicmd_n[] = {
+       gotobol,        /* 0 */
+       digit_argument,         /* 1 */
+       digit_argument,         /* 2 */
+       digit_argument,         /* 3 */
+       digit_argument,         /* 4 */
+       digit_argument,         /* 5 */
+       digit_argument,         /* 6 */
+       digit_argument,         /* 7 */
+       digit_argument,         /* 8 */
+       digit_argument,         /* 9 */
+};
+
+static PF vicmd_s1[] = {
+       extend,                 /* : */
+       rescan,                 /* ; */
+       rescan,                 /* < */
+       rescan,                 /* = */
+       rescan,                 /* > */
+       vi_rsearch,             /* ? */
+       rescan,                 /* @ */
+};
+
+static PF vicmd_uc[] = {
+       rescan,                 /* A */
+       rescan,                 /* B */
+       rescan,                 /* C */
+       killline,               /* D */
+       rescan,                 /* E */
+       rescan,                 /* F */
+       rescan,                 /* G */
+       backline,               /* H */
+       rescan,                 /* I */
+       backchar,               /* J */
+       forwchar,               /* K */
+       forwline,               /* L */
+       rescan,                 /* M */
+       rescan,                 /* N */
+       vi_Open,                /* O */
+       rescan,                 /* P */
+       rescan,                 /* Q */
+       rescan,                 /* R */
+       rescan,                 /* S */
+       rescan,                 /* T */
+       rescan,                 /* U */
+       rescan,                 /* V */
+       forwword,               /* W */
+       forwdel,                /* X */
+       rescan,                 /* Y */
+       rescan,                 /* Z */
+};
+
+static PF vicmd_lcs1[] = {
+       rescan,                 /* [ */
+       rescan,                 /* \ */
+       rescan,                 /* ] */
+       gotobol,                /* ^ */
+       rescan,                 /* _ */
+       rescan,                 /* ` */
+};
+
+static PF vicmd_lc[] = {
+       vi_append,              /* a */
+       backword,               /* b */
+       rescan,                 /* c */
+       rescan,                 /* d */
+       forwword,               /* e */
+       rescan,                 /* f */
+       rescan,                 /* g */
+       backchar,               /* h */
+       vi_toggle,              /* i */
+       forwline,               /* j */
+       backline,               /* k */
+       forwchar,               /* l */
+       rescan,                 /* m */
+       rescan,                 /* n */
+       vi_open,                /* o */
+       vi_paste,               /* p */
+       rescan,                 /* q */
+       rescan,                 /* r */
+       rescan,                 /* s */
+       rescan,                 /* t */
+       undo,                   /* u */
+       rescan,                 /* v */
+       forwword,               /* w */
+       forwdel,                /* x */
+       rescan,                 /* y */
+       rescan,                 /* z */
+};
+
+static PF vicmd_lcs2[] = {
+       gotobop,                /* { */
+       rescan,                 /* | */
+       gotoeop,                /* } */
+       rescan,                 /* ~ */
+       rescan                  /* DEL */
+};
+
+static struct KEYMAPE (8 + IMAPEXT) vicmdmap = {
+       8,
+       8 + IMAPEXT,
+       rescan,
+       {
+               { CCHR('@'), CCHR('Z'), vicmd_cc, NULL  },
+               { '!', '/', vicmd_s0, NULL      },
+               { '0', '9', vicmd_n, NULL       },
+               { ':', '@', vicmd_s1, NULL      },
+               { 'A', 'Z', vicmd_uc, NULL      },
+               { 'a', 'z', vicmd_lc, NULL      },
+               { '[', '`', vicmd_lcs1, NULL    },
+               { '{', CCHR('?'), vicmd_lcs2, NULL      },
+       }
+};
+
+/*
+ * VI Insertion mode.
+ */
+static PF vii_esc[] = {
+       vi_toggle               /* ESC */
+};
+
+static struct KEYMAPE (1 + IMAPEXT) viimap = {
+       1,
+       1 + IMAPEXT,
+       rescan,
+       {
+               { CCHR('['), CCHR('['), vii_esc, NULL   }
+       }
+};
+
+void
+vi_init(void)
+{
+       funmap_add(vi, "vi-mode");
+       funmap_add(vi_toggle, "vi-mode-toggle");
+       maps_add((KEYMAP *)&vicmdmap, "vi");
+       maps_add((KEYMAP *)&viimap, "vi-ins");
+}
+
+/*
+ * Enable / dsable vi-mode
+ */
+/* ARGSUSED */
+int
+vi(int f, int n)
+{
+       int ret1 = TRUE, ret2 = TRUE;
+
+       if (curbp->b_flag & (BFVICMD | BFVIINS)) {
+               /* disable vi-mode */
+               if (curbp->b_flag & BFVICMD) {
+                       curbp->b_flag &= ~BFVICMD;
+                       ret1 = changemode(f, n, "vi");
+               }
+               if (curbp->b_flag & BFVIINS) {
+                       curbp->b_flag &= ~BFVIINS;
+                       ret2 =changemode(f, n, "vi-ins");
+               }
+               return (ret1 == TRUE && ret2 == TRUE);
+       }
+       /* enable vi-mode */
+       curbp->b_flag |= BFVICMD;
+       return (changemode(f, n, "vi"));
+}
+
+/*
+ * If vi-mode is enabled, toggle between cmd and ins modes
+ */
+/* ARGSUSED */
+int
+vi_toggle(int f, int n)
+{
+       int ret1, ret2;
+
+       /* we must be enabled */
+       if ((curbp->b_flag & (BFVICMD | BFVIINS)) == 0)
+               return (FALSE);
+
+       if (curbp->b_flag & BFVICMD) {
+               curbp->b_flag &= ~BFVICMD;
+               curbp->b_flag |= BFVIINS;
+       } else {
+               curbp->b_flag &= ~BFVIINS;
+               curbp->b_flag |= BFVICMD;
+       }
+
+       ret1 = changemode(f, n, "vi-ins");
+       ret2 = changemode(f, n, "vi");
+
+       return (ret1 == TRUE && ret2 == TRUE);
+}
+
+/*
+ * move forward (past cursor) and append text
+ */
+/* ARGSUSED */
+int
+vi_append(int f, int n)
+{
+       forwchar(FFARG, 1);
+       return (vi_toggle(f, n));
+}
+
+/*
+ * read in a pattern and search for it
+ */
+/* ARGSUSED */
+int
+vi_search(int f, int n)
+{
+       char    tpat[NPAT], *rep;
+       int     retval;
+       int     again = FALSE;
+
+       rep = eread("/", tpat, NPAT, EFNUL | EFNEW | EFCR);
+
+       if (rep == NULL)
+               return(ABORT);
+       if (rep[0] != '\0') {
+               (void)strlcpy(pat, tpat, sizeof(pat));
+               retval = TRUE;
+       } else {
+               again = forwchar(FFRAND, 1);
+       }
+       if (pat[0] == '\0')
+               return(FALSE);
+
+       srch_lastdir = SRCH_FORW;
+       if (forwsrch() == FALSE) {
+               ewprintf("Pattern not found");
+               if (again == TRUE)
+                       backchar(FFRAND, 1);
+               return (FALSE);
+       }
+       backchar(FFRAND, strlen(pat));
+       return (TRUE);
+}
+
+/*
+ * read in a pattern and search (backwards) for it
+ */
+/* ARGSUSED */
+int
+vi_rsearch(int f, int n)
+{
+       char    tpat[NPAT], *rep;
+       int     retval;
+       int     again = FALSE;
+
+       rep = eread("?", tpat, NPAT, EFNUL | EFNEW | EFCR);
+
+       if (rep == NULL)
+               return(ABORT);
+       if (rep[0] != '\0') {
+               (void)strlcpy(pat, tpat, sizeof(pat));
+               retval = TRUE;
+       } else {
+               again = backchar(FFRAND, 1);
+       }
+       if (pat[0] == '\0')
+               return(FALSE);
+
+       srch_lastdir = SRCH_BACK;
+       if (backsrch() == FALSE) {
+               ewprintf("Pattern not found");
+               if (again == TRUE)
+                       forwchar(FFRAND, 1);
+               return (FALSE);
+       }
+       return (TRUE);
+}
+
+/*
+ * open a new line below the current line and start adding text
+ */
+/* ARGSUSED */
+int
+vi_open(int f, int n)
+{
+       gotoeol(FFRAND, 1);
+       newline(FFRAND, 1);
+       vi_toggle(f, n);
+       return (TRUE);
+}
+/*
+ * open a new line above the current line and start adding text
+ */
+/* ARGSUSED */
+int
+vi_Open(int f, int n)
+{
+       gotobol(FFRAND, 1);
+       newline(FFRAND, 1);
+       backchar(FFRAND, 1);
+       vi_toggle(f, n);
+       return (TRUE);
+}
+
+/*
+ *
+ */
+/* ARGSUSED */
+int
+vi_paste(int f, int n)
+{
+
+       gotoeol(FFRAND, 1);
+       while (n--) {
+               newline(FFRAND, 1);
+               yank(FFRAND, 1);
+       }
+       gotobol(FFRAND, 1);
+       return (TRUE);
+}
+#endif
+

--
Kjell Wooding <[EMAIL PROTECTED]>

Reply via email to