aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-13 22:13:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-13 22:13:14 -0700
commit799957d64606e79c905d1667e48b9c1540d086d9 (patch)
tree1b178eff65de2caf06b961de0185367bdfae24c5 /pw.c
parent507a4d9c547c46d08ae36e8666ff16a60092b530 (diff)
downloadpw-799957d64606e79c905d1667e48b9c1540d086d9.tar.gz
pw-799957d64606e79c905d1667e48b9c1540d086d9.tar.bz2
pw-799957d64606e79c905d1667e48b9c1540d086d9.zip
Much better editing.
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c73
1 files changed, 62 insertions, 11 deletions
diff --git a/pw.c b/pw.c
index 8f2ee3c..287bd50 100644
--- a/pw.c
+++ b/pw.c
@@ -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;