summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/man/1/acme23
-rw-r--r--sys/src/cmd/acme/acme.c7
-rw-r--r--sys/src/cmd/acme/dat.h11
-rw-r--r--sys/src/cmd/acme/exec.c51
-rw-r--r--sys/src/cmd/acme/look.c6
-rw-r--r--sys/src/cmd/acme/text.c39
-rw-r--r--sys/src/cmd/acme/util.c3
-rw-r--r--sys/src/cmd/acme/wind.c9
8 files changed, 115 insertions, 34 deletions
diff --git a/sys/man/1/acme b/sys/man/1/acme
index 2220fa670..36fbd8ae3 100644
--- a/sys/man/1/acme
+++ b/sys/man/1/acme
@@ -4,7 +4,7 @@ acme, win \- interactive text windows
.SH SYNOPSIS
.B acme
[
-.B -ab
+.B -aib
]
[
.B -c
@@ -174,6 +174,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
@@ -430,6 +440,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.
diff --git a/sys/src/cmd/acme/acme.c b/sys/src/cmd/acme/acme.c
index 5c67c9bfd..69ea715ce 100644
--- a/sys/src/cmd/acme/acme.c
+++ b/sys/src/cmd/acme/acme.c
@@ -66,7 +66,7 @@ threadmain(int argc, char *argv[])
loadfile = nil;
ARGBEGIN{
case 'a':
- globalautoindent = TRUE;
+ globalindent[AUTOINDENT] = TRUE;
break;
case 'b':
bartflag = TRUE;
@@ -89,6 +89,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)
@@ -96,7 +99,7 @@ threadmain(int argc, char *argv[])
break;
default:
Usage:
- fprint(2, "usage: acme [-ab] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n");
+ fprint(2, "usage: acme [-aib] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n");
exits("usage");
}ARGEND
diff --git a/sys/src/cmd/acme/dat.h b/sys/src/cmd/acme/dat.h
index 2c4d40d79..070be119b 100644
--- a/sys/src/cmd/acme/dat.h
+++ b/sys/src/cmd/acme/dat.h
@@ -224,6 +224,13 @@ void textsetselect(Text*, uint, uint);
void textshow(Text*, uint, uint, int);
void texttype(Text*, Rune);
+enum
+{
+ SPACESINDENT = 0,
+ AUTOINDENT,
+ NINDENT,
+};
+
struct Window
{
QLock;
@@ -235,7 +242,7 @@ struct Window
uchar isscratch;
uchar filemenu;
uchar dirty;
- uchar autoindent;
+ uchar indent[NINDENT];
uchar showdel;
uint noredraw;
int id;
@@ -538,7 +545,7 @@ int plumbeditfd;
char wdir[];
int editing;
int messagesize; /* negotiated in 9P version setup */
-int globalautoindent;
+int globalindent[NINDENT];
Channel *cplumb; /* chan(Plumbmsg*) */
Channel *cwait; /* chan(Waitmsg) */
diff --git a/sys/src/cmd/acme/exec.c b/sys/src/cmd/acme/exec.c
index fa18e8af2..baf125927 100644
--- a/sys/src/cmd/acme/exec.c
+++ b/sys/src/cmd/acme/exec.c
@@ -73,7 +73,7 @@ Exectab exectab[] = {
{ L"Get", get, FALSE, TRUE, XXX },
{ L"ID", id, FALSE, XXX, XXX },
{ L"Incl", incl, FALSE, XXX, XXX },
- { L"Indent", indent, FALSE, XXX, XXX },
+ { L"Indent", indent, FALSE, AUTOINDENT, XXX },
{ L"Kill", kill, FALSE, XXX, XXX },
{ L"Load", dump, FALSE, FALSE, XXX },
{ L"Local", local, FALSE, XXX, XXX },
@@ -87,6 +87,7 @@ Exectab exectab[] = {
{ L"Send", sendx, TRUE, XXX, XXX },
{ L"Snarf", cut, FALSE, TRUE, FALSE },
{ L"Sort", sort, FALSE, XXX, XXX },
+ { L"Spaces", indent, FALSE, SPACESINDENT, XXX },
{ L"Tab", tab, FALSE, XXX, XXX },
{ L"Undo", undo, FALSE, TRUE, XXX },
{ L"Zerox", zeroxx, FALSE, XXX, XXX },
@@ -1087,57 +1088,67 @@ incl(Text *et, Text*, Text *argt, int, int, Rune *arg, int narg)
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, L"ON", n) == 0){
- globalautoindent = TRUE;
- warning(nil, "Indent ON\n");
+ globalindent[type] = TRUE;
+ warning(nil, "%s ON\n", strs[type]);
return IGlobal;
}
if(runestrncmp(s, L"OFF", n) == 0){
- globalautoindent = FALSE;
- warning(nil, "Indent OFF\n");
+ globalindent[type] = FALSE;
+ warning(nil, "%s OFF\n", strs[type]);
return IGlobal;
}
- return runestrncmp(s, L"on", n) == 0;
+ if(runestrncmp(s, L"on", n) == 0)
+ return TRUE;
+ if(runestrncmp(s, L"off", n) == 0)
+ return FALSE;
+ return IError;
}
static void
-fixindent(Window *w, void*)
+fixindent(Window *w, void *v)
{
- w->autoindent = globalautoindent;
+ int t;
+
+ t = (int)v;
+ w->indent[t] = globalindent[t];
}
void
-indent(Text *et, Text*, Text *argt, int, int, Rune *arg, int narg)
+indent(Text *et, Text*, Text *argt, int type, int, Rune *arg, int narg)
{
Rune *a, *r;
Window *w;
- int na, len, autoindent;
+ int na, len, ival;
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
diff --git a/sys/src/cmd/acme/look.c b/sys/src/cmd/acme/look.c
index d8882995a..60ade8b25 100644
--- a/sys/src/cmd/acme/look.c
+++ b/sys/src/cmd/acme/look.c
@@ -663,9 +663,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];
}
if(e->a1 == e->a0)
eval = FALSE;
diff --git a/sys/src/cmd/acme/text.c b/sys/src/cmd/acme/text.c
index 7380d0163..b96213a68 100644
--- a/sys/src/cmd/acme/text.c
+++ b/sys/src/cmd/acme/text.c
@@ -502,6 +502,27 @@ textreadc(Text *t, uint q)
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)
{
@@ -510,8 +531,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){
@@ -775,8 +799,19 @@ texttype(Text *t, Rune r)
for(i=0; i<t->file->ntext; i++)
textfill(t->file->text[i]);
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->what == Body && 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);
diff --git a/sys/src/cmd/acme/util.c b/sys/src/cmd/acme/util.c
index aa5d3ac14..bf00a9e65 100644
--- a/sys/src/cmd/acme/util.c
+++ b/sys/src/cmd/acme/util.c
@@ -85,7 +85,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; i<NINDENT; i++)
+ w->indent[i] = globalindent[i];
return w;
}
diff --git a/sys/src/cmd/acme/wind.c b/sys/src/cmd/acme/wind.c
index 90acb486b..7c222a17c 100644
--- a/sys/src/cmd/acme/wind.c
+++ b/sys/src/cmd/acme/wind.c
@@ -20,7 +20,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;
@@ -78,13 +78,14 @@ wininit(Window *w, Window *clone, Rectangle r)
draw(screen, br, button, nil, button->r.min);
w->filemenu = TRUE;
w->maxlines = w->body.maxlines;
- w->autoindent = globalautoindent;
+ for(i=0; i<NINDENT; i++)
+ w->indent[i] = globalindent[i];
if(clone){
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);
winsettag(w);
- w->autoindent = clone->autoindent;
}
}