From 87fb9538cb25714c485484e809a646f32ed99f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 30 Jan 2025 01:12:41 -0300 Subject: [PATCH] Fix multi-line search in buffer bug. Added: display new line character in selection. Fixed a crash when trying to write into a broken pipe. --- include/eepp/ui/uicodeeditor.hpp | 6 +- src/eepp/system/process.cpp | 1 + src/eepp/ui/doc/textdocument.cpp | 1 + src/eepp/ui/uicodeeditor.cpp | 101 ++++++++++-------- .../ecode/plugins/debugger/busprocess.cpp | 11 +- 5 files changed, 72 insertions(+), 48 deletions(-) diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index c78685edb..ff9021cc8 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -516,7 +516,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { virtual Vector2d getTextPositionOffset( const TextPosition& pos, std::optional lineHeight = {}, - bool allowVisualLineEnd = false ) const; + bool allowVisualLineEnd = false, + bool visualizeNewLine = false ) const; Vector2d getTextPositionOffsetSanitized( TextPosition pos, std::optional lineHeight = {} ) const; @@ -529,7 +530,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { std::optional lineHeight = {}, /* if passed it will clip rectangles against the visual line range */ std::optional visibleLineRange = - std::optional() ); + std::optional(), + bool visualizeNewLines = false ); virtual Float getLineWidth( const Int64& docLine ); diff --git a/src/eepp/system/process.cpp b/src/eepp/system/process.cpp index 13cd16925..18abff147 100644 --- a/src/eepp/system/process.cpp +++ b/src/eepp/system/process.cpp @@ -228,6 +228,7 @@ size_t Process::readStdErr( char* const buffer, const size_t& size ) { size_t Process::write( const char* buffer, const size_t& size ) { eeASSERT( mProcess != nullptr ); + eeASSERT( isAlive() ); if ( mShuttingDown ) return 0; Lock l( mStdInMutex ); diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 6d4fc845d..6f0af1b49 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -2827,6 +2827,7 @@ TextDocument::SearchResult TextDocument::find( const String& text, TextPosition TextPosition( initPos.line(), curSearch.size() ) ); if ( foundRange.end().column() == (Int64)mLines[foundRange.end().line()].size() ) foundRange.setEnd( positionOffset( foundRange.end(), 1 ) ); + range.result = foundRange; return range; } else { return find( text, range.result.end(), caseSensitive, wholeWord, type, restrictRange ); diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index a5fd35e7a..2d5ef6d27 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -2231,7 +2231,8 @@ void UICodeEditor::setScrollY( const Float& val, bool emmitEvent ) { Vector2d UICodeEditor::getTextPositionOffset( const TextPosition& position, std::optional lineHeight, - bool allowVisualLineEnd ) const { + bool allowVisualLineEnd, + bool visualizeNewLine ) const { double lh = lineHeight ? *lineHeight : getLineHeight(); if ( mDocView.isWrappedLine( position.line() ) ) { auto info = mDocView.getVisibleLineRange( position, allowVisualLineEnd ); @@ -2246,13 +2247,15 @@ Vector2d UICodeEditor::getTextPositionOffset( const TextPosition& position, const auto& line = mDoc->line( position.line() ).getText(); auto partialLine = line.view().substr( info.range.start().column(), info.range.end().column() ); - return { Text::findCharacterPos( position.column() - info.range.start().column(), mFont, - getCharacterSize(), partialLine, - mFontStyleConfig.Style, mTabWidth, - mFontStyleConfig.OutlineThickness, false ) - .x + - offsetX, - offsetY }; + Float x = + Text::findCharacterPos( position.column() - info.range.start().column(), mFont, + getCharacterSize(), partialLine, mFontStyleConfig.Style, + mTabWidth, mFontStyleConfig.OutlineThickness, false ) + .x; + if ( visualizeNewLine && allowVisualLineEnd && + position.column() == (Int64)mDoc->line( position.line() ).getText().size() - 1 ) + x += getGlyphWidth(); + return { x + offsetX, offsetY }; } const String& line = mDoc->line( position.line() ).getText(); Float glyphWidth = getGlyphWidth(); @@ -2261,23 +2264,28 @@ Vector2d UICodeEditor::getTextPositionOffset( const TextPosition& position, for ( auto i = info.range.start().column(); i < maxCol; i++ ) { if ( line[i] == '\t' ) { x += glyphWidth * mTabWidth; - } else if ( line[i] != '\n' && line[i] != '\r' ) { + } else if ( visualizeNewLine || ( line[i] != '\n' && line[i] != '\r' ) ) { x += glyphWidth; } } + if ( visualizeNewLine && allowVisualLineEnd && + position.column() == (Int64)mDoc->line( position.line() ).getText().size() - 1 ) + x += glyphWidth; return { x + offsetX, offsetY }; } double offsetY = mDocView.getLineYOffset( position.line(), lh ); if ( isNotMonospace() ) { - return { Text::findCharacterPos( - ( position.column() == (Int64)mDoc->line( position.line() ).getText().size() ) - ? position.column() - 1 - : position.column(), - mFont, getCharacterSize(), mDoc->line( position.line() ).getText(), - mFontStyleConfig.Style, mTabWidth, mFontStyleConfig.OutlineThickness, false ) - .x, - offsetY }; + bool isLastChar = + position.column() == (Int64)mDoc->line( position.line() ).getText().size(); + Float x = Text::findCharacterPos( + isLastChar ? position.column() - 1 : position.column(), mFont, + getCharacterSize(), mDoc->line( position.line() ).getText(), + mFontStyleConfig.Style, mTabWidth, mFontStyleConfig.OutlineThickness, false ) + .x; + if ( visualizeNewLine && isLastChar ) + x += getGlyphWidth(); + return { x, offsetY }; } const String& line = mDoc->line( position.line() ).getText(); @@ -2287,7 +2295,7 @@ Vector2d UICodeEditor::getTextPositionOffset( const TextPosition& position, for ( auto i = 0; i < maxCol; i++ ) { if ( line[i] == '\t' ) { x += glyphWidth * mTabWidth; - } else if ( line[i] != '\n' && line[i] != '\r' ) { + } else if ( visualizeNewLine || ( line[i] != '\n' && line[i] != '\r' ) ) { x += glyphWidth; } } @@ -3470,20 +3478,15 @@ void UICodeEditor::drawWordRanges( const TextRanges& ranges, const DocumentLineR continue; if ( ignoreSelectionMatch && selection.inSameLine() && - selection.start().line() == range.start().line() && - selection.start().column() == range.start().column() ) { + selection.start() == range.start() ) { continue; } if ( ranges.isSorted() && range.start().line() == lastSkipLine ) continue; - Int64 startCol = range.start().column(); - Int64 endCol = range.end().column(); - - auto rects = getTextRangeRectangles( - { { range.start().line(), startCol }, { range.start().line(), endCol } }, startScroll, - {}, lineHeight, visibleLineRange ); + auto rects = + getTextRangeRectangles( range, startScroll, {}, lineHeight, visibleLineRange, true ); for ( const auto& rect : rects ) { if ( area.intersect( rect ) ) { @@ -3756,11 +3759,10 @@ void UICodeEditor::drawLineText( const Int64& line, Vector2f position, const Flo } } -std::vector -UICodeEditor::getTextRangeRectangles( const TextRange& range, const Vector2f& startScroll, - std::optional lineRange, - std::optional lineHeight, - std::optional visibleLineRange ) { +std::vector UICodeEditor::getTextRangeRectangles( + const TextRange& range, const Vector2f& startScroll, + std::optional lineRange, std::optional lineHeight, + std::optional visibleLineRange, bool visualizeNewLines ) { std::vector rects; Float lh = lineHeight ? *lineHeight : getLineHeight(); Int64 startLine = @@ -3794,7 +3796,8 @@ UICodeEditor::getTextRangeRectangles( const TextRange& range, const Vector2f& st Vector2d endOffset; if ( ln == range.start().line() && fromInfo.range.start().line() == ln && realFromInfoVisibleIndex == static_cast( visibleIdx ) ) { - startOffset = getTextPositionOffset( range.start(), lh ); + startOffset = + getTextPositionOffset( range.start(), lh, false, visualizeNewLines ); } else { startOffset = getTextPositionOffset( info, lh ); } @@ -3808,10 +3811,11 @@ UICodeEditor::getTextRangeRectangles( const TextRange& range, const Vector2f& st auto nextInfo = mDocView.getVisibleIndexPosition( static_cast( visibleIdx + 1 ) ); if ( nextInfo.line() == info.line() ) { - endOffset = - getTextPositionOffset( { info.line(), nextInfo.column() }, lh, true ); + endOffset = getTextPositionOffset( { info.line(), nextInfo.column() }, lh, + true, visualizeNewLines ); } else { - endOffset = getTextPositionOffset( mDoc->endOfLine( { ln, 0 } ), lh, true ); + endOffset = getTextPositionOffset( mDoc->endOfLine( { ln, 0 } ), lh, true, + visualizeNewLines ); } } selRect.Right = startScroll.x + endOffset.x; @@ -3819,17 +3823,21 @@ UICodeEditor::getTextRangeRectangles( const TextRange& range, const Vector2f& st } } else { if ( range.start().line() == ln ) { - auto startOffset = getTextPositionOffset( { ln, range.start().column() }, lh ); + auto startOffset = getTextPositionOffset( { ln, range.start().column() }, lh, false, + visualizeNewLines ); selRect.Top = startScroll.y + startOffset.y; selRect.Bottom = selRect.Top + lh; selRect.Left = startScroll.x + startOffset.x; if ( range.end().line() == ln ) { selRect.Right = - startScroll.x + getTextPositionOffset( { ln, range.end().column() }, lh ).x; + startScroll.x + getTextPositionOffset( { ln, range.end().column() }, lh, + false, visualizeNewLines ) + .x; } else { - selRect.Right = - startScroll.x + - getTextPositionOffset( { ln, static_cast( line.length() ) }, lh ).x; + selRect.Right = startScroll.x + getTextPositionOffset( + { ln, static_cast( line.length() ) }, + lh, false, visualizeNewLines ) + .x; } } else if ( range.end().line() == ln ) { auto startOffset = getTextPositionOffset( { ln, 0 }, lh ); @@ -3837,15 +3845,18 @@ UICodeEditor::getTextRangeRectangles( const TextRange& range, const Vector2f& st selRect.Bottom = selRect.Top + lh; selRect.Left = startScroll.x + startOffset.x; selRect.Right = - startScroll.x + getTextPositionOffset( { ln, range.end().column() }, lh ).x; + startScroll.x + getTextPositionOffset( { ln, range.end().column() }, lh, false, + visualizeNewLines ) + .x; } else { auto startOffset = getTextPositionOffset( { ln, 0 }, lh ); selRect.Top = startScroll.y + startOffset.y; selRect.Bottom = selRect.Top + lh; selRect.Left = startScroll.x + startOffset.x; - selRect.Right = - startScroll.x + - getTextPositionOffset( { ln, static_cast( line.length() ) }, lh ).x; + selRect.Right = startScroll.x + + getTextPositionOffset( { ln, static_cast( line.length() ) }, + lh, false, visualizeNewLines ) + .x; } rects.push_back( selRect ); } @@ -3861,7 +3872,7 @@ void UICodeEditor::drawTextRange( const TextRange& range, const DocumentLineRang primitives.setForceDraw( false ); primitives.setColor( Color( backgroundColor ).blendAlpha( mAlpha ) ); auto rects = - getTextRangeRectangles( range, startScroll, lineRange, lineHeight, visibleLineRange ); + getTextRangeRectangles( range, startScroll, lineRange, lineHeight, visibleLineRange, true ); for ( const auto& rect : rects ) primitives.drawRectangle( rect ); if ( !rects.empty() ) diff --git a/src/tools/ecode/plugins/debugger/busprocess.cpp b/src/tools/ecode/plugins/debugger/busprocess.cpp index b91ef259d..9f440b786 100644 --- a/src/tools/ecode/plugins/debugger/busprocess.cpp +++ b/src/tools/ecode/plugins/debugger/busprocess.cpp @@ -38,7 +38,16 @@ void BusProcess::startAsyncRead( ReadFn readFn ) { } size_t BusProcess::write( const char* buffer, const size_t& size ) { - return mProcess.write( buffer, size ); + if ( mState == State::Running ) { + if ( !mProcess.isAlive() ) { + setState( State::Closed ); + return 0; + } + + return mProcess.write( buffer, size ); + } + + return 0; } } // namespace ecode