void meUndoAddInsChar(void) { if(meModeTest(frameCur->bufferCur->mode,MDUNDO)) { meUByte type=meUNDO_SINGLE|meUNDO_INSERT ; meUndoNode *nn ; if(frameCur->bufferCur->undoContFlag == undoContFlag) type |= meUNDO_CONTINUE ; if(((nn = frameCur->bufferCur->undoHead) != NULL) && (nn->type == type) && (nn->udata.dotp == frameCur->windowCur->dotLineNo) && (nn->doto+1 == frameCur->windowCur->dotOffset)) { nn->doto++ ; nn->count++ ; frameCur->bufferCur->undoContFlag = undoContFlag ; } else if((nn = meUndoCreateNode(sizeof(meUndoNode))) != NULL) { nn->type |= meUNDO_SINGLE|meUNDO_INSERT ; nn->count = 1 ; } } }
void meUndoAddReplaceBgn(meLine *elinep, meUShort elineo) { if(meModeTest(frameCur->bufferCur->mode,MDUNDO)) { meUndoNode *nn ; int len ; if(elinep == frameCur->bufferCur->baseLine) { elinep = meLineGetPrev(elinep) ; elineo = meLineGetLength(elinep) ; } if(elinep == frameCur->windowCur->dotLine) len = elineo - frameCur->windowCur->dotOffset ; else { meLine *ll = frameCur->windowCur->dotLine ; len = meLineGetLength(ll) - frameCur->windowCur->dotOffset + elineo+1 ; while((ll = meLineGetNext(ll)) != elinep) len += meLineGetLength(ll)+1 ; } if((nn = meUndoCreateNode(sizeof(meUndoNode)+len)) != NULL) { meLine *ll = frameCur->windowCur->dotLine ; meUByte *dd=nn->str, *ss=ll->text+frameCur->windowCur->dotOffset ; nn->type |= meUNDO_DELETE ; /* This should be zero because added on the end call. */ nn->count = 0; if(elinep == frameCur->windowCur->dotLine) { for(; len ; len--) *dd++ = *ss++ ; } else { len = meLineGetLength(ll) - frameCur->windowCur->dotOffset ; for(; len ; len--) *dd++ = *ss++ ; *dd++ = meCHAR_NL ; while((ll = meLineGetNext(ll)) != elinep) { len = meLineGetLength(ll) ; ss = ll->text ; for(; len ; len--) *dd++ = *ss++ ; *dd++ = meCHAR_NL ; } ss = ll->text ; for(; elineo ; elineo--) *dd++ = *ss++ ; } *dd = '\0' ; } } }
void meUndoAddDelChar(void) { if(meModeTest(frameCur->bufferCur->mode,MDUNDO)) { meUByte type=meUNDO_SINGLE|meUNDO_DELETE ; meUndoNode *nn ; meUByte cc ; if((cc = frameCur->windowCur->dotLine->text[frameCur->windowCur->dotOffset]) == '\0') { if((frameCur->windowCur->dotLineNo == frameCur->bufferCur->lineCount-1) && (frameCur->windowCur->dotOffset)) /* This is trying to just remove the end line when the line * before is not empty, this will fail so don't store it */ return ; cc = meCHAR_NL ; } if(frameCur->bufferCur->undoContFlag == undoContFlag) type |= meUNDO_CONTINUE ; nn = frameCur->bufferCur->undoHead ; if((nn != NULL) && ((nn->type & ~meUNDO_FORWARD) == type) && (nn->udata.dotp == frameCur->windowCur->dotLineNo)) { if(!(nn->type & meUNDO_FORWARD) && (nn->doto == frameCur->windowCur->dotOffset)) ; else if(((nn->doto-1) == frameCur->windowCur->dotOffset) && (((nn->type & meUNDO_FORWARD) != 0) || (nn->count == 1))) { nn->doto-- ; nn->type |= meUNDO_FORWARD ; } else goto meUndoAddDelCharNew ; if(!(nn->count & 0x0f) && ((nn = meRealloc(nn,sizeof(meUndoNode)+nn->count+18)) == NULL)) return ; frameCur->bufferCur->undoHead = nn ; nn->str[nn->count++] = cc ; nn->str[nn->count] = '\0' ; frameCur->bufferCur->undoContFlag = undoContFlag ; } else { meUndoAddDelCharNew: if((nn = meUndoCreateNode(sizeof(meUndoNode)+18)) != NULL) { nn->type |= meUNDO_DELETE|meUNDO_SINGLE ; nn->count = 1 ; nn->str[0] = cc ; nn->str[1] = '\0' ; } } } }
void meUndoAddReplaceEnd(meInt numChars) { if(meModeTest(frameCur->bufferCur->mode,MDUNDO)) { frameCur->bufferCur->undoHead->udata.dotp = frameCur->windowCur->dotLineNo ; frameCur->bufferCur->undoHead->doto = frameCur->windowCur->dotOffset ; frameCur->bufferCur->undoHead->count = numChars ; frameCur->bufferCur->undoHead->type |= meUNDO_INSERT ; } }
void meUndoAddInsChars(meInt numChars) { meUndoNode *nn ; if(meModeTest(frameCur->bufferCur->mode,MDUNDO) && ((nn = meUndoCreateNode(sizeof(meUndoNode))) != NULL)) { nn->type |= meUNDO_INSERT ; nn->count = numChars ; } }
static int helpBufferLoad(meBuffer *hbp) { if(!meModeTest(hbp->mode,MDLOCK)) { meUByte fname[meBUF_SIZE_MAX] ; meModeSet(hbp->mode,MDLOCK) ; if(!fileLookup(helpFileName,NULL,meFL_CHECKDOT|meFL_USESRCHPATH,fname)) return mlwrite(MWABORT,(meUByte *)"[Help file \"%s\" is not on-line]",helpFileName); /* and read the stuff in */ meModeClear(hbp->mode,MDVIEW) ; ffReadFile(fname,meRWFLAG_SILENT,hbp,hbp->baseLine,0,0,0) ; helpBufferReset(hbp) ; } return true ; }
meInt * meUndoAddLineSort(meInt lineCount) { meUndoNode *nn ; meInt *lineSort ; if(meModeTest(frameCur->bufferCur->mode,MDUNDO) && ((nn = meUndoCreateNode(sizeof(meUndoNode))) != NULL) && ((lineSort = meMalloc((lineCount + 1) * sizeof(meInt))) != NULL)) { nn->type |= meUNDO_SPECIAL|meUNDO_LINE_SORT ; nn->count = lineCount ; nn->udata.lineSort = lineSort ; *lineSort++ = frameCur->windowCur->dotLineNo ; return lineSort ; } return NULL ; }
void meUndoAddReplace(meUByte *dstr, meInt count) { if(meModeTest(frameCur->bufferCur->mode,MDUNDO)) { meUndoCoord *co ; meUndoNode *nn ; int doto, contFlag ; contFlag = (frameCur->bufferCur->undoContFlag == undoContFlag) ; nn = frameCur->bufferCur->undoHead ; if((nn == NULL) || !meUndoIsReplace(nn) || (nn->count != count) || (nn->doto == 0xffff) || meStrcmp(nn->str,dstr)) { meUByte *dd ; if((nn = meUndoCreateNode(sizeof(meUndoNode)+meStrlen(dstr))) == NULL) return ; nn->type |= meUNDO_DELETE|meUNDO_INSERT|meUNDO_REPLACE ; nn->udata.pos = NULL ; nn->doto = 0 ; nn->count = count ; dd = nn->str ; while((*dd++ = *dstr++)) ; } /* replace is the same as last time */ if(!(nn->doto & 0x0f) && ((nn->udata.pos = meRealloc(nn->udata.pos,sizeof(meUndoCoord)* (nn->doto+16))) == NULL)) return ; co = nn->udata.pos ; doto = frameCur->windowCur->dotOffset ; if(contFlag) /* sub 1 of so 0 becomes less than 0 */ doto = -1 - doto ; co[nn->doto][0] = frameCur->windowCur->dotLineNo ; co[nn->doto++][1] = doto ; frameCur->bufferCur->undoContFlag = undoContFlag ; } }
void meUndoAddDelChars(meInt numChars) { meUndoNode *nn ; if(numChars < 0) numChars = 0 ; if(meModeTest(frameCur->bufferCur->mode,MDUNDO) && ((nn = meUndoCreateNode(sizeof(meUndoNode)+numChars)) != NULL)) { meLine *ll = frameCur->windowCur->dotLine ; int len ; meUByte *dd=nn->str, *ss=ll->text+frameCur->windowCur->dotOffset ; nn->type |= meUNDO_DELETE ; nn->count = 0; if((len = meLineGetLength(ll) - frameCur->windowCur->dotOffset) < numChars) { for(;;) { numChars-=len+1 ; for(; len ; len--) *dd++ = *ss++ ; ll = meLineGetNext(ll) ; ss = ll->text ; /* A bit of a bodge here to cope with the bogus last line * If the last but 1 line's '\n' is about to be removed * don't actually store the '\n' as this is automatically * added by the system */ if((numChars == 0) && (ll == frameCur->bufferCur->baseLine)) break ; *dd++ = meCHAR_NL ; if(numChars <= (len=meLineGetLength(ll))) break ; } } for(; numChars ; numChars--) *dd++ = *ss++ ; *dd = '\0' ; } }
void meUndoAddRepChar(void) { if(meModeTest(frameCur->bufferCur->mode,MDUNDO)) { meUByte type=meUNDO_SINGLE|meUNDO_INSERT|meUNDO_DELETE|meUNDO_FORWARD ; meUndoNode *nn ; meUByte cc ; if(frameCur->bufferCur->undoContFlag == undoContFlag) type |= meUNDO_CONTINUE ; if((cc = frameCur->windowCur->dotLine->text[frameCur->windowCur->dotOffset]) == '\0') cc = meCHAR_NL ; nn = frameCur->bufferCur->undoHead ; if((nn != NULL) && (nn->type == type) && (nn->udata.dotp == frameCur->windowCur->dotLineNo) && (nn->doto == frameCur->windowCur->dotOffset)) { if(!(nn->count & 0x0f) && ((nn = meRealloc(nn,sizeof(meUndoNode)+nn->count+18)) == NULL)) return ; frameCur->bufferCur->undoHead = nn ; nn->str[nn->count++] = cc ; nn->str[nn->count] = '\0' ; frameCur->bufferCur->undoContFlag = undoContFlag ; } else if((nn = meUndoCreateNode(sizeof(meUndoNode)+18)) != NULL) { nn->type |= meUNDO_DELETE|meUNDO_SINGLE|meUNDO_INSERT ; nn->count = 1 ; nn->str[0] = cc ; nn->str[1] = '\0' ; } nn->doto++ ; } }
static int findHelpItem(meUByte *item, int silent) { meWindow *wp ; meBuffer *bp, *hbp ; meLine *lp, *elp ; int sectLen, itemLen, ii ; meUByte *ss, cc, sect[5] ; itemLen = meStrlen(item) ; if((item[itemLen-1] == ')') && ((item[(ii=itemLen-3)] == '(') || (item[(ii=itemLen-4)] == '(') )) { sectLen = itemLen-ii-2 ; meStrcpy(sect,item+ii) ; itemLen = ii ; item[itemLen] = '\0' ; } else { sectLen = 0 ; sect[0] = '\0' ; sect[1] = '\0' ; } if((hbp=helpBufferFind()) == NULL) return meABORT ; elp = hbp->baseLine ; try_again: lp = meLineGetNext(elp) ; while(lp != elp) { if((lp->text[0] == '!') && (!sectLen || ((sect[1] == lp->text[2]) && (((sectLen == 1) && (lp->text[3] == ' ')) || (sect[2] == lp->text[3]))))) { if((cc=lp->text[1]) == ' ') { ii = meLineGetLength(lp) - 4 ; if(ii != itemLen) ii = -1 ; } else { ii = cc - '0' ; if(ii > itemLen) ii = -1 ; } if((ii > 0) && !meStrncmp(item,lp->text+4,ii)) break ; } lp = meLineGetNext(lp) ; } if(lp == elp) { meMacro *mac ; if(!meModeTest(hbp->mode,MDLOCK)) { if(helpBufferLoad(hbp) == meABORT) return meABORT ; goto try_again ; } if((getMacroTypeS(item) == TKCMD) && ((ii = decode_fncname(item,1)) >= CK_MAX) && ((mac = getMacro(ii)) != NULL) && (mac->hlp->flag & meMACRO_FILE)) { meModeClear(hbp->mode,MDVIEW) ; if(mac->fname != NULL) execFile(mac->fname,0,1) ; else execFile(mac->name,0,1) ; helpBufferReset(hbp) ; if(!(mac->hlp->flag & meMACRO_FILE)) goto try_again ; } if(!silent) mlwrite(MWABORT,(meUByte *)"[Can't find help on %s%s]",item,sect); return meABORT ; } if((wp = meWindowPopup(BhelpN,BFND_CREAT|BFND_CLEAR|WPOP_USESTR,NULL)) == NULL) return false ; if((sectLen == 0) && (lp->text[2] != ' ')) { ss = sect ; *ss++ = '(' ; *ss++ = lp->text[2] ; if(lp->text[3] != ' ') *ss++ = lp->text[3] ; *ss++ = ')' ; *ss = '\0' ; } bp = wp->buffer ; /* Add the header */ { meUByte buff[meBUF_SIZE_MAX] ; sprintf((char *)buff,"\033cD%s%s\033cA",lp->text+4,sect) ; addLineToEob(bp,buff) ; addLineToEob(bp,(meUByte *)"\n\033lsMicroEmacs\033lm[Home]\033le \033lsCommand G\033lm[Commands]\033le \033lsVariable \033lm[Variables]\033le \033lsMacro Lan\033lm[Macro-Dev]\033le \033lsGlobal G\033lm[Glossary]\033le") ; memset(buff,boxChars[BCEW],78) ; buff[78] = '\n' ; buff[79] = '\0' ; addLineToEob(bp,buff) ; } while(((lp=meLineGetNext(lp)) != elp) && (lp->text[0] == '!')) ; while((lp != elp) && ((cc=lp->text[0]) != '!')) { if(cc == '|') { if(meStrcmp(item,lp->text+1)) lp = meLineGetNext(lp) ; } else if(cc == '$') { if(lp->text[1] == 'a') { if(sect[1] == '5') { meUByte line[meBUF_SIZE_MAX], *ss ; if((ss = getval(item)) != NULL) { addLineToEob(bp,(meUByte *)"\n\n\033cEVALUE\033cA\n") ; meStrcpy(line," \"") ; meStrncpy(line+5,ss,meBUF_SIZE_MAX-13) ; line[meBUF_SIZE_MAX-2] = '\0' ; meStrcat(line,"\"") ; addLineToEob(bp,line) ; } } if(sect[1] == '2') { if((ii = decode_fncname(item,1)) >= 0) { meBind *ktp ; meUByte line[meBUF_SIZE_MAX], *ss ; addLineToEob(bp,(meUByte *)"\n\n\033cEBINDINGS\033cA\n") ; meStrcpy(line," ") ; ss = line+4 ; for(ktp = &keytab[0] ; ktp->code != ME_INVALID_KEY ; ktp++) { if(ktp->index == ii) { *ss++ = '"' ; meGetStringFromKey(ktp->code,ss); ss += meStrlen(ss) ; *ss++ = '"' ; *ss++ = ' ' ; } } if(ss == line+4) meStrcpy(ss,"none") ; else *ss = '\0' ; addLineToEob(bp,line) ; } } } } else addLineToEob(bp,lp->text) ; lp = meLineGetNext(lp) ; } /* Add the footer */ { meUByte buff[meBUF_SIZE_MAX] ; buff[0] = '\n' ; memset(buff+1,boxChars[BCEW],78) ; sprintf((char *)buff+79,"\n\033lsCopyright\033lm%s\033le",meCopyright) ; addLineToEob(bp,buff) ; } bp->dotLine = meLineGetNext(bp->baseLine); bp->dotOffset = 0 ; bp->dotLineNo = 0 ; meModeClear(bp->mode,MDEDIT) ; /* don't flag this as a change */ meModeSet(bp->mode,MDVIEW) ; /* put this buffer view mode */ resetBufferWindows(bp) ; /* Update the window */ mlerase(MWCLEXEC); /* clear the mode line */ return true ; }
int meUndo(int f, int n) { if(n < -1) { #ifndef NDEBUG if(n == -4) { meUndoNode *nn ; FILE *undoFp=NULL ; if(undoFp == NULL) undoFp = fopen("undo.log","w+") ; fprintf(undoFp,"[Undo stack for %s]\n",frameCur->bufferCur->name) ; nn=frameCur->bufferCur->undoHead ; while(nn != NULL) { if(meUndoIsLineSort(nn)) { fprintf(undoFp,"Undo 0x%02x %p %ld %ld:",nn->type,nn->next, nn->udata.lineSort[0],nn->count) ; for(n=0 ; n<nn->count ; n++) fprintf(undoFp," %ld",nn->udata.lineSort[n+1]) ; fprintf(undoFp,"\n") ; } #if MEOPT_NARROW else if(meUndoIsNarrow(nn)) { meUndoNarrow *nun = (meUndoNarrow *) nn ; fprintf(undoFp,"Undo 0x%02x %p Nrrw %x %ld %ld %d [%s]\n",nun->type,nun->next, nun->name,nun->count,nun->udata.dotp,nun->markupCmd,nun->str) ; } #endif else { fprintf(undoFp,"Undo 0x%02x %p %ld (%ld,%d) [%s]\n",nn->type,nn->next,nn->count, nn->udata.dotp,nn->doto,nn->str) ; if(meUndoIsReplace(nn)) { for(n=0 ; n<nn->doto ; n++) fprintf(undoFp,"(%d,%d) ",nn->udata.pos[n][0],nn->udata.pos[n][1]) ; fprintf(undoFp,"\n") ; } } nn = nn->next ; } fprintf(undoFp,"---------------\n") ; fflush(undoFp) ; } else #endif undoContFlag++ ; } else if(!meModeTest(frameCur->bufferCur->mode,MDUNDO)) return ctrlg(meFALSE,1) ; else if(n < 0) meUndoRemove(frameCur->bufferCur) ; else { static meUndoNode *cun ; static meInt ccount ; static meUShort cdoto ; if((lastflag != meCFUNDO) && ((cun = frameCur->bufferCur->undoHead) != NULL)) { cdoto = cun->doto ; ccount = cun->count ; } for(;;) { meInt count, cont ; if((cun == NULL) || ((n <= 0) && !meModeTest(frameCur->bufferCur->mode,MDEDIT))) break ; if(bufferSetEdit() <= 0) /* Check we can change the buffer */ return meABORT ; cont=0 ; if(cun->type & meUNDO_SPECIAL) { if(meUndoIsSetEdit(cun)) { if(!(cun->type & meUNDO_UNSET_EDIT)) { autowriteremove(frameCur->bufferCur) ; meModeClear(frameCur->bufferCur->mode,MDEDIT) ; frameAddModeToWindows(WFMODE) ; /* update ALL mode lines */ } } else if(meUndoIsLineSort(cun)) { meLine *ln, *eln, **list ; meInt *lineSort, *undoInfo, dddd ; lineSort = cun->udata.lineSort ; windowGotoLine(meTRUE,(*lineSort++) + 1) ; if((list = meMalloc(cun->count * sizeof(meLine *))) == NULL) return meABORT ; undoInfo = meUndoAddLineSort(cun->count) ; eln = frameCur->windowCur->dotLine ; ln = meLineGetPrev(eln) ; for(count=0 ; count<cun->count ; eln=meLineGetNext(eln),count++) { list[*lineSort++] = eln ; eln->prev = (meLine *) count ; } for(count=0 ; count<cun->count ; ln=meLineGetNext(ln),count++) { if(undoInfo != NULL) { dddd = (meInt) list[count]->prev ; *undoInfo++ = dddd ; } ln->next = list[count] ; list[count]->prev = ln ; } ln->next = eln ; eln->prev = ln ; frameCur->windowCur->dotLine = list[0] ; meFree(list) ; } #if MEOPT_NARROW else if(meUndoIsNarrow(cun)) { meUndoNarrow *nun = (meUndoNarrow *) cun ; meInt name ; name = nun->name ; windowGotoLine(meTRUE,nun->udata.dotp+1) ; if(nun->type & meUNDO_NARROW_ADD) { meNarrow *nrrw ; nrrw = frameCur->bufferCur->narrow ; while(nrrw->name != name) nrrw = nrrw->next ; frameCur->bufferCur->dotLine = frameCur->windowCur->dotLine ; frameCur->bufferCur->dotLineNo = frameCur->windowCur->dotLineNo ; frameCur->bufferCur->dotOffset = 0 ; meBufferRemoveNarrow(frameCur->bufferCur,nrrw, (nun->markupCmd > 0) ? nun->str:NULL,1) ; } else { meLine *slp ; slp = frameCur->windowCur->dotLine ; windowGotoLine(meTRUE,ccount+1) ; meBufferCreateNarrow(frameCur->bufferCur,slp,frameCur->windowCur->dotLine, nun->udata.dotp,ccount,name,nun->scheme, (nun->markupFlag) ? nun->str:NULL,nun->markupCmd,1) ; } } #endif if(cun->type & meUNDO_CONTINUE) cont=1 ; goto meUndoNext ; } if(cun->type & meUNDO_REPLACE) { windowGotoLine(meTRUE,cun->udata.pos[cdoto-1][0]+1) ; count = cun->udata.pos[cdoto-1][1] ; if(count < 0) { cont = 1 ; count = -1 - count ; } frameCur->windowCur->dotOffset = (meUShort) count ; } else { if(cun->type & meUNDO_CONTINUE) cont = 1 ; windowGotoLine(meTRUE,cun->udata.dotp+1) ; frameCur->windowCur->dotOffset = cdoto ; } if(cun->type & meUNDO_SINGLE) { ccount-- ; count = 1 ; } else count = ccount ; if(cun->type & meUNDO_INSERT) { meWindowBackwardChar(frameCur->windowCur,count) ; if((count == 1)) meUndoAddDelChar() ; else meUndoAddDelChars(count) ; mldelete(count,NULL) ; } if(cun->type & meUNDO_DELETE) { /* When dealing with long lines this loop becomes infinitly * long because of the number of times that the line is * re-allocated - pre-allocate the line length first. In order * to reduce the processing overhead then we find the longest * strings and then add them back in in one go, this ensures * that we only ever re-allocate the line once. * Jon - 99/12/12. */ meUByte *ss, cc ; ss = cun->str ; /* Deal with a single character undo */ if(cun->type & meUNDO_SINGLE) { ss += ccount ; if((cc = *ss++) == meCHAR_NL) lineInsertNewline(meBUFINSFLAG_UNDOCALL); else if (cc != '\0') lineInsertChar(1, cc); meUndoAddInsChar() ; } else { /* Deal with a multiple character undo. */ count = bufferInsertText(ss,meBUFINSFLAG_UNDOCALL) ; if(count > 0) meUndoAddInsChars(count) ; } } if((cun->type & meUNDO_SINGLE) && (ccount > 0)) { if(cun->type & meUNDO_FORWARD) cdoto++ ; else if(cun->type & meUNDO_INSERT) cdoto-- ; } else if(cun->type & meUNDO_REPLACE) { cdoto-- ; if(!cdoto) goto meUndoNext ; } else { meUndoNext: if((cun = cun->next) != NULL) { cdoto = cun->doto ; ccount = cun->count ; } } if(!cont && (--n == 0)) break ; } thisflag = meCFUNDO ; } return meTRUE ; }