commit b4704695f1c7c3ade4b6748ae50129fb404f5214 from: Omar Polo via: Omar Polo date: Thu Jan 26 11:03:56 2023 UTC soft-tabs thanks to mkhl and neutralinsomniac (and probably other guys at 9front) commit - e2a141ae0952c2d28a9f500bb9da6dc72e57be3c commit + b4704695f1c7c3ade4b6748ae50129fb404f5214 blob - 852a8f7f1e803c2662691fffa27510cb0e448c02 blob + 2fdda118f6a24e605187160a126ca78a0345c2e5 --- man/man1/acme.1 +++ man/man1/acme.1 @@ -4,7 +4,7 @@ acme, win, awd \- interactive text windows .SH SYNOPSIS .B acme [ -.B -abr +.B -aibr ] [ .B -f @@ -203,6 +203,16 @@ The option .B -a causes each window to start in autoindent mode. +.PP +When a window is in spacesindent mode +(see the +.B Spaces +command below) and a tab character is typed, +acme indents the line with spaces equal to the current +tabstop for the window. The option +.B -i +causes each window to start in spacesindent +mode. .SS "Directory context Each window's tag names a directory: explicitly if the window holds a directory; implicitly if it holds a regular file @@ -469,6 +479,17 @@ Place selected text in snarf buffer. Arrange the windows in the column from top to bottom in lexicographical order based on their names. .TP +.B Spaces +Set the spacesindent mode according to the argument: +.B on +and +.B off +set the mode for the current window; +.B ON +and +.B OFF +set the mode for all existing and future windows. +.TP .B Tab Set the width of tab stops for this window to the value of the argument, in units of widths of the zero character. blob - 0e6bc0fd7f077ef5453d5c33736924aa8424c2a3 blob + 9342965d3bcf2e5dbf0ba29d929734f2f1e5d7eb --- src/cmd/acme/acme.c +++ src/cmd/acme/acme.c @@ -78,7 +78,7 @@ threadmain(int argc, char *argv[]) } break; case 'a': - globalautoindent = TRUE; + globalindent[AUTOINDENT] = TRUE; break; case 'b': bartflag = TRUE; @@ -101,6 +101,9 @@ threadmain(int argc, char *argv[]) if(fontnames[1] == nil) goto Usage; break; + case 'i': + globalindent[SPACESINDENT] = TRUE; + break; case 'l': loadfile = ARGF(); if(loadfile == nil) @@ -121,7 +124,7 @@ threadmain(int argc, char *argv[]) break; default: Usage: - fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n"); + fprint(2, "usage: acme -aib -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n"); threadexitsall("usage"); }ARGEND blob - e540605a316dbcc3fa05f4205e0f4e6b0a674b57 blob + e05783ba445aa224611fd83536641a79f1c16d0f --- src/cmd/acme/dat.h +++ src/cmd/acme/dat.h @@ -229,6 +229,13 @@ void textsetselect(Text*, uint, uint); void textshow(Text*, uint, uint, int); void texttype(Text*, Rune); +enum +{ + SPACESINDENT = 0, + AUTOINDENT, + NINDENT, +}; + struct Window { QLock lk; @@ -240,7 +247,7 @@ struct Window uchar isscratch; uchar filemenu; uchar dirty; - uchar autoindent; + uchar indent[NINDENT]; uchar showdel; int id; Range addr; @@ -552,7 +559,7 @@ extern char wdir[]; /* must use extern because no dim int editing; int erroutfd; int messagesize; /* negotiated in 9P version setup */ -int globalautoindent; +int globalindent[NINDENT]; int dodollarsigns; char* mtpt; blob - 1dd0228895443eeef4c05f91ec6f5f9c3ad21068 blob + 9171d7a998d764c0eb6d3e10a5e14cdccf2e3624 --- src/cmd/acme/exec.c +++ src/cmd/acme/exec.c @@ -92,6 +92,7 @@ static Rune LRedo[] = { 'R', 'e', 'd', 'o', 0 }; static Rune LSend[] = { 'S', 'e', 'n', 'd', 0 }; static Rune LSnarf[] = { 'S', 'n', 'a', 'r', 'f', 0 }; static Rune LSort[] = { 'S', 'o', 'r', 't', 0 }; +static Rune LSpaces[] = { 'S', 'p', 'a', 'c', 'e', 's', 0 }; static Rune LTab[] = { 'T', 'a', 'b', 0 }; static Rune LUndo[] = { 'U', 'n', 'd', 'o', 0 }; static Rune LZerox[] = { 'Z', 'e', 'r', 'o', 'x', 0 }; @@ -109,7 +110,7 @@ Exectab exectab[] = { { LGet, get, FALSE, TRUE, XXX }, { LID, id, FALSE, XXX, XXX }, { LIncl, incl, FALSE, XXX, XXX }, - { LIndent, indent, FALSE, XXX, XXX }, + { LIndent, indent, FALSE, AUTOINDENT, XXX }, { LKill, xkill, FALSE, XXX, XXX }, { LLoad, dump, FALSE, FALSE, XXX }, { LLocal, local, FALSE, XXX, XXX }, @@ -123,6 +124,7 @@ Exectab exectab[] = { { LSend, sendx, TRUE, XXX, XXX }, { LSnarf, cut, FALSE, TRUE, FALSE }, { LSort, sort, FALSE, XXX, XXX }, + { LSpaces, indent, FALSE, SPACESINDENT, XXX }, { LTab, tab, FALSE, XXX, XXX }, { LUndo, undo, FALSE, TRUE, XXX }, { LZerox, zeroxx, FALSE, XXX, XXX }, @@ -915,7 +917,7 @@ put(Text *et, Text *_0, Text *argt, int _1, int _2, Ru warning(nil, "no file name\n"); return; } - if(w->autoindent) + if(w->indent[AUTOINDENT]) trimspaces(et); namer = bytetorune(name, &nname); putfile(f, 0, f->b.nc, namer, nname); @@ -1387,66 +1389,75 @@ incl(Text *et, Text *_0, Text *argt, int _1, int _2, R static Rune LON[] = { 'O', 'N', 0 }; static Rune LOFF[] = { 'O', 'F', 'F', 0 }; static Rune Lon[] = { 'o', 'n', 0 }; +static Rune Loff[] = { 'o', 'f', 'f', 0 }; enum { IGlobal = -2, IError = -1, - Ion = 0, - Ioff = 1 }; static int -indentval(Rune *s, int n) +indentval(Rune *s, int n, int type) { + static char *strs[] = { + [SPACESINDENT] = "Spaces", + [AUTOINDENT] = "Indent", + }; + if(n < 2) return IError; if(runestrncmp(s, LON, n) == 0){ - globalautoindent = TRUE; - warning(nil, "Indent ON\n"); + globalindent[type] = TRUE; + warning(nil, "%s ON\n", strs[type]); return IGlobal; } if(runestrncmp(s, LOFF, n) == 0){ - globalautoindent = FALSE; - warning(nil, "Indent OFF\n"); + globalindent[type] = FALSE; + warning(nil, "%s OFF\n", strs[type]); return IGlobal; } - return runestrncmp(s, Lon, n) == 0; + if(runestrncmp(s, Lon, n) == 0) + return TRUE; + if(runestrncmp(s, Loff, n) == 0) + return FALSE; + return IError; } static void fixindent(Window *w, void *arg) { - USED(arg); - w->autoindent = globalautoindent; + int t; + + t = (int)arg; + w->indent[t] = globalindent[t]; } void -indent(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg) +indent(Text *et, Text* _0, Text *argt, int type, int _1, Rune *arg, int narg) { Rune *a, *r; Window *w; - int na, len, autoindent; + int na, len, ival; USED(_0); USED(_1); - USED(_2); w = nil; if(et!=nil && et->w!=nil) w = et->w; - autoindent = IError; + ival = IError; getarg(argt, FALSE, TRUE, &r, &len); if(r!=nil && len>0) - autoindent = indentval(r, len); + ival = indentval(r, len, type); else{ a = findbl(arg, narg, &na); if(a != arg) - autoindent = indentval(arg, narg-na); + ival = indentval(arg, narg-na, type); } - if(autoindent == IGlobal) - allwindows(fixindent, nil); - else if(w != nil && autoindent >= 0) - w->autoindent = autoindent; + if(ival == IGlobal) + allwindows(fixindent, (void*)type); + else if(w != nil && ival >= 0) + w->indent[type] = ival; } void blob - a7172b505f71d405da0d9ad6766e4540df54a887 blob + ce528330caa24eeb537bf76b88cf196eae3fd00e --- src/cmd/acme/look.c +++ src/cmd/acme/look.c @@ -797,9 +797,11 @@ openfile(Text *t, Expand *e) runemove(rp, ow->incl[i], n); winaddincl(w, rp, n); } - w->autoindent = ow->autoindent; + for(i=0; i < NINDENT; i++) + w->indent[i] = ow->indent[i]; }else - w->autoindent = globalautoindent; + for(i=0; i < NINDENT; i++) + w->indent[i] = globalindent[i]; xfidlog(w, "new"); } if(e->a1 == e->a0) blob - 09422dda077cfa755a87ba156da88fafa25cd7b1 blob + ff2da5b3e06a235c6976a582fd47ba9f6950c143 --- src/cmd/acme/text.c +++ src/cmd/acme/text.c @@ -531,7 +531,28 @@ textreadc(Text *t, uint q) bufread(&t->file->b, q, &r, 1); return r; } + +static int +spacesindentbswidth(Text *t) +{ + uint q, col; + Rune r; + col = textbswidth(t, 0x15); + q = t->q0; + while(q > 0){ + r = textreadc(t, q-1); + if(r != ' ') + break; + q--; + if(--col % t->tabstop == 0) + break; + } + if(t->q0 == q) + return 1; + return t->q0-q; +} + int textbswidth(Text *t, Rune c) { @@ -540,8 +561,11 @@ textbswidth(Text *t, Rune c) int skipping; /* there is known to be at least one character to erase */ - if(c == 0x08) /* ^H: erase character */ + if(c == 0x08){ /* ^H: erase character */ + if(t->what == Body && t->w->indent[SPACESINDENT]) + return spacesindentbswidth(t); return 1; + } q = t->q0; skipping = TRUE; while(q > 0){ @@ -887,8 +911,19 @@ texttype(Text *t, Rune r) textfill(t->file->text[i]); t->iq1 = t->q0; return; + case '\t': + if(t->what == Body && t->w->indent[SPACESINDENT]){ + nnb = textbswidth(t, 0x15); + if(nnb == 1 && textreadc(t, t->q0-1) == '\n') + nnb = 0; + nnb = t->tabstop - nnb % t->tabstop; + rp = runemalloc(nnb); + for(nr = 0; nr < nnb; nr++) + rp[nr] = ' '; + } + break; case '\n': - if(t->w->autoindent){ + if(t->what == Body && t->w->indent[AUTOINDENT]){ /* find beginning of previous line using backspace code */ nnb = textbswidth(t, 0x15); /* ^U case */ rp = runemalloc(nnb + 1); blob - c153f8c180c0c2325d9b26c1b29e0f6257ba61b4 blob + ecd0450341809c99bcf3a55eb6a8aafd6d29164a --- src/cmd/acme/util.c +++ src/cmd/acme/util.c @@ -107,7 +107,8 @@ errorwin1(Rune *dir, int ndir, Rune **incl, int nincl) runemove(r, incl[i], n); winaddincl(w, r, n); } - w->autoindent = globalautoindent; + for(i=0; iindent[i] = globalindent[i]; return w; } blob - 9441bbb76077ff5aea945f3813efa501e32adf25 blob + 0cea1694a118c07fc8c98ee947c98895f55238cc --- src/cmd/acme/wind.c +++ src/cmd/acme/wind.c @@ -21,7 +21,7 @@ wininit(Window *w, Window *clone, Rectangle r) File *f; Reffont *rf; Rune *rp; - int nc; + int nc, i; w->tag.w = w; w->taglines = 1; @@ -80,10 +80,12 @@ wininit(Window *w, Window *clone, Rectangle r) draw(screen, br, button, nil, button->r.min); w->filemenu = TRUE; w->maxlines = w->body.fr.maxlines; - w->autoindent = globalautoindent; + for(i=0; iindent[i] = globalindent[i]; if(clone){ w->dirty = clone->dirty; - w->autoindent = clone->autoindent; + for(i=0; iindent[i] = clone->indent[i]; textsetselect(&w->body, clone->body.q0, clone->body.q1); winsettag(w); }