aboutsummaryrefslogtreecommitdiffstats
path: root/pw.c
diff options
context:
space:
mode:
Diffstat (limited to 'pw.c')
-rw-r--r--pw.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/pw.c b/pw.c
index 5e52a6c..1abe3d0 100644
--- a/pw.c
+++ b/pw.c
@@ -47,6 +47,7 @@
#define ctrl(ch) ((ch) & 0x1f)
#define BS 8
+#define TAB 9
#define CR 13
#define ESC 27
#define DEL 127
@@ -94,6 +95,7 @@ typedef struct pwstate {
int vsplit1, vsplit2, vs2pos;
int hist;
int columns;
+ int tstop;
unsigned stat;
int sncount, tcount;
char *curcmd, *savedcmd;
@@ -256,16 +258,25 @@ static char *addch(char *line, int ch)
abort();
}
-static char *addchesc(char *line, int ch)
+static char *addchesc(char *line, int tstop, int ch)
{
- if (ch == DEL) {
+ switch (ch) {
+ case DEL:
line = addch(line, '^');
line = addch(line, '?');
- } else if (ch < 32) {
- line = addch(line, '^');
- line = addch(line, ch + 64);
- } else {
+ break;
+ case TAB:
+ for (size_t len = dslen(line); line = addch(line, ' '), ++len % tstop != 0;)
+ /* empty */;
+ break;
+ default:
+ if (ch < 32) {
+ line = addch(line, '^');
+ line = addch(line, ch + 64);
+ break;
+ }
line = addch(line, ch);
+ break;
}
return line;
@@ -682,6 +693,7 @@ static int decodeparms(pwstate *pw, char *parms,
char *rpane = strtok(0, ", \t");
char *vs2pos = strtok(0, ", \t");
char *flags = strtok(0, ", \t");
+ char *tstop = strtok(0, ", \t");
pw->hpos = pw->vsplit1 = pw->vsplit2 = pw->vs2pos = 0;
pw->stat &= ~stat_save;
@@ -715,6 +727,13 @@ static int decodeparms(pwstate *pw, char *parms,
pw->stat |= (stat & stat_save);
}
+ if (tstop && ((pw->tstop = getznn(tstop, &err)) < 0 || pw->tstop > 16)) {
+ snprintf(resbuf, size, "bad tab stop size%s: %s\n", tstop, err);
+ if (pw->tstop == 0)
+ pw->tstop = 8;
+ return 0;
+ }
+
return 1;
}
@@ -898,8 +917,8 @@ static execode execute(pwstate *pw, char *cmd, char *resbuf,
break;
}
- fprintf(f, ":p%d,%d,%d,%d,%d\n", pw->hpos, pw->vsplit1, pw->vsplit2,
- pw->vs2pos, (int) pw->stat & stat_save);
+ fprintf(f, ":p%d,%d,%d,%d,%d,%d\n", pw->hpos, pw->vsplit1, pw->vsplit2,
+ pw->vs2pos, (int) pw->stat & stat_save, pw->tstop);
if (pw->tcount)
fprintf(f, ":f%d\n", pw->tcount);
@@ -1086,7 +1105,7 @@ void clipsplits(pwstate *pw)
int main(int argc, char **argv)
{
- struct pwstate pw = { .columns = 80, .maxlines = 15 };
+ struct pwstate pw = { .columns = 80, .maxlines = 15, .tstop = 8 };
char *line = 0;
FILE *tty = fopen("/dev/tty", "r+");
int maxed = 0;
@@ -1321,7 +1340,7 @@ int main(int argc, char **argv)
if ((pw.stat & stat_eof) == 0) {
int ch;
while ((ch = getc(stdin)) != EOF && ch != '\n' && dslen(line) < maxlen)
- line = addchesc(line, ch);
+ line = addchesc(line, pw.tstop, ch);
if (ch == EOF) {
if (feof(stdin) || (errno != EAGAIN && errno != EWOULDBLOCK)) {
nfds = 1;
@@ -1617,6 +1636,12 @@ int main(int argc, char **argv)
if ((pw.stat & stat_eof) == 0)
pw.stat |= stat_susp;
break;
+ case 't':
+ if (cmdcount < 1 || cmdcount > 16)
+ cmdcount = 8;
+ pw.tstop = cmdcount;
+ pw.stat |= stat_force;
+ break;
case CR:
pw.stat &= ~stat_susp;
break;