示例#1
0
void EmacsBuffer::setPointToMark(mintchar_t mark) {
    mintcount_t old_point = _point;
    _point = getMarkPosition(mark);
    // FIXME: This could be optimised by checking distances from BOB/EOB
    //        Also by checking the actual marks used.  Some marks never
    //        change the current line (ie BOL/EOL).
    if (old_point < _point) {
        // Moved forward in the buffer
        _pointLine += countNewlines(old_point, _point);
    } else if (old_point > _point) {
        // Moved backwards in the buffer
        _pointLine -= countNewlines(_point, old_point);
    } // else
} // EmacsBuffer::SetPointToMark
示例#2
0
void EmacsBuffer::setPointRow(mintcount_t li) {
    if (_pointLine <= li) {
        // Not enough lines to have point at row 'li'
        _topline = 0;
        _toplineLine = 0;
    } else {
        _topline = backwardLines(getMarkPosition(MARK_BOL), li);
        _toplineLine = countNewlines(getMarkPosition(MARK_BOB), _topline);
    } // else
} // EmacsBuffer::setPointRow
示例#3
0
bool EmacsBuffer::deleteToMark(mintchar_t mark) {
    mintcount_t mark_pos = getMarkPosition(mark);
    mintcount_t max_pos = std::max(mark_pos, _point);
    mintcount_t min_pos = std::min(mark_pos, _point);
    if (min_pos != max_pos) {
        mintcount_t nchar = max_pos - min_pos;
        if (nchar == _text.size()) {
            // Optimisation for removing whole buffer
            _countNewlines = 0;
            _pointLine = 0;
            _topline = 0;
            _toplineLine = 0;
        } else {
            // Adjust total line count for the lines we are deleting
            mintcount_t allnewlines = countNewlines(min_pos, max_pos);
            _countNewlines -= allnewlines;
            if (max_pos == _point) {
                // Remove any lines prior to point if we are deleting backwards
                _pointLine -= allnewlines;
            } // if
            if (_topline >= max_pos) {
                // Topline is after the deleted text, adjust by amount deleted
                _topline -= nchar;
                _toplineLine -= allnewlines;
            } else if (_topline > min_pos) {
                // If it's in the deleted text, we set it to the BOL near min_pos.
                mintcount_t newpos = getMarkPosition(MARK_BOL, min_pos);
                _toplineLine -= countNewlines(min_pos, _topline);
                _topline = newpos;
            } // else if
        } // else
        _modified = true;
        _text.erase(min_pos, nchar);
        _point = min_pos;
        adjustMarksDel(nchar);
    } // if
    return true;
} // DeleteToMark
示例#4
0
bool EmacsBuffer::insertString(const MintString& str) {
    if (!str.empty()) {
        _modified = true;
#if defined(USE_BUFFER_ROPE) && !defined(USE_MINTSTRING_ROPE)
        _text.insert(_point, str.data(), str.size());
#else
        _text.insert(_point, str);
#endif
        mintcount_t extra_chars = str.size();
        mintcount_t extra_newlines = countNewlines(_point, _point + extra_chars);
        _countNewlines += extra_newlines;
        _pointLine += extra_newlines;
        if (_topline > _point) {
            // topline moves if it is after point
            _topline += extra_chars;
            _toplineLine += extra_newlines;
        } // if
        adjustMarksIns(extra_chars);
        _point += extra_chars;
    } // if
    return true;
} // EmacsBuffer::insertString
示例#5
0
void parseSourceFile(pSourceModule* pMod, bool debug=false) {

    boost::object_pool<pSourceRef> tokenPool;
    lexer::pLexer lexer(pMod->source());

    void* pParser = corvusParseAlloc(malloc);

#ifndef NDEBUG
    // DEBUG
    if (debug)
        corvusParseTrace(stderr, (char*)"trace: ");
#endif

    // start at begining of source file
    AST::pParseContext& context = pMod->context();
    context.incLineNum(); // line 1
    context.setLastToken(tokenPool.construct(pSourceRef(lexer.sourceBegin(), 0)));
    context.setLastNewline(lexer.sourceBegin());

    pSourceRef* curRange;
    pSourceCharIterator lastNL;

    bool inlineHtml = false;
    std::string HEREDOC_ID;

    pSourceCharIterator sourceEnd(lexer.sourceEnd());
    lexer::rmatch match(lexer.sourceBegin(), lexer.sourceEnd());

    do {

        corvus_nextLangToken(match);

        //std::cout << "match: [" << match.str() << "]\n";

        // always make a range unless the scanner didn't match, in which case
        // we handle separately below
        if (match.id != match.npos()) {
            curRange = tokenPool.construct(pSourceRef(match.start, match.end-match.start));
            context.setTokenLine(curRange);
        }

        switch (match.id) {
            case 0:
            {
                // end of input (success)
                break;
            }
            case T_CLOSE_TAG:
            {
                // we swallow one newline if it follows
                //if ((match.end != sourceEnd) && (*match.end == '\n'))
                //    ++tokEnd;
                break;
            }
            case T_OPEN_TAG:
            {
                // state change (no parse), but count newlines from OPEN tag
                countNewlines(context, match, lastNL);
                break;
            }
            case ~0: // npos
            {
                // if state is HTML, collect characters for INLINE HTML token
                if (match.state == 0) {
                    // we go until a single < is found, or end of input
                    // this potentially breaks up inline htmls
                    // at tags that don't turn out to be php open tags,
                    // but that way we let the lexer handle the matching
                    // and limit the special handler code here                    
                    while ((*match.end != '<') && (match.end != sourceEnd)) {
                        match.end++;
                    }
                    inlineHtml = true;
                    curRange = tokenPool.construct(pSourceRef(match.start, match.end-match.start));
                    context.setTokenLine(curRange);
                    countNewlines(context, match, lastNL);
                }
                // if state is HEREDOC, collect heredoc string, looking for heredoc id
                else if (match.state == 3) {
                    // assert we have a heredoc ID
                    assert(HEREDOC_ID.length() && "no heredoc id");
                    std::pair<pSourceCharIterator,pSourceCharIterator> idr = find_heredoc_id(HEREDOC_ID, lexer, match, pMod);
                    countNewlines(context, match, lastNL);
                    curRange = tokenPool.construct(pSourceRef(match.start, match.end-match.start));
                    context.setTokenLine(curRange);
                    corvusParse(pParser, T_HEREDOC_STRING, curRange, pMod);
                    match.start = idr.first;
                    match.end = idr.second;
                    curRange = tokenPool.construct(pSourceRef(match.start, match.end-match.start));
                    context.setTokenLine(curRange);
                    corvusParse(pParser, T_HEREDOC_END, curRange, pMod);
                    match.state = 1;
                    HEREDOC_ID.clear();
                }
                else {
                    // unmatched token: error
                    pMod->context().parseError(curRange, pSourceRange());
                }
                break;
            }
            case T_HEREDOC_START:
            {
                // save the heredoc id so we can match the end
                pSourceCharIterator ms = match.start;
                while (*ms == '<' ||
                       *ms == ' ' ||
                       *ms == '\t' ||
                       *ms == '\'' ||
                       *ms == '"'
                       )
                    ms++;
                if (*(match.end-2) == '"' || *(match.end-2) == '\'')
                    HEREDOC_ID.assign(ms, match.end-2);
                else
                    HEREDOC_ID.assign(ms, match.end-1);
                countNewlines(context, match, lastNL);
                corvusParse(pParser, T_HEREDOC_START, curRange, pMod);
                break;
            }
            case T_WHITESPACE:
            case T_INLINE_HTML:
            case T_DOC_COMMENT:
            case T_MULTILINE_COMMENT:
            case T_SINGLELINE_COMMENT:
            {
                // handle newlines
                countNewlines(context, match, lastNL);
                break;
            }
            default:
            {
                // parse
                corvusParse(pParser, match.id, curRange, pMod);
                break;
            }
        }

        // next token
        context.setLastToken(curRange);

    }
    while (match.id != 0);

    // finish parse
    corvusParse(pParser, 0, 0, pMod); // note, this may generate a parse error still
    context.finishParse(); // so don't finish until here
    corvusParseFree(pParser, free);

}
示例#6
0
mintcount_t EmacsBuffer::getPointRow() {
    return countNewlines(getMarkPosition(MARK_TOPLINE), getMarkPosition(MARK_POINT));
} // EmacsBuffer::getPointRow