[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