Added duplicate-line-or-selection TextDocument command.

Updated README.
This commit is contained in:
Martín Lucas Golini
2025-12-06 12:28:35 -03:00
parent 662cf33baa
commit ab738ea79d
3 changed files with 44 additions and 3 deletions

View File

@@ -12,12 +12,10 @@ framework heavily focused on the development of rich graphical user interfaces.
### Cross platform functionality
* Official support for Linux, Windows, macOS, Android and iOS.
* Official support for Linux, Windows, macOS, FreeBSD, Haiku, Android and iOS.
* Exports to HTML5 using emscripten with some minor limitations.
* Also works on BSD and Haiku.
### UI Module
* Base widgets to manage the app/game objects as nodes, with all basic input interaction events ( clicks, keypress, mouser over, focus, etc ).

View File

@@ -717,6 +717,8 @@ class EE_API TextDocument {
void joinLines();
void duplicateLineOrSelection();
void moveToNextParagraph();
void moveToPreviousParagraph();

View File

@@ -4378,6 +4378,46 @@ void TextDocument::joinLines() {
mergeSelection();
}
void TextDocument::duplicateLineOrSelection() {
AtomicBoolScopedOp op( mRunningTransaction, true );
// Must process from bottom to top to not invalidate positions of cursors above.
for ( Int64 i = mSelection.size() - 1; i >= 0; --i ) {
TextRange sel = getSelectionIndex( i );
if ( sel.hasSelection() ) {
TextRange normalizedSel = sel.normalized();
String selectedText = getText( normalizedSel );
if ( !selectedText.empty() ) {
TextPosition insertionPoint = normalizedSel.end();
TextPosition endOfInsertion = insert( i, insertionPoint, selectedText );
// After duplicating selection, select the new duplicated text.
// The selection direction should be preserved.
if ( sel.isNormalized() ) {
setSelection( i, { insertionPoint, endOfInsertion } );
} else {
setSelection( i, { endOfInsertion, insertionPoint } );
}
}
} else {
Int64 lineNum = sel.start().line();
// Don't duplicate the last empty line.
if ( lineNum >= (Int64)linesCount() - 1 && getLineLength( lineNum ) <= 1 ) {
continue;
}
String lineText = getLineText( lineNum );
TextPosition insertionPoint = { lineNum + 1, 0 };
insert( i, insertionPoint, lineText );
TextPosition newCursorPos = { lineNum + 1, sel.start().column() };
setSelection( i, newCursorPos );
}
}
mergeSelection();
}
TextPosition TextDocument::findPreviousEmptyLines( size_t selIdx ) {
Int64 startLine = mSelection[selIdx].normalized().start().line() - 1;
bool found = false;
@@ -4625,6 +4665,7 @@ void TextDocument::initializeCommands() {
mCommands["from-base64"] = [this] { fromBase64(); };
mCommands["trim-trailing-whitespace"] = [this] { trimTrailingWhitespace(); };
mCommands["join-lines"] = [this] { joinLines(); };
mCommands["duplicate-line-or-selection"] = [this] { duplicateLineOrSelection(); };
mCommands["convert-indentation-to-tabs"] = [this] { convertIndentationToTabs(); };
mCommands["convert-indentation-to-spaces"] = [this] { convertIndentationToSpaces(); };