📄 wind.c
字号:
if(!w->mouseopen) switch(r){ case Kdown: n = w->maxlines/3; goto case_Down; case Kscrollonedown: n = mousescrollsize(w->maxlines); if(n <= 0) n = 1; goto case_Down; case Kpgdown: n = 2*w->maxlines/3; case_Down: q0 = w->org+frcharofpt(w, Pt(w->Frame.r.min.x, w->Frame.r.min.y+n*w->font->height)); wsetorigin(w, q0, TRUE); return; case Kup: n = w->maxlines/3; goto case_Up; case Kscrolloneup: n = mousescrollsize(w->maxlines); if(n <= 0) n = 1; goto case_Up; case Kpgup: n = 2*w->maxlines/3; case_Up: q0 = wbacknl(w, w->org, n); wsetorigin(w, q0, TRUE); return; case Kleft: if(w->q0 > 0){ q0 = w->q0-1; wsetselect(w, q0, q0); wshow(w, q0); } return; case Kright: if(w->q1 < w->nr){ q1 = w->q1+1; wsetselect(w, q1, q1); wshow(w, q1); } return; case Khome: wshow(w, 0); return; case Kend: wshow(w, w->nr); return; case 0x01: /* ^A: beginning of line */ if(w->q0==0 || w->q0==w->qh || w->r[w->q0-1]=='\n') return; nb = wbswidth(w, 0x15 /* ^U */); wsetselect(w, w->q0-nb, w->q0-nb); wshow(w, w->q0); return; case 0x05: /* ^E: end of line */ q0 = w->q0; while(q0 < w->nr && w->r[q0]!='\n') q0++; wsetselect(w, q0, q0); wshow(w, w->q0); return; } if(w->rawing && (w->q0==w->nr || w->mouseopen)){ waddraw(w, &r, 1); return; } if(r==0x1B || (w->holding && r==0x7F)){ /* toggle hold */ if(w->holding) --w->holding; else w->holding++; wrepaint(w); if(r == 0x1B) return; } if(r != 0x7F){ wsnarf(w); wcut(w); } switch(r){ case 0x7F: /* send interrupt */ w->qh = w->nr; wshow(w, w->qh); notefd = emalloc(sizeof(int)); *notefd = w->notefd; proccreate(interruptproc, notefd, 4096); return; case 0x06: /* ^F: file name completion */ case Kins: /* Insert: file name completion */ rp = namecomplete(w); if(rp == nil) return; nr = runestrlen(rp); q0 = w->q0; q0 = winsert(w, rp, nr, q0); wshow(w, q0+nr); free(rp); return; case 0x08: /* ^H: erase character */ case 0x15: /* ^U: erase line */ case 0x17: /* ^W: erase word */ if(w->q0==0 || w->q0==w->qh) return; nb = wbswidth(w, r); q1 = w->q0; q0 = q1-nb; if(q0 < w->org){ q0 = w->org; nb = q1-q0; } if(nb > 0){ wdelete(w, q0, q0+nb); wsetselect(w, q0, q0); } return; } /* otherwise ordinary character; just insert */ q0 = w->q0; q0 = winsert(w, &r, 1, q0); wshow(w, q0+1);}voidwsetcols(Window *w){ if(w->holding) if(w == input) w->cols[TEXT] = w->cols[HTEXT] = holdcol; else w->cols[TEXT] = w->cols[HTEXT] = lightholdcol; else if(w == input) w->cols[TEXT] = w->cols[HTEXT] = display->black; else w->cols[TEXT] = w->cols[HTEXT] = darkgrey;}voidwrepaint(Window *w){ wsetcols(w); if(!w->mouseopen) _frredraw(w, w->Frame.r.min, w->cols[TEXT], w->cols[BACK]); if(w == input){ wborder(w, Selborder); wsetcursor(w, 0); }else wborder(w, Unselborder);}intwbswidth(Window *w, Rune c){ uint q, eq, stop; Rune r; int skipping; /* there is known to be at least one character to erase */ if(c == 0x08) /* ^H: erase character */ return 1; q = w->q0; stop = 0; if(q > w->qh) stop = w->qh; skipping = TRUE; while(q > stop){ r = w->r[q-1]; if(r == '\n'){ /* eat at most one more character */ if(q == w->q0) /* eat the newline */ --q; break; } if(c == 0x17){ eq = isalnum(r); if(eq && skipping) /* found one; stop skipping */ skipping = FALSE; else if(!eq && !skipping) break; } --q; } return w->q0-q;}voidwsnarf(Window *w){ if(w->q1 == w->q0) return; nsnarf = w->q1-w->q0; snarf = runerealloc(snarf, nsnarf); snarfversion++; /* maybe modified by parent */ runemove(snarf, w->r+w->q0, nsnarf); putsnarf();}voidwcut(Window *w){ if(w->q1 == w->q0) return; wdelete(w, w->q0, w->q1); wsetselect(w, w->q0, w->q0);}voidwpaste(Window *w){ uint q0; if(nsnarf == 0) return; wcut(w); q0 = w->q0; if(w->rawing && q0==w->nr){ waddraw(w, snarf, nsnarf); wsetselect(w, q0, q0); }else{ q0 = winsert(w, snarf, nsnarf, w->q0); wsetselect(w, q0, q0+nsnarf); }}voidwplumb(Window *w){ Plumbmsg *m; static int fd = -2; char buf[32]; uint p0, p1; Cursor *c; if(fd == -2) fd = plumbopen("send", OWRITE|OCEXEC); if(fd < 0) return; m = emalloc(sizeof(Plumbmsg)); m->src = estrdup("rio"); m->dst = nil; m->wdir = estrdup(w->dir); m->type = estrdup("text"); p0 = w->q0; p1 = w->q1; if(w->q1 > w->q0) m->attr = nil; else{ while(p0>0 && w->r[p0-1]!=' ' && w->r[p0-1]!='\t' && w->r[p0-1]!='\n') p0--; while(p1<w->nr && w->r[p1]!=' ' && w->r[p1]!='\t' && w->r[p1]!='\n') p1++; sprint(buf, "click=%d", w->q0-p0); m->attr = plumbunpackattr(buf); } if(p1-p0 > messagesize-1024){ plumbfree(m); return; /* too large for 9P */ } m->data = runetobyte(w->r+p0, p1-p0, &m->ndata); if(plumbsend(fd, m) < 0){ c = lastcursor; riosetcursor(&query, 1); sleep(300); riosetcursor(c, 1); } plumbfree(m);}intwinborder(Window *w, Point xy){ return ptinrect(xy, w->screenr) && !ptinrect(xy, insetrect(w->screenr, Selborder));}voidwmousectl(Window *w){ int but; if(w->mc.buttons == 1) but = 1; else if(w->mc.buttons == 2) but = 2; else if(w->mc.buttons == 4) but = 3; else{ if(w->mc.buttons == 8) wkeyctl(w, Kscrolloneup); if(w->mc.buttons == 16) wkeyctl(w, Kscrollonedown); return; } incref(w); /* hold up window while we track */ if(w->deleted) goto Return; if(ptinrect(w->mc.xy, w->scrollr)){ if(but) wscroll(w, but); goto Return; } if(but == 1) wselect(w); /* else all is handled by main process */ Return: wclose(w);}voidwdelete(Window *w, uint q0, uint q1){ uint n, p0, p1; n = q1-q0; if(n == 0) return; runemove(w->r+q0, w->r+q1, w->nr-q1); w->nr -= n; if(q0 < w->q0) w->q0 -= min(n, w->q0-q0); if(q0 < w->q1) w->q1 -= min(n, w->q1-q0); if(q1 < w->qh) w->qh -= n; else if(q0 < w->qh) w->qh = q0; if(q1 <= w->org) w->org -= n; else if(q0 < w->org+w->nchars){ p1 = q1 - w->org; if(p1 > w->nchars) p1 = w->nchars; if(q0 < w->org){ w->org = q0; p0 = 0; }else p0 = q0 - w->org; frdelete(w, p0, p1); wfill(w); }}static Window *clickwin;static uint clickmsec;static Window *selectwin;static uint selectq;/* * called from frame library */voidframescroll(Frame *f, int dl){ if(f != &selectwin->Frame) error("frameselect not right frame"); wframescroll(selectwin, dl);}voidwframescroll(Window *w, int dl){ uint q0; if(dl == 0){ wscrsleep(w, 100); return; } if(dl < 0){ q0 = wbacknl(w, w->org, -dl); if(selectq > w->org+w->p0) wsetselect(w, w->org+w->p0, selectq); else wsetselect(w, selectq, w->org+w->p0); }else{ if(w->org+w->nchars == w->nr) return; q0 = w->org+frcharofpt(w, Pt(w->Frame.r.min.x, w->Frame.r.min.y+dl*w->font->height)); if(selectq >= w->org+w->p1) wsetselect(w, w->org+w->p1, selectq); else wsetselect(w, selectq, w->org+w->p1); } wsetorigin(w, q0, TRUE);}voidwselect(Window *w){ uint q0, q1; int b, x, y, first; first = 1; selectwin = w; /* * Double-click immediately if it might make sense. */ b = w->mc.buttons; q0 = w->q0; q1 = w->q1; selectq = w->org+frcharofpt(w, w->mc.xy); if(clickwin==w && w->mc.msec-clickmsec<500) if(q0==q1 && selectq==w->q0){ wdoubleclick(w, &q0, &q1); wsetselect(w, q0, q1); flushimage(display, 1); x = w->mc.xy.x; y = w->mc.xy.y; /* stay here until something interesting happens */ do readmouse(&w->mc); while(w->mc.buttons==b && abs(w->mc.xy.x-x)<3 && abs(w->mc.xy.y-y)<3); w->mc.xy.x = x; /* in case we're calling frselect */ w->mc.xy.y = y; q0 = w->q0; /* may have changed */ q1 = w->q1; selectq = q0; } if(w->mc.buttons == b){ w->scroll = framescroll; frselect(w, &w->mc); /* horrible botch: while asleep, may have lost selection altogether */ if(selectq > w->nr) selectq = w->org + w->p0; w->Frame.scroll = nil; if(selectq < w->org) q0 = selectq; else q0 = w->org + w->p0; if(selectq > w->org+w->nchars) q1 = selectq; else q1 = w->org+w->p1; } if(q0 == q1){ if(q0==w->q0 && clickwin==w && w->mc.msec-clickmsec<500){ wdoubleclick(w, &q0, &q1); clickwin = nil; }else{ clickwin = w; clickmsec = w->mc.msec; } }else clickwin = nil; wsetselect(w, q0, q1); flushimage(display, 1); while(w->mc.buttons){ w->mc.msec = 0; b = w->mc.buttons; if(b & 6){ if(b & 2){ wsnarf(w); wcut(w); }else{ if(first){ first = 0; getsnarf(); } wpaste(w); } } wscrdraw(w); flushimage(display, 1); while(w->mc.buttons == b) readmouse(&w->mc); clickwin = nil; }}voidwsendctlmesg(Window *w, int type, Rectangle r, Image *image){ Wctlmesg wcm; wcm.type = type; wcm.r = r; wcm.image = image; send(w->cctl, &wcm);}intwctlmesg(Window *w, int m, Rectangle r, Image *i){ char buf[64]; switch(m){ default: error("unknown control message"); break; case Wakeup: break; case Moved: case Reshaped: if(w->deleted){ freeimage(i); break; } w->screenr = r; strcpy(buf, w->name); wresize(w, i, m==Moved); w->wctlready = 1; proccreate(deletetimeoutproc, estrdup(buf), 4096); if(Dx(r) > 0){ if(w != input) wcurrent(w); }else if(w == input) wcurrent(nil); flushimage(display, 1); break; case Refresh: if(w->deleted || Dx(w->screenr)<=0 || !rectclip(&r, w->i->r)) break; if(!w->mouseopen) wrefresh(w, r); flushimage(display, 1); break; case Movemouse: if(sweeping || !ptinrect(r.min, w->i->r)) break; wmovemouse(w, r.min); case Rawon: break; case Rawoff: if(w->deleted) break; while(w->nraw > 0){ wkeyctl(w, w->raw[0]); --w->nraw; runemove(w->raw, w->raw+1, w->nraw); } break; case Holdon: case Holdoff: if(w->deleted) break; wrepaint(w); flushimage(display, 1); break; case Deleted: if(w->deleted) break; write(w->notefd, "hangup", 6); proccreate(deletetimeoutproc, estrdup(w->name), 4096); wclosewin(w); break; case Exited: frclear(w, TRUE); close(w->notefd); chanfree(w->mc.c); chanfree(w->ck); chanfree(w->cctl); chanfree(w->conswrite); chanfree(w->consread); chanfree(w->mouseread); chanfree(w->wctlread); free(w->raw); free(w->r); free(w->dir); free(w->label); free(w); break; } return m;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -