[prev in list] [next in list] [prev in thread] [next in thread]
List: openbsd-misc
Subject: vi keys in mg
From: Kjell Wooding <kjell () openbsd ! org>
Date: 2007-04-01 18:58:38
Message-ID: 20070401185838.GB14350 () tash ! pintday ! org
[Download RAW message or body]
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 <kjell@openbsd.org>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic