Esempio n. 1
0
	QString Help::getKeyword(KTextEditor::View *view)
	{
		if(!view) {
			return QString();
		}

		// get current position
		int row, col, col1, col2;
		QString word;
		KTextEditor::Document *doc = view->document();
		KTextEditor::Cursor cursor = view->cursorPosition();
		row = cursor.line();
		col = cursor.column();

		if (m_edit->getCurrentWord(doc, row, col, KileDocument::EditorExtension::smTex, word, col1, col2)) {
		   // There is no starred keyword in the references. So if     // dani 04.08.2004
			// we find one, we better try the unstarred keyword.
			if(word.right(1) == "*") {
				return word.left(word.length() - 1);
			}
			else {
				return word;
			}
		}
		else {
			return QString();
		}
	}
KTextEditor::Range IncludeHelperCompletionModel::completionRange(
    KTextEditor::View* view
  , const KTextEditor::Cursor& position
  )
{
    kDebug(DEBUG_AREA) << "cursor: " << position;
    auto line = view->document()->line(position.line());
    auto r = parseIncludeDirective(line, false);
    if (r.m_range.isValid())
    {
        auto start = line.lastIndexOf('/', r.m_range.end().column() - 1);
        kDebug(DEBUG_AREA) << "init start=" << start;
        start = start == -1 ? r.m_range.start().column() : start + 1;
        kDebug(DEBUG_AREA) << "fixed start=" << start;
        KTextEditor::Range range(
            position.line()
          , start
          , position.line()
          , r.m_range.end().column()
          );
        kDebug(DEBUG_AREA) << "selected range: " << range;
        return range;
    }
    kDebug(DEBUG_AREA) << "default select";
#if 0
    return KTextEditor::Range();
#else
    return KTextEditor::CodeCompletionModelControllerInterface3::completionRange(view, position);
#endif
}
Esempio n. 3
0
bool PythonCodeCompletionModel::shouldStartCompletion(KTextEditor::View* view, const QString& inserted,
                                                bool userInsertion, const KTextEditor::Cursor& position)
{
    QList<QString> words;
    words << "for" << "raise" << "except" << "in";
    foreach ( const QString& word, words ) {
        if ( view->document()->line(position.line()).mid(0, position.column()).endsWith(word + " ") ) {
            return true;
        }
    }
    // shebang / encoding lines
    if ( view->document()->line(position.line()).mid(0, position.column()).endsWith("#") && 
         position.line() < 2 )
    {
        return true;
    }

    // we're probably dealing with string formatting completion
    // is there any other case where this condition is true?
    if ( ! userInsertion && inserted.startsWith('{') ) {
        return true;
    }

    return KDevelop::CodeCompletionModel::shouldStartCompletion(view, inserted, userInsertion, position);
}
Esempio n. 4
0
void TextBuffer::wrapLine (const KTextEditor::Cursor &position)
{
  // only allowed if editing transaction running
  Q_ASSERT (m_editingTransactions > 0);

  // get block, this will assert on invalid line
  int blockIndex = blockForLine (position.line());

  // let the block handle the wrapLine
  // this can only lead to one more line in this block
  // no other blocks will change
  ++m_lines; // first alter the line counter, as functions called will need the valid one
  m_blocks.at(blockIndex)->wrapLine (position);

  // remember changes
  ++m_revision;

  // update changed line interval
  if (position.line() < m_editingMinimalLineChanged || m_editingMinimalLineChanged == -1)
    m_editingMinimalLineChanged = position.line();

  if (position.line() <= m_editingMaximalLineChanged)
    ++m_editingMaximalLineChanged;
  else
    m_editingMaximalLineChanged = position.line() + 1;

  // fixup all following blocks
  fixStartLines (blockIndex);

  // balance the changed block if needed
  balanceBlock (blockIndex);

  // emit signal about done change
  emit lineWrapped (position);
}
Esempio n. 5
0
void TextBuffer::insertText (const KTextEditor::Cursor &position, const QString &text)
{
  // only allowed if editing transaction running
  Q_ASSERT (m_editingTransactions > 0);

  // skip work, if no text to insert
  if (text.isEmpty())
    return;

  // get block, this will assert on invalid line
  int blockIndex = blockForLine (position.line());

  // let the block handle the insertText
  m_blocks.at(blockIndex)->insertText (position, text);

  // remember changes
  ++m_revision;

  // update changed line interval
  if (position.line () < m_editingMinimalLineChanged || m_editingMinimalLineChanged == -1)
    m_editingMinimalLineChanged = position.line ();

  if (position.line () > m_editingMaximalLineChanged)
    m_editingMaximalLineChanged = position.line ();

  // emit signal about done change
  emit textInserted (position, text);
}
Esempio n. 6
0
void KateAutoIndent::scriptIndent (KateView *view, const KTextEditor::Cursor &position, QChar typedChar)
{
  QPair<int, int> result = m_script->indent (view, position, typedChar, indentWidth);
  int newIndentInChars = result.first;

  // handle negative values special
  if (newIndentInChars < -1)
    return;

  // reuse indentation of the previous line, just like the "normal" indenter
  if (newIndentInChars == -1)
  {
    // keep indent of previous line
    keepIndent (position.line());

    return;
  }

  int align = result.second;
  if (align > 0)
    kDebug (13060) << "Align: " << align;

  // we got a positive or zero indent to use...
  doIndent (position.line(), newIndentInChars, align);
}
Esempio n. 7
0
unsigned int KDocumentTextBuffer::cursorToOffset_kte( const KTextEditor::Cursor &cursor )
{
    unsigned int offset = 0;
    for( int i = 0; i < cursor.line(); i++ ) {
        offset += countUnicodeCharacters(kDocument()->line(i)) + 1; // Add newline
    }
    offset += countUnicodeCharacters(kDocument()->line(cursor.line()).left(cursor.column()));
    return offset;
}
Esempio n. 8
0
void TextHistory::wrapLine(const KTextEditor::Cursor &position)
{
    // create and add new entry
    Entry entry;
    entry.type = Entry::WrapLine;
    entry.line = position.line();
    entry.column = position.column();
    addEntry(entry);
}
Esempio n. 9
0
void DebugSession::jumpToCursor()
{
    if (KDevelop::IDocument* doc = KDevelop::ICore::self()->documentController()->activeDocument()) {
        KTextEditor::Cursor cursor = doc->cursorPosition();
        if ( cursor.isValid() ) {
            // TODO disable all other breakpoints
            addSimpleUserCommand(QString("jump " + QString::number(cursor.line() + 1)).toAscii());
        }
    }
}
Esempio n. 10
0
Recorder::Recorder(KTextEditor::View *view, Manager *manager) : QObject(view), m_manager(manager), m_view(view)
{
	connect(m_manager, SIGNAL(watchedKeySequencesChanged()), this, SLOT(reloadWatchedKeySequences()));
	connect(this, SIGNAL(detectedTypedKeySequence(const QString&)), m_manager, SLOT(keySequenceTyped(const QString&)));
	KTextEditor::Cursor cursor = m_view->cursorPosition();
	m_oldLine = cursor.line();
	m_oldCol = cursor.column();

	reloadWatchedKeySequences();
}
Esempio n. 11
0
void SwapFile::wrapLine (const KTextEditor::Cursor &position)
{
  // skip if not open
  if (!m_swapfile.isOpen ())
    return;
  
  // format: qint8, int, int
  m_stream << EA_WrapLine << position.line() << position.column();

  m_needSync = true;
}
Esempio n. 12
0
void SwapFile::insertText (const KTextEditor::Cursor &position, const QString &text)
{
  // skip if not open
  if (!m_swapfile.isOpen ())
    return;
  
  // format: qint8, int, int, bytearray
  m_stream << EA_InsertText << position.line() << position.column() << text.toUtf8 ();

  m_needSync = true;
}
Esempio n. 13
0
void TextHistory::insertText(const KTextEditor::Cursor &position, int length, int oldLineLength)
{
    // create and add new entry
    Entry entry;
    entry.type = Entry::InsertText;
    entry.line = position.line();
    entry.column = position.column();
    entry.length = length;
    entry.oldLineLength = oldLineLength;
    addEntry(entry);
}
Esempio n. 14
0
/**
 * Returns the current position of the cursor.
 * @param	nLine	Holds the line on which the cursor is currently located
 * @param	nCol	Holds the column on which the cursor is currently located
 * @return	true if successful, false otherwise (cursor interface was not
 *			obtained)
 */
bool EditorPage::getCursorPos(uint& nLine, uint& nCol)
{
    int line, col;
	// Get the cursor position (adjusted to 1-based counting)
	const KTextEditor::Cursor c = m_pView->cursorPosition();
    c.position(line, col);
    nLine = line;
    nCol = col;
	nLine++;
	nCol++;
	
	return true;
}
Esempio n. 15
0
bool KateNewCompletionModel::shouldStartCompletion(KTextEditor::View* view, const QString &insertedText, bool userInsertion, const KTextEditor::Cursor &position)
{
    if (!userInsertion) return false;
    if(insertedText.isEmpty())
        return false;

    KateView *v = qobject_cast<KateView*> (view);

    QString text = view->document()->line(position.line()).left(position.column());
    static const QRegExp ktuan_new_class("((new \\w*)|(gen\\w*)|(get\\w*))$");
    if (ktuan_new_class.indexIn(text) >= 0) return true;
    return false;
}
Esempio n. 16
0
void DebugSession::runToCursor()
{
    if (KDevelop::IDocument* doc = KDevelop::ICore::self()->documentController()->activeDocument()) {
        KTextEditor::Cursor cursor = doc->cursorPosition();
        if ( cursor.isValid() ) {
            // TODO disable all other breakpoints
            QString temporaryBreakpointLocation = doc->url().path() + ':' + QString::number(cursor.line() + 1);
            InternalPdbCommand* temporaryBreakpointCmd = new InternalPdbCommand(0, 0, "tbreak " + temporaryBreakpointLocation + '\n');
            addCommand(temporaryBreakpointCmd);
            addSimpleInternalCommand("continue");
            updateLocation();
        }
    }
}
Esempio n. 17
0
/**
 * This returns the view line upon which realCursor is situated.
 * The view line is the number of lines in the view from the first line
 * The supplied cursor should be in real lines.
 */
int KateLayoutCache::viewLine(const KTextEditor::Cursor& realCursor)
{
  if (realCursor.column() <= 0 || realCursor.line() < 0) return 0;

  KateLineLayoutPtr thisLine = line(realCursor.line());

  for (int i = 0; i < thisLine->viewLineCount(); ++i) {
    const KateTextLayout& l = thisLine->viewLine(i);
    if (realCursor.column() >= l.startCol() && realCursor.column() < l.endCol())
      return i;
  }

  return thisLine->viewLineCount() - 1;
}
Esempio n. 18
0
void TextCursor::setPosition(const KTextEditor::Cursor& position, bool init)
{
  // any change or init? else do nothing
  if (!init && position.line() == line() && position.column() == m_column)
    return;

  // remove cursor from old block in any case
  if (m_block)
    m_block->removeCursor (this);

  // first: validate the line and column, else invalid
  if (position.column() < 0 || position.line () < 0 || position.line () >= m_buffer.lines ()) {
    if (!m_range)
      m_buffer.m_invalidCursors.insert (this);
    m_block = 0;
    m_line = m_column = -1;
    return;
  }

  // else, find block
  TextBlock *block = m_buffer.blockForIndex (m_buffer.blockForLine (position.line()));
  Q_ASSERT(block);

  // get line
  TextLine textLine = block->line (position.line());

#if 0 // this is no good idea, smart cursors don't do that, too, for non-wrapping cursors
  // now, validate column, else stay invalid
  if (position.column() > textLine->text().size()) {
    if (!m_range)
      m_buffer.m_invalidCursors.insert (this);
    m_block = 0;
    m_line = m_column = -1;
    return;
  }
#endif

  // if cursor was invalid before, remove it from invalid cursor list
  if (!m_range && !m_block && !init) {
    Q_ASSERT(m_buffer.m_invalidCursors.contains (this));
    m_buffer.m_invalidCursors.remove (this);
  }

  // else: valid cursor
  m_block = block;
  m_line = position.line () - m_block->startLine ();
  m_column = position.column ();
  m_block->insertCursor (this);
}
/**
 * Initiate completion when there is \c #include on a line (\c m_range
 * in a result of \c parseIncludeDirective() not empty -- i.e. there is some file present)
 * and cursor placed within that range... despite of completeness of the whole line.
 */
bool IncludeHelperCompletionModel::shouldStartCompletion(
    KTextEditor::View* view
  , const QString& inserted_text
  , bool user_insertion
  , const KTextEditor::Cursor& position
  )
{
    kDebug(DEBUG_AREA) << "position=" << position << ", inserted_text=" << inserted_text << ", ui=" << user_insertion;

    m_should_complete = false;
    auto* doc = view->document();                           // get current document
    auto line = doc->line(position.line());                 // get current line
    auto* iface = qobject_cast<KTextEditor::HighlightInterface*>(doc);
    // Do nothing if no highlighting interface or not suitable document or
    // a place within it... (we won't to complete smth in non C++ files or comments for example)
    if (!iface || !isSuitableDocumentAndHighlighting(doc->mimeType(), iface->highlightingModeAt(position)))
        return m_should_complete;

    // Try to parse it...
    auto r = parseIncludeDirective(line, false);
    m_should_complete = r.m_range.isValid();
    if (m_should_complete)
    {
        kDebug(DEBUG_AREA) << "range=" << r.m_range;
        m_should_complete = position.column() >= r.m_range.start().column()
          && position.column() <= r.m_range.end().column();
        if (m_should_complete)
        {
            m_closer = r.close_char();
            kDebug(DEBUG_AREA) << "closer=" << m_closer;
        }
    }
    else if (position.column() == line.length())
    {
        auto text = tryToCompleteIncludeDirective(line.mid(0, position.column()).trimmed());
        m_should_complete = !text.isEmpty();
        if (m_should_complete)
        {
            /// \todo Hardcoded angle bracket! Better to check what file was selected
            /// (from system path or session specific) and replace it accordingly...
            text += QLatin1String(" <");
            auto start = position;
            start.setColumn(0);
            auto range = KTextEditor::Range{start, position};
            view->document()->replaceText(range, text);
        }
    }
    return m_should_complete;
}
Esempio n. 20
0
// TODO: will be a word in two lines ?
QString EditorPage::getWordUnderCursor(uint* pPosInWord)
{
	QString sLine;
	int nLine, nCol, nFrom, nTo, nLast, nLength;
	QChar ch;

	const KTextEditor::Cursor c = m_pView->cursorPosition();

	// Get the line on which the cursor is positioned
    c.position(nLine, nCol);
    const KTextEditor::Cursor cFrom(nLine, 0);
    const KTextEditor::Cursor cTo = m_pDoc->endOfLine(nLine);
    KTextEditor::Range range(cFrom, cTo);

    sLine = m_pDoc->text(range);
	
	// Find the beginning of the current word
	for (nFrom = nCol; nFrom > 0;) {
		ch = sLine.at(nFrom - 1);
		if (!ch.isLetter() && !ch.isDigit() && ch != '_')
			break;
		
		nFrom--;
	}
	
	// Find the end of the current word
	nLast = sLine.length();
	for (nTo = nCol; nTo < nLast;) {
		ch = sLine.at(nTo);
		if (!ch.isLetter() && !ch.isDigit() && ch != '_')
			break;
		
		nTo++;
	}

	// Mark empty words
	nLength = nTo - nFrom;
	if (nLength == 0)
		return QString::null;
	
	// Return the in-word position, if required
	if (pPosInWord != NULL)
		*pPosInWord = nCol - nFrom;
	
	// Extract the word under the cursor from the entire line
	return sLine.mid(nFrom, nLength);
}
Esempio n. 21
0
KateTextLayout KateLayoutCache::textLayout( const KTextEditor::Cursor & realCursor )
{
  /*if (realCursor >= viewCacheStart() && (realCursor < viewCacheEnd() || realCursor == viewCacheEnd() && !m_textLayouts.last().wrap()))
    foreach (const KateTextLayout& l, m_textLayouts)
      if (l.line() == realCursor.line() && (l.endCol() < realCursor.column() || !l.wrap()))
        return l;*/

  return line(realCursor.line())->viewLine(viewLine(realCursor));
}
Esempio n. 22
0
KTextEditor::Cursor KDocumentTextBuffer::offsetRelativeTo_kte(const KTextEditor::Cursor& cursor, unsigned int offset)
{
    int lineno = cursor.line();
    const QString& firstLine = kDocument()->line(lineno).mid(cursor.column());
    unsigned int remaining = offset;
    int surrogates = surrogatesForCodePoints(firstLine, remaining);
    while ( remaining > 0 ) {
        remaining -= 1; // for the newline character
        lineno += 1;
        if ( remaining == 0 ) {
            surrogates = 0;
            break;
        }
        const QString& line = kDocument()->line(lineno);
        Q_ASSERT( lineno < kDocument()->lines() );
        surrogates = surrogatesForCodePoints(line, remaining);
    }
    return KTextEditor::Cursor(lineno, lineno == cursor.line() ? cursor.column() + surrogates : surrogates);
}
Esempio n. 23
0
bool KateWordCompletionModel::shouldStartCompletion(KTextEditor::View* view, const QString &insertedText, bool userInsertion, const KTextEditor::Cursor &position)
{
    if (!userInsertion) return false;
    if(insertedText.isEmpty())
        return false;

    KateView *v = qobject_cast<KateView*> (view);

    QString text = view->document()->line(position.line()).left(position.column());
    uint check=v->config()->wordCompletionMinimalWordLength();
    if (check<=0) return true;
    int start=text.length();
    int end=text.length()-check;
    if (end<0) return false;
    for (int i=start-1;i>=end;i--) {
      QChar c=text.at(i);
      if (! (c.isLetter() || (c.isNumber()) || c=='_') ) return false;
    }
    return true;
}
Esempio n. 24
0
// Return the range containing the word left of the cursor
KTextEditor::Range KateWordCompletionModel::completionRange(KTextEditor::View* view, const KTextEditor::Cursor &position)
{
  int line = position.line();
  int col = position.column();

  KTextEditor::Document *doc = view->document();
  while ( col > 0 )
  {
    QChar c = ( doc->character( KTextEditor::Cursor( line, col-1 ) ) );
    if ( c.isLetterOrNumber() || c.isMark() || c == '_' )
    {
      col--;
      continue;
    }

    break;
  }

  return KTextEditor::Range( KTextEditor::Cursor( line, col ), position );
}
Esempio n. 25
0
// Return the range containing the word left of the cursor
KTextEditor::Range KateNewCompletionModel::completionRange(KTextEditor::View* view, const KTextEditor::Cursor &position)
{
  int line = position.line();
  int col = position.column();

  KTextEditor::Document *doc = view->document();

  // ktuan java case: new List<Integer>
  // yieldXXX, Ent::load('XXX, genXXX, getXXX
  {
    QString text = view->document()->line(position.line()).left(position.column());
    const static QRegExp ktuan_new_class("((new \\w*)|(gen\\w*)|(get\\w*))$");
    int pos = ktuan_new_class.indexIn(text);
    if (pos >= 0) {
      return KTextEditor::Range( KTextEditor::Cursor( line, pos ), position );
    }
  }

  return KTextEditor::Range( KTextEditor::Cursor( line, col ), position );
}
Esempio n. 26
0
// Take the given QML line and check if it's a line of the form foo.bar: value.
// Return ranges for the key and the value.
const QPair<KTextEditor::Range, KTextEditor::Range> parseProperty(const QString& line, const KTextEditor::Cursor& position) {
    QStringList items = line.split(';');
    QString matchingItem;
    int col_offset = -1;
    // This is to also support FooAnimation { foo: bar; baz: bang; duration: 200 }
    // or similar
    foreach ( const QString& item, items ) {
        col_offset += item.size() + 1;
        if ( position.column() < col_offset ) {
            matchingItem = item;
            break;
        }
    }
QString VariableController::expressionUnderCursor(KTextEditor::Document* doc, const KTextEditor::Cursor& cursor)
{
    QString line = doc->line(cursor.line());
    int index = cursor.column();
    QChar c = line[index];
    if (!c.isLetterOrNumber() && c != '_' && c != '$')
        return QString();

    int start = Utils::expressionAt(line, index);
    int end = index;
    for (; end < line.size(); ++end) {
        QChar c = line[end];
        if (!(c.isLetterOrNumber() || c == '_' || c == '$'))
            break;
    }
    if (!(start < end))
        return QString();

    QString expression(line.mid(start, end-start));
    expression = expression.trimmed();
    return expression;
}
Esempio n. 28
0
void ModelTest::completionItems()
{
    KTextEditor::Document* doc = KTextEditor::Editor::instance()->createDocument(0);

    QFETCH(QString, text);
    QFETCH(QString, type);

    KTextEditor::Cursor position;
    QString textBeforeCursor = text.left(text.indexOf('|'));
    position.setLine(textBeforeCursor.count('\n'));
    position.setColumn(textBeforeCursor.mid(textBeforeCursor.lastIndexOf('\n')).length());

    text.replace('|', "");

    QTemporaryFile file("XXXXXXXXX."+type);
    file.open();
    file.write(text.toUtf8());
    file.close();

    doc->openUrl(KUrl("file://"+QDir::current().absoluteFilePath(file.fileName())));

    QCOMPARE(doc->mimeType(), QString("text/")+type);

    KTextEditor::View* view = doc->createView(0);
    CodeCompletionModel* model = new CodeCompletionModel(doc);

    QCOMPARE(model->rowCount(), 0);
    model->completionInvoked(view, model->completionRange(view, position), KTextEditor::CodeCompletionModel::ManualInvocation);
    QStringList completions;
    for (int i=0; i < model->rowCount(); ++i) {
        completions << model->data(model->index(i, CodeCompletionModel::Name), Qt::DisplayRole).toString();
    }
    kDebug() << "completions" << completions;
    QFETCH(QStringList, result);
    foreach (const QString &i, result) {
        QVERIFY(completions.contains(i));
    }
Esempio n. 29
0
bool Recorder::eventFilter(QObject* /* o */, QEvent *e)
{
	if (e->type() == QEvent::KeyPress) {
		QKeyEvent *keyEvent = (QKeyEvent*)(e);
		int curLine, curCol;
		KTextEditor::Cursor cursor = m_view->cursorPosition();
		curLine = cursor.line();
		curCol = cursor.column();
		if(curLine != m_oldLine || m_oldCol+1 != curCol) {
			m_typedSequence.clear();
			m_oldLine = curLine;
			m_oldCol = curCol;
		}
		else {
			++m_oldCol;
		}
		m_typedSequence += keyEvent->text();
		if(m_typedSequence.length() == m_maxSequenceLength + 1) {
			m_typedSequence = m_typedSequence.mid(1, m_typedSequence.length() - 1);
		}
		return seekForKeySequence(m_typedSequence);
	}
	return false;
}
/**
 * We don't care about how many lines possible was inserted. Just consider
 * a current one.
 */
bool PreprocessorCompletionModel::shouldStartCompletion(
    KTextEditor::View* const view
  , const QString& /*inserted_text*/
  , const bool /*user_insertion*/
  , const KTextEditor::Cursor& position
  )
{
    m_should_complete = false;
    auto* const doc = view->document();                     // get current document
    auto* const iface = qobject_cast<KTextEditor::HighlightInterface*>(doc);
    // Do nothing if no highlighting interface or not suitable document or
    // a place within it... (we won't to complete smth in non C++ files or comments for example)
    if (!iface || !isSuitableDocumentAndHighlighting(doc->mimeType(), iface->highlightingModeAt(position)))
        return false;

    auto text_before = doc->text({KTextEditor::Cursor(position.line(), 0), position});
    kDebug(DEBUG_AREA) << "text_before=" << text_before;
    /// Check if current line starts w/ \c '#' which is a sign of a preprocessor directive.
    if (text_before[0] == '#')
    {
        text_before = text_before.remove(0, 1).trimmed();
        kDebug(DEBUG_AREA) << "again text_before=" << text_before;
        /// Then make sure the text after it, is a subset of some
        /// hardcoded item from the \c COMPLETIONS table.
        m_should_complete = text_before.isEmpty() || std::any_of(
            begin(COMPLETIONS)
          , end(COMPLETIONS)
          , [&text_before](const auto& item)
            {
                auto text = item.text;
                const auto end_of_first_word = text.indexOf(' ');
                if (end_of_first_word != -1)
                    // Strip tail of the completion item... only first word is interesting!
                    text = text.left(end_of_first_word);
                return text_before.size() < text.size() && text.startsWith(text_before);
            }
          );
        kDebug(DEBUG_AREA) << "m_should_complete=" << m_should_complete;
        return m_should_complete;
    }
    return false;
}