mothra: snarf and paste
This commit is contained in:
parent
f68d096fb7
commit
948d0a1180
12 changed files with 143 additions and 133 deletions
|
@ -97,11 +97,12 @@ Clicking the
|
|||
.B moth mode
|
||||
menu option again exits moth mode.
|
||||
.TP
|
||||
.B snarf url
|
||||
Copy the current URL to the snarf buffer.
|
||||
.B snarf
|
||||
Copy the current entry text or selected page text to snarf buffer.
|
||||
If nothing is selected, the current URL is copied.
|
||||
.TP
|
||||
.B paste
|
||||
Paste the current snarf buffer at the current cursor position.
|
||||
Paste the snarf buffer to the current text entry.
|
||||
.TP
|
||||
.B save hit
|
||||
Save the current URL to the hit list.
|
||||
|
|
|
@ -139,6 +139,7 @@ void pl_interior(int state, Point *ul, Point *size){
|
|||
*size=subpt(*size, Pt(4*FWID+2*SPACE, 4*FWID+2*SPACE));
|
||||
}
|
||||
}
|
||||
|
||||
void pl_drawicon(Image *b, Rectangle r, int stick, int flags, Icon *s){
|
||||
Rectangle save;
|
||||
Point ul, offs;
|
||||
|
|
|
@ -48,46 +48,25 @@ void pl_drawedit(Panel *p){
|
|||
if(sb && sb->setscrollbar)
|
||||
sb->setscrollbar(sb, ep->t->top, ep->t->bot, ep->t->etext-ep->t->text);
|
||||
}
|
||||
void pl_snarfedit(Panel *p, int cut){
|
||||
int fd, n, r, s0, s1;
|
||||
char *s, *x;
|
||||
|
||||
char *pl_snarfedit(Panel *p){
|
||||
int s0, s1;
|
||||
Rune *t;
|
||||
|
||||
if((fd=open("/dev/snarf", cut ? OWRITE|OTRUNC : OREAD))<0)
|
||||
return;
|
||||
if(cut){
|
||||
t=pleget(p);
|
||||
plegetsel(p, &s0, &s1);
|
||||
if(t==0 || s0>=s1){
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
s = smprint("%.*S", s1-s0, t+s0);
|
||||
if((n = strlen(s))>0)
|
||||
write(fd, s, n);
|
||||
free(s);
|
||||
plepaste(p, 0, 0);
|
||||
}else{
|
||||
n=0;
|
||||
s=nil;
|
||||
for(;;){
|
||||
if((x=realloc(s, n+1024)) == nil){
|
||||
free(s);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
s=x;
|
||||
if((r = read(fd, s+n, 1024)) <= 0)
|
||||
break;
|
||||
n += r;
|
||||
}
|
||||
t=runesmprint("%.*s", n, s);
|
||||
t=pleget(p);
|
||||
plegetsel(p, &s0, &s1);
|
||||
if(t==0 || s0>=s1)
|
||||
return nil;
|
||||
return smprint("%.*S", s1-s0, t+s0);
|
||||
}
|
||||
void pl_pasteedit(Panel *p, char *s){
|
||||
Rune *t;
|
||||
if(t=runesmprint("%s", s)){
|
||||
plepaste(p, t, runestrlen(t));
|
||||
free(s);
|
||||
free(t);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Should do double-clicks:
|
||||
* If ep->sel0==ep->sel1 on entry and the
|
||||
|
@ -106,18 +85,20 @@ void pl_snarfedit(Panel *p, int cut){
|
|||
*/
|
||||
int pl_hitedit(Panel *p, Mouse *m){
|
||||
Edit *ep;
|
||||
if((m->buttons&7)==1){
|
||||
if(m->buttons&1){
|
||||
plgrabkb(p);
|
||||
ep=p->data;
|
||||
ep->t->b=p->b;
|
||||
twhilite(ep->t, ep->sel0, ep->sel1, 0);
|
||||
twselect(ep->t, m);
|
||||
ep->sel0=ep->t->sel0;
|
||||
ep->sel1=ep->t->sel1;
|
||||
plgrabkb(p);
|
||||
if((m->buttons&7)==3)
|
||||
pl_snarfedit(p, 1);
|
||||
if((m->buttons&7)==3){
|
||||
plsnarf(p);
|
||||
plepaste(p, 0, 0); /* cut */
|
||||
}
|
||||
else if((m->buttons&7)==5)
|
||||
pl_snarfedit(p, 0);
|
||||
plpaste(p);
|
||||
else if(ep->hit)
|
||||
(*ep->hit)(p);
|
||||
}
|
||||
|
@ -171,7 +152,13 @@ void pl_typeedit(Panel *p, Rune c){
|
|||
twhilite(t, ep->sel0, ep->sel1, 0);
|
||||
switch(c){
|
||||
case Kesc:
|
||||
pl_snarfedit(p, 1);
|
||||
plsnarf(p);
|
||||
plepaste(p, 0, 0); /* cut */
|
||||
break;
|
||||
case Kdel: /* clear */
|
||||
ep->sel0=0;
|
||||
ep->sel1=plelen(p);
|
||||
plepaste(p, 0, 0); /* cut */
|
||||
break;
|
||||
case Kbs: /* ^H: erase character */
|
||||
if(ep->sel0!=0) --ep->sel0;
|
||||
|
@ -187,6 +174,8 @@ void pl_typeedit(Panel *p, Rune c){
|
|||
twreplace(t, ep->sel0, ep->sel1, 0, 0);
|
||||
break;
|
||||
default:
|
||||
if((c & 0xFF00) == KF || (c & 0xFF00) == Spec)
|
||||
break;
|
||||
twreplace(t, ep->sel0, ep->sel1, &c, 1);
|
||||
++ep->sel0;
|
||||
break;
|
||||
|
@ -233,6 +222,8 @@ void plinitedit(Panel *v, int flags, Point minsize, Rune *text, int ntext, void
|
|||
v->getsize=pl_getsizeedit;
|
||||
v->childspace=pl_childspaceedit;
|
||||
v->free=pl_freeedit;
|
||||
v->snarf=pl_snarfedit;
|
||||
v->paste=pl_pasteedit;
|
||||
v->kind="edit";
|
||||
ep->hit=hit;
|
||||
ep->minsize=minsize;
|
||||
|
|
|
@ -15,35 +15,31 @@ struct Entry{
|
|||
Point minsize;
|
||||
};
|
||||
#define SLACK 7 /* enough for one extra rune and ◀ and a nul */
|
||||
void pl_snarfentry(Panel *p, int cut){
|
||||
char *pl_snarfentry(Panel *p){
|
||||
Entry *ep;
|
||||
int fd, n;
|
||||
char *s;
|
||||
int n;
|
||||
|
||||
ep=p->data;
|
||||
if((fd=open("/dev/snarf", cut ? OWRITE|OTRUNC : OREAD))<0)
|
||||
n=ep->entp-ep->entry;
|
||||
if(n<=0) return nil;
|
||||
return smprint("%.*s", n, ep->entry);
|
||||
}
|
||||
void pl_pasteentry(Panel *p, char *s){
|
||||
Entry *ep;
|
||||
char *e;
|
||||
int n, m;
|
||||
|
||||
ep=p->data;
|
||||
n=ep->entp-ep->entry;
|
||||
m=strlen(s);
|
||||
if((e=realloc(ep->entry,n+m+SLACK))==0)
|
||||
return;
|
||||
if(cut){
|
||||
if((n=ep->entp-ep->entry)>0)
|
||||
write(fd, ep->entry, n);
|
||||
ep->entp=ep->entry;
|
||||
}else{
|
||||
n=1024;
|
||||
s=malloc(n+SLACK);
|
||||
if(s==0){
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
if((n=readn(fd, s, n))<0)
|
||||
n=0;
|
||||
free(ep->entry);
|
||||
s=realloc(s, n+SLACK);
|
||||
ep->entry=s;
|
||||
ep->eent=s+n;
|
||||
ep->entp=s+n;
|
||||
}
|
||||
close(fd);
|
||||
*ep->entp='\0';
|
||||
ep->entry=e;
|
||||
e+=n;
|
||||
strncpy(e, s, m);
|
||||
e+=m;
|
||||
*e='\0';
|
||||
ep->entp=ep->eent=e;
|
||||
pldraw(p, p->b);
|
||||
}
|
||||
void pl_drawentry(Panel *p){
|
||||
|
@ -68,20 +64,29 @@ void pl_drawentry(Panel *p){
|
|||
free(s);
|
||||
}
|
||||
int pl_hitentry(Panel *p, Mouse *m){
|
||||
if((m->buttons&OUT)==0 && (m->buttons&7)){
|
||||
if((m->buttons&7)==1){
|
||||
plgrabkb(p);
|
||||
|
||||
p->state=DOWN;
|
||||
pldraw(p, p->b);
|
||||
while(m->buttons&7){
|
||||
while(m->buttons&1){
|
||||
int old;
|
||||
old=m->buttons;
|
||||
*m=emouse();
|
||||
if((old&7)==1){
|
||||
if((m->buttons&7)==3)
|
||||
pl_snarfentry(p, 1);
|
||||
if((m->buttons&7)==3){
|
||||
Entry *ep;
|
||||
|
||||
plsnarf(p);
|
||||
|
||||
/* cut */
|
||||
ep=p->data;
|
||||
ep->entp=ep->entry;
|
||||
*ep->entp='\0';
|
||||
pldraw(p, p->b);
|
||||
}
|
||||
if((m->buttons&7)==5)
|
||||
pl_snarfentry(p, 0);
|
||||
plpaste(p);
|
||||
}
|
||||
}
|
||||
p->state=UP;
|
||||
|
@ -100,8 +105,9 @@ void pl_typeentry(Panel *p, Rune c){
|
|||
if(ep->hit) ep->hit(p, ep->entry);
|
||||
return;
|
||||
case Kesc:
|
||||
pl_snarfentry(p, 1);
|
||||
return;
|
||||
plsnarf(p);
|
||||
/* no break */
|
||||
case Kdel: /* clear */
|
||||
case Knack: /* ^U: erase line */
|
||||
ep->entp=ep->entry;
|
||||
*ep->entp='\0';
|
||||
|
@ -118,7 +124,7 @@ void pl_typeentry(Panel *p, Rune c){
|
|||
*ep->entp='\0';
|
||||
break;
|
||||
default:
|
||||
if(c < 0x20 || c == Kdel || (c & 0xFF00) == KF || (c & 0xFF00) == Spec)
|
||||
if(c < 0x20 || (c & 0xFF00) == KF || (c & 0xFF00) == Spec)
|
||||
break;
|
||||
ep->entp+=runetochar(ep->entp, &c);
|
||||
if(ep->entp>ep->eent){
|
||||
|
@ -162,6 +168,8 @@ void plinitentry(Panel *v, int flags, int wid, char *str, void (*hit)(Panel *, c
|
|||
v->childspace=pl_childspaceentry;
|
||||
ep->minsize=Pt(wid, font->height);
|
||||
v->free=pl_freeentry;
|
||||
v->snarf=pl_snarfentry;
|
||||
v->paste=pl_pasteentry;
|
||||
elen=100;
|
||||
if(str) elen+=strlen(str);
|
||||
if(ep->entry==nil)
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
#include <event.h>
|
||||
#include <panel.h>
|
||||
#include "pldefs.h"
|
||||
Panel *pl_kbfocus;
|
||||
|
||||
void plgrabkb(Panel *g){
|
||||
pl_kbfocus=g;
|
||||
plkbfocus=g;
|
||||
}
|
||||
void plkeyboard(Rune c){
|
||||
if(pl_kbfocus){
|
||||
pl_kbfocus->type(pl_kbfocus, c);
|
||||
if(plkbfocus){
|
||||
plkbfocus->type(plkbfocus, c);
|
||||
flushimage(display, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the most leafward, highest priority panel containing p
|
||||
*/
|
||||
|
|
|
@ -89,6 +89,8 @@ Panel *pl_newpanel(Panel *parent, int ndata){
|
|||
v->scroll=pl_scrollerror;
|
||||
v->setscrollbar=pl_setscrollbarerror;
|
||||
v->free=0;
|
||||
v->snarf=0;
|
||||
v->paste=0;
|
||||
if(ndata)
|
||||
v->data=pl_emalloc(ndata);
|
||||
else
|
||||
|
@ -99,6 +101,8 @@ void plfree(Panel *p){
|
|||
Panel *cp, *ncp;
|
||||
if(p==0)
|
||||
return;
|
||||
if(p==plkbfocus)
|
||||
plkbfocus=0;
|
||||
for(cp=p->child;cp;cp=ncp){
|
||||
ncp=cp->next;
|
||||
plfree(cp);
|
||||
|
|
|
@ -26,7 +26,8 @@ OFILES=\
|
|||
slider.$O\
|
||||
textview.$O\
|
||||
textwin.$O\
|
||||
utf.$O
|
||||
utf.$O\
|
||||
snarf.$O
|
||||
|
||||
HFILES=panel.h pldefs.h rtext.h
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ struct Panel{
|
|||
void (*scroll)(Panel *, int, int, int, int); /* scroll bar to scrollee */
|
||||
void (*setscrollbar)(Panel *, int, int, int); /* scrollee to scroll bar */
|
||||
void (*free)(Panel *); /* free fields of data when done */
|
||||
char* (*snarf)(Panel *); /* snarf text from panel */
|
||||
void (*paste)(Panel *, char *); /* paste text into panel */
|
||||
};
|
||||
/*
|
||||
* Panel flags
|
||||
|
@ -101,6 +103,8 @@ struct Panel{
|
|||
#define PL_HOT 1
|
||||
#define PL_SEL 2
|
||||
|
||||
Panel *plkbfocus; /* the panel in keyboard focus */
|
||||
|
||||
int plinit(int); /* initialization */
|
||||
void plpack(Panel *, Rectangle); /* figure out where to put the Panel & children */
|
||||
void plmove(Panel *, Point); /* move an already-packed panel to a new location */
|
||||
|
@ -122,6 +126,7 @@ void plescroll(Panel *, int); /* scroll an edit window */
|
|||
Scroll plgetscroll(Panel *); /* get scrolling information from panel */
|
||||
void plsetscroll(Panel *, Scroll); /* set scrolling information */
|
||||
void plplacelabel(Panel *, int); /* label placement */
|
||||
|
||||
/*
|
||||
* Panel creation & reinitialization functions
|
||||
*/
|
||||
|
@ -174,7 +179,6 @@ char *plrtsnarftext(Rtext *);
|
|||
|
||||
int plgetpostextview(Panel *);
|
||||
void plsetpostextview(Panel *, int);
|
||||
char *plsnarftext(Panel *);
|
||||
|
||||
/*
|
||||
* Idols
|
||||
|
@ -183,3 +187,11 @@ Idol *plmkidol(Idol**, Image*, Image*, char*, void*);
|
|||
void plfreeidol(Idol*);
|
||||
Point plidolsize(Idol*, Font*, int);
|
||||
void *plidollistgetsel(Panel*);
|
||||
|
||||
/*
|
||||
* Snarf
|
||||
*/
|
||||
void plputsnarf(char *);
|
||||
char *plgetsnarf(void);
|
||||
void plsnarf(Panel *); /* snarf a panel */
|
||||
void plpaste(Panel *); /* paste a panel */
|
||||
|
|
|
@ -75,6 +75,8 @@ int pl_hitpopup(Panel *g, Mouse *m){
|
|||
}
|
||||
}
|
||||
plmouse(p, m);
|
||||
if((m->buttons&7)==0)
|
||||
g->state=UP;
|
||||
return (m->buttons&7)!=0;
|
||||
}
|
||||
void pl_typepopup(Panel *g, Rune c){
|
||||
|
|
|
@ -291,26 +291,30 @@ void plrtseltext(Rtext *t, Rtext *s, Rtext *e){
|
|||
}
|
||||
|
||||
char *plrtsnarftext(Rtext *w){
|
||||
char *b, *p, *e;
|
||||
char *b, *p, *e, *t;
|
||||
int n;
|
||||
|
||||
p = e = 0;
|
||||
b=p=e=0;
|
||||
for(; w; w = w->next){
|
||||
if((w->flags&PL_SEL)==0 || w->b!=0 || w->p!=0 || w->text==0)
|
||||
if((w->flags&PL_SEL)==0 || w->text==0)
|
||||
continue;
|
||||
n = strlen(w->text)+4;
|
||||
if((b = realloc(p, (e+n) - p)) == nil)
|
||||
break;
|
||||
e = (e - p) + b;
|
||||
p = b;
|
||||
n = strlen(w->text)+64;
|
||||
if(p+n >= e){
|
||||
n = (p+n+64)-b;
|
||||
if((t = realloc(b, n))==0)
|
||||
break;
|
||||
p = t+(p-b);
|
||||
e = t+n;
|
||||
b = t;
|
||||
}
|
||||
if(w->space == 0)
|
||||
e += sprint(e, "%s", w->text);
|
||||
p += sprint(p, "%s", w->text);
|
||||
else if(w->space > 0)
|
||||
e += sprint(e, " %s", w->text);
|
||||
p += sprint(p, " %s", w->text);
|
||||
else if(PL_OP(w->space) == PL_TAB)
|
||||
e += sprint(e, "\t%s", w->text);
|
||||
p += sprint(p, "\t%s", w->text);
|
||||
if(w->nextline == w->next)
|
||||
e += sprint(e, "\n");
|
||||
p += sprint(p, "\n");
|
||||
}
|
||||
return p;
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,8 @@ void pl_drawtextview(Panel *p){
|
|||
* If t is a panel word, pass the mouse event on to it
|
||||
*/
|
||||
void pl_passon(Rtext *t, Mouse *m){
|
||||
if(t && t->b==0 && t->p!=0) plmouse(t->p, m);
|
||||
if(t && t->b==0 && t->p!=0)
|
||||
plmouse(t->p, m);
|
||||
}
|
||||
int pl_hittextview(Panel *p, Mouse *m){
|
||||
Rtext *oldhitword, *oldhitfirst;
|
||||
|
@ -166,6 +167,11 @@ int pl_pritextview(Panel *p, Point xy){
|
|||
}
|
||||
return PRI_NORMAL;
|
||||
}
|
||||
|
||||
char* pl_snarftextview(Panel *p){
|
||||
return plrtsnarftext(((Textview *)p->data)->text);
|
||||
}
|
||||
|
||||
void plinittextview(Panel *v, int flags, Point minsize, Rtext *t, void (*hit)(Panel *, int, Rtext *)){
|
||||
Textview *tp;
|
||||
tp=v->data;
|
||||
|
@ -185,6 +191,7 @@ void plinittextview(Panel *v, int flags, Point minsize, Rtext *t, void (*hit)(Pa
|
|||
tp->hitfirst=0;
|
||||
tp->hitword=0;
|
||||
v->scroll=pl_scrolltextview;
|
||||
v->snarf=pl_snarftextview;
|
||||
tp->twid=-1;
|
||||
v->scr.pos=Pt(0,0);
|
||||
v->scr.size=Pt(0,1);
|
||||
|
@ -202,9 +209,3 @@ void plsetpostextview(Panel *p, int yoffs){
|
|||
((Textview *)p->data)->yoffs=yoffs;
|
||||
pldraw(p, p->b);
|
||||
}
|
||||
char* plsnarftext(Panel *p){
|
||||
static char *b = nil;
|
||||
free(b);
|
||||
b = plrtsnarftext(((Textview *)p->data)->text);
|
||||
return b;
|
||||
}
|
||||
|
|
|
@ -118,20 +118,21 @@ int subpanel(Panel *obj, Panel *subj){
|
|||
* Make sure that the keyboard focus is on-screen, by adjusting it to
|
||||
* be the cmd entry if necessary.
|
||||
*/
|
||||
void adjkb(void){
|
||||
int adjkb(void){
|
||||
Rtext *t;
|
||||
int yoffs;
|
||||
extern Panel *pl_kbfocus; /* this is a secret panel library name */
|
||||
if(current){
|
||||
yoffs=text->r.min.y-plgetpostextview(text);
|
||||
for(t=current->text;t;t=t->next) if(!eqrect(t->r, Rect(0,0,0,0))){
|
||||
if(t->r.max.y+yoffs>text->r.max.y) break;
|
||||
if(t->r.min.y+yoffs>=text->r.min.y
|
||||
if(t->r.max.y+yoffs>=text->r.min.y
|
||||
&& t->r.min.y+yoffs<text->r.max.y
|
||||
&& t->b==0
|
||||
&& subpanel(t->p, pl_kbfocus)) return;
|
||||
&& subpanel(t->p, plkbfocus))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
plgrabkb(cmd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scrolltext(int dy, int whence)
|
||||
|
@ -1013,33 +1014,16 @@ void killpix(Www *w){
|
|||
w->pix=0;
|
||||
updtext(w);
|
||||
}
|
||||
|
||||
void snarf(Panel *p){
|
||||
char *s;
|
||||
int fd;
|
||||
|
||||
if((fd=open("/dev/snarf", OWRITE|OTRUNC))>=0){
|
||||
s = plsnarftext(text);
|
||||
if(s==0)
|
||||
s = urlstr(selection);
|
||||
fprint(fd, "%s", s);
|
||||
close(fd);
|
||||
}
|
||||
if(p==0) p=cmd;
|
||||
plputsnarf(urlstr(selection));
|
||||
/* non-ops if nothing selected */
|
||||
plsnarf(p);
|
||||
plsnarf(text);
|
||||
}
|
||||
void paste(Panel *p){
|
||||
char buf[1024];
|
||||
int n, len, fd;
|
||||
if((fd=open("/dev/snarf", OREAD))<0)
|
||||
return;
|
||||
nstrcpy(buf, plentryval(p), sizeof(buf));
|
||||
len=strlen(buf);
|
||||
n=read(fd, buf+len, sizeof(buf)-len-1);
|
||||
if(n>0){
|
||||
buf[len+n]='\0';
|
||||
plinitentry(cmd, PACKE|EXPAND, 0, buf, docmd);
|
||||
pldraw(cmd, screen);
|
||||
}
|
||||
close(fd);
|
||||
if(p==0) p=cmd;
|
||||
plpaste(p);
|
||||
}
|
||||
void hit3(int button, int item){
|
||||
char name[NNAME];
|
||||
|
@ -1069,10 +1053,10 @@ void hit3(int button, int item){
|
|||
mothon(current, !mothmode);
|
||||
break;
|
||||
case 2:
|
||||
snarf(cmd);
|
||||
snarf(plkbfocus);
|
||||
break;
|
||||
case 3:
|
||||
paste(cmd);
|
||||
paste(plkbfocus);
|
||||
break;
|
||||
case 4:
|
||||
snprint(name, sizeof(name), "%s/hit.html", home);
|
||||
|
|
Loading…
Reference in a new issue