aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-10-21 10:27:11 -0700
committerNicholas Noll <nbnoll@eml.cc>2021-10-21 10:27:11 -0700
commit89e6da0a7cc2cd8551ae31ac623232a0ccce905d (patch)
tree26690759ff80b44da050824958fd70384e8725f0
parent7e1eaee616365799cfc4cc787fdaa9448958536b (diff)
feat(rc): vi mode fleshed out
-rw-r--r--sys/cmd/rc/exec.c8
-rw-r--r--sys/cmd/rc/input.c572
-rw-r--r--sys/cmd/rc/main.c1
3 files changed, 385 insertions, 196 deletions
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c
index eede516..6d0c0a9 100644
--- a/sys/cmd/rc/exec.c
+++ b/sys/cmd/rc/exec.c
@@ -700,21 +700,23 @@ void
Xasync(void)
{
int pid;
+ /*
int null = open("/dev/null", 0);
if(!null){
Xerror("can not open /dev/null\n");
return;
}
+ */
switch(pid=fork()){
case -1:
- close(null);
+ // close(null);
Xerror("fork failed: try again");
break;
case 0: // child in background
initchild(runner,0);
- pushredir(Ropen, null, 0);
+ /* pushredir(Ropen, null, 0); */
run(runner->code.exe, runner->code.i+1, runner->local, 0);
runner->caller = nil;
@@ -723,7 +725,7 @@ Xasync(void)
default: // parent in foreground
initparent(runner,pid,1);
- close(null);
+ // close(null);
runner->code.i = runner->code.exe[runner->code.i].i; /* jump to end of async command */
/* don't wait: continue running */
diff --git a/sys/cmd/rc/input.c b/sys/cmd/rc/input.c
index 5e5fc78..a89dbda 100644
--- a/sys/cmd/rc/input.c
+++ b/sys/cmd/rc/input.c
@@ -2,6 +2,35 @@
#include <termios.h>
#include <sys/ioctl.h>
+/* don't change order of these without modifying matrix */
+enum
+{
+ NonPrintable,
+ Alnum,
+ Punctation,
+ Space
+};
+
+static int ascii[256] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
struct Mode {
ushort raw : 1;
ushort multiline : 1;
@@ -17,24 +46,33 @@ static struct Mode mode;
static struct termios originalterm;
/*
- * The structure represents the state during line editing.
- * We pass this state to functions implementing specific editing
- * functionalities
+ * the structure represents the state during line editing.
+ * we pass this state to functions implementing specific editing functionalities
*/
-struct TerminalState
+struct TerminalState
{
- int ifd; /* Terminal stdin file descriptor. */
- int ofd; /* Terminal stdout file descriptor. */
- char *buf; /* Edited line buffer. */
- uintptr buflen; /* Edited line buffer size. */
- char *prompt; /* Prompt to display. */
- uintptr plen; /* Prompt length. */
- uintptr pos; /* Current cursor position. */
- uintptr oldpos; /* Previous refresh cursor position. */
- uintptr len; /* Current edited line length. */
- uintptr cols; /* Number of columns in terminal. */
- uintptr maxrows; /* Maximum num of rows used so far (multiline mode) */
- int history_index; /* The history index we are currently editing. */
+ int ifd; /* terminal stdin file descriptor. */
+ int ofd; /* terminal stdout file descriptor. */
+
+ char *buf; /* edited line buffer. */
+ intptr buflen; /* edited line buffer size. */
+
+ struct {
+ int cap, len;
+ char *buf;
+ } yank; /* yank buffer */
+
+ char *prompt; /* prompt to display. */
+ intptr plen; /* prompt length. */
+
+ intptr pos; /* current cursor position. */
+ intptr oldpos; /* previous refresh cursor position. */
+
+ intptr len; /* current edited line length. */
+ intptr cols; /* number of columns in terminal. */
+
+ intptr maxrows; /* maximum num of rows used so far (multiline mode) */
+ int history_index; /* the history index we are currently editing. */
};
enum
@@ -60,10 +98,12 @@ enum
KeyBackspace = 127 /* Backspace */
};
-
-
static void doatexit(void);
+/* vi operations */
+typedef intptr (*Noun)(struct TerminalState*, int);
+typedef void (*Verb)(struct TerminalState*, intptr);
+
static
void
normalcursor(int fd)
@@ -269,11 +309,11 @@ refreshsingleline(struct TerminalState *term)
char esc[64];
struct Buffer ab;
- uintptr plen = term->plen;
+ intptr plen = term->plen;
int fd = term->ofd;
char *buf = term->buf;
- uintptr len = term->len;
- uintptr pos = term->pos;
+ intptr len = term->len;
+ intptr pos = term->pos;
while((plen+pos) >= term->cols) {
buf++;
@@ -292,15 +332,7 @@ refreshsingleline(struct TerminalState *term)
/* write the prompt and the current buffer content */
append(&ab,term->prompt,strlen(term->prompt));
-#if 0
- if(mode.vi.on){
- if(mode.vi.insert)
- append(&ab,"[I]",3);
- else
- append(&ab,"[N]",3);
- }
- append(&ab,">",1);
-#endif
+
if(mode.mask == 1)
while(len--)
append(&ab,"*",1);
@@ -419,7 +451,7 @@ refreshline(struct TerminalState *term)
/* insert the character 'c' at cursor current position.
* on error writing to the terminal -1 is returned, otherwise 0. */
int
-insert(struct TerminalState *term, char c)
+insertchar(struct TerminalState *term, char c)
{
char d;
if(term->len < term->buflen){
@@ -432,7 +464,7 @@ insert(struct TerminalState *term, char c)
d = (mode.mask==1) ? '*' : c;
if(write(term->ofd,&d,1) == -1)
return 0;
- } else
+ }else
refreshline(term);
}else{
memmove(term->buf+term->pos+1,term->buf+term->pos,term->len-term->pos);
@@ -446,113 +478,160 @@ insert(struct TerminalState *term, char c)
return 1;
}
-/* move cursor to the left n boxes */
-static
-void
-moveleft(struct TerminalState *term, int n)
+int
+insertchars(struct TerminalState *term, int len, char *buf)
{
- if(term->pos > n){
- term->pos -= n;
+ if(term->len + len > term->buflen)
+ len = term->buflen - term->len;
+
+ if(term->len == term->pos){
+ memcpy(term->buf, buf, len);
+ term->pos += len;
+ term->len += len;
+ term->buf[term->len] = '\0';
+ // transfer the modeline here?
refreshline(term);
- }else if(term->pos){
- term->pos = 0;
+ }else{
+ memmove(term->buf+term->pos+len,term->buf+term->pos,term->len-term->pos);
+ memcpy(term->buf+term->pos, buf, len);
+ term->pos += len;
+ term->len += len;
+ term->buf[term->len] = '\0';
refreshline(term);
}
+
+ return 1;
}
-/* move cursor to the right n boxes */
+// -----------------------------------------------------------------------
+// vi functionality
+
+/* modes */
+
static
void
-moveright(struct TerminalState *term, int n)
+normalmode(int fd)
{
- if(term->pos < term->len-n){
- term->pos += n;
- refreshline(term);
- }else if(term->pos != term->len){
- term->pos = term->len;
- refreshline(term);
- }
+ mode.vi.insert = 0;
+ normalcursor(fd);
}
-/* Move cursor to the start of the line. */
static
void
-movehome(struct TerminalState *term) {
- if(term->pos != 0){
- term->pos = 0;
- refreshline(term);
- }
+insertmode(int fd)
+{
+ mode.vi.insert = 1;
+ insertcursor(fd);
}
-/* move cursor to the end of the line. */
+/* actions */
+
static
void
-moveend(struct TerminalState *term)
+move(struct TerminalState *term, intptr to)
{
- if(term->pos != term->len){
- term->pos = term->len;
+ if(to != term->pos){
+ term->pos = to;
refreshline(term);
}
}
-/* Substitute the currently edited line with the next or previous history
- * entry as specified by 'dir'. */
+static
void
-movehistory(struct TerminalState *term, int dir)
+yank(struct TerminalState *term, intptr to)
{
+ intptr len, off;
+
+ if(to == term->pos)
+ return; // noop
+
+ if(to > term->pos){
+ len = to - term->pos;
+ off = term->pos;
+ }else{
+ len = term->pos - to;
+ off = to;
+ }
+
+ if(term->yank.cap < len+1){
+ efree(term->yank.buf);
+ term->yank.cap = len+1;
+ term->yank.buf = emalloc(len+1);
+ }
+ term->yank.len = len;
+ memcpy(term->yank.buf, term->buf+off, len);
+ term->yank.buf[len] = 0;
}
-/* delete the character at the right of the cursor without altering the cursor
- * position. basically this is what happens with the "Delete" keyboard key. */
+static
void
-delete(struct TerminalState *term)
+delete(struct TerminalState *term, intptr to)
{
- if(term->len > 0 && term->pos < term->len){
- memmove(term->buf+term->pos,term->buf+term->pos+1,term->len-term->pos-1);
- term->len--;
- term->buf[term->len] = '\0';
- refreshline(term);
+ intptr diff;
+
+ // delete characters in front of us (exclusive)
+ if(to > term->pos){
+ diff = to - term->pos;
+ memmove(term->buf+term->pos, term->buf+to, term->len-to+1);
+ term->len -= diff;
+ goto refresh;
}
+
+ // delete characters behind us
+ if(to < term->pos){
+ diff = term->pos - to;
+ memmove(term->buf+to, term->buf+term->pos, term->len-term->pos+1);
+ term->pos = to;
+ term->len -= diff;
+ goto refresh;
+ }
+ // do nothing
+ return;
+
+refresh:
+ refreshline(term);
}
-/* backspace implementation. */
+/* movements */
+
+// move cursor to the left n boxes
static
-void
-backspace(struct TerminalState *term)
+intptr
+left(struct TerminalState *term, int n)
{
- if(term->pos > 0 && term->len > 0){
- memmove(term->buf+term->pos-1,term->buf+term->pos,term->len-term->pos);
- term->pos--;
- term->len--;
- term->buf[term->len] = '\0';
- refreshline(term);
- }
+ intptr d;
+ d = term->pos - n;
+ return MAX(d, 0);
}
-#define ITERATE_BACK_UNTIL(CONDITION) \
- uintptr d, x = term->pos; \
- char *it = term->buf + x; \
- \
- while(n-- > 0 && it > term->buf){ \
- while(it > term->buf && CONDITION(it[-1])) \
- --it; \
- } \
- \
- return it; \
+// move cursor to the right n boxes
+static
+intptr
+right(struct TerminalState *term, int n)
+{
+ intptr d;
+ d = term->pos + n;
+ return MIN(d, term->len);
+}
+
+void
+movehistory(struct TerminalState *term, int dir)
+{
+}
static
-int
+intptr
prevword(struct TerminalState *term, int n)
{
+ int c;
char *it = term->buf + term->pos;
while(n-- > 0 && it > term->buf){
- /* consume any leading space chars */
- while(isspace(it[-1]) && --it >= term->buf)
- ;
+ while(it > term->buf && ascii[it[-1]] == Space)
+ --it;
- /* consume word chars */
- while(it > term->buf && (isalnum(it[-1]) || it[-1] == '_'))
+ c = ascii[it[-1]];
+ while(it > term->buf && ascii[it[-1]] == c)
--it;
}
@@ -560,18 +639,36 @@ prevword(struct TerminalState *term, int n)
}
static
-int
+intptr
+prevWord(struct TerminalState *term, int n)
+{
+ char *it = term->buf + term->pos;
+
+ while(n-- > 0 && it > term->buf){
+ while(it > term->buf && ascii[it[-1]] == Space)
+ --it;
+
+ while(it > term->buf && ascii[it[-1]] != Space)
+ --it;
+ }
+
+ return it-term->buf;
+}
+
+static
+intptr
nextword(struct TerminalState *term, int n)
{
+ int c;
char *it = term->buf + term->pos;
char *end = term->buf + term->len;
while(n-- > 0 && it < end){
- /* consume any leading word chars */
- while(it < end && (isalnum(*it) || *it == '_'))
+ c = ascii[*it];
+ while(it < end && ascii[*it] == c)
++it;
- /* consume any space chars */
- while(isspace(*it) && it < end)
+
+ while(it < end && ascii[*it] == Space)
++it;
}
@@ -579,39 +676,59 @@ nextword(struct TerminalState *term, int n)
}
static
-void
-deleteprevword(struct TerminalState *term)
+intptr
+nextWord(struct TerminalState *term, int n)
{
- uintptr old_pos = term->pos;
- uintptr diff;
-
- while(term->pos > 0 && term->buf[term->pos-1] == ' ')
- term->pos--;
- while(term->pos > 0 && term->buf[term->pos-1] != ' ')
- term->pos--;
+ char *it = term->buf + term->pos;
+ char *end = term->buf + term->len;
- diff = old_pos - term->pos;
- memmove(term->buf+term->pos,term->buf+old_pos,term->len-old_pos+1);
+ while(n-- > 0 && it < end){
+ while(it < end && ascii[*it] != Space)
+ ++it;
- term->len -= diff;
+ while(it < end && ascii[*it] == Space)
+ ++it;
+ }
- refreshline(term);
+ return it-term->buf;
}
static
-void
-normalmode(int fd)
+intptr
+nextend(struct TerminalState *term, int n)
{
- mode.vi.insert = 0;
- normalcursor(fd);
+ int c;
+ char *it = term->buf + term->pos;
+ char *end = term->buf + term->len;
+
+ while(n-- > 0 && it+1 < end){
+ while(it+1 < end && ascii[it[1]] == Space)
+ ++it;
+
+ c = ascii[it[1]];
+ while(it+1 < end && ascii[it[1]] == c)
+ ++it;
+ }
+
+ return it-term->buf;
}
static
-void
-insertmode(int fd)
+intptr
+nextEnd(struct TerminalState *term, int n)
{
- mode.vi.insert = 1;
- insertcursor(fd);
+ char *it = term->buf + term->pos;
+ char *end = term->buf + term->len;
+
+ while(n-- > 0 && it+1 < end){
+ while(it+1 < end && ascii[it[1]] == Space)
+ ++it;
+
+ while(it < end && ascii[it[1]] != Space)
+ ++it;
+ }
+
+ return it-term->buf;
}
static
@@ -619,6 +736,7 @@ int
vi(struct TerminalState *term, char c)
{
int n = 1;
+ Verb verb = move;
action:
switch(c){
@@ -634,34 +752,73 @@ action:
}
goto action;
- /* movements */
- case 'l':
- moveright(term, n);
- break;
-
- case 'h':
- moveleft(term, n);
- break;
-
- case '0':
- movehome(term);
- break;
-
- case '$':
- moveend(term);
+ /* composable actions */
+ case 'l': verb(term, right(term, n)); break;
+ case 'h': verb(term, left(term, n)); break;
+ case '0': verb(term, 0); break;
+ case '$': verb(term, term->len); break;
+ case 'b': verb(term, prevword(term,n)); break;
+ case 'B': verb(term, prevWord(term,n)); break;
+ case 'w': verb(term, nextword(term,n)); break;
+ case 'W': verb(term, nextWord(term,n)); break;
+ case 'e': verb(term, nextend(term,n)); break;
+ case 'E': verb(term, nextEnd(term,n)); break;
+
+ /* verb switches */
+ case 'd': // delete
+ verb = delete;
+ if(read(term->ifd, &c, 1)<1)
+ return -1;
+ /* special cases */
+ switch(c){
+ case 'd':
+ move(term, 0);
+ delete(term, term->len);
+ return 0;
+ default:
+ goto action;
+ }
+ case 'y': // yank
+ verb = yank;
+ if(read(term->ifd, &c, 1)<1)
+ return -1;
+ /* special cases */
+ switch(c){
+ case 'y':
+ if(term->yank.cap < term->len+1){
+ efree(term->yank.buf);
+ term->yank.len = term->len;
+ term->yank.cap = term->len+1;
+ term->yank.buf = emalloc(term->yank.cap);
+ }
+ memcpy(term->yank.buf, term->buf, term->len+1);
+ break;
+ default:
+ goto action;
+ }
break;
- case 'b':
- term->pos = prevword(term,n);
+ case 'p': // put
+ insertchars(term, term->yank.len, term->yank.buf);
refreshline(term);
- break;
+ return 0;
- case 'w':
- term->pos = nextword(term,n);
- refreshline(term);
+ /* special cases
+ * sadly I don't know a better way than to have these checks for move
+ * the vi language doesn't fully compose
+ */
+ case 'i': insertmode:
+ if(verb != move) goto unrecognized;
+ insertmode(term->ofd);
break;
+ case 'I':
+ if(verb != move) goto unrecognized;
+ move(term, 0);
+ goto insertmode;
+
case 'a':
+ if(verb != move) goto unrecognized;
if(term->pos < term->len){
term->pos++;
refreshline(term);
@@ -669,37 +826,54 @@ action:
goto insertmode;
case 'A':
- moveend(term);
+ if(verb != move) goto unrecognized;
+ move(term, term->len);
goto insertmode;
- case 'I':
- movehome(term);
- goto insertmode;
+ case 'x':
+ if(verb != move) goto unrecognized;
+ delete(term, right(term, 1));
+ break;
- case 'i': insertmode:
- insertmode(term->ofd);
+ case 'X':
+ if(verb != move) goto unrecognized;
+ delete(term, left(term, 1));
+ break;
+
+ case 'r':
+ if(verb != move) goto unrecognized;
+ if(read(term->ifd, &c, 1)<1)
+ return -1;
+ if(c < ' ')
+ break;
+ term->buf[term->pos] = c;
+ refreshline(term);
break;
+ // TODO: replace mode?
+
+ case 'c':
+ if(verb != move) goto unrecognized;
+ insertmode(term->ofd);
+ verb = delete;
+ if(read(term->ifd, &c, 1)<1)
+ return -1;
+ goto action;
+
case 'C':
+ if(verb != move) goto unrecognized;
insertmode(term->ofd);
- /* fallthough */
+ goto deleteln;
+
case 'D':
+ if(verb != move) goto unrecognized;
+ deleteln:
term->len = term->pos;
term->buf[term->pos] = 0;
refreshline(term);
break;
- case 'd':
- if(read(term->ifd,&c,1))
- break;
- switch(c){
- default:
- beep();
- normalmode(term->ofd);
- break;
- }
-
- default:
+ default: unrecognized:
beep();
break;
}
@@ -708,17 +882,17 @@ action:
}
-/* This function is the core of the line editing capability of linenoise.
- * It expects 'fd' to be already in "raw mode" so that every key pressed
- * will be returned ASAP to read().
+/* this function is the core of the line editing capability of linenoise.
+ * it expects 'fd' to be already in "raw mode" so that every key pressed
+ * will be returned asap to read().
*
- * The resulting string is put into 'buf' when the user type enter, or
+ * the resulting string is put into 'buf' when the user type enter, or
* when ctrl+d is typed.
*
- * The function returns the length of the current buffer. */
+ * the function returns the length of the current buffer. */
static
int
-interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
+interact(int ifd, int ofd, char *buf, intptr len, char *prompt)
{
char c;
int n;
@@ -741,9 +915,12 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
term.maxrows = 0;
term.history_index = 0;
- /* Buffer starts empty. */
+ term.yank.buf = nil;
+ term.yank.cap = term.yank.len = 0;
+
+ /* buffer starts empty. */
term.buf[0] = '\0';
- term.buflen--; /* Make sure there is always space for the nulterm */
+ term.buflen--; /* make sure there is always space for the nulterm */
if(write(term.ofd,prompt,term.plen) == -1)
return -1;
@@ -751,13 +928,13 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
for(;;){
n = read(term.ifd,&c,1);
if(n <= 0)
- return term.len;
+ goto finish;
switch(c){
case KeyEnter:
if(mode.multiline)
- moveend(&term);
- return (int)term.len;
+ move(&term, term.len);
+ goto finish;
case KeyCtrlC:
errno = EAGAIN;
@@ -765,12 +942,12 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
case KeyBackspace:
case KeyCtrlH:
- backspace(&term);
+ delete(&term, left(&term, 1));
break;
case KeyCtrlD:
if(term.len > 0)
- delete(&term);
+ delete(&term, right(&term, 1));
break;
case KeyCtrlT:
@@ -784,11 +961,11 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
break;
case KeyCtrlB:
- moveleft(&term, 1);
+ move(&term, left(&term, 1));
break;
case KeyCtrlF: /* ctrl-f */
- moveright(&term, 1);
+ move(&term, right(&term, 1));
break;
case KeyCtrlP: /* ctrl-p */
@@ -803,6 +980,7 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
/*
* try to read two bytes representing the escape sequence.
* if we read less than 2 and we are in vi mode, interpret as command
+ *
* NOTE: we could do a timed read here
*/
switch(read(term.ifd,esc,2)){
@@ -821,8 +999,10 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
if(mode.vi.on){
if(mode.vi.insert){
normalmode(term.ofd);
- if(vi(&term,esc[0]) < 0)
- return -1;
+ if(vi(&term,esc[0]) < 0){
+ term.len = -1;
+ goto finish;
+ }
continue;
}
}
@@ -840,7 +1020,7 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
if(esc[2] == '~'){
switch(esc[1]){
case '3': /* delete key. */
- delete(&term);
+ delete(&term, left(&term,1));
break;
}
}
@@ -853,16 +1033,16 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
movehistory(&term, 0);
break;
case 'C': /* right */
- moveright(&term, 1);
+ move(&term, right(&term, 1));
break;
case 'D': /* left */
- moveleft(&term, 1);
+ move(&term, left(&term, 1));
break;
case 'H': /* home */
- movehome(&term);
+ move(&term, 0);
break;
case 'F': /* end*/
- moveend(&term);
+ move(&term, term.len);
break;
}
}
@@ -871,10 +1051,10 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
else if(esc[0] == 'O'){
switch(esc[1]) {
case 'H': /* home */
- movehome(&term);
+ move(&term, 0);
break;
case 'F': /* end*/
- moveend(&term);
+ move(&term, term.len);
break;
}
}
@@ -883,10 +1063,14 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
default:
if(mode.vi.on && !mode.vi.insert){
- if(vi(&term,c) < 0)
- return -1;
- }else if(!insert(&term,c))
- return -1;
+ if(vi(&term,c) < 0){
+ term.len = -1;
+ goto finish;
+ }
+ }else if(!insertchar(&term,c)){
+ term.len = -1;
+ goto finish;
+ }
break;
case KeyCtrlU: /* Ctrl+u, delete the whole line. */
@@ -902,11 +1086,11 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
break;
case KeyCtrlA: /* Ctrl+a, go to the start of the line */
- movehome(&term);
+ move(&term, 0);
break;
case KeyCtrlE: /* ctrl+e, go to the end of the line */
- moveend(&term);
+ move(&term, term.len);
break;
case KeyCtrlL: /* ctrl+term, clear screen */
@@ -915,10 +1099,12 @@ interact(int ifd, int ofd, char *buf, uintptr len, char *prompt)
break;
case KeyCtrlW: /* ctrl+w, delete previous word */
- deleteprevword(&term);
+ delete(&term, prevword(&term,1));
break;
}
}
+finish:
+ efree(term.yank.buf);
return term.len;
}
@@ -964,7 +1150,7 @@ printkeycode(void)
*/
static
int
-raw(char *buf, uintptr len, char *prompt)
+raw(char *buf, intptr len, char *prompt)
{
int n;
diff --git a/sys/cmd/rc/main.c b/sys/cmd/rc/main.c
index cb927e9..86c6792 100644
--- a/sys/cmd/rc/main.c
+++ b/sys/cmd/rc/main.c
@@ -58,5 +58,6 @@ main(int argc, char *argv[])
initpath();
initshell();
+ enablevi();
xboot(argc, argv);
}