コード例 #1
0
ファイル: undo.c プロジェクト: Russtopia/microemacs
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' ;
        }
    }
}
コード例 #2
0
ファイル: macro.c プロジェクト: collects/me
int
insMacro(int f, int n)
{
    meWindow          *wp ;
    register meLine   *lp, *slp ;
    meMacro         *mac ;
    meUByte            buf[meBUF_SIZE_MAX] ;
    meInt            nol, lineNo, len ;
    int              ii ;
    
    meStrcpy(buf,"define-macro ") ;
    if((mac=userGetMacro(buf+13, meBUF_SIZE_MAX-13)) == NULL)
        return false ;
    
    if((ii=bufferSetEdit()) <= 0)               /* Check we can change the buffer */
        return ii ;
    frameCur->windowCur->dotOffset = 0 ;
    slp = frameCur->windowCur->dotLine ;
    lineNo = frameCur->windowCur->dotLineNo ;
    nol = addLine(slp,buf) ;
    len = meStrlen(buf) + 9 ;
    lp = meLineGetNext(mac->hlp);            /* First line.          */
    while (lp != mac->hlp)
    {
        nol += addLine(slp,lp->text) ;
        len += meLineGetLength(lp) + 1 ;
        lp = meLineGetNext(lp);
    }
    nol += addLine(slp,(meUByte *)"!emacro") ;
    frameCur->bufferCur->lineCount += nol ;
    meFrameLoopBegin() ;
    for (wp=loopFrame->windowList; wp!=NULL; wp=wp->next)
    {
        if (wp->buffer == frameCur->bufferCur)
        {
            if(wp->dotLineNo >= lineNo)
                wp->dotLineNo += nol ;
            if(wp->markLineNo >= lineNo)
                wp->markLineNo += nol ;
            wp->updateFlags |= WFMAIN|WFMOVEL ;
        }
    }
    meFrameLoopEnd() ;
#if MEOPT_UNDO
    meUndoAddInsChars(len) ;
#endif
    return true ;
}
コード例 #3
0
ファイル: macro.c プロジェクト: collects/me
/* macroHelpDefine:
 * Set up a macro help definition
 */
int
macroHelpDefine(int f, int n)
{
    meUByte name[meBUF_SIZE_MAX] ;
    meUByte sect[20] ;
    
    if((lpStoreBp=helpBufferFind()) == NULL)
        return meABORT ;
    if(meGetString((meUByte *)"Enter name", MLCOMMAND, 0, name+4, meBUF_SIZE_MAX-4) <= 0)
        return false ;
    sect[0] = '\0' ;
    if(meGetString((meUByte *)"Enter section", 0, 0, sect, 20) == meABORT)
        return false ;
    /* and set the macro store pointers to it */
    lpStore = meLineGetNext(lpStoreBp->baseLine) ;
    name[0] = '!' ;
    name[1] = (f) ? '0'+n:' ' ;
    if(sect[0] == '\0')
    {
        name[2] = ' ' ; 
        name[3] = ' ' ; 
    }
    else
    {
        name[2] = sect[0] ; 
        name[3] = (sect[1] == '\0') ? ' ':sect[1] ;
    }
    addLine(lpStore,name) ;
    lpStoreBp->lineCount++ ;
    mcStore = 2 ;
    return true ;
}
コード例 #4
0
ファイル: macro.c プロジェクト: collects/me
void 
helpBufferReset(meBuffer *bp)
{
    meModeClear(bp->mode,MDEDIT) ;
    meModeSet(bp->mode,MDVIEW) ;
    bp->dotLine = meLineGetNext(bp->baseLine) ;
    bp->dotOffset = 0 ;
    bp->dotLineNo = 0 ;
    bp->vertScroll = 0 ;
    bp->markLine = NULL ;
    resetBufferWindows(bp) ;
}
コード例 #5
0
ファイル: region.c プロジェクト: Russtopia/microemacs
/*
 * This routine figures out the
 * bounds of the region in the current window, and
 * fills in the fields of the "meRegion" structure pointed
 * to by "rp". Because the dot and mark are usually very
 * close together, we scan outward from dot looking for
 * mark. This should save time. Return a standard code.
 * Callers of this routine should be prepared to get
 * an "meABORT" status; we might make this have the
 * conform thing later.
 */
int
getregion(register meRegion *rp)
{
    meLine *lp, *elp;
    long  size;
    
    if (frameCur->windowCur->markLine == NULL)
        return noMarkSet() ;
    if(frameCur->windowCur->dotLine == frameCur->windowCur->markLine)
    {
        rp->line = frameCur->windowCur->dotLine;
        if (frameCur->windowCur->dotOffset < frameCur->windowCur->markOffset) 
        {
            rp->offset = frameCur->windowCur->dotOffset;
            rp->size = (long)(frameCur->windowCur->markOffset-frameCur->windowCur->dotOffset);
        }
        else
        {
            rp->offset = frameCur->windowCur->markOffset;
            rp->size = (long)(frameCur->windowCur->dotOffset-frameCur->windowCur->markOffset);
        }
        rp->lineNo = frameCur->windowCur->dotLineNo;
        return meTRUE ;
    }
    if(frameCur->windowCur->dotLineNo < frameCur->windowCur->markLineNo)
    {
        elp = frameCur->windowCur->markLine ;
        lp = frameCur->windowCur->dotLine ;
        rp->lineNo = frameCur->windowCur->dotLineNo ;
        rp->offset = frameCur->windowCur->dotOffset ;
        size = frameCur->windowCur->dotOffset ;
        size = frameCur->windowCur->markOffset + meLineGetLength(lp) - size -
                  frameCur->windowCur->dotLineNo + frameCur->windowCur->markLineNo ;
    }
    else
    {
        elp = frameCur->windowCur->dotLine ;
        lp = frameCur->windowCur->markLine ;
        rp->lineNo = frameCur->windowCur->markLineNo ;
        rp->offset = frameCur->windowCur->markOffset ;
        size = frameCur->windowCur->markOffset ;
        size = frameCur->windowCur->dotOffset + meLineGetLength(lp) - size +
                  frameCur->windowCur->dotLineNo - frameCur->windowCur->markLineNo ;
    }
    rp->line = lp ;
    while((lp=meLineGetNext(lp)) != elp)
        size += meLineGetLength(lp) ;
    rp->size = size ;
    return meTRUE ;
}
コード例 #6
0
ファイル: region.c プロジェクト: Russtopia/microemacs
/*
 * Upper case region. Zap all of the lower
 * case characters in the region to upper case. Use
 * the region code to set the limits. Scan the buffer,
 * doing the changes. Call "lineSetChanged" to ensure that
 * redisplay is done in all buffers. Bound to
 * "C-X C-U".
 */
int
upperRegion(int f, int n)
{
    meLine *line ;
    int   loffs ;
    long  lline ;
    register char  c;
    register int   s;
    meRegion         region;
    
    if((s=getregion(&region)) <= 0)
        return (s);
    if((s=bufferSetEdit()) <= 0)               /* Check we can change the buffer */
        return s ;
    line = frameCur->windowCur->dotLine ;
    loffs = frameCur->windowCur->dotOffset ;
    lline = frameCur->windowCur->dotLineNo ;
    frameCur->windowCur->dotLine = region.line ;
    frameCur->windowCur->dotOffset = region.offset ;
    frameCur->windowCur->dotLineNo = region.lineNo ;
    while (region.size--)
    {
        if((c = meLineGetChar(frameCur->windowCur->dotLine, frameCur->windowCur->dotOffset)) == '\0')
        {
            frameCur->windowCur->dotLine = meLineGetNext(frameCur->windowCur->dotLine);
            frameCur->windowCur->dotOffset = 0;
            frameCur->windowCur->dotLineNo++ ;
        }
        else
        {
            if(isLower(c))
            {
                lineSetChanged(WFMAIN);
#if MEOPT_UNDO
                meUndoAddRepChar() ;
#endif
                c = toggleCase(c) ;
                meLineSetChar(frameCur->windowCur->dotLine, frameCur->windowCur->dotOffset, c);
            }
            (frameCur->windowCur->dotOffset)++ ;
        }
    }
    frameCur->windowCur->dotLine = line ;
    frameCur->windowCur->dotOffset = loffs ;
    frameCur->windowCur->dotLineNo = lline ;
    return meTRUE ;
}
コード例 #7
0
ファイル: undo.c プロジェクト: Russtopia/microemacs
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' ;
    }
}
コード例 #8
0
ファイル: region.c プロジェクト: Russtopia/microemacs
static int
yankRectangleKill(struct meKill *pklist, int soff, int notLast)
{
    meUByte *off, *ss, *tt, *dd=NULL, cc ;
    int ii, jj, kk, lsspc, lespc, ldel, linsc, coff ;
    meKillNode *killp ;
    
    killp = pklist->kill ;
    while (killp != NULL)
    {
        ss = killp->data ;
        while(*ss != '\0')
        {
            tt = ss ;
            while(((cc = *ss) != '\0') && (cc != meCHAR_NL))
                ss++ ;
            ii = (size_t) ss - (size_t) tt ;
            windCurLineOffsetEval(frameCur->windowCur) ;
            off = frameCur->windowCur->dotCharOffset->text ;
            ldel = lsspc = lespc = 0 ;
            coff = 0 ;
            jj = 0 ;
            kk = frameCur->windowCur->dotLine->length ;
            while(jj < kk)
            {
                if(coff == soff)
                    break ;
                if((coff+off[jj]) > soff)
                {
                    /* if its a tab we can remove the tab and replace with spaces */
                    if(meLineGetChar(frameCur->windowCur->dotLine,jj) == meCHAR_TAB)
                    {
                        ldel = 1 ;
                        lespc = off[jj] - soff + coff ;
                    }
                    break ;
                }
                coff += off[jj++] ;
            }
            lsspc = soff - coff ;
            linsc = ii + lsspc + lespc - ldel ;
            frameCur->windowCur->dotOffset = jj ;
            /* Make space for the characters */
            if((dd = lineMakeSpace(linsc)) == NULL)
                return meABORT ;
            lineSetChanged(WFMOVEC|WFMAIN) ;
#if MEOPT_UNDO
            if(ldel > 0)
            {
                *dd = meCHAR_TAB ;
                frameCur->windowCur->dotOffset = jj ;
                meUndoAddDelChars(ldel) ;
            }
#endif
            /* add the starting spaces */
            while(--lsspc >= 0)
                *dd++ = ' ' ;
            while(--ii >= 0)
                *dd++ = *tt++ ;
            /* add the ending spaces (only if we've deleted a TAB),
             * preserve dd so the end point is correct */
            tt = dd ;
            while(--lespc >= 0)
                *tt++ = ' ' ;
#if MEOPT_UNDO
            if(ldel > 0)
            {
                frameCur->windowCur->dotOffset += linsc+ldel ;
                meUndoAddReplaceEnd(linsc+ldel) ;
            }
            else
                meUndoAddInsChars(linsc) ;
#endif
            if(*ss == meCHAR_NL)
                ss++ ;
            frameCur->windowCur->dotLineNo++ ;
            frameCur->windowCur->dotLine  = meLineGetNext(frameCur->windowCur->dotLine);
            frameCur->windowCur->dotOffset  = 0;
        }
        killp = killp->next;
    }
    if((dd != NULL) && !notLast)
    {
        frameCur->windowCur->dotLineNo-- ;
        frameCur->windowCur->dotLine = meLineGetPrev(frameCur->windowCur->dotLine);
        frameCur->windowCur->dotOffset = ((size_t) dd - (size_t) meLineGetText(frameCur->windowCur->dotLine)) ;
    }
    return meTRUE ;
}
コード例 #9
0
ファイル: region.c プロジェクト: Russtopia/microemacs
int
killRectangle(int f, int n)
{
    meUByte *kstr ;
    meInt slno, elno, size ;
    int soff, eoff, coff, llen, dotPos ;
    
    if (frameCur->windowCur->markLine == NULL)
        return noMarkSet() ;
    if(frameCur->windowCur->dotLine == frameCur->windowCur->markLine)
        return killRegion(f,n) ;
    if(bufferSetEdit() <= 0)               /* Check we can change the buffer */
        return meFALSE ;
    
    eoff = getcwcol() ;
    /* remember we have swapped */
    windowSwapDotAndMark(0,1) ;
    soff = getcwcol() ;
    if(soff > eoff)
    {
        llen = eoff ;
        eoff = soff ;
        soff = llen ;
    }
    llen = eoff - soff ;
    if((dotPos=frameCur->windowCur->dotLineNo > frameCur->windowCur->markLineNo))
        windowSwapDotAndMark(0,1) ;
    slno = frameCur->windowCur->dotLineNo ;
    elno = frameCur->windowCur->markLineNo ;
    /* calculate the maximum length */
    size = (elno - slno + 1) * (llen + 1) ;
    
    /* sort out the kill buffer */
    if((lastflag != meCFKILL) && (thisflag != meCFKILL))
        killSave();
    if((kstr = killAddNode(size)) == NULL)
        return meFALSE ;
    thisflag = meCFKILL;
    for(;;)
    {
        meUByte *off, cc ;
        int lspc=0, ii, jj, kk, ll ;
        
        windCurLineOffsetEval(frameCur->windowCur) ;
        off = frameCur->windowCur->dotCharOffset->text ;
        coff = 0 ;
        ii = 0 ;
        kk = frameCur->windowCur->dotLine->length ;
        while(ii < kk)
        {
            if(coff == soff)
                break ;
            if((coff+off[ii]) > soff)
            {
                lspc = soff - coff ;
                /* as we can convert tabs to spaces, adjust the offset */
                if(meLineGetChar(frameCur->windowCur->dotLine,ii) == meCHAR_TAB)
                    off[ii] -= lspc ;
                coff = soff ;
                break ;
            }
            coff += off[ii++] ;
        }
        jj = ii ;
        if(coff < soff)
        {
            /* line too short to even get to the start point */
            lspc = soff - coff ;
            memset(kstr,' ',llen) ;
            kstr += llen ;
        }
        else
        {
            while(jj < kk)
            {
                if(coff == eoff)
                    break ;
                if((ll = off[jj]) != 0)
                {
                    cc = meLineGetChar(frameCur->windowCur->dotLine,jj) ;
                    if((coff+ll) > eoff)
                    {
                        /* as we can convert tabs to spaces, delete and convert */
                        if(cc == meCHAR_TAB)
                        {
                            lspc += coff + ll - eoff ;
                            jj++ ;
                        }
                        break ;
                    }
                    coff += ll ;
                    if(cc == meCHAR_TAB)
                    {
                        /* convert tabs to spaces for better column support */
                        do
                            *kstr++ = ' ' ;
                        while(--ll > 0) ;
                    }
                    else
                        *kstr++ = cc ;
                }
                jj++ ;
            }
            if(coff < eoff)
            {
                /* line too short to get to the end point, fill with spaces */
                coff = eoff - coff ;
                memset(kstr,' ',coff) ;
                kstr += coff ;
            }
            
        }
        *kstr++ = '\n' ;
        frameCur->windowCur->dotOffset = ii ;
        if((jj -= ii) > 0)
        {
#if MEOPT_UNDO
            meUndoAddDelChars(jj) ;
#endif
            mldelete(jj,NULL) ;
        }
        if(lspc)
        {
            if(lineInsertChar(lspc,' ') <= 0)
            {
                *kstr = '\0' ;
                return meFALSE ;
            }
#if MEOPT_UNDO
            if(jj > 0)
                meUndoAddReplaceEnd(lspc) ;
            else
                meUndoAddInsChars(lspc) ;
#endif
        }
        if(frameCur->windowCur->dotLineNo == elno)
            break ;
        /* move on to the next line */
        frameCur->windowCur->dotLineNo++ ;
        frameCur->windowCur->dotLine  = meLineGetNext(frameCur->windowCur->dotLine);
        frameCur->windowCur->dotOffset  = 0;
    }
    *kstr = '\0' ;
    if(dotPos)
        windowSwapDotAndMark(0,1) ;
    return meTRUE ;
}
コード例 #10
0
ファイル: region.c プロジェクト: Russtopia/microemacs
/*
 * Copy all of the characters in the
 * region to the kill buffer. Don't move dot
 * at all. This is a bit like a kill region followed
 * by a yank. Bound to "M-W".
 */
int	
copyRegion(int f, int n)
{
    meRegion region ;
    meLine *line;
    meUByte  *ss, *dd ;
    meInt left, ii, ret ;
#if MEOPT_NARROW
    meUShort eoffset ;
    meLine *markLine, *dotLine, *elp ;
    meInt markLineNo, dotLineNo, expandNarrows=meFALSE ;
    meUShort markOffset, dotOffset ;
#endif
    
    if(getregion(&region) <= 0)
        return meFALSE ;
    left = region.size ;
    line = region.line ;
#if MEOPT_NARROW
    if((n & 0x01) && (frameCur->bufferCur->narrow != NULL) &&
       (frameCur->windowCur->dotLine != frameCur->windowCur->markLine))
    {
        /* expand narrows that are within the region */
        expandNarrows = meTRUE ;
        dotLine = frameCur->windowCur->dotLine ;
        dotLineNo = frameCur->windowCur->dotLineNo ;
        dotOffset = frameCur->windowCur->dotOffset ;
        markLine = frameCur->windowCur->markLine ;
        markLineNo = frameCur->windowCur->markLineNo ;
        markOffset = frameCur->windowCur->markOffset ;
        if(line == dotLine)
        {
            elp = markLine ;
            eoffset = markOffset ;
        }
        else
        {
            elp = dotLine ;
            eoffset = dotOffset ;
        }
        left += meBufferRegionExpandNarrow(frameCur->bufferCur,&line,region.offset,elp,eoffset,0) ;
        if(((frameCur->windowCur->dotLine != dotLine) && dotOffset) ||
           ((frameCur->windowCur->markLine != markLine) && markOffset))
        {
            ret = mlwrite(MWABORT,(meUByte *)"[Bad region definition]") ;
            goto copy_region_exit ;
        }
    }
#endif
    if(lastflag != meCFKILL)                /* Kill type command.   */
        killSave();
    if(left == 0)
    {
        thisflag = meCFKILL ;
        ret =  meTRUE ;
        goto copy_region_exit ;
    }
    
    if((dd = killAddNode(left)) == NULL)
    {
        ret = meFALSE ;
        goto copy_region_exit ;
    }
    if((ii = region.offset) == meLineGetLength(line))
        goto add_newline ;                 /* Current offset.      */
    ss = line->text+ii ;
    ii = meLineGetLength(line) - ii ;
    goto copy_middle ;
    while(left)
    {
        ss = line->text ;
        ii = meLineGetLength(line) ;
copy_middle:
        /* Middle of line.      */
        if(ii > left)
        {
            ii = left ;
            left = 0 ;
        }
        else
            left -= ii ;
        while(ii--)
            *dd++ = *ss++ ;
add_newline:
        if(left != 0)
        {
            *dd++ = meCHAR_NL ;
            line = meLineGetNext(line);
            left-- ;
        }
    }
    thisflag = meCFKILL ;
    ret = meTRUE ;

copy_region_exit:

#if MEOPT_NARROW
    if(expandNarrows)
    {
        meBufferCollapseNarrowAll(frameCur->bufferCur) ;
        frameCur->windowCur->dotLine = dotLine ;
        frameCur->windowCur->dotLineNo = dotLineNo ;
        frameCur->windowCur->dotOffset = dotOffset ;
        frameCur->windowCur->markLine = markLine ;
        frameCur->windowCur->markLineNo = markLineNo ;
        frameCur->windowCur->markOffset = markOffset ;
    }
#endif
    return ret ;
}
コード例 #11
0
ファイル: macro.c プロジェクト: 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 ;
}
コード例 #12
0
ファイル: undo.c プロジェクト: Russtopia/microemacs
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 ;
}
コード例 #13
0
ファイル: registry.c プロジェクト: alepharchives/ordoemacs
/*
 * Parse the file and import into the registry.
 */
static void
parseFile(meRegNode *rnp, meLine *hlp)
{
    meLine  *lp;                          /* Current line pointer */
    meRegNode *cnp;                         /* Current node pointer */
    meRegNode *lnp;                         /* Last node pointer */
    meUByte *lsp;                         /* Current line string pointer */
    meUByte  buf [meTOKENBUF_SIZE_MAX];              /* Local parse buffer */
    int level = 0;                      /* Nesting depth */
    int needValue = 0;                  /* Need a value flag */

    cnp = rnp;                          /* Current node pointer */
    lnp = NULL;                         /* No last node pointer */
    lp = meLineGetNext(hlp) ;                   /* Initial line pointer */
    lsp = lp->text ;                  /* Initial line string pointer */
    lineNo = 1;                         /* Initial line number */
    
    /* Read in the file until all processed. */
    while (lp != hlp)
    {
        lsp = token(lsp,buf) ;
        switch (buf[0])
        {
        case '\0':
            /* end of line, move to next */
        case ';':
            /* comment to the end of line, move to next */
            lp = meLineGetNext(lp) ;                   /* Initial line pointer */
            lsp = lp->text ;                 /* Initial line string pointer */
            lineNo++ ;                         /* Initial line number */
            break ;
            
        case '"':
            if (needValue)
            {
                /* Link the value to the name */
                meStrrep(&lnp->value,buf+1) ;
                needValue = 0;
            }
            else
            {
                /* Allocate a new node and link to the tree */
                if ((lnp = rnodeFind (cnp,buf+1)) == NULL)
                {
                    if ((lnp = rnodeNew (buf+1)) != NULL)
                        rnodeLink (cnp, lnp);
                }
            }
            break;
        
        case '{':
            if ((lnp == NULL) || needValue)
            {
                mlwrite(MWWAIT,(meUByte *)"[Registry error: unexpected '{' %s:%d]",
                        rnp->value, lineNo);
                return ;
            }
            level++;
            cnp = lnp;
            lnp = NULL;
            break;
        case '}':
            if(needValue || (level <= 0))
            {
                mlwrite(MWWAIT,(meUByte *)"[Registry error: mismatched '}' %s:%d]",
                        rnp->value, lineNo);
                return ;
            }
            cnp = cnp->parent;        /* Back up a level */
            lnp = NULL;
            level--;
            break;
        case '=':
            if(needValue || (lnp == NULL))
            {
                mlwrite(MWWAIT,(meUByte *)"[Registry error: expected <name>=<value> %s:%d]",
                        rnp->value, lineNo);
                return ;
            }
            needValue = 1;
            break;
        default:
            if(!isDigit(buf[0]) || needValue || (lnp == NULL))
            {
                mlwrite(MWWAIT,(meUByte *)"[Registry error: unexpected token \"%s\":%d]",
                        buf,lineNo);
                return ;
            }
            lnp->mode |= meAtoi(buf) ;
        }
    }

    /* End of file. Check for unmatched braces. */
    if (level > 0)
        mlwrite(MWWAIT,(meUByte *)"[Registry error: mismatched '}' at EOF. %d levels open %s:%d]",
                level, rnp->value, lineNo);
}
コード例 #14
0
ファイル: registry.c プロジェクト: alepharchives/ordoemacs
/*
 * listRegistry
 * List the contents of the registry.
 */
int
listRegistry (int f, int n)
{
    meBuffer *bp;                         /* Buffer pointer */
    meWindow *wp;                         /* Window associated with buffer */
    meRegNode *rnp, *cnp, *nnp ;          /* Draw the nodes */
    meUByte vstrbuf [meBUF_SIZE_MAX];     /* Vertical string buffer */
    meUByte *bn, buf[meBUF_SIZE_MAX*2];   /* Working line buffer */
    int level = 0;                        /* Depth in the registry */
    int len;                              /* Length of the string */

    rnp = &root;
    if((n & 0x02) != 0)
    {
        if(meGetString((meUByte *)"Registry Path",0, 0, buf, meBUF_SIZE_MAX) == meABORT)
            return meABORT;

        /* Find the node */
        if((rnp = regFind(rnp,buf)) == NULL)
            return mlwrite(MWCLEXEC|MWABORT,(meUByte *)"[Cannot find node %s]",buf);
    }
    
    if((n & 0x01) == 0)
    {
        /* prompt for and get the new buffer name */
        if((len = getBufferName((meUByte *) "Buffer", 0, 0, buf)) <= 0)
            return len ;
        bn = buf ;
    }
    else
        bn = BregistryN ;
    
    /* Find the buffer and vapour the old one */
    if((wp = meWindowPopup(bn,BFND_CREAT|BFND_CLEAR|WPOP_USESTR,NULL)) == NULL)
        return meFALSE;
    bp = wp->buffer ;                   /* Point to the buffer */

    /* Recurse the children of the node and write to file */
    do
    {
        /* get the current node's first drawn child */
        cnp = rnp->child ;
        while((cnp != NULL) && (cnp->mode & meREGMODE_INVISIBLE))
            cnp = cnp->next ;

        /* get the current node's next drawn sibling */
        nnp = rnp->next ;
        while((nnp != NULL) && (nnp->mode & meREGMODE_INVISIBLE))
            nnp = nnp->next ;

        /* Add continuation bars if we are at a child level */
        if((len = level) != 0)
            meStrncpy (buf, vstrbuf, len);
        
        /* Add connection bars for siblings */
        if(level && (nnp != NULL))
            buf [len++] = boxChars[BCNES] ;
        else
            buf [len++] = boxChars[BCNE];
        
        /* Add continuation barss for children */
        if (rnp->mode & meREGMODE_INTERNAL)
            buf[len++] = '!';
        else if (cnp == NULL)
            buf[len++] = boxChars[BCEW];
        else if (rnp->mode & meREGMODE_HIDDEN)
            buf[len++] = '+';
        else
            buf[len++] = '-';
        buf[len++] = ' ';
        
        /* Add the name of the node */
        buf[len++] = '"';
        len = expandexp(-1,rnp->name,(meBUF_SIZE_MAX*2)-7,len,buf,-1,NULL,meEXPAND_BACKSLASH|meEXPAND_FFZERO) ;
        buf[len++] = '"';
        
        /* Add the value */
        if ((rnp->value != NULL) && !(rnp->mode & meREGMODE_INTERNAL))
        {
            buf[len++] = ' ';
            buf[len++] = '=';
            buf[len++] = ' ';
            buf[len++] = '"';
            len = expandexp(-1,rnp->value,(meBUF_SIZE_MAX*2)-2,len,buf,-1,NULL,meEXPAND_BACKSLASH|meEXPAND_FFZERO) ;
            buf[len++] = '"';
        }
        /* Add the string to the print buffer */
        buf[len] = '\0';
        addLineToEob(bp,buf);
        /* Descend child */
        if((cnp != NULL) && !(rnp->mode & (meREGMODE_HIDDEN|meREGMODE_INTERNAL)))
        {
            vstrbuf[level] = (level && (nnp != NULL)) ? boxChars[BCNS] : ' ' ;
            level++;
            rnp = cnp ;
            continue ;
        }
        
        /* Ascend the tree */
        while((nnp == NULL) && (--level >= 0) && ((rnp = rnp->parent) != NULL))
        {
            /* Move to next drawn sibling */
            nnp = rnp->next ;
            while((nnp != NULL) && (nnp->mode & meREGMODE_INVISIBLE))
                nnp = nnp->next ;
        }
        rnp = nnp ;
    } while((level > 0) && (rnp != NULL)) ;

    /* Set up the buffer for display */
    bp->dotLine = meLineGetNext(bp->baseLine);
    bp->dotOffset = 0 ;
    bp->dotLineNo = 0 ;
    meModeSet(bp->mode,MDVIEW) ;
    meModeClear(bp->mode,MDAUTOSV) ;
    meModeClear(bp->mode,MDUNDO) ;
    resetBufferWindows(bp) ;
    return meTRUE;
}