all repos — acme @ 2908f1ff9b0a64cfba245aa0a748d8babc889e12

fork of the acme editor from plan9port - keybinds, tweaks, config.h, etc

add active tick indication; v9001-a02

window tag/body with keyboard focus will render tick in hilighted text color; doesn't work yet for column/row tags
Iris Lightshard nilix@nilfm.cc
commit

2908f1ff9b0a64cfba245aa0a748d8babc889e12

parent

65086bf370181c8e36a64d572dc51d290e4488a2

M README.mdREADME.md

@@ -2,6 +2,8 @@ # acme9k

This is a fork of the `acme` text editor from the `plan9port` distribution. It combines the customizability of [lumar](https://github.com/lumar)/[sminez](https://github.com/sminez/plan9port)'s forks and [acme2k](https://github.com/karahobny/acme2k) with upstream fixes from [9fans](https://github.com/9fans/plan9port) and some custom work. +Namely, when click-to-focus is enabled, the active window body or tag renders the tick (aka the text cursor) with the hilight color (`COLOR_<TAG|BODY>_HI`); otherwise the tick is rendered with the text color (`COLOR_<TAG|BODY>_TX`). This is all done with a fork of `libframe` which is included in the distribution and compiled into the program. + See the `config.def.h` for out of the box customizations that can be done. [![screenshot](./scrot.png)](./scrot.png)

@@ -44,13 +46,14 @@ After building, run `./install.sh`; If run as a regular user, it will install to `~/bin/9`; if run as root, it will overwrite the systemwide `acme` in `$PLAN9/bin`

## TODO -* [ ] add an indicator of the active window when click to focus (`bartflag`) is enabled +- [ ] allow active tick to be rendered for row/column tags, not just window body and tags +- [ ] compile helpers ## thanks -* [rob pike](https://github.com/robpike) author of the original acme for plan9 -* [russ cox](https://research.swtch.com) and the rest of the [9fans](https://github.com/9fans) for plan9port -* [lumar](https://github.com/lumar) - looks like they deleted their github repos but I originally pulled my keybinds from there -* [sminez](https://github.com/sminez) - possibly the original source of lumar's keybindings -* [karahobny](https://github.com/karahobny) - creator of acme2k, a big inspiration for this project -* [aksr](https://github.com/aksr) - source of the missing tag border pixel fix +- [rob pike](https://github.com/robpike) author of the original acme for plan9 +- [russ cox](https://research.swtch.com) and the rest of the [9fans](https://github.com/9fans) for plan9port +- [lumar](https://github.com/lumar) - looks like they deleted their github repos but I originally pulled my keybinds from there +- [sminez](https://github.com/sminez) - possibly the original source of lumar's keybindings +- [karahobny](https://github.com/karahobny) - creator of acme2k, a big inspiration for this project +- [aksr](https://github.com/aksr) - source of the missing tag border pixel fix
M acme.cacme.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>

@@ -43,7 +43,7 @@ Rune snarfrune[NSnarf + 1];

char* fontnames[2] = {PRIMARY_FONT, SECONDARY_FONT}; -char version[] = "acme9k v9001-a01"; +char version[] = "acme9k v9001-a02"; Command* command;

@@ -510,7 +510,10 @@ Mouse m;

char* act; enum { MResize, MMouse, MPlumb, MWarnings, NMALT }; static Alt alts[NMALT + 1]; + + /* make sure we don't recklessly refresh the ticks */ int click; + Text* oldbarttext; USED(v); threadsetname("mousethread");

@@ -598,6 +601,7 @@ else if (m.buttons == 2)

but = 2; else if (m.buttons == 4) but = 3; + oldbarttext = barttext; barttext = t; if (t->what == Body && ptinrect(m.xy, t->scrollr)) { if (but) {

@@ -668,15 +672,16 @@ } else if (m.buttons & 4) {

if (textselect3(t, &q0, &q1)) look3(t, q0, q1, FALSE); } + if (w) winunlock(w); goto Continue; } Continue: - /*if (click && w) { - /* draw hilighted border around active window - windrawideco(w, w->col->row->col, w->col->row->ncol); - }*/ + /* won't refresh ticks if scrolling didn't change the active frame! */ + if (oldbarttext != barttext && (m.buttons & (8 | 16) || click) && t) { + textsettick(t, t->row); + } qunlock(&row.lk); break; }
M addr.caddr.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M buff.cbuff.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M cols.ccols.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>

@@ -160,6 +160,7 @@ savemouse(w);

/* near the button, but in the body */ moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3))); barttext = &w->body; + textsettick(&w->body, c->row); return w; }

@@ -494,6 +495,7 @@ free(nl);

free(ny); c->safe = TRUE; winmousebut(w); + textsettick(&w->body, c->row); } void coldragwin(Column* c, Window* w, int but) {

@@ -581,6 +583,7 @@ r.max.y = c->w[i + 1]->r.min.y - Border;

winresize(w, r, c->safe, TRUE); c->safe = TRUE; winmousebut(w); + textsettick(&w->body, c->row); } Text* colwhich(Column* c, Point p) {
M config.def.hconfig.def.h

@@ -1,5 +1,5 @@

/****************** - * acme9k1 config * + * acme9k config * ******************/ /**********
M dat.hdat.h

@@ -228,7 +228,7 @@ void textsetorigin(Text*, uint, int);

void textsetselect(Text*, uint, uint); void textshow(Text*, uint, uint, int); void texttype(Text*, Rune); - +void textsettick(Text*, Row*); enum {

@@ -304,7 +304,6 @@ void winmousebut(Window*);

void winaddincl(Window*, Rune*, int); void wincleartag(Window*); char *winctlprint(Window*, char*, int); -void windrawideco(Window*, Column**, int); struct Column {
M disk.cdisk.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M ecmd.cecmd.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M edit.cedit.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M elog.celog.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M exec.cexec.c

@@ -6,7 +6,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M file.cfile.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M fsys.cfsys.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
A libframe/frame.h

@@ -0,0 +1,101 @@

+#ifndef _FRAME_H_ +#define _FRAME_H_ 1 +#if defined(__cplusplus) +extern "C" { +#endif + +AUTOLIB(frame) + +typedef struct Frbox Frbox; +typedef struct Frame Frame; + +enum{ + BACK, + HIGH, + BORD, + TEXT, + HTEXT, + NCOL +}; + +#define FRTICKW 3 +struct Frbox +{ + long wid; /* in pixels */ + long nrune; /* <0 ==> negate and treat as break char */ + uchar *ptr; + short bc; /* break char */ + short minwid; +}; + +struct Frame +{ + Font *font; /* of chars in the frame */ + Display *display; /* on which frame appears */ + Image *b; /* on which frame appears */ + Image *cols[NCOL]; /* text and background colors */ + Rectangle r; /* in which text appears */ + Rectangle entire; /* of full frame */ + void (*scroll)(Frame*, int); /* scroll function provided by application */ + Frbox *box; + ulong p0, p1; /* selection */ + ushort nbox, nalloc; + ushort maxtab; /* max size of tab, in pixels */ + ushort nchars; /* # runes in frame */ + ushort nlines; /* # lines with text */ + ushort maxlines; /* total # lines in frame */ + ushort lastlinefull; /* last line fills frame */ + ushort modified; /* changed since frselect() */ + Image *tick; /* typing tick when frame is inactive */ + Image* activetick; /* typing tick when frame has keyboard focus */ + Image* currenttick; /* points to the appropriate one of tick or activetick */ + Image *tickback; /* saved image under tick */ + int ticked; /* flag: is tick onscreen? */ + int noredraw; /* don't draw on the screen */ + int tickscale; /* tick scaling factor */ +}; + +ulong frcharofpt(Frame*, Point); +Point frptofchar(Frame*, ulong); +int frdelete(Frame*, ulong, ulong); +void frinsert(Frame*, Rune*, Rune*, ulong); +void frselect(Frame*, Mousectl*); +void frselectpaint(Frame*, Point, Point, Image*); +void frdrawsel(Frame*, Point, ulong, ulong, int); +Point frdrawsel0(Frame*, Point, ulong, ulong, Image*, Image*); +void frinit(Frame*, Rectangle, Font*, Image*, Image**); +void frsetrects(Frame*, Rectangle, Image*); +void frclear(Frame*, int); +void frredraw(Frame*); + +uchar *_frallocstr(Frame*, unsigned); +void _frinsure(Frame*, int, unsigned); +Point _frdraw(Frame*, Point); +void _frgrowbox(Frame*, int); +void _frfreebox(Frame*, int, int); +void _frmergebox(Frame*, int); +void _frdelbox(Frame*, int, int); +void _frsplitbox(Frame*, int, int); +int _frfindbox(Frame*, int, ulong, ulong); +void _frclosebox(Frame*, int, int); +int _frcanfit(Frame*, Point, Frbox*); +void _frcklinewrap(Frame*, Point*, Frbox*); +void _frcklinewrap0(Frame*, Point*, Frbox*); +void _fradvance(Frame*, Point*, Frbox*); +int _frnewwid(Frame*, Point, Frbox*); +int _frnewwid0(Frame*, Point, Frbox*); +void _frclean(Frame*, Point, int, int); +void _frdrawtext(Frame*, Point, Image*, Image*); +void _fraddbox(Frame*, int, int); +Point _frptofcharptb(Frame*, ulong, Point, int); +Point _frptofcharnb(Frame*, ulong, int); +int _frstrlen(Frame*, int); +void frtick(Frame*, Point, int); +void frinittick(Frame*); + +#define NRUNE(b) ((b)->nrune<0? 1 : (b)->nrune) +#define NBYTE(b) strlen((char*)(b)->ptr) +#if defined(__cplusplus) +} +#endif +#endif
M libframe/frbox.clibframe/frbox.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" #define SLOP 25
M libframe/frdelete.clibframe/frdelete.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" int frdelete(Frame* f, ulong p0, ulong p1) { Point pt0, pt1, ppt0;
M libframe/frdraw.clibframe/frdraw.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" void _frdrawtext(Frame* f, Point pt, Image* text, Image* back) { Frbox* b;

@@ -136,7 +136,7 @@

static void _frtick(Frame* f, Point pt, int ticked) { Rectangle r; - if (f->ticked == ticked || f->tick == 0 || !ptinrect(pt, f->r)) + if (f->ticked == ticked || f->currenttick == 0 || !ptinrect(pt, f->r)) return; pt.x -= f->tickscale; /* looks best just left of where requested */ r = Rect(pt.x, pt.y, pt.x + FRTICKW * f->tickscale, pt.y + f->font->height);

@@ -145,7 +145,7 @@ if (r.max.x > f->r.max.x)

r.max.x = f->r.max.x; if (ticked) { draw(f->tickback, f->tickback->r, f->b, nil, pt); - draw(f->b, r, f->tick, nil, ZP); + draw(f->b, r, f->currenttick, nil, ZP); } else draw(f->b, r, f->tickback, nil, ZP); f->ticked = ticked;
M libframe/frinit.clibframe/frinit.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" void frinit(Frame* f, Rectangle r, Font* ft, Image* b, Image* cols[NCOL]) { f->font = ft;

@@ -42,6 +42,16 @@ 0,

DWhite); if (f->tick == nil) return; + if (f->activetick) + freeimage(f->activetick); + f->activetick = allocimage( + f->display, + Rect(0, 0, f->tickscale * FRTICKW, ft->height), + b->chan, + 0, + DWhite); + if (f->activetick == nil) + return; if (f->tickback) freeimage(f->tickback); f->tickback = allocimage(f->display, f->tick->r, b->chan, 0, DWhite);

@@ -50,9 +60,9 @@ freeimage(f->tick);

f->tick = 0; return; } - /* background color */ + /* inactive background color */ draw(f->tick, f->tick->r, f->cols[BACK], nil, ZP); - /* vertical line */ + /* inactive vertical line */ draw( f->tick, Rect(

@@ -63,7 +73,7 @@ ft->height),

f->cols[TEXT], nil, ZP); - /* box on each end */ + /* inactive box on each end */ draw( f->tick, Rect(0, 0, f->tickscale * FRTICKW, f->tickscale * FRTICKW),

@@ -80,6 +90,39 @@ ft->height),

f->cols[TEXT], nil, ZP); + + /* active background color */ + draw(f->activetick, f->activetick->r, f->cols[BACK], nil, ZP); + /* active vertical line */ + draw( + f->activetick, + Rect( + f->tickscale * (FRTICKW / 2), + 0, + f->tickscale * (FRTICKW / 2 + 1), + ft->height), + f->cols[HIGH], + nil, + ZP); + /* active box on each end */ + draw( + f->activetick, + Rect(0, 0, f->tickscale * FRTICKW, f->tickscale * FRTICKW), + f->cols[HIGH], + nil, + ZP); + draw( + f->activetick, + Rect( + 0, + ft->height - f->tickscale * FRTICKW, + f->tickscale * FRTICKW, + ft->height), + f->cols[HIGH], + nil, + ZP); + + f->currenttick = f->tick; } void frsetrects(Frame* f, Rectangle r, Image* b) {

@@ -96,8 +139,10 @@ _frdelbox(f, 0, f->nbox - 1);

if (f->box) free(f->box); if (freeall) { + freeimage(f->activetick); freeimage(f->tick); freeimage(f->tickback); + f->currenttick = nil; f->tick = 0; f->tickback = 0; }
M libframe/frinsert.clibframe/frinsert.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" #define DELTA 25 #define TMPSIZE 256
M libframe/frptofchar.clibframe/frptofchar.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" Point _frptofcharptb(Frame* f, ulong p, Point pt, int bn) { uchar* s;
M libframe/frselect.clibframe/frselect.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" static int region(int a, int b) { if (a < b)
M libframe/frstr.clibframe/frstr.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" #define CHUNK 16 #define ROUNDUP(n) ((n + CHUNK) & ~(CHUNK - 1))
M libframe/frutil.clibframe/frutil.c

@@ -2,7 +2,7 @@ #include <u.h>

#include <libc.h> #include <draw.h> #include <mouse.h> -#include <frame.h> +#include "frame.h" int _frcanfit(Frame* f, Point pt, Frbox* b) { int left, w, nr;
M logf.clogf.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M look.clook.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <regexp.h> #include <9pclient.h>
M mkfilemkfile

@@ -4,7 +4,15 @@ TARG=acme

DIRS=mail libframe OFILES=\ + libframe/frbox.$O\ + libframe/frdelete.$O\ + libframe/frdraw.$O\ libframe/frinit.$O\ + libframe/frinsert.$O\ + libframe/frptofchar.$O\ + libframe/frselect.$O\ + libframe/frstr.$O\ + libframe/frutil.$O\ acme.$O\ addr.$O\ buff.$O\

@@ -27,7 +35,8 @@ util.$O\

wind.$O\ xfid.$O\ -HFILES=dat.h\ +HFILES=libframe/frame.h\ + dat.h\ edit.h\ fns.h\

@@ -36,7 +45,7 @@ <$PLAN9/src/mkdirs

edit.$O ecmd.$O elog.$O: edit.h -LDFLAGS=-L./libframe -lframe $LDFLAGS +# LDFLAGS=-L./libframe -lframe $LDFLAGS likeplan9:V: mkdir -p likeplan9
M regx.cregx.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M rows.crows.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <bio.h> #include <plumb.h>
M scrl.cscrl.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M text.ctext.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>

@@ -36,17 +36,39 @@ memmove(t->fr.cols, cols, sizeof t->fr.cols);

textredraw(t, r, rf->f, screen, -1, 0); } -void textdrawactive(Text* t, int active) { - Image* b; - Rectangle br; +void _textsettick(Text* current, Text* self) { + self->fr.currenttick = + (self == current) ? self->fr.activetick : self->fr.tick; +} + +void textsettick(Text* t, Row* r) { + Column** allcolumns; + Column* cptr; + Window* wptr; + int ncols, ccnt, wcnt; + + if (!bartflag) + return; - b = t->fr.cols[BACK]; - if (active) - b = t->fr.cols[HIGH]; - br.min = t->scrollr.max; - br.max.x = br.min.x + 1; - br.max.y = br.min.y + Dy(t->all); - draw(screen, br, b, nil, b->r.min); + allcolumns = r->col; + ncols = r->ncol; + + _textsettick(t, &r->tag); + for (ccnt = 0; ccnt < ncols; ccnt++) { + cptr = allcolumns[ccnt]; + _textsettick(t, &cptr->tag); + for (wcnt = 0; wcnt < cptr->nw; wcnt++) { + wptr = cptr->w[wcnt]; + winlock(wptr, 'M'); + _textsettick(t, &wptr->tag); + _textsettick(t, &wptr->body); + winunlock(wptr); + } + } + /* force redraw to refresh all ticks; + * kind of expensive, but we only do it when the active frame changes + */ + rowresize(r, r->r); } void textredraw(Text* t, Rectangle r, Font* f, Image* b, int odx, int active) {

@@ -77,7 +99,6 @@ } else {

textfill(t); textsetselect(t, t->q0, t->q1); } - /*textdrawactive(t, active);*/ } int textresize(Text* t, Rectangle r, int keepextra) {
M time.ctime.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M util.cutil.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>
M wind.cwind.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>

@@ -86,35 +86,6 @@ for (i = 0; i < NINDENT; i++)

w->indent[i] = clone->indent[i]; textsetselect(&w->body, clone->body.q0, clone->body.q1); winsettag(w); - } -} - -void windrawideco(Window* active, Column** allcols, int ncol) { - Window* wptr; - Column* cptr; - int wcnt, ccnt; - - for (ccnt = 0; ccnt < ncol; ccnt++) { - cptr = allcols[ccnt]; - for (wcnt = 0; wcnt < cptr->nw; wcnt++) { - wptr = cptr->w[wcnt]; - winlock(wptr, 'M'); - textredraw( - &wptr->tag, - wptr->tag.scrollr, - wptr->tag.fr.font, - screen, - -1, - wptr->id == active->id); - textredraw( - &wptr->body, - wptr->body.scrollr, - wptr->body.fr.font, - screen, - -1, - wptr->id == active->id); - winunlock(wptr); - } } }
M xfid.cxfid.c

@@ -5,7 +5,7 @@ #include <thread.h>

#include <cursor.h> #include <mouse.h> #include <keyboard.h> -#include <frame.h> +#include "libframe/frame.h" #include <fcall.h> #include <plumb.h> #include <libsec.h>