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
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
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
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
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); }
mintcount_t EmacsBuffer::getPointRow() { return countNewlines(getMarkPosition(MARK_TOPLINE), getMarkPosition(MARK_POINT)); } // EmacsBuffer::getPointRow