Exemplo n.º 1
0
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 ;
        }
    }
}
Exemplo n.º 2
0
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' ;
        }
    }
}
Exemplo n.º 3
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' ;
            }
        }
    }
}
Exemplo n.º 4
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 ;
    }
}
Exemplo n.º 5
0
void
meUndoAddInsChars(meInt numChars)
{
    meUndoNode *nn ;

    if(meModeTest(frameCur->bufferCur->mode,MDUNDO) &&
       ((nn = meUndoCreateNode(sizeof(meUndoNode))) != NULL))
    {
        nn->type |= meUNDO_INSERT ;
        nn->count = numChars ;
    }
}
Exemplo n.º 6
0
Arquivo: macro.c Projeto: collects/me
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 ;
}
Exemplo n.º 7
0
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 ;
}
Exemplo n.º 8
0
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 ;
    }
}
Exemplo n.º 9
0
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' ;
    }
}
Exemplo n.º 10
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++ ;
    }
}
Exemplo n.º 11
0
Arquivo: macro.c Projeto: collects/me
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 ;
}
Exemplo n.º 12
0
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 ;
}