Thanks for sharing this! I'd already backported a few of the features, but I hadn't yet got around to looking at the chording code etc. It's great to have selection working! I'm not sure if I did something wrong (I've checked the changes a few times) but scrolling only works "sometimes", mostly it seems to get stuck when scrolling back up? Can anyone confirm? In my experience sam's scrolling seems to be pretty broken (at least in the plan9port version) so it might not have anything to do with these changes. All the best, P.S. where does Kcmd come from? I've grepped the plan9port tree but I don't see a definition? On Fri, 27 May 2016 at 00:05 wrote: > The 9front sam in > > https://bitbucket.org/kremlin_/front9port > https://bitbucket.org/iru/sam9f-unix > > doesn't exchange the snarf buffer with X, and the pipe in /srv doesn't > work. > > This diff will makes the minimal changes to have those features of 9front > sam in the last p9p. The code fell off from the front. > > trebol. > > > diff -rpuN src/cmd/sam/cmd.c sam/cmd.c > --- src/cmd/sam/cmd.c 2016-04-18 19:07:22.000000000 +0100 > +++ sam/cmd.c 2016-05-25 23:56:34.040909362 +0100 > @@ -35,6 +35,8 @@ struct cmdtab cmdtab[]={ > '>', 0, 0, 0, 0, aDot, 0, linex, > plan9_cmd, > '<', 0, 0, 0, 0, aDot, 0, linex, > plan9_cmd, > '|', 0, 0, 0, 0, aDot, 0, linex, > plan9_cmd, > + '^', 0, 0, 0, 0, aDot, 0, linex, > plan9_cmd, > + '_', 0, 0, 0, 0, aDot, 0, linex, > plan9_cmd, > '=', 0, 0, 0, 0, aDot, 0, linex, > eq_cmd, > 'c'|0x100,0, 0, 0, 0, aNo, 0, wordx, > cd_cmd, > 0, 0, 0, 0, 0, 0, 0, 0 > @@ -76,7 +78,13 @@ inputc(void) > > Again: > nbuf = 0; > - if(downloaded){ > + if(cmdbufpos > cmdbuf.nc && cmdbuf.nc > 0){ > + cmdbufpos = 0; > + bufreset(&cmdbuf); > + } > + if(cmdbufpos < cmdbuf.nc && cmdbuf.nc > 0) > + bufread(&cmdbuf, cmdbufpos++, &r, 1); > + else if(downloaded){ > while(termoutp == terminp){ > cmdupdate(); > if(patset) > diff -rpuN src/cmd/sam/sam.h sam/sam.h > --- src/cmd/sam/sam.h 2016-04-18 19:07:22.000000000 +0100 > +++ sam/sam.h 2016-05-25 23:45:05.652931784 +0100 > @@ -369,6 +369,8 @@ extern int quitok; > extern Address addr; > extern Buffer snarfbuf; > extern Buffer plan9buf; > +extern Buffer cmdbuf; > +extern int cmdbufpos; > extern List file; > extern List tempfile; > extern File *cmd; > diff -rpuN src/cmd/sam/shell.c sam/shell.c > --- src/cmd/sam/shell.c 2016-04-18 19:07:22.000000000 +0100 > +++ sam/shell.c 2016-05-25 23:46:25.262692361 +0100 > @@ -6,6 +6,8 @@ extern jmp_buf mainloop; > char errfile[64]; > String plan9cmd; /* null terminated */ > Buffer plan9buf; > +Buffer cmdbuf; > +int cmdbufpos; > void checkerrs(void); > > void > @@ -40,7 +42,7 @@ plan9(File *f, int type, String *s, int > } > if(type!='!' && pipe(pipe1)==-1) > error(Epipe); > - if(type=='|') > + if(type=='|' || type=='_') > snarf(f, addr.r.p1, addr.r.p2, &plan9buf, 1); > if((pid=fork()) == 0){ > setname(f); > @@ -61,14 +63,14 @@ plan9(File *f, int type, String *s, int > } > } > if(type != '!') { > - if(type=='<' || type=='|') > - dup(pipe1[1], 1); > - else if(type == '>') > + if(type == '>') > dup(pipe1[0], 0); > + else > + dup(pipe1[1], 1); > close(pipe1[0]); > close(pipe1[1]); > } > - if(type == '|'){ > + if(type == '|' || type == '_'){ > if(pipe(pipe2) == -1) > exits("pipe"); > if((pid = fork())==0){ > @@ -100,7 +102,7 @@ plan9(File *f, int type, String *s, int > close(pipe2[0]); > close(pipe2[1]); > } > - if(type=='<'){ > + if(type=='<' || type=='^'){ > close(0); /* so it won't read from terminal > */ > open("/dev/null", 0); > } > @@ -128,9 +130,14 @@ plan9(File *f, int type, String *s, int > writeio(f); > bpipeok = 0; > closeio((Posn)-1); > + }else if(type == '^' || type == '_'){ > + int nulls; > + close(pipe1[1]); > + bufload(&cmdbuf, cmdbufpos, pipe1[0], &nulls); > + close(pipe1[0]); > } > retcode = waitfor(pid); > - if(type=='|' || type=='<') > + if(type=='|' || type=='<' || type=='_' || type=='^') > if(retcode!=0) > warn(Wbadstatus); > if(downloaded) > diff -rpuN src/cmd/samterm/main.c samterm/main.c > --- src/cmd/samterm/main.c 2016-04-18 19:07:22.000000000 +0100 > +++ samterm/main.c 2016-05-26 16:12:12.452556184 +0100 > @@ -23,11 +23,8 @@ long modified = 0; /* strange lookahead > char hostlock = 1; > char hasunlocked = 0; > int maxtab = 8; > -int chord; > int autoindent; > > -#define chording 0 /* code here for reference but it causes deadlocks > */ > - > void > notifyf(void *a, char *msg) > { > @@ -39,7 +36,7 @@ notifyf(void *a, char *msg) > void > threadmain(int argc, char *argv[]) > { > - int i, got, scr, w; > + int i, got, scr, chord, w; > Text *t; > Rectangle r; > Flayer *nwhich; > @@ -85,6 +82,7 @@ threadmain(int argc, char *argv[]) > > got = 0; > if(protodebug) print("loop\n"); > + chord = 0; > for(;;got = waitforio()){ > if(hasunlocked && RESIZED()) > resize(); > @@ -108,19 +106,32 @@ threadmain(int argc, char *argv[]) > continue; > } > nwhich = flwhich(mousep->xy); > - scr = which && ptinrect(mousep->xy, which->scroll); > + scr = which && (ptinrect(mousep->xy, > which->scroll) || > + mousep->buttons&(8|16)); > if(mousep->buttons) > flushtyping(1); > - if(chording && chord==1 && !mousep->buttons) > + if((mousep->buttons&1)==0) > chord = 0; > - if(chording && chord) > + if(chord && which && which==nwhich){ > chord |= mousep->buttons; > - else if(mousep->buttons&1){ > + t = (Text *)which->user1; > + if(!t->lock){ > + w = which-t->l; > + if(chord&2){ > + cut(t, w, 1, 1); > + chord &= ~2; > + } > + if(chord&4){ > + paste(t, w); > + chord &= ~4; > + } > + } > + }else if(mousep->buttons&(1|8)){ > if(nwhich){ > if(nwhich!=which) > current(nwhich); > else if(scr) > - scroll(which, 1); > + scroll(which, > (mousep->buttons&8) ? 4 : 1); > else{ > t=(Text *)which->user1; > if(flselect(which)){ > @@ -137,27 +148,14 @@ threadmain(int argc, char *argv[]) > scroll(which, 2); > else > menu2hit(); > - }else if((mousep->buttons&4)){ > + }else if(mousep->buttons&(4|16)){ > if(scr) > - scroll(which, 3); > + scroll(which, (mousep->buttons&16) > ? 5 : 3); > else > menu3hit(); > } > mouseunblock(); > } > - if(chording && chord){ > - t = (Text*)which->user1; > - if(!t->lock && !hostlock){ > - w = which-t->l; > - if(chord&2){ > - cut(t, w, 1, 1); > - chord &= ~2; > - }else if(chord&4){ > - paste(t, w); > - chord &= ~4; > - } > - } > - } > } > } > > @@ -497,6 +495,7 @@ flushtyping(int clearesc) > #define CUT (Kcmd+'x') > #define COPY (Kcmd+'c') > #define PASTE (Kcmd+'v') > +#define Kstx 0x02 > > int > nontypingkey(int c) > @@ -512,6 +511,7 @@ nontypingkey(int c) > case PAGEUP: > case RIGHTARROW: > case SCROLLKEY: > + case Kstx: > return 1; > } > if(c >= Kcmd) > @@ -669,6 +669,15 @@ type(Flayer *l, int res) /* what a blood > } > } > } > + }else if(c == Kstx){ > + t = &cmd; > + for(l=t->l; l->textfn==0; l++) > + ; > + current(l); > + flushtyping(0); > + a = t->rasp.nrunes; > + flsetselect(l, a, a); > + center(l, a); > }else{ > if(c==ESC && typeesc>=0){ > l->p0 = typeesc; > diff -rpuN src/cmd/samterm/scroll.c samterm/scroll.c > --- src/cmd/samterm/scroll.c 2016-04-18 19:07:22.000000000 +0100 > +++ samterm/scroll.c 2016-05-26 02:07:31.922977720 +0100 > @@ -115,7 +115,7 @@ scroll(Flayer *l, int but) > draw(scrback, Rect(0,0,Dx(l->scroll), Dy(l->scroll)), l->f.b, nil, > l->scroll.min); > do{ > oin = in; > - in = abs(x-mousep->xy.x)<=FLSCROLLWID(l)/2; > + in = (but > 3) || (but == 2) || > abs(x-mousep->xy.x)<=FLSCROLLWID(l)/2; > if(oin && !in) > scrunmark(l, r); > if(in){ > @@ -126,9 +126,7 @@ scroll(Flayer *l, int but) > my = s.min.y; > if(my >= s.max.y) > my = s.max.y; > - if(!eqpt(mousep->xy, Pt(x, my))) > - moveto(mousectl, Pt(x, my)); > - if(but == 1){ > + if(but == 1 || but == 4){ > p0 = l->origin-frcharofpt(&l->f, > Pt(s.max.x, my)); > rt = scrpos(l->scroll, p0, p0+l->f.nchars, > tot); > y = rt.min.y; > @@ -136,7 +134,7 @@ scroll(Flayer *l, int but) > y = my; > if(y > s.max.y-2) > y = s.max.y-2; > - }else if(but == 3){ > + }else if(but == 3 || but == 5){ > p0 = l->origin+frcharofpt(&l->f, > Pt(s.max.x, my)); > rt = scrpos(l->scroll, p0, p0+l->f.nchars, > tot); > y = rt.min.y; > @@ -147,19 +145,21 @@ scroll(Flayer *l, int but) > scrmark(l, r); > } > } > - }while(button(but)); > + }while(but <= 3 && button(but)); > if(in){ > h = s.max.y-s.min.y; > scrunmark(l, r); > p0 = 0; > - if(but == 1) > + if(but == 1 || but == 4){ > + but = 1; > p0 = (long)(my-s.min.y)/l->f.font->height+1; > - else if(but == 2){ > + }else if(but == 2){ > if(tot > 1024L*1024L) > p0 = ((tot>>10)*(y-s.min.y)/h)<<10; > else > p0 = tot*(y-s.min.y)/h; > - }else if(but == 3){ > + }else if(but == 3 || but == 5){ > + but = 3; > p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my)); > if(p0 > tot) > p0 = tot; > > >