spred: command window improvements
This commit is contained in:
parent
a67d18ccf1
commit
74a276d076
1 changed files with 153 additions and 20 deletions
|
@ -69,7 +69,7 @@ cmdscroll(Win *w, int l)
|
||||||
|
|
||||||
}
|
}
|
||||||
frdelete(&w->fr, 0, w->fr.nchars);
|
frdelete(&w->fr, 0, w->fr.nchars);
|
||||||
frinsert(&w->fr, w->runes + w->toprune, w->runes + w->nrunes, 0);
|
frinsert(&w->fr, w->runes + w->toprune, w->runes + w->nrunes, 0);
|
||||||
scrollbar(w);
|
scrollbar(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +120,8 @@ cmdinsert(Win *w, Rune *r, int nr, int rp)
|
||||||
cmdscroll(w, 1);
|
cmdscroll(w, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(w->opoint > rp)
|
||||||
|
w->opoint += nr;
|
||||||
return nr;
|
return nr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,15 +139,58 @@ cmddel(Win *w, int a, int b)
|
||||||
if(w->toprune >= a)
|
if(w->toprune >= a)
|
||||||
w->toprune = a;
|
w->toprune = a;
|
||||||
}
|
}
|
||||||
|
if(a <= w->opoint && w->opoint < b)
|
||||||
|
w->opoint = a;
|
||||||
|
else if(w->opoint >= b)
|
||||||
|
w->opoint -= b - a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setsel(Win *w, int p0, int p1)
|
||||||
|
{
|
||||||
|
frdrawsel(&w->fr, frptofchar(&w->fr, w->fr.p0), w->fr.p0, w->fr.p1, 0);
|
||||||
|
w->fr.p0 = p0;
|
||||||
|
w->fr.p1 = p1;
|
||||||
|
frdrawsel(&w->fr, frptofchar(&w->fr, p0), p0, p1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmdline(Win *w)
|
||||||
|
{
|
||||||
|
static char buf[4096];
|
||||||
|
Rune *q;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
q = w->runes + w->opoint;
|
||||||
|
p = buf;
|
||||||
|
while(q < w->runes + w->nrunes && p < buf + nelem(buf) + 1)
|
||||||
|
p += runetochar(p, q++);
|
||||||
|
*p = 0;
|
||||||
|
w->opoint = w->nrunes;
|
||||||
|
docmd(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cmdkey(Win *w, Rune r)
|
cmdkey(Win *w, Rune r)
|
||||||
{
|
{
|
||||||
static char buf[4096];
|
switch(r){
|
||||||
char *p;
|
case Kview:
|
||||||
Rune *q;
|
cmdscroll(w, 3);
|
||||||
|
return;
|
||||||
|
case Kup:
|
||||||
|
cmdscroll(w, -3);
|
||||||
|
return;
|
||||||
|
case Kleft:
|
||||||
|
if(w->fr.p0 == 0)
|
||||||
|
return;
|
||||||
|
setsel(w, w->fr.p0 - 1, w->fr.p0 - 1);
|
||||||
|
return;
|
||||||
|
case Kright:
|
||||||
|
if(w->toprune + w->fr.p1 == w->nrunes)
|
||||||
|
return;
|
||||||
|
setsel(w, w->fr.p1 + 1, w->fr.p1 + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(w->fr.p0 < w->fr.p1)
|
if(w->fr.p0 < w->fr.p1)
|
||||||
cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
|
cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
|
||||||
switch(r){
|
switch(r){
|
||||||
|
@ -158,27 +203,114 @@ cmdkey(Win *w, Rune r)
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
cmdinsert(w, &r, 1, w->fr.p0 + w->toprune);
|
cmdinsert(w, &r, 1, w->fr.p0 + w->toprune);
|
||||||
if(w->toprune + w->fr.p0 == w->nrunes){
|
if(w->toprune + w->fr.p0 == w->nrunes)
|
||||||
q = w->runes + w->opoint;
|
cmdline(w);
|
||||||
p = buf;
|
|
||||||
while(q < w->runes + w->nrunes && p < buf + nelem(buf) + 1)
|
|
||||||
p += runetochar(p, q++);
|
|
||||||
*p = 0;
|
|
||||||
w->opoint = w->nrunes;
|
|
||||||
docmd(buf);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Kview:
|
|
||||||
cmdscroll(w, 3);
|
|
||||||
break;
|
|
||||||
case Kup:
|
|
||||||
cmdscroll(w, -3);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cmdinsert(w, &r, 1, w->fr.p0 + w->toprune);
|
cmdinsert(w, &r, 1, w->fr.p0 + w->toprune);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
tosnarf(Win *w, int p0, int p1)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
static char buf[512];
|
||||||
|
char *c, *ce;
|
||||||
|
Rune *rp, *re;
|
||||||
|
|
||||||
|
if(p0 >= p1)
|
||||||
|
return 0;
|
||||||
|
fd = open("/dev/snarf", OWRITE|OTRUNC);
|
||||||
|
if(fd < 0){
|
||||||
|
cmdprint("tosnarf: %r");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
c = buf;
|
||||||
|
ce = buf + sizeof(buf);
|
||||||
|
rp = w->runes + p0;
|
||||||
|
re = w->runes + p1;
|
||||||
|
for(; rp < re; rp++){
|
||||||
|
if(c + UTFmax > ce){
|
||||||
|
write(fd, buf, c - buf);
|
||||||
|
c = buf;
|
||||||
|
}
|
||||||
|
c += runetochar(c, rp);
|
||||||
|
}
|
||||||
|
if(c > buf)
|
||||||
|
write(fd, buf, c - buf);
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
fromsnarf(Win *w, int p0)
|
||||||
|
{
|
||||||
|
int fd, rc;
|
||||||
|
char *buf, *p;
|
||||||
|
Rune *rbuf, *r;
|
||||||
|
int nc, end;
|
||||||
|
|
||||||
|
fd = open("/dev/snarf", OREAD);
|
||||||
|
if(fd < 0){
|
||||||
|
cmdprint("fromsnarf: %r");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
buf = nil;
|
||||||
|
nc = 0;
|
||||||
|
for(;;){
|
||||||
|
buf = realloc(buf, nc + 4096);
|
||||||
|
rc = readn(fd, buf + nc, nc + 4096);
|
||||||
|
if(rc <= 0)
|
||||||
|
break;
|
||||||
|
nc += rc;
|
||||||
|
if(rc < 4096)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
rbuf = emalloc(sizeof(Rune) * nc);
|
||||||
|
r = rbuf;
|
||||||
|
for(p = buf; p < buf + nc; r++)
|
||||||
|
p += chartorune(r, p);
|
||||||
|
end = p0 == w->nrunes;
|
||||||
|
cmdinsert(w, rbuf, r - rbuf, p0);
|
||||||
|
if(end && r > rbuf && r[-1] == '\n')
|
||||||
|
cmdline(w);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmdmenu(Win *w, Mousectl *mc)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
CUT,
|
||||||
|
PASTE,
|
||||||
|
SNARF,
|
||||||
|
};
|
||||||
|
static char *ms[] = {
|
||||||
|
[CUT] "cut",
|
||||||
|
[PASTE] "paste",
|
||||||
|
[SNARF] "snarf",
|
||||||
|
nil,
|
||||||
|
};
|
||||||
|
static Menu m = {ms};
|
||||||
|
|
||||||
|
switch(menuhit(2, mc, &m, nil)){
|
||||||
|
case CUT:
|
||||||
|
if(tosnarf(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1) >= 0)
|
||||||
|
cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
|
||||||
|
break;
|
||||||
|
case SNARF:
|
||||||
|
tosnarf(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
|
||||||
|
break;
|
||||||
|
case PASTE:
|
||||||
|
if(w->fr.p0 < w->fr.p1)
|
||||||
|
cmddel(w, w->toprune + w->fr.p0, w->toprune + w->fr.p1);
|
||||||
|
fromsnarf(w, w->toprune + w->fr.p0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cmdprint(char *fmt, ...)
|
cmdprint(char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -196,6 +328,7 @@ Wintab cmdtab = {
|
||||||
.init = cmdinit,
|
.init = cmdinit,
|
||||||
.draw = cmddraw,
|
.draw = cmddraw,
|
||||||
.click = cmdclick,
|
.click = cmdclick,
|
||||||
|
.menu = cmdmenu,
|
||||||
.rmb = cmdrmb,
|
.rmb = cmdrmb,
|
||||||
.key = cmdkey,
|
.key = cmdkey,
|
||||||
.hexcols = {
|
.hexcols = {
|
||||||
|
|
Loading…
Reference in a new issue