diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2022-05-13 07:15:16 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2022-05-13 07:15:16 -0700 |
commit | 297cf626809f27e3543576cb3547eb1868b663c8 (patch) | |
tree | fb594eb7a9641c4ba61ea82f0028b2915d79d785 | |
parent | 8a337f186d99881114ceefb02a513db48f97408f (diff) | |
download | pw-297cf626809f27e3543576cb3547eb1868b663c8.tar.gz pw-297cf626809f27e3543576cb3547eb1868b663c8.tar.bz2 pw-297cf626809f27e3543576cb3547eb1868b663c8.zip |
Expand tabs to spaces, with configurable tab size.
-rw-r--r-- | pw.1 | 39 | ||||
-rw-r--r-- | pw.c | 45 |
2 files changed, 64 insertions, 20 deletions
@@ -114,15 +114,25 @@ trimmed, it is terminated by the character to indicate that there are more characters. The display may be scrolled interactively to read the long lines. -The ASCII DEL character (127) is displayed as +Control characters are replaced as follows. The ASCII +.I DEL +character (127) is converted to the character sequence .B ^? -and ASCII control characters are displayed as +and other ASCII control characters are converted to .BR ^@ , .BR ^A ", ..." .BR ^Z ", ..." -.BR ^_ . -All other characters are sent to the display as-is. No attempt is made -to account for the width of East Asian Unicode characters, and such. +.BR ^_ , +except for +.I TAB +which is expanded into spaces according to the current tab stop. +All other characters remain as-is. No attempt is made to account for the width +of East Asian Unicode characters, and such. + +The above replacement of control characters happens when lines are read from +the input source, not when they are being displayed. Therefore, changing +the tab stop size has no effect on lines which are already captured and +displayed. When the display is scrolled horizontally, the .B > @@ -251,6 +261,12 @@ and characters which indicate line truncation and pane separation are shown in inverse video (dark foreground, light background). +.IP [\fIcount\fP]\fBt\fP +Set the tab stop size. If count is omitted, zero, or greater than 16, +then the value 8 is substituted. The tab stop size does not affect lines +which have already been captured and displayed; tabs are expanded to spaces +when lines are read from standard input and entered into the FIFO. + .IP \fBCtrl-G\fP Shows the status of the display parameters, in a form which can be given to the @@ -669,7 +685,7 @@ the trigger count is reset to zero. Thus when the command is used to resume capture, the same number of capture events will have to occur again before the next automatic suspension. -.IP "\fB:p\fP [\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP]]]]] +.IP "\fB:p\fP [\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP]]]]]] Sets the display parameters, exactly in the manner of the .B -p option. Any parameters not specified are reset to their default initial values: @@ -837,7 +853,7 @@ option. If neither option is used, then .I pattern is interpreted as a BRE. -.IP "\fB-p\fP [\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP]]]]] +.IP "\fB-p\fP [\fIinteger\fP[,[\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP[,\fIinteger\fP]]]]]] Specify the display parameters, as comma-separated non-negative integers. The meaning of these integer values is: .RS @@ -846,9 +862,9 @@ horizontal scroll position; .IP 2. width of left pane; .IP 3. -width of middle pane; and +width of middle pane; .IP 4. -middle pane view offset; and +middle pane view offset; .IP 5. bitmask of several flags controlling line number display .RB ( # @@ -856,13 +872,16 @@ command), highlighting .RB ( Ctrl-I/Tab command), and suspended mode .RB ( Space -command). The values are internal and undocumented. +command), the values being internal and undocumented; and +.IP 6. +the tab stop size. .PP All five numbers are optional, and default to zero if omitted. Since .B -p requires an argument, the only way all four may be omitted is if a blank or empty argument is given. +The tab stop must be in the range 0 to 16. A value of 0 is interpreted as 8. The .B Ctrl-G command displays these same parameters in the same format, so it is possible to @@ -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; |