commit a9d876ca6180454418dc257ff8e1a3556345a812
parent 60777b454326ce3790fcaf530fe3fd73469b5605
Author: Dimitris Zervas <dzervas@dzervas.gr>
Date:   Wed,  9 Jul 2014 03:01:06 +0300
Added vim-like command mode
Diffstat:
2 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/config.h b/config.h
@@ -92,6 +92,7 @@ static const Key curskeys[] = { /* Plain keys here, no CONTROL or META */
 { .keyv.i = KEY_RIGHT,      { 0,     0,    0,   0 },   f_moveboth, { .m = m_nextchar } },
 { .keyv.i = KEY_SLEFT,      { 0,     0,    0,   0 },   f_moveboth, { .m = m_prevword } },
 { .keyv.i = KEY_SRIGHT,     { 0,     0,    0,   0 },   f_moveboth, { .m = m_nextword } },
+//{ .keyv.i = KEY_ESC,        { t_nocomm,0,   0,   0 },   f_toggle,   { .i = S_Command  } },
 };
 
 static const Key stdkeys[] = {
@@ -146,7 +147,7 @@ static const Key stdkeys[] = {
 { .keyv.c = CONTROL('X'), { t_mod, t_rw, 0,   0 },  f_save,      { 0 } },
 { .keyv.c = CONTROL('X'), { 0,     0,    0,   0 },  f_toggle,    { .i = S_Running } },
 { .keyv.c = META('x'),    { 0,     0,    0,   0 },  f_spawn,     CMD_P },
-{ .keyv.c = CONTROL('Y'), { t_rw,  0,    0,   0 },  f_pipenull,  FROMCLIP },
+//{ .keyv.c = CONTROL('Y'), { t_rw,  0,    0,   0 },  f_pipenull,  FROMCLIP },
 { .keyv.c = CONTROL('Z'), { 0     ,0,    0,   0 },  f_suspend,   { 0 } },
 { .keyv.c = CONTROL('['), { 0,     0,    0,   0 },  f_spawn,     CMD_P },
 { .keyv.c = CONTROL('\\'),{ t_rw,  0,    0,   0 },  f_spawn,     PIPE },
@@ -160,6 +161,13 @@ static const Key stdkeys[] = {
 { .keyv.c = CONTROL('?'), { t_rw,  0,    0,   0 },  f_delete,    { .m = m_prevchar } },
 { .keyv.c = META(','),    { 0,     0,    0,   0 },  f_move,      { .m = m_bof } },
 { .keyv.c = META('.'),    { 0,     0,    0,   0 },  f_move,      { .m = m_eof } },
+{ .keyv.c = CONTROL('Y'), { t_nocomm,0,  0,   0 },  f_toggle,    { .i = S_Command  } },
+};
+
+static const Key commkeys[] = { /* Command mode keys here */
+/* keyv.c,                  tests,                     func,       arg */
+{ .keyv.c = { 'i' },            { 0,     0,    0,   0 },   f_toggle,   { .i = S_Command  } },
+{ .keyv.c = { ':' },            { 0,     0,    0,   0 },   f_spawn,    CMD_P },
 };
 
 #if HANDLE_MOUSE
diff --git a/sandy.c b/sandy.c
@@ -137,6 +137,9 @@ enum { /* To use in statusflags */
 	S_GroupUndo  = 1<<9,  /* Last action was an insert, so another insert should group with it, set automatically */
 	S_AutoIndent = 1<<10, /* Perform autoindenting on RET */
 	S_DumpStdout = 1<<11, /* Dump to stdout instead of writing to a file */
+//#if COMMAND_MODE
+	S_Command    = 1<<12, /* Command mode */
+//#endif
 };
 
 enum { /* To use in Undo.flags */
@@ -243,8 +246,10 @@ static bool           i_writefile(char*);
 /* t_* functions to know whether to process an action or keybinding */
 static bool t_ai(void);
 static bool t_bol(void);
+//static bool t_comm(void);
 static bool t_eol(void);
 static bool t_mod(void);
+static bool t_nocomm(void);
 static bool t_rw(void);
 static bool t_redo(void);
 static bool t_sel(void);
@@ -816,8 +821,21 @@ i_edit(void) {
 			continue;
 		}
 		statusflags&=~(S_InsEsc);
+//#if COMMAND_MODE
+		if(t_rw() && t_nocomm()) f_insert(&(const Arg){ .v = c });
+/*#else
 		if(t_rw()) f_insert(&(const Arg){ .v = c });
-		else tmptitle="WARNING! File is read-only!!!";
+#endif*/
+		else if(!t_rw()) tmptitle="WARNING! File is read-only!!!";
+		else {
+			for(i=0; i<LENGTH(commkeys); i++) {
+				if(memcmp(c, commkeys[i].keyv.c, sizeof commkeys[i].keyv.c) == 0 && i_dotests(commkeys[i].test) ) {
+					if(commkeys[i].func != f_insert) statusflags&=~(S_GroupUndo);
+					commkeys[i].func(&(commkeys[i].arg));
+					break;
+				}
+			}
+		}
 	}
 }
 
@@ -1438,7 +1456,8 @@ i_update(void) {
 	else {
 		statusflags&=~S_Warned; /* Reset warning */
 		snprintf(buf, 4, "%ld%%", (100*ncur)/nlst);
-		snprintf(title, BUFSIZ, "%s [%s]%s%s%s%s %ld,%d  %s",
+		snprintf(title, BUFSIZ, "%s %s [%s]%s%s%s%s %ld,%d  %s",
+			(t_nocomm()?"Insert":"Command"),
 			(statusflags&S_DumpStdout?"<Stdout>":(filename == NULL?"<No file>":filename)),
 			(syntx>=0 ? syntaxes[syntx].name : "none"),
 			(t_mod()?"[+]":""),
@@ -1675,6 +1694,11 @@ t_bol(void) {
 	return (fcur.o == 0);
 }
 
+//bool /* TRUE if we are in command mode */
+//t_comm(void) {
+//	return (statusflags & S_Command);
+//}
+
 bool /* TRUE at end of line */
 t_eol(void) {
 	return (fcur.o == fcur.l->len);
@@ -1685,6 +1709,11 @@ t_mod(void) {
 	return (statusflags & S_Modified);
 }
 
+bool /* TRUE if we are not in command mode FIXME: Find a way to use t_comm */
+t_nocomm(void) {
+	return !(statusflags & S_Command);
+}
+
 bool /* TRUE if the file is writable */
 t_rw(void) {
 	return !(statusflags & S_Readonly);
@@ -1742,7 +1771,7 @@ main(int argc, char **argv){
 			i++;
 			break;
 		} else if(!strcmp(argv[i], "-v"))
-			i_die("sandy-"VERSION", © 2011 sandy engineers, see LICENSE for details\n");
+			i_die("sandy-"VERSION", © 2014 sandy engineers, see LICENSE for details\n");
 		else
 			i_usage();
 	}