Esempio n. 1
0
int KateViInsertMode::findNextMergeableBracketPos(const Cursor& startPos)
{
  const QString lineAfterCursor = doc()->text(Range(startPos, Cursor(startPos.line(), doc()->lineLength(startPos.line()))));
  QRegExp whitespaceThenOpeningBracket("^\\s*(\\()");
  int nextMergableBracketAfterCursorPos = -1;
  if (lineAfterCursor.contains(whitespaceThenOpeningBracket))
  {
    nextMergableBracketAfterCursorPos =  whitespaceThenOpeningBracket.pos(1);
  }
  return nextMergableBracketAfterCursorPos;
}
Esempio n. 2
0
bool KateViInsertMode::commandMoveOneWordLeft()
{
  Cursor c( m_view->cursorPosition() );
  c = findPrevWordStart( c.line(), c.column() );

  if (!c.isValid()) {
    c = Cursor(0,0);
  }

  updateCursor( c );
  return true;
}
Esempio n. 3
0
void RangeTest::testRangeStringConversion()
{
    using KTextEditor::Cursor;
    using KTextEditor::Range;

    KTextEditor::Range r;
    QCOMPARE(r.start(), Cursor(0, 0));
    QCOMPARE(r.end(), Cursor(0, 0));
    QCOMPARE(r.toString(), QStringLiteral("[(0, 0), (0, 0)]"));

    r = Range::fromString(QStringLiteral("[(0, 0), (0, 0)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(0, 0), (0, 0)]"));
    r = Range::fromString(QStringLiteral("[(0,0),(0,0)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(0, 0), (0, 0)]"));
    r = Range::fromString(QStringLiteral("[(-1, -1), (-1, -1)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(-1, -1), (-1, -1)]"));
    r = Range::fromString(QStringLiteral("[(-1, -1), (0, 0)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(-1, -1), (0, 0)]"));
    r = Range::fromString(QStringLiteral("[(0, 0), (-1, -1)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(-1, -1), (0, 0)]")); // start > end -> swap

    r = Range::fromString(QStringLiteral("[(0, 0), (12, 42)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(0, 0), (12, 42)]"));
    r = Range::fromString(QStringLiteral("[(12, 42), (0, 0)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(0, 0), (12, 42)]")); // start > end -> swap
    r = Range::fromString(QStringLiteral("[(12,42),(0,0)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(0, 0), (12, 42)]")); // start > end -> swap
    r = Range::fromString(QStringLiteral("[(-12, -42), (0, 0)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(-12, -42), (0, 0)]"));
    r = Range::fromString(QStringLiteral("[(0, 0), (-12, -42)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(-12, -42), (0, 0)]")); // start > end -> swap

    // invalid input
    r = Range::fromString(QStringLiteral("[(0:0)(-12:-42)]"));
    QCOMPARE(r.toString(), QStringLiteral("[(-1, -1), (-1, -1)]"));
    r = Range::fromString(QStringLiteral("[0,1]"));
    QCOMPARE(r.toString(), QStringLiteral("[(-1, -1), (-1, -1)]"));
}
Esempio n. 4
0
// 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;
}
Esempio n. 5
0
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();
  }
}
Esempio n. 6
0
// leave insert mode when esc, etc, is pressed. if leaving block
// prepend/append, the inserted text will be added to all block lines. if
// ctrl-c is used to exit insert mode this is not done.
void KateViInsertMode::leaveInsertMode( bool force )
{
    m_view->abortCompletion();
    if ( !force )
    {
      if ( m_blockInsert != None ) { // block append/prepend

          // make sure cursor haven't been moved
          if ( m_blockRange.startLine == m_view->cursorPosition().line() ) {
              int start, len;
              QString added;
              Cursor c;

              switch ( m_blockInsert ) {
              case Append:
              case Prepend:
                  if ( m_blockInsert == Append ) {
                      start = m_blockRange.endColumn+1;
                  } else {
                      start = m_blockRange.startColumn;
                  }

                  len = m_view->cursorPosition().column()-start;
                  added = getLine().mid( start, len );

                  c = Cursor( m_blockRange.startLine, start );
                  for ( int i = m_blockRange.startLine+1; i <= m_blockRange.endLine; i++ ) {
                      c.setLine( i );
                      doc()->insertText( c, added );
                  }
                  break;
              case AppendEOL:
                  start = m_eolPos;
                  len = m_view->cursorPosition().column()-start;
                  added = getLine().mid( start, len );

                  c = Cursor( m_blockRange.startLine, start );
                  for ( int i = m_blockRange.startLine+1; i <= m_blockRange.endLine; i++ ) {
                      c.setLine( i );
                      c.setColumn( doc()->lineLength( i ) );
                      doc()->insertText( c, added );
                  }
                  break;
              default:
                  error("not supported");
              }
          }

          m_blockInsert = None;
      }
      else
      {
          const QString added = doc()->text(Range(m_viInputModeManager->getMarkPosition('^'), m_view->cursorPosition()));

          if (m_count > 1)
          {
              for (unsigned int i = 0; i < m_count - 1; i++)
              {
                  if (m_countedRepeatsBeginOnNewLine)
                  {
                      doc()->newLine(m_view);
                  }
                  doc()->insertText( m_view->cursorPosition(), added );
              }
          }
      }
    }
    m_countedRepeatsBeginOnNewLine = false;
    startNormalMode();
}