use the acme ctl file ismodified field instead of maintaining our own dirtied variable. When the user tries to Get a modified file, we do remember if we have warned already, and reset that information in the same places where we used to set the dirtied variable. this patch includes the acme-wiki-filemenu-in-tag patch (the change in wiki.c around 441c445,447) which depends on acme-enable-menu-via-ctl , and the acme-wiki-fix-dirtystate patch (ignore writes to body or tag; winclean after setting file name and tag commands). Axel. Reference: /n/sources/patch/applied/acme-wiki-use-winismodified Date: Mon Aug 15 14:58:49 CES 2005 --- /acme/wiki/src/awiki.h Mon Aug 15 14:36:26 2005 +++ /acme/wiki/src/awiki.h Mon Aug 15 14:36:23 2005 @@ -42,7 +42,7 @@ int nbuf; Event e[NEVENT]; - int dirtied; + int warned; int id; int open; Channel *cevent; /* chan(Event*) */ @@ -61,6 +61,7 @@ extern void wineventproc(void*); extern void winwritebody(Window*, char*, int); extern void winclean(Window*); +extern int winisdirty(Window*); extern int winselect(Window*, char*, int); extern int winsetaddr(Window*, char*, int); extern char* winreadbody(Window*, int*); --- /acme/wiki/src/wiki.c Mon Aug 15 14:36:40 2005 +++ /acme/wiki/src/wiki.c Mon Aug 15 14:36:36 2005 @@ -249,11 +249,13 @@ if(iscmd(s, "Diff")) return wikidiff(w); if(iscmd(s, "Get")){ - if(w->win->dirtied){ - w->win->dirtied = 0; + if(winisdirty(w->win) && !w->win->warned){ + w->win->warned = 1; fprint(2, "%s/%s modified\n", dir, w->arg); - }else + }else{ + w->win->warned = 0; wikiget(w); + } return 1; } if(iscmd(s, "Put")){ @@ -343,9 +345,11 @@ break; case 'E': /* write to body or tag; can't affect us */ + break; + case 'K': /* type away; we don't care */ if(e->c2 == 'I' || e->c2 == 'D') - w->dirtied = 1; + w->warned = 0; break; case 'M': /* mouse event */ @@ -406,7 +410,7 @@ case 'I': /* mouse: text inserted in body */ case 'D': /* mouse: text deleted from body */ - w->dirtied = 1; + w->warned = 0; break; default: @@ -438,7 +442,9 @@ if(w->addr) winselect(w->win, w->addr, 1); } - wintagwrite(w->win, "Get Put History Diff New", 4+4+8+4+4); + fprint(w->win->ctl, "menu\n"); + wintagwrite(w->win, "Get History Diff New", 4+8+4+4); + winclean(w->win); while(!w->dead && (e = recvp(w->win->cevent))) acmeevent(w, e); --- /acme/wiki/src/win.c Mon Aug 15 14:36:56 2005 +++ /acme/wiki/src/win.c Mon Aug 15 14:36:53 2005 @@ -269,6 +269,27 @@ } int +winisdirty(Window *w) +{ + char m; + + if (seek(w->ctl, 4*(11+1) + 10, 0) < 0) + error("control file seek error: %r"); + + if(read(w->ctl, &m, 1) != 1) + error("control file read error: %r"); + + if (m == '0') + return 0; + else if (m == '1') + return 1; + else + error("can't parse ismodified field: %c", m); + return 1; // better safe than sorry + +} + +int winsetaddr(Window *w, char *addr, int errok) { if(w->addr < 0)