diff options
Diffstat (limited to 'pw.c')
-rw-r--r-- | pw.c | 73 |
1 files changed, 62 insertions, 11 deletions
@@ -100,6 +100,7 @@ typedef struct pwstate { unsigned stat; int sncount, tcount; char *curcmd, *savedcmd; + size_t editpos; char cmdbuf[cmdsize]; } pwstate; @@ -607,6 +608,13 @@ static void drawstatus(pwstate *pw) fputs(status, stdout); clreol(0); + if (pw->curcmd) { + if (pw->curcmd[pw->editpos] != 0) { + putchar('\r'); + if (pw->editpos > 0) + printf("\033[%dC", pw->editpos); + } + } fflush(stdout); } @@ -1708,6 +1716,7 @@ int main(int argc, char **argv) case ':': case '/': case '?': kbd_state = kbd_lcmd; histpos = 0; + pw.editpos = 1; pw.cmdbuf[0] = ch; pw.cmdbuf[1] = 0; pw.curcmd = pw.cmdbuf; @@ -1848,6 +1857,12 @@ int main(int argc, char **argv) case 'B': ch = ctrl('n'); goto fakecmd; + case 'D': + ch = ctrl('b'); + goto fakecmd; + case 'C': + ch = ctrl('f'); + goto fakecmd; } break; case kbd_lcmd: @@ -1890,29 +1905,62 @@ int main(int argc, char **argv) cmdcount = INT_MAX; prevcmd = 0; break; + case ctrl('b'): + if (pw.editpos > 1) + pw.editpos--; + break; + case ctrl('f'): + if (pw.cmdbuf[pw.editpos] != 0) + pw.editpos++; + break; + case ctrl('k'): + pw.cmdbuf[pw.editpos] = 0; + break; + case ctrl('a'): + pw.editpos = 1; + break; + case ctrl('e'): + pw.editpos = strlen(pw.cmdbuf); + break; case BS: case DEL: { size_t len = strlen(pw.cmdbuf); + if (pw.editpos > 1 || (pw.editpos == 1 && len == 1)) { + pw.editpos--; + memmove(pw.cmdbuf + pw.editpos, pw.cmdbuf + pw.editpos + 1, + len - pw.editpos); + } + if (len == 1) { kbd_state = kbd_cmd; pw.curcmd = 0; // cmdcount deliberately not reset to INT_MAX - } else { - pw.cmdbuf[--len] = 0; } } break; + case ctrl('d'): + { + size_t len = strlen(pw.cmdbuf); + if (pw.editpos < len) + memmove(pw.cmdbuf + pw.editpos, pw.cmdbuf + pw.editpos + 1, + len - pw.editpos + 1); + } + break; case ctrl('u'): - pw.cmdbuf[1] = 0; + memmove(pw.cmdbuf + 1, pw.cmdbuf + pw.editpos, + strlen(pw.cmdbuf + pw.editpos) + 1); + pw.editpos = 1; break; case ctrl('w'): { - size_t len = strlen(pw.cmdbuf); - while (len > 1 && isspace((unsigned char) pw.cmdbuf[len - 1])) - len--; - while (len > 1 && !isspace((unsigned char) pw.cmdbuf[len - 1])) - len--; - pw.cmdbuf[len] = 0; + size_t npos = pw.editpos; + while (npos > 1 && isspace((unsigned char) pw.cmdbuf[npos - 1])) + npos--; + while (npos > 1 && !isspace((unsigned char) pw.cmdbuf[npos - 1])) + npos--; + memmove(pw.cmdbuf + npos, pw.cmdbuf + pw.editpos, + strlen(pw.cmdbuf + pw.editpos) + 1); + pw.editpos = npos; } break; case ctrl('p'): @@ -1932,6 +1980,7 @@ int main(int argc, char **argv) if (histpos < nhist) { char *cmd = (*hist)[histpos++]; strcpy(pw.cmdbuf, cmd); + pw.editpos = strlen(cmd); } } else { if (histpos >= 1) { @@ -1941,6 +1990,7 @@ int main(int argc, char **argv) if (histpos > 1) { char *cmd = (*hist)[--histpos - 1]; strcpy(pw.cmdbuf, cmd); + pw.editpos = strlen(cmd); } else if (histpos == 1) { --histpos; strcpy(pw.cmdbuf, pw.savedcmd); @@ -1955,8 +2005,9 @@ int main(int argc, char **argv) { size_t len = strlen(pw.cmdbuf); if (len < sizeof pw.cmdbuf - 1 && (int) len < pw.columns - 1) { - pw.cmdbuf[len++] = ch; - pw.cmdbuf[len] = 0; + memmove(pw.cmdbuf + pw.editpos + 1, pw.cmdbuf + pw.editpos, + len - pw.editpos + 1); + pw.cmdbuf[pw.editpos++] = ch; } } break; |