Improve editor "add-cursor-above" and "add-cursor-below" behavior.

This commit is contained in:
Martín Lucas Golini
2025-11-16 20:04:46 -03:00
parent 24e8ec447b
commit c704e00833
4 changed files with 61 additions and 1 deletions

View File

@@ -590,6 +590,10 @@ class EE_API TextDocument {
void addCursorBelow();
size_t getTopMostCursorIndex();
size_t getBottomMostCursorIndex();
TextRange getTopMostCursor();
TextRange getBottomMostCursor();

View File

@@ -448,6 +448,10 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
void moveToNextLine();
void addCursorAbove();
void addCursorBelow();
void moveToPreviousPage();
void moveToNextPage();

View File

@@ -4634,6 +4634,34 @@ void TextDocument::initializeCommands() {
}
}
size_t TextDocument::getTopMostCursorIndex() {
if ( mSelection.size() == 1 )
return 0;
TextRange topMost( mSelection[0] );
size_t topMostIndex = 0;
for ( size_t i = 1; i < mSelection.size(); ++i ) {
if ( mSelection[i] < topMost ) {
topMost = mSelection[i];
topMostIndex = i;
}
}
return topMostIndex;
}
size_t TextDocument::getBottomMostCursorIndex() {
if ( mSelection.size() == 1 )
return 0;
TextRange bottomMost( mSelection[0] );
size_t bottomMostIndex = 0;
for ( size_t i = 1; i < mSelection.size(); ++i ) {
if ( mSelection[i] > bottomMost ) {
bottomMost = mSelection[i];
bottomMostIndex = i;
}
}
return bottomMostIndex;
}
TextRange TextDocument::getTopMostCursor() {
if ( mSelection.size() == 1 )
return mSelection.front();

View File

@@ -2652,7 +2652,7 @@ Float UICodeEditor::getTextWidth( const StringType& line, bool fromMonospaceLine
Vector2d UICodeEditor::getTextPositionOffsetSanitized( TextPosition position,
std::optional<Float> lineHeight ) const {
position.setLine( eeclamp<Int64>( position.line(), 0L, mDoc->linesCount() - 1 ) );
// This is different from sanitizePosition, sinze allows the last character.
// This is different from sanitizePosition, since allows the last character.
position.setColumn(
eeclamp<Int64>( position.column(), 0L,
eemax<Int64>( 0, position.line() < static_cast<Int64>( mDoc->linesCount() )
@@ -3423,6 +3423,24 @@ void UICodeEditor::moveToNextPage() {
jumpLinesDown( getViewPortLineCount().y );
}
void UICodeEditor::addCursorAbove() {
size_t cursorIdx = mDoc->getTopMostCursorIndex();
TextPosition curPos = mDoc->getSelections()[cursorIdx].start();
if ( curPos.line() == 0 )
return;
auto newPos( moveToLineOffset( curPos, -1, cursorIdx ) );
mDoc->addSelection( { newPos, newPos } );
}
void UICodeEditor::addCursorBelow() {
size_t cursorIdx = mDoc->getBottomMostCursorIndex();
TextPosition curPos = mDoc->getSelections()[cursorIdx].start();
if ( curPos.line() >= (Int64)mDoc->linesCount() - 1 )
return;
auto newPos( moveToLineOffset( curPos, 1, cursorIdx ) );
mDoc->addSelection( { newPos, newPos } );
}
void UICodeEditor::moveToStartOfLine() {
for ( size_t i = 0; i < mDoc->getSelections().size(); ++i ) {
auto selection = mDoc->getSelectionIndex( i );
@@ -4545,6 +4563,12 @@ void UICodeEditor::registerCommands() {
if ( !editor->mLink.empty() )
Engine::instance()->openURI( editor->mLink );
} );
mDoc->setCommand( "add-cursor-above", []( Client* client ) {
static_cast<UICodeEditor*>( client )->addCursorAbove();
} );
mDoc->setCommand( "add-cursor-below", []( Client* client ) {
static_cast<UICodeEditor*>( client )->addCursorBelow();
} );
mUnlockedCmd.insert( { "copy", "select-all", "open-containing-folder",
"copy-containing-folder-path", "copy-file-path",