void CodeEditorComponent::mouseDoubleClick (const MouseEvent& e)
{
    CodeDocument::Position tokenStart (getPositionAt (e.x, e.y));
    CodeDocument::Position tokenEnd (tokenStart);

    if (e.getNumberOfClicks() > 2)
    {
        tokenStart.setLineAndIndex (tokenStart.getLineNumber(), 0);
        tokenEnd.setLineAndIndex (tokenStart.getLineNumber() + 1, 0);
    }
    else
    {
        while (CharacterFunctions::isLetterOrDigit (tokenEnd.getCharacter()))
            tokenEnd.moveBy (1);

        tokenStart = tokenEnd;

        while (tokenStart.getIndexInLine() > 0
                && CharacterFunctions::isLetterOrDigit (tokenStart.movedBy (-1).getCharacter()))
            tokenStart.moveBy (-1);
    }

    moveCaretTo (tokenEnd, false);
    moveCaretTo (tokenStart, true);
}
void CodeEditorComponent::moveLineDelta (const int delta, const bool selecting)
{
    CodeDocument::Position pos (caretPos);
    const int newLineNum = pos.getLineNumber() + delta;

    if (columnToTryToMaintain < 0)
        columnToTryToMaintain = indexToColumn (pos.getLineNumber(), pos.getIndexInLine());

    pos.setLineAndIndex (newLineNum, columnToIndex (newLineNum, columnToTryToMaintain));

    const int colToMaintain = columnToTryToMaintain;
    moveCaretTo (pos, selecting);
    columnToTryToMaintain = colToMaintain;
}
const CodeDocument::Position CodeDocument::Position::movedByLines (const int deltaLines) const
{
    CodeDocument::Position p (*this);
    p.setLineAndIndex (getLineNumber() + deltaLines, getIndexInLine());
    return p;
}