Exemplo n.º 1
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 6
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();
  }
}