From 88e2adbcf17b63f4da8a55ecfd1eebcf854c4106 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 25 Jan 2023 20:15:00 -0300 Subject: [PATCH] Multi cursor fixes. Fixed GCC13 build. --- .../eepp/ui/css/stylesheetselectorrule.hpp | 1 + include/eepp/ui/doc/textdocument.hpp | 4 - include/eepp/ui/doc/textrange.hpp | 18 +++++ src/eepp/ui/doc/textdocument.cpp | 79 +++++++------------ src/eepp/ui/uicodeeditor.cpp | 1 + src/tools/ecode/appconfig.cpp | 4 +- 6 files changed, 49 insertions(+), 58 deletions(-) diff --git a/include/eepp/ui/css/stylesheetselectorrule.hpp b/include/eepp/ui/css/stylesheetselectorrule.hpp index 73d3ffa3c..3e956491e 100644 --- a/include/eepp/ui/css/stylesheetselectorrule.hpp +++ b/include/eepp/ui/css/stylesheetselectorrule.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace EE { namespace UI { class UIWidget; diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index 6d7c5abc6..88dd15a95 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -577,10 +577,6 @@ class EE_API TextDocument { void removeFromStartOfSelectedLines( const String& text, bool skipEmpty, bool removeExtraSpaces = false ); - void addLinesSinceCursorIndex( const size_t& cursorIdx, const size_t& numLines ); - - void removeLinesSinceCursorIndex( const size_t& cursorIdx, const size_t& numLines ); - /** @return The number of lines removed (complete lines, not modified lines) */ size_t remove( const size_t& cursorIdx, TextRange range, UndoStackContainer& undoStack, const Time& time, bool fromUndoRedo = false ); diff --git a/include/eepp/ui/doc/textrange.hpp b/include/eepp/ui/doc/textrange.hpp index 17674f417..fcf408124 100644 --- a/include/eepp/ui/doc/textrange.hpp +++ b/include/eepp/ui/doc/textrange.hpp @@ -158,6 +158,24 @@ class EE_API TextRanges : public std::vector { sort(); return oldSize != size(); } + + std::string toString() const { + std::string str; + for ( size_t i = 0; i < size(); ++i ) { + str += ( *this )[i].toString(); + if ( i != size() - 1 ) + str += ";"; + } + return str; + } + + static TextRanges fromString( const std::string& str ) { + auto rangesStr = String::split( str, ';' ); + TextRanges ranges; + for ( const auto& rangeStr : rangesStr ) + ranges.emplace_back( TextRange::fromString( rangeStr ) ); + return ranges; + } }; }}} // namespace EE::UI::Doc diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index bc17e0536..f83e820cb 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -865,11 +865,20 @@ TextPosition TextDocument::insert( const size_t& cursorIdx, TextPosition positio if ( mSelection.size() > 1 ) { for ( auto& sel : mSelection ) { auto selNorm( sel.normalized() ); + if ( selNorm.start().line() < position.line() ) + continue; + Int64 addLines = position.line() < selNorm.start().line() || + position.column() < selNorm.start().column() + ? linesAdd + : 0; + sel.start().setLine( sel.start().line() + addLines ); + sel.end().setLine( sel.end().line() + addLines ); if ( selNorm.start().line() == position.line() && selNorm.start().column() >= position.column() ) { sel.start().setColumn( positionOffset( sel.start(), text.size() ).column() ); sel.end().setColumn( positionOffset( sel.end(), text.size() ).column() ); } + sel = sanitizeRange( sel ); } } @@ -967,20 +976,23 @@ size_t TextDocument::remove( const size_t& cursorIdx, TextRange range, if ( mSelection.size() > 1 ) { for ( auto& sel : mSelection ) { auto selNorm( sel.normalized() ); - auto ranNorm( range.normalized() ); + auto ranNorm( originalRange.normalized() ); if ( selNorm.start().line() < ranNorm.end().line() ) - break; - + continue; + Int64 lineRem = ranNorm.end().line() - ranNorm.start().line(); + Int64 colRem = 0; if ( selNorm.end().line() == ranNorm.end().line() && ranNorm.end().column() < selNorm.start().column() ) { - auto colRem = ranNorm.start().line() == ranNorm.end().line() - ? ranNorm.end().column() - ranNorm.start().column() - : ranNorm.end().column(); - sel.start().setColumn( sel.start().column() - colRem ); - sel.end().setColumn( sel.end().column() - colRem ); - sel = sanitizeRange( sel ); + colRem = ranNorm.start().line() == ranNorm.end().line() + ? ranNorm.end().column() - ranNorm.start().column() + : ranNorm.end().column(); } + sel.start().setLine( sel.start().line() - lineRem ); + sel.start().setColumn( sel.start().column() - colRem ); + sel.end().setLine( sel.end().line() - lineRem ); + sel.end().setColumn( sel.end().column() - colRem ); + sel = sanitizeRange( sel ); } } @@ -1168,24 +1180,21 @@ TextRange TextDocument::getDocRange() const { void TextDocument::deleteTo( const size_t& cursorIdx, int offset ) { eeASSERT( cursorIdx < mSelection.size() ); TextPosition cursorPos = mSelection[cursorIdx].normalized().start(); - size_t linesRemoved = 0; if ( mSelection[cursorIdx].hasSelection() ) { - linesRemoved = remove( cursorIdx, getSelectionIndex( cursorIdx ) ); + remove( cursorIdx, getSelectionIndex( cursorIdx ) ); } else { TextPosition delPos = positionOffset( cursorPos, offset ); TextRange range( cursorPos, delPos ); - linesRemoved = remove( cursorIdx, range ); + remove( cursorIdx, range ); range = range.normalized(); cursorPos = range.start(); } - removeLinesSinceCursorIndex( cursorIdx + 1, linesRemoved ); setSelection( cursorIdx, cursorPos ); } void TextDocument::deleteSelection( const size_t& cursorIdx ) { TextPosition cursorPos = getSelectionIndex( cursorIdx ).normalized().start(); - size_t linesRemoved = remove( cursorIdx, getSelectionIndex( cursorIdx ) ); - removeLinesSinceCursorIndex( cursorIdx + 1, linesRemoved ); + remove( cursorIdx, getSelectionIndex( cursorIdx ) ); setSelection( cursorIdx, cursorPos ); } @@ -1268,11 +1277,6 @@ void TextDocument::textInput( const String& text ) { if ( mSelection[i].hasSelection() ) deleteTo( i, 0 ); setSelection( i, insert( i, getSelectionIndex( i ).start(), text ) ); - - if ( i + 1 >= mSelection.size() ) - continue; - - addLinesSinceCursorIndex( i + 1, text.countChar( '\n' ) ); } } @@ -1439,8 +1443,7 @@ void TextDocument::deleteCurrentLine() { } auto start = startOfLine( getSelectionIndex( i ).start() ); auto end = positionOffset( endOfLine( getSelectionIndex( i ).start() ), 1 ); - size_t linesRemoved = remove( i, { start, end } ); - removeLinesSinceCursorIndex( i + 1, linesRemoved ); + remove( i, { start, end } ); setSelection( i, start ); } } @@ -1640,32 +1643,6 @@ void TextDocument::removeFromStartOfSelectedLines( const String& text, bool skip TextPosition( range.end().line(), range.end().column() - endRemoved ), swap ); } -void TextDocument::addLinesSinceCursorIndex( const size_t& cursorIdx, const size_t& numLines ) { - if ( cursorIdx >= mSelection.size() || 0 == numLines ) - return; - - for ( size_t z = cursorIdx; z < mSelection.size(); z++ ) { - mSelection[z].setStart( TextPosition( mSelection[z].start().line() + numLines, - mSelection[z].start().column() ) ); - mSelection[z].setEnd( - TextPosition( mSelection[z].end().line() + numLines, mSelection[z].end().column() ) ); - mSelection[z] = sanitizeRange( mSelection[z] ); - } -} - -void TextDocument::removeLinesSinceCursorIndex( const size_t& cursorIdx, const size_t& numLines ) { - if ( cursorIdx >= mSelection.size() || 0 == numLines ) - return; - - for ( size_t z = cursorIdx; z < mSelection.size(); z++ ) { - mSelection[z].setStart( TextPosition( mSelection[z].start().line() - numLines, - mSelection[z].start().column() ) ); - mSelection[z].setEnd( - TextPosition( mSelection[z].end().line() - numLines, mSelection[z].end().column() ) ); - mSelection[z] = sanitizeRange( mSelection[z] ); - } -} - void TextDocument::indent() { if ( hasSelection() ) { insertAtStartOfSelectedLines( getIndentString(), false ); @@ -1738,16 +1715,14 @@ void TextDocument::setIndentWidth( const Uint32& tabWidth ) { void TextDocument::deleteTo( const size_t& cursorIdx, TextPosition position ) { TextPosition cursorPos = getSelectionIndex( cursorIdx ).normalized().start(); - size_t linesRemoved = 0; if ( getSelectionIndex( cursorIdx ).hasSelection() ) { - linesRemoved = remove( cursorIdx, getSelectionIndex( cursorIdx ) ); + remove( cursorIdx, getSelectionIndex( cursorIdx ) ); } else { TextRange range( cursorPos, position ); - linesRemoved = remove( cursorIdx, range ); + remove( cursorIdx, range ); range = range.normalized(); cursorPos = range.start(); } - removeLinesSinceCursorIndex( cursorIdx + 1, linesRemoved ); setSelection( cursorIdx, cursorPos ); } diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 4d0aeff6e..ef751b5d6 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -3426,4 +3426,5 @@ void UICodeEditor::invalidateLinesCache() { invalidateDraw(); } } + }} // namespace EE::UI diff --git a/src/tools/ecode/appconfig.cpp b/src/tools/ecode/appconfig.cpp index ecdb4b280..57d68495c 100644 --- a/src/tools/ecode/appconfig.cpp +++ b/src/tools/ecode/appconfig.cpp @@ -302,7 +302,7 @@ json saveNode( Node* node ) { json f; f["type"] = "editor"; f["path"] = editor->getDocument().getFilePath(); - f["selection"] = editor->getDocument().getSelection().toString(); + f["selection"] = editor->getDocument().getSelections().toString(); files.emplace_back( f ); } } else if ( ownedWidget->isType( UI_TYPE_TERMINAL ) ) { @@ -365,7 +365,7 @@ static void loadDocuments( UICodeEditorSplitter* editorSplitter, std::shared_ptr std::string path( file["path"] ); if ( !FileSystem::fileExists( path ) ) return; - TextRange selection( TextRange::fromString( file["selection"] ) ); + TextRanges selection( TextRanges::fromString( file["selection"] ) ); UITab* tab = nullptr; if ( ( tab = editorSplitter->isDocumentOpen( path, false, true ) ) != nullptr ) { auto tabAndEditor = editorSplitter->createCodeEditorInTabWidget( curTabWidget );