// Start Normal mode just for one command and return to Insert mode bool KateViInsertMode::commandSwitchToNormalModeForJustOneCommand(){ m_viInputModeManager->setTemporaryNormalMode(true); m_viInputModeManager->changeViMode(NormalMode); const Cursor cursorPos = m_view->cursorPosition(); // If we're at end of the line, move the cursor back one step, as in Vim. if (doc()->line(cursorPos.line()).length() == cursorPos.column()) { m_view->setCursorPosition(Cursor(cursorPos.line(), cursorPos.column() - 1)); } m_view->setCaretStyle( KateRenderer::Block, true ); m_view->updateViModeBarMode(); m_viewInternal->repaint(); return true; }
bool SmartCursor::advance(int distance, AdvanceMode mode) { Cursor c = *this; if (mode == ByCharacter) { while (distance) { int lineLength = document()->lineLength(c.line()); if (distance > 0) { int advance = qMin(lineLength - c.column(), distance); if (distance > advance) { if (c.line() + 1 >= document()->lines()) return false; c.setPosition(c.line() + 1, 0); // Account for end of line advancement distance -= advance + 1; } else { c.setColumn(c.column() + distance); distance = 0; } } else { int back = qMin(c.column(), -distance); if (-distance > back) { if (c.line() - 1 < 0) return false; c.setPosition(c.line() - 1, document()->lineLength(c.line() - 1)); // Account for end of line advancement distance += back + 1; } else { c.setColumn(c.column() + distance); distance = 0; } } } } else { // Not supported by the interface alone return false; } setPosition(c); return true; }
bool KateViInsertMode::commandInsertContentOfRegister(){ Cursor c( m_view->cursorPosition() ); Cursor cAfter = c; QChar reg = getChosenRegister( m_register ); OperationMode m = getRegisterFlag( reg ); QString textToInsert = getRegisterContent( reg ); if ( textToInsert.isNull() ) { error(i18n("Nothing in register %1", reg )); return false; } if ( m == LineWise ) { textToInsert.chop( 1 ); // remove the last \n c.setColumn( doc()->lineLength( c.line() ) ); // paste after the current line and ... textToInsert.prepend( QChar( '\n' ) ); // ... prepend a \n, so the text starts on a new line cAfter.setLine( cAfter.line()+1 ); cAfter.setColumn( 0 ); } else { cAfter.setColumn(cAfter.column() + textToInsert.length()); } doc()->insertText( c, textToInsert, m == Block ); updateCursor( cAfter ); return true; }
Range::Range(const Cursor& start, int width) : m_start(new Cursor(start)) , m_end(new Cursor(start.line(), start.column() + width)) { m_start->setRange(this); m_end->setRange(this); }
Range CodeCompletionModelControllerInterface::completionRange(View* view, const Cursor &position) { Cursor end = position; QString text = view->document()->line(end.line()); static QRegExp findWordStart( "\\b([_\\w]+)$" ); static QRegExp findWordEnd( "^([_\\w]*)\\b" ); Cursor start = end; if (findWordStart.lastIndexIn(text.left(end.column())) >= 0) start.setColumn(findWordStart.pos(1)); if (findWordEnd.indexIn(text.mid(end.column())) >= 0) end.setColumn(end.column() + findWordEnd.cap(1).length()); //kDebug()<<"returning:"<<Range(start,end); return Range(start, end); }
void KateViInsertMode::replayCompletion() { const KateViInputModeManager::Completion completion = m_viInputModeManager->nextLoggedCompletion(); // Find beginning of the word. Cursor cursorPos = m_view->cursorPosition(); Cursor wordStart = Cursor::invalid(); if (!doc()->character(cursorPos).isLetterOrNumber() && doc()->character(cursorPos) != '_') { cursorPos.setColumn(cursorPos.column() - 1); } while (cursorPos.column() >= 0 && (doc()->character(cursorPos).isLetterOrNumber() || doc()->character(cursorPos) == '_')) { wordStart = cursorPos; cursorPos.setColumn(cursorPos.column() - 1); } // Find end of current word. cursorPos = m_view->cursorPosition(); Cursor wordEnd = Cursor(cursorPos.line(), cursorPos.column() - 1); while (cursorPos.column() < doc()->lineLength(cursorPos.line()) && (doc()->character(cursorPos).isLetterOrNumber() || doc()->character(cursorPos) == '_')) { wordEnd = cursorPos; cursorPos.setColumn(cursorPos.column() + 1); } QString completionText = completion.completedText(); const Range currentWord = Range(wordStart, Cursor(wordEnd.line(), wordEnd.column() + 1)); // Should we merge opening brackets? Yes, if completion is a function with arguments and after the cursor // there is (optional whitespace) followed by an open bracket. int offsetFinalCursorPosBy = 0; if (completion.completionType() == KateViInputModeManager::Completion::FunctionWithArgs) { const int nextMergableBracketAfterCursorPos = findNextMergeableBracketPos(currentWord.end()); if (nextMergableBracketAfterCursorPos != -1) { if (completionText.endsWith("()")) { // Strip "()". completionText = completionText.left(completionText.length() - 2); } else if (completionText.endsWith("();")) { // Strip "();". completionText = completionText.left(completionText.length() - 3); } // Ensure cursor ends up after the merged open bracket. offsetFinalCursorPosBy = nextMergableBracketAfterCursorPos + 1; } else { if (!completionText.endsWith("()") && !completionText.endsWith("();")) { // Original completion merged with an opening bracket; we'll have to add our own brackets. completionText.append("()"); } // Position cursor correctly i.e. we'll have added "functionname()" or "functionname();"; need to step back by // one or two to be after the opening bracket. offsetFinalCursorPosBy = completionText.endsWith(';') ? -2 : -1; } } Cursor deleteEnd = completion.removeTail() ? currentWord.end() : Cursor(m_view->cursorPosition().line(), m_view->cursorPosition().column() + 0); if (currentWord.isValid()) { doc()->removeText(Range(currentWord.start(), deleteEnd)); doc()->insertText(currentWord.start(), completionText); } else { doc()->insertText(m_view->cursorPosition(), completionText); } if (offsetFinalCursorPosBy != 0) { m_view->setCursorPosition(Cursor(m_view->cursorPosition().line(), m_view->cursorPosition().column() + offsetFinalCursorPosBy)); } if (!m_viInputModeManager->isReplayingLastChange()) { Q_ASSERT(m_viInputModeManager->isReplayingMacro()); // Post the completion back: it needs to be added to the "last change" list ... m_viInputModeManager->logCompletionEvent(completion); // ... but don't log the ctrl-space that led to this call to replayCompletion(), as // a synthetic ctrl-space was just added to the last change keypresses by logCompletionEvent(), and we don't // want to duplicate them! m_viInputModeManager->doNotLogCurrentKeypress(); } }