mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
completion, pageup/pagedown
This commit is contained in:
parent
97fdda4e86
commit
c197370550
5 changed files with 139 additions and 7 deletions
|
@ -138,6 +138,7 @@ threadmain(int argc, char *argv[])
|
||||||
|
|
||||||
d = display;
|
d = display;
|
||||||
font = d->defaultfont;
|
font = d->defaultfont;
|
||||||
|
//assert(font);
|
||||||
|
|
||||||
reffont.f = font;
|
reffont.f = font;
|
||||||
reffonts[0] = &reffont;
|
reffonts[0] = &reffont;
|
||||||
|
@ -790,6 +791,7 @@ rfget(int fix, int save, int setfont, char *name)
|
||||||
}
|
}
|
||||||
f = openfont(display, name);
|
f = openfont(display, name);
|
||||||
if(f == nil){
|
if(f == nil){
|
||||||
|
fprint(2, "can't open font file %s: %r\n", name);
|
||||||
warning(nil, "can't open font file %s: %r\n", name);
|
warning(nil, "can't open font file %s: %r\n", name);
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,7 @@ coladd(Column *c, Window *w, Window *clone, int y)
|
||||||
w->col = c;
|
w->col = c;
|
||||||
winresize(w, r, FALSE);
|
winresize(w, r, FALSE);
|
||||||
}
|
}
|
||||||
|
//assert(w->body.w == w);
|
||||||
w->tag.col = c;
|
w->tag.col = c;
|
||||||
w->tag.row = c->row;
|
w->tag.row = c->row;
|
||||||
w->body.col = c;
|
w->body.col = c;
|
||||||
|
|
|
@ -36,6 +36,6 @@ UPDATE=\
|
||||||
|
|
||||||
<$PLAN9/src/mkone
|
<$PLAN9/src/mkone
|
||||||
|
|
||||||
LDFLAGS=$LDFLAGS -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
|
LDFLAGS=$LDFLAGS -lcomplete -lplumb -lfs -lmux -lthread -lframe -ldraw -lbio -l9 -lfmt -lutf -L$X11/lib -lX11
|
||||||
|
|
||||||
edit.$O ecmd.$O elog.$O: edit.h
|
edit.$O ecmd.$O elog.$O: edit.h
|
||||||
|
|
|
@ -8,11 +8,13 @@
|
||||||
#include <frame.h>
|
#include <frame.h>
|
||||||
#include <fcall.h>
|
#include <fcall.h>
|
||||||
#include <plumb.h>
|
#include <plumb.h>
|
||||||
|
#include <complete.h>
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
|
|
||||||
Image *tagcols[NCOL];
|
Image *tagcols[NCOL];
|
||||||
Image *textcols[NCOL];
|
Image *textcols[NCOL];
|
||||||
|
static Rune Ldot[] = { '.', 0 };
|
||||||
|
|
||||||
enum{
|
enum{
|
||||||
TABDIR = 3 /* width of tabs in directory windows */
|
TABDIR = 3 /* width of tabs in directory windows */
|
||||||
|
@ -526,24 +528,136 @@ textbswidth(Text *t, Rune c)
|
||||||
return t->q0-q;
|
return t->q0-q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
textfilewidth(Text *t, uint q0, int oneelement)
|
||||||
|
{
|
||||||
|
uint q;
|
||||||
|
Rune r;
|
||||||
|
|
||||||
|
q = q0;
|
||||||
|
while(q > 0){
|
||||||
|
r = textreadc(t, q-1);
|
||||||
|
if(r<=' ')
|
||||||
|
break;
|
||||||
|
if(oneelement && r=='/')
|
||||||
|
break;
|
||||||
|
--q;
|
||||||
|
}
|
||||||
|
return q0-q;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rune*
|
||||||
|
textcomplete(Text *t)
|
||||||
|
{
|
||||||
|
int i, nstr, npath;
|
||||||
|
uint q;
|
||||||
|
Rune tmp[200];
|
||||||
|
Rune *str, *path;
|
||||||
|
Rune *rp;
|
||||||
|
Completion *c;
|
||||||
|
char *s, *dirs;
|
||||||
|
Runestr dir;
|
||||||
|
|
||||||
|
/* control-f: filename completion; works back to white space or / */
|
||||||
|
if(t->q0<t->file->b.nc && textreadc(t, t->q0)>' ') /* must be at end of word */
|
||||||
|
return nil;
|
||||||
|
nstr = textfilewidth(t, t->q0, TRUE);
|
||||||
|
str = runemalloc(nstr);
|
||||||
|
npath = textfilewidth(t, t->q0-nstr, FALSE);
|
||||||
|
path = runemalloc(npath);
|
||||||
|
|
||||||
|
c = nil;
|
||||||
|
rp = nil;
|
||||||
|
dirs = nil;
|
||||||
|
|
||||||
|
q = t->q0-nstr;
|
||||||
|
for(i=0; i<nstr; i++)
|
||||||
|
str[i] = textreadc(t, q++);
|
||||||
|
q = t->q0-nstr-npath;
|
||||||
|
for(i=0; i<npath; i++)
|
||||||
|
path[i] = textreadc(t, q++);
|
||||||
|
/* is path rooted? if not, we need to make it relative to window path */
|
||||||
|
if(npath>0 && path[0]=='/')
|
||||||
|
dir = (Runestr){path, npath};
|
||||||
|
else{
|
||||||
|
dir = dirname(t, nil, 0);
|
||||||
|
if(dir.nr + 1 + npath > nelem(tmp)){
|
||||||
|
free(dir.r);
|
||||||
|
goto Return;
|
||||||
|
}
|
||||||
|
if(dir.nr == 0){
|
||||||
|
dir.nr = 1;
|
||||||
|
dir.r = runestrdup(Ldot);
|
||||||
|
}
|
||||||
|
runemove(tmp, dir.r, dir.nr);
|
||||||
|
tmp[dir.nr] = '/';
|
||||||
|
runemove(tmp+dir.nr+1, path, npath);
|
||||||
|
free(dir.r);
|
||||||
|
dir.r = tmp;
|
||||||
|
dir.nr += 1+npath;
|
||||||
|
dir = cleanrname(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
s = smprint("%.*S", nstr, str);
|
||||||
|
dirs = smprint("%.*S", dir.nr, dir.r);
|
||||||
|
c = complete(dirs, s);
|
||||||
|
free(s);
|
||||||
|
if(c == nil){
|
||||||
|
warning(nil, "error attempting completion: %r\n");
|
||||||
|
goto Return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!c->advance){
|
||||||
|
warning(nil, "%.*S%s%.*S*\n",
|
||||||
|
dir.nr, dir.r,
|
||||||
|
dir.nr>0 && dir.r[dir.nr-1]!='/' ? "/" : "",
|
||||||
|
nstr, str);
|
||||||
|
for(i=0; i<c->nfile; i++)
|
||||||
|
warning(nil, " %s\n", c->filename[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->advance)
|
||||||
|
rp = runesmprint("%s", c->string);
|
||||||
|
else
|
||||||
|
rp = nil;
|
||||||
|
Return:
|
||||||
|
freecompletion(c);
|
||||||
|
free(dirs);
|
||||||
|
free(str);
|
||||||
|
free(path);
|
||||||
|
return rp;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
texttype(Text *t, Rune r)
|
texttype(Text *t, Rune r)
|
||||||
{
|
{
|
||||||
uint q0, q1;
|
uint q0, q1;
|
||||||
int nnb, nb, n, i;
|
int nnb, nb, n, i;
|
||||||
|
int nr;
|
||||||
|
Rune *rp;
|
||||||
Text *u;
|
Text *u;
|
||||||
|
|
||||||
if(t->what!=Body && r=='\n')
|
if(t->what!=Body && r=='\n')
|
||||||
return;
|
return;
|
||||||
|
nr = 1;
|
||||||
|
rp = &r;
|
||||||
switch(r){
|
switch(r){
|
||||||
case Kdown:
|
|
||||||
case Kleft:
|
case Kleft:
|
||||||
|
if(t->q0 > 0)
|
||||||
|
textshow(t, t->q0-1, t->q0-1, TRUE);
|
||||||
|
return;
|
||||||
case Kright:
|
case Kright:
|
||||||
|
if(t->q1 < t->file->b.nc)
|
||||||
|
textshow(t, t->q1+1, t->q1+1, TRUE);
|
||||||
|
return;
|
||||||
|
case Kdown:
|
||||||
|
case Kpgdown:
|
||||||
n = t->fr.maxlines/2;
|
n = t->fr.maxlines/2;
|
||||||
q0 = t->org+frcharofpt(&t->fr, Pt(t->fr.r.min.x, t->fr.r.min.y+n*t->fr.font->height));
|
q0 = t->org+frcharofpt(&t->fr, Pt(t->fr.r.min.x, t->fr.r.min.y+n*t->fr.font->height));
|
||||||
textsetorigin(t, q0, FALSE);
|
textsetorigin(t, q0, FALSE);
|
||||||
return;
|
return;
|
||||||
case Kup:
|
case Kup:
|
||||||
|
case Kpgup:
|
||||||
n = t->fr.maxlines/2;
|
n = t->fr.maxlines/2;
|
||||||
q0 = textbacknl(t, t->org, n);
|
q0 = textbacknl(t, t->org, n);
|
||||||
textsetorigin(t, q0, FALSE);
|
textsetorigin(t, q0, FALSE);
|
||||||
|
@ -561,6 +675,13 @@ texttype(Text *t, Rune r)
|
||||||
}
|
}
|
||||||
textshow(t, t->q0, t->q0, 1);
|
textshow(t, t->q0, t->q0, 1);
|
||||||
switch(r){
|
switch(r){
|
||||||
|
case 0x06: /* ^F: complete */
|
||||||
|
case Kins:
|
||||||
|
rp = textcomplete(t);
|
||||||
|
if(rp == nil)
|
||||||
|
return;
|
||||||
|
nr = runestrlen(rp);
|
||||||
|
break; /* fall through to normal insertion case */
|
||||||
case 0x1B:
|
case 0x1B:
|
||||||
if(t->eq0 != ~0)
|
if(t->eq0 != ~0)
|
||||||
textsetselect(t, t->eq0, t->q0);
|
textsetselect(t, t->eq0, t->q0);
|
||||||
|
@ -623,16 +744,19 @@ texttype(Text *t, Rune r)
|
||||||
u->cq0 = t->q0;
|
u->cq0 = t->q0;
|
||||||
else if(t->q0 != u->cq0+u->ncache)
|
else if(t->q0 != u->cq0+u->ncache)
|
||||||
error("text.type cq1");
|
error("text.type cq1");
|
||||||
textinsert(u, t->q0, &r, 1, FALSE);
|
textinsert(u, t->q0, rp, nr, FALSE);
|
||||||
if(u != t)
|
if(u != t)
|
||||||
textsetselect(u, u->q0, u->q1);
|
textsetselect(u, u->q0, u->q1);
|
||||||
if(u->ncache == u->ncachealloc){
|
if(u->ncache+nr > u->ncachealloc){
|
||||||
u->ncachealloc += 10;
|
u->ncachealloc += 10 + nr;
|
||||||
u->cache = runerealloc(u->cache, u->ncachealloc);
|
u->cache = runerealloc(u->cache, u->ncachealloc);
|
||||||
}
|
}
|
||||||
u->cache[u->ncache++] = r;
|
runemove(u->cache+u->ncache, rp, nr);
|
||||||
|
u->ncache += nr;
|
||||||
}
|
}
|
||||||
textsetselect(t, t->q0+1, t->q0+1);
|
if(rp != &r)
|
||||||
|
free(rp);
|
||||||
|
textsetselect(t, t->q0+nr, t->q0+nr);
|
||||||
if(r=='\n' && t->w!=nil)
|
if(r=='\n' && t->w!=nil)
|
||||||
wincommit(t->w, t);
|
wincommit(t->w, t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ wininit(Window *w, Window *clone, Rectangle r)
|
||||||
filereset(w->tag.file);
|
filereset(w->tag.file);
|
||||||
textsetselect(&w->tag, nc, nc);
|
textsetselect(&w->tag, nc, nc);
|
||||||
}
|
}
|
||||||
|
//assert(w->body.w == w);
|
||||||
r1 = r;
|
r1 = r;
|
||||||
r1.min.y += font->height + 1;
|
r1.min.y += font->height + 1;
|
||||||
if(r1.max.y < r1.min.y)
|
if(r1.max.y < r1.min.y)
|
||||||
|
@ -57,6 +58,7 @@ wininit(Window *w, Window *clone, Rectangle r)
|
||||||
rf = rfget(FALSE, FALSE, FALSE, clone->body.reffont->f->name);
|
rf = rfget(FALSE, FALSE, FALSE, clone->body.reffont->f->name);
|
||||||
}else
|
}else
|
||||||
rf = rfget(FALSE, FALSE, FALSE, nil);
|
rf = rfget(FALSE, FALSE, FALSE, nil);
|
||||||
|
//assert(w->body.w == w);
|
||||||
f = fileaddtext(f, &w->body);
|
f = fileaddtext(f, &w->body);
|
||||||
w->body.what = Body;
|
w->body.what = Body;
|
||||||
textinit(&w->body, f, r1, rf, textcols);
|
textinit(&w->body, f, r1, rf, textcols);
|
||||||
|
@ -72,6 +74,7 @@ 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;
|
||||||
|
//assert(w->body.w == w);
|
||||||
if(clone){
|
if(clone){
|
||||||
w->dirty = clone->dirty;
|
w->dirty = clone->dirty;
|
||||||
textsetselect(&w->body, clone->body.q0, clone->body.q1);
|
textsetselect(&w->body, clone->body.q0, clone->body.q1);
|
||||||
|
@ -138,6 +141,7 @@ winlock(Window *w, int owner)
|
||||||
int i;
|
int i;
|
||||||
File *f;
|
File *f;
|
||||||
|
|
||||||
|
fprint(2, "winlock %p %d %lux\n", w, owner, getcallerpc(&w));
|
||||||
f = w->body.file;
|
f = w->body.file;
|
||||||
for(i=0; i<f->ntext; i++)
|
for(i=0; i<f->ntext; i++)
|
||||||
winlock1(f->text[i]->w, owner);
|
winlock1(f->text[i]->w, owner);
|
||||||
|
@ -149,6 +153,7 @@ winunlock(Window *w)
|
||||||
int i;
|
int i;
|
||||||
File *f;
|
File *f;
|
||||||
|
|
||||||
|
fprint(2, "winunlock %p %lux\n", w, getcallerpc(&w));
|
||||||
f = w->body.file;
|
f = w->body.file;
|
||||||
for(i=0; i<f->ntext; i++){
|
for(i=0; i<f->ntext; i++){
|
||||||
w = f->text[i]->w;
|
w = f->text[i]->w;
|
||||||
|
|
Loading…
Reference in a new issue