ref: 50c661ce3e4ff694080d8ff68167b507a4baf153
parent: 67ea0e0d70e735cfc86e3e82a37e3a911fe243e6
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Sep 23 16:14:47 EDT 2012
mothra: snarf and paste
--- a/sys/man/1/mothra
+++ b/sys/man/1/mothra
@@ -97,11 +97,12 @@
.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.
--- a/sys/src/cmd/mothra/libpanel/draw.c
+++ b/sys/src/cmd/mothra/libpanel/draw.c
@@ -139,6 +139,7 @@
*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;
--- a/sys/src/cmd/mothra/libpanel/edit.c
+++ b/sys/src/cmd/mothra/libpanel/edit.c
@@ -48,46 +48,25 @@
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,7 +85,8 @@
*/
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);
@@ -113,11 +93,12 @@
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,8 +152,14 @@
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;
twreplace(t, ep->sel0, ep->sel1, 0, 0);
@@ -187,6 +174,8 @@
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 @@
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;
--- a/sys/src/cmd/mothra/libpanel/entry.c
+++ b/sys/src/cmd/mothra/libpanel/entry.c
@@ -15,35 +15,31 @@
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 @@
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 @@
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 @@
*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 @@
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)
--- a/sys/src/cmd/mothra/libpanel/event.c
+++ b/sys/src/cmd/mothra/libpanel/event.c
@@ -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
*/
--- a/sys/src/cmd/mothra/libpanel/mem.c
+++ b/sys/src/cmd/mothra/libpanel/mem.c
@@ -89,6 +89,8 @@
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 @@
Panel *cp, *ncp;
if(p==0)
return;
+ if(p==plkbfocus)
+ plkbfocus=0;
for(cp=p->child;cp;cp=ncp){ncp=cp->next;
plfree(cp);
--- a/sys/src/cmd/mothra/libpanel/mkfile
+++ b/sys/src/cmd/mothra/libpanel/mkfile
@@ -26,7 +26,8 @@
slider.$O\
textview.$O\
textwin.$O\
- utf.$O
+ utf.$O\
+ snarf.$O
HFILES=panel.h pldefs.h rtext.h
--- a/sys/src/cmd/mothra/libpanel/panel.h
+++ b/sys/src/cmd/mothra/libpanel/panel.h
@@ -55,6 +55,8 @@
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 @@
#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 @@
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 @@
int plgetpostextview(Panel *);
void plsetpostextview(Panel *, int);
-char *plsnarftext(Panel *);
/*
* Idols
@@ -183,3 +187,11 @@
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 */
--- a/sys/src/cmd/mothra/libpanel/popup.c
+++ b/sys/src/cmd/mothra/libpanel/popup.c
@@ -75,6 +75,8 @@
}
}
plmouse(p, m);
+ if((m->buttons&7)==0)
+ g->state=UP;
return (m->buttons&7)!=0;
}
void pl_typepopup(Panel *g, Rune c){--- a/sys/src/cmd/mothra/libpanel/rtext.c
+++ b/sys/src/cmd/mothra/libpanel/rtext.c
@@ -291,26 +291,30 @@
}
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;
}
--- a/sys/src/cmd/mothra/libpanel/textview.c
+++ b/sys/src/cmd/mothra/libpanel/textview.c
@@ -52,7 +52,8 @@
* 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 @@
}
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 @@
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);
@@ -201,10 +208,4 @@
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;
}
--- a/sys/src/cmd/mothra/mothra.c
+++ b/sys/src/cmd/mothra/mothra.c
@@ -118,20 +118,21 @@
* 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 @@
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 @@
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);
--
⑨