mirror of
https://hacklab.nilfm.cc/acme
synced 2024-10-22 14:31:48 +00:00
582 lines
12 KiB
C
582 lines
12 KiB
C
|
enum
|
||
|
{
|
||
|
Qdir,
|
||
|
Qacme,
|
||
|
Qcons,
|
||
|
Qconsctl,
|
||
|
Qdraw,
|
||
|
Qeditout,
|
||
|
Qindex,
|
||
|
Qlabel,
|
||
|
Qlog,
|
||
|
Qnew,
|
||
|
|
||
|
QWaddr,
|
||
|
QWbody,
|
||
|
QWctl,
|
||
|
QWdata,
|
||
|
QWeditout,
|
||
|
QWerrors,
|
||
|
QWevent,
|
||
|
QWrdsel,
|
||
|
QWwrsel,
|
||
|
QWtag,
|
||
|
QWxdata,
|
||
|
QMAX
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
Blockincr = 256,
|
||
|
Maxblock = 8*1024,
|
||
|
NRange = 10,
|
||
|
Infinity = 0x7FFFFFFF /* huge value for regexp address */
|
||
|
};
|
||
|
|
||
|
#define Buffer AcmeBuffer
|
||
|
typedef struct Block Block;
|
||
|
typedef struct Buffer Buffer;
|
||
|
typedef struct Command Command;
|
||
|
typedef struct Column Column;
|
||
|
typedef struct Dirlist Dirlist;
|
||
|
typedef struct Dirtab Dirtab;
|
||
|
typedef struct Disk Disk;
|
||
|
typedef struct Expand Expand;
|
||
|
typedef struct Fid Fid;
|
||
|
typedef struct File File;
|
||
|
typedef struct Elog Elog;
|
||
|
typedef struct Mntdir Mntdir;
|
||
|
typedef struct Range Range;
|
||
|
typedef struct Rangeset Rangeset;
|
||
|
typedef struct Reffont Reffont;
|
||
|
typedef struct Row Row;
|
||
|
typedef struct Runestr Runestr;
|
||
|
typedef struct Text Text;
|
||
|
typedef struct Timer Timer;
|
||
|
typedef struct Window Window;
|
||
|
typedef struct Xfid Xfid;
|
||
|
|
||
|
struct Runestr
|
||
|
{
|
||
|
Rune *r;
|
||
|
int nr;
|
||
|
};
|
||
|
|
||
|
struct Range
|
||
|
{
|
||
|
int q0;
|
||
|
int q1;
|
||
|
};
|
||
|
|
||
|
struct Block
|
||
|
{
|
||
|
vlong addr; /* disk address in bytes */
|
||
|
union
|
||
|
{
|
||
|
uint n; /* number of used runes in block */
|
||
|
Block *next; /* pointer to next in free list */
|
||
|
} u;
|
||
|
};
|
||
|
|
||
|
struct Disk
|
||
|
{
|
||
|
int fd;
|
||
|
vlong addr; /* length of temp file */
|
||
|
Block *free[Maxblock/Blockincr+1];
|
||
|
};
|
||
|
|
||
|
Disk* diskinit(void);
|
||
|
Block* disknewblock(Disk*, uint);
|
||
|
void diskrelease(Disk*, Block*);
|
||
|
void diskread(Disk*, Block*, Rune*, uint);
|
||
|
void diskwrite(Disk*, Block**, Rune*, uint);
|
||
|
|
||
|
struct Buffer
|
||
|
{
|
||
|
uint nc;
|
||
|
Rune *c; /* cache */
|
||
|
uint cnc; /* bytes in cache */
|
||
|
uint cmax; /* size of allocated cache */
|
||
|
uint cq; /* position of cache */
|
||
|
int cdirty; /* cache needs to be written */
|
||
|
uint cbi; /* index of cache Block */
|
||
|
Block **bl; /* array of blocks */
|
||
|
uint nbl; /* number of blocks */
|
||
|
};
|
||
|
void bufinsert(Buffer*, uint, Rune*, uint);
|
||
|
void bufdelete(Buffer*, uint, uint);
|
||
|
uint bufload(Buffer*, uint, int, int*, DigestState*);
|
||
|
void bufread(Buffer*, uint, Rune*, uint);
|
||
|
void bufclose(Buffer*);
|
||
|
void bufreset(Buffer*);
|
||
|
|
||
|
struct Elog
|
||
|
{
|
||
|
short type; /* Delete, Insert, Filename */
|
||
|
uint q0; /* location of change (unused in f) */
|
||
|
uint nd; /* number of deleted characters */
|
||
|
uint nr; /* # runes in string or file name */
|
||
|
Rune *r;
|
||
|
};
|
||
|
void elogterm(File*);
|
||
|
void elogclose(File*);
|
||
|
void eloginsert(File*, int, Rune*, int);
|
||
|
void elogdelete(File*, int, int);
|
||
|
void elogreplace(File*, int, int, Rune*, int);
|
||
|
void elogapply(File*);
|
||
|
|
||
|
struct File
|
||
|
{
|
||
|
Buffer b; /* the data */
|
||
|
Buffer delta; /* transcript of changes */
|
||
|
Buffer epsilon; /* inversion of delta for redo */
|
||
|
Buffer *elogbuf; /* log of pending editor changes */
|
||
|
Elog elog; /* current pending change */
|
||
|
Rune *name; /* name of associated file */
|
||
|
int nname; /* size of name */
|
||
|
uvlong qidpath; /* of file when read */
|
||
|
ulong mtime; /* of file when read */
|
||
|
int dev; /* of file when read */
|
||
|
uchar sha1[20]; /* of file when read */
|
||
|
int unread; /* file has not been read from disk */
|
||
|
int editclean; /* mark clean after edit command */
|
||
|
|
||
|
int seq; /* if seq==0, File acts like Buffer */
|
||
|
int mod;
|
||
|
Text *curtext; /* most recently used associated text */
|
||
|
Text **text; /* list of associated texts */
|
||
|
int ntext;
|
||
|
int dumpid; /* used in dumping zeroxed windows */
|
||
|
};
|
||
|
File* fileaddtext(File*, Text*);
|
||
|
void fileclose(File*);
|
||
|
void filedelete(File*, uint, uint);
|
||
|
void filedeltext(File*, Text*);
|
||
|
void fileinsert(File*, uint, Rune*, uint);
|
||
|
uint fileload(File*, uint, int, int*, DigestState*);
|
||
|
void filemark(File*);
|
||
|
void filereset(File*);
|
||
|
void filesetname(File*, Rune*, int);
|
||
|
void fileundelete(File*, Buffer*, uint, uint);
|
||
|
void fileuninsert(File*, Buffer*, uint, uint);
|
||
|
void fileunsetname(File*, Buffer*);
|
||
|
void fileundo(File*, int, uint*, uint*);
|
||
|
uint fileredoseq(File*);
|
||
|
|
||
|
enum /* Text.what */
|
||
|
{
|
||
|
Columntag,
|
||
|
Rowtag,
|
||
|
Tag,
|
||
|
Body
|
||
|
};
|
||
|
|
||
|
struct Text
|
||
|
{
|
||
|
File *file;
|
||
|
Frame fr;
|
||
|
Reffont *reffont;
|
||
|
uint org;
|
||
|
uint q0;
|
||
|
uint q1;
|
||
|
int what;
|
||
|
int tabstop;
|
||
|
Window *w;
|
||
|
Rectangle scrollr;
|
||
|
Rectangle lastsr;
|
||
|
Rectangle all;
|
||
|
Row *row;
|
||
|
Column *col;
|
||
|
|
||
|
uint iq1; /* last input position */
|
||
|
uint eq0; /* start of typing for ESC */
|
||
|
uint cq0; /* cache position */
|
||
|
int ncache; /* storage for insert */
|
||
|
int ncachealloc;
|
||
|
Rune *cache;
|
||
|
int nofill;
|
||
|
int needundo;
|
||
|
};
|
||
|
|
||
|
uint textbacknl(Text*, uint, uint);
|
||
|
uint textbsinsert(Text*, uint, Rune*, uint, int, int*);
|
||
|
int textbswidth(Text*, Rune);
|
||
|
int textclickhtmlmatch(Text*, uint*, uint*);
|
||
|
int textclickmatch(Text*, int, int, int, uint*);
|
||
|
void textclose(Text*);
|
||
|
void textcolumnate(Text*, Dirlist**, int);
|
||
|
void textcommit(Text*, int);
|
||
|
void textconstrain(Text*, uint, uint, uint*, uint*);
|
||
|
void textdelete(Text*, uint, uint, int);
|
||
|
void textdoubleclick(Text*, uint*, uint*);
|
||
|
void textfill(Text*);
|
||
|
void textframescroll(Text*, int);
|
||
|
void textinit(Text*, File*, Rectangle, Reffont*, Image**);
|
||
|
void textinsert(Text*, uint, Rune*, uint, int);
|
||
|
int textload(Text*, uint, char*, int);
|
||
|
Rune textreadc(Text*, uint);
|
||
|
void textredraw(Text*, Rectangle, Font*, Image*, int);
|
||
|
void textreset(Text*);
|
||
|
int textresize(Text*, Rectangle, int);
|
||
|
void textscrdraw(Text*);
|
||
|
void textscroll(Text*, int);
|
||
|
void textselect(Text*);
|
||
|
int textselect2(Text*, uint*, uint*, Text**);
|
||
|
int textselect23(Text*, uint*, uint*, Image*, int);
|
||
|
int textselect3(Text*, uint*, uint*);
|
||
|
void textsetorigin(Text*, uint, int);
|
||
|
void textsetselect(Text*, uint, uint);
|
||
|
void textshow(Text*, uint, uint, int);
|
||
|
void texttype(Text*, Rune);
|
||
|
|
||
|
struct Window
|
||
|
{
|
||
|
QLock lk;
|
||
|
Ref ref;
|
||
|
Text tag;
|
||
|
Text body;
|
||
|
Rectangle r;
|
||
|
uchar isdir;
|
||
|
uchar isscratch;
|
||
|
uchar filemenu;
|
||
|
uchar dirty;
|
||
|
uchar autoindent;
|
||
|
uchar showdel;
|
||
|
int id;
|
||
|
Range addr;
|
||
|
Range limit;
|
||
|
uchar nopen[QMAX];
|
||
|
uchar nomark;
|
||
|
Range wrselrange;
|
||
|
int rdselfd;
|
||
|
Column *col;
|
||
|
Xfid *eventx;
|
||
|
char *events;
|
||
|
int nevents;
|
||
|
int owner;
|
||
|
int maxlines;
|
||
|
Dirlist **dlp;
|
||
|
int ndl;
|
||
|
int putseq;
|
||
|
int nincl;
|
||
|
Rune **incl;
|
||
|
Reffont *reffont;
|
||
|
QLock ctllock;
|
||
|
uint ctlfid;
|
||
|
char *dumpstr;
|
||
|
char *dumpdir;
|
||
|
int dumpid;
|
||
|
int utflastqid;
|
||
|
int utflastboff;
|
||
|
int utflastq;
|
||
|
int tagsafe; /* taglines is correct */
|
||
|
int tagexpand;
|
||
|
int taglines;
|
||
|
Rectangle tagtop;
|
||
|
QLock editoutlk;
|
||
|
};
|
||
|
|
||
|
void wininit(Window*, Window*, Rectangle);
|
||
|
void winlock(Window*, int);
|
||
|
void winlock1(Window*, int);
|
||
|
void winunlock(Window*);
|
||
|
void wintype(Window*, Text*, Rune);
|
||
|
void winundo(Window*, int);
|
||
|
void winsetname(Window*, Rune*, int);
|
||
|
void winsettag(Window*);
|
||
|
void winsettag1(Window*);
|
||
|
void wincommit(Window*, Text*);
|
||
|
int winresize(Window*, Rectangle, int, int);
|
||
|
void winclose(Window*);
|
||
|
void windelete(Window*);
|
||
|
int winclean(Window*, int);
|
||
|
void windirfree(Window*);
|
||
|
void winevent(Window*, char*, ...);
|
||
|
void winmousebut(Window*);
|
||
|
void winaddincl(Window*, Rune*, int);
|
||
|
void wincleartag(Window*);
|
||
|
char *winctlprint(Window*, char*, int);
|
||
|
|
||
|
struct Column
|
||
|
{
|
||
|
Rectangle r;
|
||
|
Text tag;
|
||
|
Row *row;
|
||
|
Window **w;
|
||
|
int nw;
|
||
|
int safe;
|
||
|
};
|
||
|
|
||
|
void colinit(Column*, Rectangle);
|
||
|
Window* coladd(Column*, Window*, Window*, int);
|
||
|
void colclose(Column*, Window*, int);
|
||
|
void colcloseall(Column*);
|
||
|
void colresize(Column*, Rectangle);
|
||
|
Text* colwhich(Column*, Point);
|
||
|
void coldragwin(Column*, Window*, int);
|
||
|
void colgrow(Column*, Window*, int);
|
||
|
int colclean(Column*);
|
||
|
void colsort(Column*);
|
||
|
void colmousebut(Column*);
|
||
|
|
||
|
struct Row
|
||
|
{
|
||
|
QLock lk;
|
||
|
Rectangle r;
|
||
|
Text tag;
|
||
|
Column **col;
|
||
|
int ncol;
|
||
|
|
||
|
};
|
||
|
|
||
|
void rowinit(Row*, Rectangle);
|
||
|
Column* rowadd(Row*, Column *c, int);
|
||
|
void rowclose(Row*, Column*, int);
|
||
|
Text* rowwhich(Row*, Point);
|
||
|
Column* rowwhichcol(Row*, Point);
|
||
|
void rowresize(Row*, Rectangle);
|
||
|
Text* rowtype(Row*, Rune, Point);
|
||
|
void rowdragcol(Row*, Column*, int but);
|
||
|
int rowclean(Row*);
|
||
|
void rowdump(Row*, char*);
|
||
|
int rowload(Row*, char*, int);
|
||
|
void rowloadfonts(char*);
|
||
|
|
||
|
struct Timer
|
||
|
{
|
||
|
int dt;
|
||
|
int cancel;
|
||
|
Channel *c; /* chan(int) */
|
||
|
Timer *next;
|
||
|
};
|
||
|
|
||
|
struct Command
|
||
|
{
|
||
|
int pid;
|
||
|
Rune *name;
|
||
|
int nname;
|
||
|
char *text;
|
||
|
char **av;
|
||
|
int iseditcmd;
|
||
|
Mntdir *md;
|
||
|
Command *next;
|
||
|
};
|
||
|
|
||
|
struct Dirtab
|
||
|
{
|
||
|
char *name;
|
||
|
uchar type;
|
||
|
uint qid;
|
||
|
uint perm;
|
||
|
};
|
||
|
|
||
|
struct Mntdir
|
||
|
{
|
||
|
int id;
|
||
|
int ref;
|
||
|
Rune *dir;
|
||
|
int ndir;
|
||
|
Mntdir *next;
|
||
|
int nincl;
|
||
|
Rune **incl;
|
||
|
};
|
||
|
|
||
|
struct Fid
|
||
|
{
|
||
|
int fid;
|
||
|
int busy;
|
||
|
int open;
|
||
|
Qid qid;
|
||
|
Window *w;
|
||
|
Dirtab *dir;
|
||
|
Fid *next;
|
||
|
Mntdir *mntdir;
|
||
|
int nrpart;
|
||
|
uchar rpart[UTFmax];
|
||
|
vlong logoff; // for putlog
|
||
|
};
|
||
|
|
||
|
|
||
|
struct Xfid
|
||
|
{
|
||
|
void *arg; /* args to xfidinit */
|
||
|
Fcall fcall;
|
||
|
Xfid *next;
|
||
|
Channel *c; /* chan(void(*)(Xfid*)) */
|
||
|
Fid *f;
|
||
|
uchar *buf;
|
||
|
int flushed;
|
||
|
};
|
||
|
|
||
|
void xfidctl(void *);
|
||
|
void xfidflush(Xfid*);
|
||
|
void xfidopen(Xfid*);
|
||
|
void xfidclose(Xfid*);
|
||
|
void xfidread(Xfid*);
|
||
|
void xfidwrite(Xfid*);
|
||
|
void xfidctlwrite(Xfid*, Window*);
|
||
|
void xfideventread(Xfid*, Window*);
|
||
|
void xfideventwrite(Xfid*, Window*);
|
||
|
void xfidindexread(Xfid*);
|
||
|
void xfidutfread(Xfid*, Text*, uint, int);
|
||
|
int xfidruneread(Xfid*, Text*, uint, uint);
|
||
|
void xfidlogopen(Xfid*);
|
||
|
void xfidlogread(Xfid*);
|
||
|
void xfidlogflush(Xfid*);
|
||
|
void xfidlog(Window*, char*);
|
||
|
|
||
|
struct Reffont
|
||
|
{
|
||
|
Ref ref;
|
||
|
Font *f;
|
||
|
|
||
|
};
|
||
|
Reffont *rfget(int, int, int, char*);
|
||
|
void rfclose(Reffont*);
|
||
|
|
||
|
struct Rangeset
|
||
|
{
|
||
|
Range r[NRange];
|
||
|
};
|
||
|
|
||
|
struct Dirlist
|
||
|
{
|
||
|
Rune *r;
|
||
|
int nr;
|
||
|
int wid;
|
||
|
};
|
||
|
|
||
|
struct Expand
|
||
|
{
|
||
|
uint q0;
|
||
|
uint q1;
|
||
|
Rune *name;
|
||
|
int nname;
|
||
|
char *bname;
|
||
|
int jump;
|
||
|
union{
|
||
|
Text *at;
|
||
|
Rune *ar;
|
||
|
} u;
|
||
|
int (*agetc)(void*, uint);
|
||
|
int a0;
|
||
|
int a1;
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
/* fbufalloc() guarantees room off end of BUFSIZE */
|
||
|
BUFSIZE = Maxblock+IOHDRSZ, /* size from fbufalloc() */
|
||
|
RBUFSIZE = BUFSIZE/sizeof(Rune),
|
||
|
EVENTSIZE = 256,
|
||
|
};
|
||
|
|
||
|
#define Scrollwid scalesize(display, 12)
|
||
|
#define Scrollgap scalesize(display, 4)
|
||
|
#define Margin scalesize(display, 4)
|
||
|
#define Border scalesize(display, 2)
|
||
|
#define ButtonBorder scalesize(display, 2)
|
||
|
|
||
|
#define QID(w,q) ((w<<8)|(q))
|
||
|
#define WIN(q) ((((ulong)(q).path)>>8) & 0xFFFFFF)
|
||
|
#define FILE(q) ((q).path & 0xFF)
|
||
|
|
||
|
#undef FALSE
|
||
|
#undef TRUE
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
FALSE,
|
||
|
TRUE,
|
||
|
XXX
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
Empty = 0,
|
||
|
Null = '-',
|
||
|
Delete = 'd',
|
||
|
Insert = 'i',
|
||
|
Replace = 'r',
|
||
|
Filename = 'f'
|
||
|
};
|
||
|
|
||
|
enum /* editing */
|
||
|
{
|
||
|
Inactive = 0,
|
||
|
Inserting,
|
||
|
Collecting
|
||
|
};
|
||
|
|
||
|
uint globalincref;
|
||
|
uint seq;
|
||
|
uint maxtab; /* size of a tab, in units of the '0' character */
|
||
|
|
||
|
Display *display;
|
||
|
Image *screen;
|
||
|
Font *font;
|
||
|
Mouse *mouse;
|
||
|
Mousectl *mousectl;
|
||
|
Keyboardctl *keyboardctl;
|
||
|
Reffont reffont;
|
||
|
Image *modbutton;
|
||
|
Image *colbutton;
|
||
|
Image *button;
|
||
|
Image *but2col;
|
||
|
Image *but3col;
|
||
|
Cursor boxcursor;
|
||
|
Cursor2 boxcursor2;
|
||
|
Row row;
|
||
|
int timerpid;
|
||
|
Disk *disk;
|
||
|
Text *seltext;
|
||
|
Text *argtext;
|
||
|
Text *mousetext; /* global because Text.close needs to clear it */
|
||
|
Text *typetext; /* global because Text.close needs to clear it */
|
||
|
Text *barttext; /* shared between mousetask and keyboardthread */
|
||
|
int bartflag;
|
||
|
int swapscrollbuttons;
|
||
|
Window *activewin;
|
||
|
Column *activecol;
|
||
|
Buffer snarfbuf;
|
||
|
Rectangle nullrect;
|
||
|
int fsyspid;
|
||
|
char *cputype;
|
||
|
char *objtype;
|
||
|
char *home;
|
||
|
char *acmeshell;
|
||
|
char *fontnames[2];
|
||
|
Image *tagcols[NCOL];
|
||
|
Image *textcols[NCOL];
|
||
|
extern char wdir[]; /* must use extern because no dimension given */
|
||
|
int editing;
|
||
|
int erroutfd;
|
||
|
int messagesize; /* negotiated in 9P version setup */
|
||
|
int globalautoindent;
|
||
|
int dodollarsigns;
|
||
|
char* mtpt;
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
Kscrolloneup = KF|0x20,
|
||
|
Kscrollonedown = KF|0x21
|
||
|
};
|
||
|
|
||
|
Channel *cplumb; /* chan(Plumbmsg*) */
|
||
|
Channel *cwait; /* chan(Waitmsg) */
|
||
|
Channel *ccommand; /* chan(Command*) */
|
||
|
Channel *ckill; /* chan(Rune*) */
|
||
|
Channel *cxfidalloc; /* chan(Xfid*) */
|
||
|
Channel *cxfidfree; /* chan(Xfid*) */
|
||
|
Channel *cnewwindow; /* chan(Channel*) */
|
||
|
Channel *mouseexit0; /* chan(int) */
|
||
|
Channel *mouseexit1; /* chan(int) */
|
||
|
Channel *cexit; /* chan(int) */
|
||
|
Channel *cerr; /* chan(char*) */
|
||
|
Channel *cedit; /* chan(int) */
|
||
|
Channel *cwarn; /* chan(void*)[1] (really chan(unit)[1]) */
|
||
|
|
||
|
QLock editoutlk;
|
||
|
|
||
|
#define STACK 65536
|