added tabs to spaces code from mkhl

This commit is contained in:
Iris Lightshard 2020-11-17 14:26:25 -05:00
parent 770f1906a3
commit 110ffde515
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
7 changed files with 170 additions and 108 deletions

7
acme.c
View file

@ -78,7 +78,7 @@ threadmain(int argc, char *argv[])
} }
break; break;
case 'a': case 'a':
globalautoindent = TRUE; globalindent[AUTOINDENT] = TRUE;
break; break;
case 'b': case 'b':
bartflag = TRUE; bartflag = TRUE;
@ -101,6 +101,9 @@ threadmain(int argc, char *argv[])
if(fontnames[1] == nil) if(fontnames[1] == nil)
goto Usage; goto Usage;
break; break;
case 'i':
globalindent[SPACESINDENT] = TRUE;
break;
case 'l': case 'l':
loadfile = ARGF(); loadfile = ARGF();
if(loadfile == nil) if(loadfile == nil)
@ -121,7 +124,7 @@ threadmain(int argc, char *argv[])
break; break;
default: default:
Usage: 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"); threadexitsall("usage");
}ARGEND }ARGEND

12
dat.h
View file

@ -229,6 +229,14 @@ void textsetselect(Text*, uint, uint);
void textshow(Text*, uint, uint, int); void textshow(Text*, uint, uint, int);
void texttype(Text*, Rune); void texttype(Text*, Rune);
enum
{
SPACESINDENT = 0,
AUTOINDENT,
NINDENT,
};
struct Window struct Window
{ {
QLock lk; QLock lk;
@ -240,7 +248,7 @@ struct Window
uchar isscratch; uchar isscratch;
uchar filemenu; uchar filemenu;
uchar dirty; uchar dirty;
uchar autoindent; uchar indent[NINDENT];
uchar showdel; uchar showdel;
int id; int id;
Range addr; Range addr;
@ -552,7 +560,7 @@ extern char wdir[]; /* must use extern because no dimension given */
int editing; int editing;
int erroutfd; int erroutfd;
int messagesize; /* negotiated in 9P version setup */ int messagesize; /* negotiated in 9P version setup */
int globalautoindent; int globalindent[NINDENT];
int dodollarsigns; int dodollarsigns;
char* mtpt; char* mtpt;

55
exec.c
View file

@ -92,6 +92,7 @@ static Rune LRedo[] = { 'R', 'e', 'd', 'o', 0 };
static Rune LSend[] = { 'S', 'e', 'n', 'd', 0 }; static Rune LSend[] = { 'S', 'e', 'n', 'd', 0 };
static Rune LSnarf[] = { 'S', 'n', 'a', 'r', 'f', 0 }; static Rune LSnarf[] = { 'S', 'n', 'a', 'r', 'f', 0 };
static Rune LSort[] = { 'S', 'o', 'r', 't', 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 LTab[] = { 'T', 'a', 'b', 0 };
static Rune LUndo[] = { 'U', 'n', 'd', 'o', 0 }; static Rune LUndo[] = { 'U', 'n', 'd', 'o', 0 };
static Rune LZerox[] = { 'Z', 'e', 'r', 'o', 'x', 0 }; static Rune LZerox[] = { 'Z', 'e', 'r', 'o', 'x', 0 };
@ -109,7 +110,7 @@ Exectab exectab[] = {
{ LGet, get, FALSE, TRUE, XXX }, { LGet, get, FALSE, TRUE, XXX },
{ LID, id, FALSE, XXX, XXX }, { LID, id, FALSE, XXX, XXX },
{ LIncl, incl, FALSE, XXX, XXX }, { LIncl, incl, FALSE, XXX, XXX },
{ LIndent, indent, FALSE, XXX, XXX }, { LIndent, indent, FALSE, AUTOINDENT, XXX },
{ LKill, xkill, FALSE, XXX, XXX }, { LKill, xkill, FALSE, XXX, XXX },
{ LLoad, dump, FALSE, FALSE, XXX }, { LLoad, dump, FALSE, FALSE, XXX },
{ LLocal, local, FALSE, XXX, XXX }, { LLocal, local, FALSE, XXX, XXX },
@ -123,6 +124,7 @@ Exectab exectab[] = {
{ LSend, sendx, TRUE, XXX, XXX }, { LSend, sendx, TRUE, XXX, XXX },
{ LSnarf, cut, FALSE, TRUE, FALSE }, { LSnarf, cut, FALSE, TRUE, FALSE },
{ LSort, sort, FALSE, XXX, XXX }, { LSort, sort, FALSE, XXX, XXX },
{ LSpaces, indent, FALSE, SPACESINDENT, XXX },
{ LTab, tab, FALSE, XXX, XXX }, { LTab, tab, FALSE, XXX, XXX },
{ LUndo, undo, FALSE, TRUE, XXX }, { LUndo, undo, FALSE, TRUE, XXX },
{ LZerox, zeroxx, FALSE, XXX, XXX }, { LZerox, zeroxx, FALSE, XXX, XXX },
@ -911,7 +913,7 @@ put(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
warning(nil, "no file name\n"); warning(nil, "no file name\n");
return; return;
} }
if(w->autoindent) if(w->indent[NINDENT])
trimspaces(et); trimspaces(et);
namer = bytetorune(name, &nname); namer = bytetorune(name, &nname);
putfile(f, 0, f->b.nc, namer, nname); putfile(f, 0, f->b.nc, namer, nname);
@ -1383,66 +1385,75 @@ incl(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
static Rune LON[] = { 'O', 'N', 0 }; static Rune LON[] = { 'O', 'N', 0 };
static Rune LOFF[] = { 'O', 'F', 'F', 0 }; static Rune LOFF[] = { 'O', 'F', 'F', 0 };
static Rune Lon[] = { 'o', 'n', 0 }; static Rune Lon[] = { 'o', 'n', 0 };
static Rune Loff[] = { 'o', 'f', 'f', 0 };
enum { enum {
IGlobal = -2, IGlobal = -2,
IError = -1, IError = -1,
Ion = 0,
Ioff = 1
}; };
static int static int
indentval(Rune *s, int n) indentval(Rune *s, int n, int type)
{ {
static char *strs[] = {
[SPACESINDENT] = "Spaces",
[AUTOINDENT] = "Indent",
};
if(n < 2) if(n < 2)
return IError; return IError;
if(runestrncmp(s, LON, n) == 0){ if(runestrncmp(s, LON, n) == 0){
globalautoindent = TRUE; globalindent[type] = TRUE;
warning(nil, "Indent ON\n"); warning(nil, "%s ON\n", strs[type]);
return IGlobal; return IGlobal;
} }
if(runestrncmp(s, LOFF, n) == 0){ if(runestrncmp(s, LOFF, n) == 0){
globalautoindent = FALSE; globalindent[type] = FALSE;
warning(nil, "Indent OFF\n"); warning(nil, "%s OFF\n", strs[type]);
return IGlobal; 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 static void
fixindent(Window *w, void *arg) fixindent(Window *w, void *arg)
{ {
USED(arg); int t;
w->autoindent = globalautoindent;
t = (int)arg;
w->indent[t] = globalindent[t];
} }
void 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; Rune *a, *r;
Window *w; Window *w;
int na, len, autoindent; int na, len, ival;
USED(_0); USED(_0);
USED(_1); USED(_1);
USED(_2);
w = nil; w = nil;
if(et!=nil && et->w!=nil) if(et!=nil && et->w!=nil)
w = et->w; w = et->w;
autoindent = IError; ival = IError;
getarg(argt, FALSE, TRUE, &r, &len); getarg(argt, FALSE, TRUE, &r, &len);
if(r!=nil && len>0) if(r!=nil && len>0)
autoindent = indentval(r, len); ival = indentval(r, len, type);
else{ else{
a = findbl(arg, narg, &na); a = findbl(arg, narg, &na);
if(a != arg) if(a != arg)
autoindent = indentval(arg, narg-na); ival = indentval(arg, narg-na, type);
} }
if(autoindent == IGlobal) if(ival == IGlobal)
allwindows(fixindent, nil); allwindows(fixindent, (void*)type);
else if(w != nil && autoindent >= 0) else if(w != nil && ival >= 0)
w->autoindent = autoindent; w->indent[type] = ival;
} }
void void

6
look.c
View file

@ -799,9 +799,11 @@ openfile(Text *t, Expand *e)
runemove(rp, ow->incl[i], n); runemove(rp, ow->incl[i], n);
winaddincl(w, rp, n); winaddincl(w, rp, n);
} }
w->autoindent = ow->autoindent; for(i=0; i < NINDENT; i++)
w->indent[i] = ow->indent[i];
}else }else
w->autoindent = globalautoindent; for(i=0; i < NINDENT; i++)
w->indent[i] = globalindent[i];
xfidlog(w, "new"); xfidlog(w, "new");
} }
if(e->a1 == e->a0) if(e->a1 == e->a0)

39
text.c
View file

@ -532,6 +532,27 @@ textreadc(Text *t, uint q)
return r; 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 int
textbswidth(Text *t, Rune c) textbswidth(Text *t, Rune c)
{ {
@ -540,8 +561,11 @@ textbswidth(Text *t, Rune c)
int skipping; int skipping;
/* there is known to be at least one character to erase */ /* 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; return 1;
}
q = t->q0; q = t->q0;
skipping = TRUE; skipping = TRUE;
while(q > 0){ while(q > 0){
@ -910,8 +934,19 @@ texttype(Text *t, Rune r)
textfill(t->file->text[i]); textfill(t->file->text[i]);
t->iq1 = t->q0; t->iq1 = t->q0;
return; 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': case '\n':
if(t->w->autoindent){ if(t->what == Body && t->w->indent[AUTOINDENT]){
/* find beginning of previous line using backspace code */ /* find beginning of previous line using backspace code */
nnb = textbswidth(t, 0x15); /* ^U case */ nnb = textbswidth(t, 0x15); /* ^U case */
rp = runemalloc(nnb + 1); rp = runemalloc(nnb + 1);

3
util.c
View file

@ -107,7 +107,8 @@ errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
runemove(r, incl[i], n); runemove(r, incl[i], n);
winaddincl(w, r, n); winaddincl(w, r, n);
} }
w->autoindent = globalautoindent; for(i=0; i<NINDENT; i++)
w->indent[i] = globalindent[i];
return w; return w;
} }

8
wind.c
View file

@ -21,7 +21,7 @@ wininit(Window *w, Window *clone, Rectangle r)
File *f; File *f;
Reffont *rf; Reffont *rf;
Rune *rp; Rune *rp;
int nc; int nc, i;
w->tag.w = w; w->tag.w = w;
w->taglines = 1; w->taglines = 1;
@ -80,10 +80,12 @@ wininit(Window *w, Window *clone, Rectangle r)
draw(screen, br, button, nil, button->r.min); draw(screen, br, button, nil, button->r.min);
w->filemenu = TRUE; w->filemenu = TRUE;
w->maxlines = w->body.fr.maxlines; w->maxlines = w->body.fr.maxlines;
w->autoindent = globalautoindent; for(i=0; i<NINDENT; i++)
w->indent[i] = globalindent[i];
if(clone){ if(clone){
w->dirty = clone->dirty; w->dirty = clone->dirty;
w->autoindent = clone->autoindent; for(i=0; i<NINDENT; i++)
w->indent[i] = clone->indent[i];
textsetselect(&w->body, clone->body.q0, clone->body.q1); textsetselect(&w->body, clone->body.q0, clone->body.q1);
winsettag(w); winsettag(w);
} }