diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index e78d9d913..987eb4156 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -203,6 +203,8 @@ class EE_API TextDocument { String::StringBaseType getChar( const TextPosition& position ) const; + String::StringBaseType getCharFromUnsanitizedPosition( const TextPosition& position ) const; + TextPosition insert( const size_t& cursorIdx, const TextPosition& position, const String& text ); diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index ecb413d57..7a8f204d7 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -701,7 +701,13 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { Float getMinimapLineSpacing() const; bool getShowFoldingRegion() const; - void setShowFoldingRegion(bool showFoldingRegion); + void setShowFoldingRegion( bool showFoldingRegion ); + + Drawable* getFoldDrawable() const; + void setFoldDrawable(Drawable* foldDrawable); + + Drawable* getFoldedDrawable() const; + void setFoldedDrawable(Drawable* foldedDrawable); protected: struct LastXOffset { @@ -818,6 +824,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { UIIcon* mFileLockIcon{ nullptr }; std::string mFileLockIconName{ "file-lock-fill" }; LineWrapType mLineWrapType{ LineWrapType::Viewport }; + Drawable* mFoldDrawable{ nullptr }; + Drawable* mFoldedDrawable{ nullptr }; UICodeEditor( const std::string& elementTag, const bool& autoRegisterBaseCommands = true, const bool& autoRegisterBaseKeybindings = true ); diff --git a/src/eepp/ui/doc/documentview.cpp b/src/eepp/ui/doc/documentview.cpp index 92eba40b3..73bd1cfd8 100644 --- a/src/eepp/ui/doc/documentview.cpp +++ b/src/eepp/ui/doc/documentview.cpp @@ -4,6 +4,10 @@ #include #include +#ifdef EE_DEBUG +#define EE_VERIFY_STRUCTURAL_CONSISTENCY +#endif + namespace EE { namespace UI { namespace Doc { LineWrapMode DocumentView::toLineWrapMode( std::string mode ) { @@ -378,7 +382,8 @@ Float DocumentView::getLineYOffset( Int64 docIdx, Float lineHeight ) const { } bool DocumentView::isLineVisible( Int64 docIdx ) const { - return mDocLineToVisibleIndex[docIdx] != static_cast( VisibleIndex::invalid ); + return mDocLineToVisibleIndex.empty() || + mDocLineToVisibleIndex[docIdx] != static_cast( VisibleIndex::invalid ); } void DocumentView::updateCache( Int64 fromLine, Int64 toLine, Int64 numLines ) { @@ -558,7 +563,7 @@ void DocumentView::shiftFoldingRegions( Int64 fromLine, Int64 numLines ) { } void DocumentView::verifyStructuralConsistency() { -#ifdef EE_DEBUG +#ifdef EE_VERIFY_STRUCTURAL_CONSISTENCY if ( isOneToOne() ) return; diff --git a/src/eepp/ui/doc/foldrangeservice.cpp b/src/eepp/ui/doc/foldrangeservice.cpp index 2317dd4cf..ab0d8958a 100644 --- a/src/eepp/ui/doc/foldrangeservice.cpp +++ b/src/eepp/ui/doc/foldrangeservice.cpp @@ -96,6 +96,9 @@ const FoldRangeServive::FoldRangeProvider& FoldRangeServive::getProvider() const void FoldRangeServive::setProvider( const FoldRangeProvider& provider ) { mProvider = provider; + if ( provider == nullptr ) { + mFoldingRegions.clear(); + } } }}} // namespace EE::UI::Doc diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index d75ab67d9..482a809d6 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -1102,6 +1102,11 @@ String::StringBaseType TextDocument::getChar( const TextPosition& position ) con return mLines[pos.line()][pos.column()]; } +String::StringBaseType +TextDocument::getCharFromUnsanitizedPosition( const TextPosition& position ) const { + return mLines[position.line()][position.column()]; +} + TextPosition TextDocument::insert( const size_t& cursorIdx, const TextPosition& position, const String& text ) { mUndoStack.clearRedoStack(); @@ -3001,7 +3006,7 @@ TextPosition TextDocument::getMatchingBracket( TextPosition sp, SyntaxHighlighter* highlighter = getHighlighter(); int depth = 0; while ( sp.isValid() ) { - auto byte = getChar( sp ); + auto byte = getCharFromUnsanitizedPosition( sp ); if ( byte == openBracket ) { changeDepth( highlighter, depth, sp, 1 ); if ( depth == 0 ) @@ -3017,7 +3022,7 @@ TextPosition TextDocument::getMatchingBracket( TextPosition sp, } auto prevPos = sp; - sp = positionOffset( sp, dir == MatchDirection::Forward ? 1 : -1 ); + sp = positionOffset( sp, dir == MatchDirection::Forward ? 1 : -1, false ); if ( sp == prevPos ) return {}; } diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index eb1d6cff7..7339efefb 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -124,8 +124,8 @@ UICodeEditor::UICodeEditor( const std::string& elementTag, const bool& autoRegis mTabWidth( 4 ), mMouseWheelScroll( 50 ), mFontSize( mFontStyleConfig.getFontCharacterSize() ), - mLineNumberPaddingLeft( PixelDensity::dpToPx( 4 ) ), - mLineNumberPaddingRight( PixelDensity::dpToPx( 4 ) ), + mLineNumberPaddingLeft( PixelDensity::dpToPx( 6 ) ), + mLineNumberPaddingRight( PixelDensity::dpToPx( 6 ) ), mFoldRegionWidth( PixelDensity::dpToPx( 12 ) ), mKeyBindings( getUISceneNode()->getWindow()->getInput() ), mFindLongestLineWidthUpdateFrequency( Seconds( 1 ) ), @@ -1906,7 +1906,7 @@ void UICodeEditor::onDocumentTextChanged( const DocumentContentChange& change ) sendCommonEvent( Event::OnTextChanged ); mDocView.updateCache( change.range.start().line(), change.range.start().line(), 0 ); - if ( !change.text.empty() ) { + if ( !change.text.empty() && !mDocView.isWrapEnabled() ) { auto range = findLongestLineInRange( change.range ); if ( range.second > mLongestLineWidth ) { mLongestLineIndex = range.first; @@ -2712,39 +2712,39 @@ const SyntaxDefinition& UICodeEditor::getSyntaxDefinition() const { } void UICodeEditor::checkMatchingBrackets() { - if ( mHighlightMatchingBracket ) { - static const std::vector open{ '{', '(', '[' }; - static const std::vector close{ '}', ')', ']' }; - mMatchingBrackets = TextRange(); - TextPosition pos = mDoc->sanitizePosition( mDoc->getSelection().start() ); - TextDocumentLine& line = mDoc->line( pos.line() ); - auto isOpenIt = std::find( open.begin(), open.end(), line[pos.column()] ); - auto isCloseIt = std::find( close.begin(), close.end(), line[pos.column()] ); - if ( ( isOpenIt == open.end() && isCloseIt == close.end() ) && pos.column() > 0 ) { - isOpenIt = std::find( open.begin(), open.end(), line[pos.column() - 1] ); - isCloseIt = std::find( close.begin(), close.end(), line[pos.column() - 1] ); - if ( isOpenIt != open.end() ) { - pos.setColumn( pos.column() - 1 ); - } else if ( isCloseIt != close.end() ) { - pos.setColumn( pos.column() - 1 ); - } - } + if ( !mHighlightMatchingBracket ) + return; + static const std::vector open{ '{', '(', '[' }; + static const std::vector close{ '}', ')', ']' }; + mMatchingBrackets = TextRange(); + TextPosition pos = mDoc->sanitizePosition( mDoc->getSelection().start() ); + TextDocumentLine& line = mDoc->line( pos.line() ); + auto isOpenIt = std::find( open.begin(), open.end(), line[pos.column()] ); + auto isCloseIt = std::find( close.begin(), close.end(), line[pos.column()] ); + if ( ( isOpenIt == open.end() && isCloseIt == close.end() ) && pos.column() > 0 ) { + isOpenIt = std::find( open.begin(), open.end(), line[pos.column() - 1] ); + isCloseIt = std::find( close.begin(), close.end(), line[pos.column() - 1] ); if ( isOpenIt != open.end() ) { - size_t index = std::distance( open.begin(), isOpenIt ); - String::StringBaseType openBracket = open[index]; - String::StringBaseType closeBracket = close[index]; - TextPosition closePosition = mDoc->getMatchingBracket( - pos, openBracket, closeBracket, TextDocument::MatchDirection::Forward ); - mMatchingBrackets = { pos, closePosition }; + pos.setColumn( pos.column() - 1 ); } else if ( isCloseIt != close.end() ) { - size_t index = std::distance( close.begin(), isCloseIt ); - String::StringBaseType openBracket = open[index]; - String::StringBaseType closeBracket = close[index]; - TextPosition closePosition = mDoc->getMatchingBracket( - pos, openBracket, closeBracket, TextDocument::MatchDirection::Backward ); - mMatchingBrackets = { pos, closePosition }; + pos.setColumn( pos.column() - 1 ); } } + if ( isOpenIt != open.end() ) { + size_t index = std::distance( open.begin(), isOpenIt ); + String::StringBaseType openBracket = open[index]; + String::StringBaseType closeBracket = close[index]; + TextPosition closePosition = mDoc->getMatchingBracket( + pos, openBracket, closeBracket, TextDocument::MatchDirection::Forward ); + mMatchingBrackets = { pos, closePosition }; + } else if ( isCloseIt != close.end() ) { + size_t index = std::distance( close.begin(), isCloseIt ); + String::StringBaseType openBracket = open[index]; + String::StringBaseType closeBracket = close[index]; + TextPosition closePosition = mDoc->getMatchingBracket( + pos, openBracket, closeBracket, TextDocument::MatchDirection::Backward ); + mMatchingBrackets = { pos, closePosition }; + } } Int64 UICodeEditor::getColFromXOffset( VisibleIndex visibleIndex, const Float& x ) const { @@ -3778,29 +3778,78 @@ void UICodeEditor::drawLineNumbers( const DocumentLineRange& lineRange, const Ve mFontStyleConfig.ShadowOffset ); } - if ( mShowFoldingRegion && mFoldsVisible && - mDoc->getFoldRangeService().isFoldingRegionInLine( i ) ) { - Float dim = PixelDensity::dpToPx( 6 ); - Float center = ( mFoldRegionWidth - dim ) * 0.5f; + if ( mShowFoldingRegion && mDoc->getFoldRangeService().isFoldingRegionInLine( i ) ) { bool isFolded = mDocView.isFolded( i ); - Float dimH = isFolded ? dim : eeceil( dim * 0.75f ); - lnPos = Vector2f( screenStart.x + ( mShowLineNumber ? lineNumberWidth : 0.f ) + center, - lnPos.y + eeceil( ( lineHeight - dimH ) * 0.5f ) ); - primitives.setColor( mLineNumberFontColor ); - Triangle2f tri; - if ( isFolded ) { - tri.V[0] = { 0, 0 }; - tri.V[1] = { 0, dim }; - tri.V[2] = { dim, dim * 0.5f }; - } else { - tri.V[0] = { 0, 0 }; - tri.V[1] = { dim, 0 }; - tri.V[2] = { dim * 0.5f, dim * 0.75f }; + + if ( mFoldsVisible ) { + if ( ( isFolded && mFoldedDrawable ) || ( !isFolded && mFoldedDrawable ) ) { + Drawable* drawable = isFolded ? mFoldedDrawable : mFoldDrawable; + GlyphDrawable::DrawMode oldMode; + + if ( drawable->getDrawableType() == Drawable::Type::GLYPH ) { + oldMode = static_cast( drawable )->getDrawMode(); + static_cast( drawable ) + ->setDrawMode( GlyphDrawable::DrawMode::Text ); + } + + lnPos = Vector2f( screenStart.x + ( mShowLineNumber ? lineNumberWidth : 0.f ), + lnPos.y ); + + drawable->setColorFilter( mLineNumberActiveFontColor ); + drawable->draw( lnPos ); + + if ( drawable->getDrawableType() == Drawable::Type::GLYPH ) + static_cast( drawable )->setDrawMode( oldMode ); + } else { + Float dim = PixelDensity::dpToPx( 6 ); + Float center = ( mFoldRegionWidth - dim ) * 0.5f; + Float dimH = isFolded ? dim : eeceil( dim * 0.75f ); + lnPos = Vector2f( screenStart.x + ( mShowLineNumber ? lineNumberWidth : 0.f ) + + center, + lnPos.y + eeceil( ( lineHeight - dimH ) * 0.5f ) ); + primitives.setColor( mLineNumberActiveFontColor ); + Triangle2f tri; + if ( isFolded ) { + tri.V[0] = { 0, 0 }; + tri.V[1] = { 0, dim }; + tri.V[2] = { dim, dim * 0.5f }; + } else { + tri.V[0] = { 0, 0 }; + tri.V[1] = { dim, 0 }; + tri.V[2] = { dim * 0.5f, dim * 0.75f }; + } + tri.V[0] += lnPos; + tri.V[1] += lnPos; + tri.V[2] += lnPos; + primitives.drawTriangle( tri ); + } + } + + if ( isFolded ) { + FontStyleConfig fontStyle( mFontStyleConfig ); + const auto& style = mColorScheme.getSyntaxStyle( "normal"_sst ); + fontStyle.FontColor = style.color; + + Vector2f offset( startScroll ); + offset.x += getGlyphWidth(); + + if ( mDocView.isWrappedLine( i ) ) { + auto info = mDocView.getVisibleLineRange( { i, 0 }, true ); + offset += getTextPositionOffset( info.range.end(), lineHeight, true ); + } else { + offset += getTextPositionOffset( + { i, static_cast( mDoc->line( i ).getText().size() ) }, lineHeight, + true ); + } + + Text::draw( String( (String::StringBaseType)0x2026 /* … */ ), offset, fontStyle, + mTabWidth ); + + primitives.setColor( mLineBreakColumnColor ); + primitives.drawLine( + { { startScroll.x, offset.y + lineHeight }, + { startScroll.x + mSize.getWidth(), offset.y + lineHeight } } ); } - tri.V[0] += lnPos; - tri.V[1] += lnPos; - tri.V[2] += lnPos; - primitives.drawTriangle( tri ); } } } @@ -4566,6 +4615,22 @@ void UICodeEditor::setShowFoldingRegion( bool showFoldingRegion ) { } } +Drawable* UICodeEditor::getFoldDrawable() const { + return mFoldDrawable; +} + +void UICodeEditor::setFoldDrawable( Drawable* foldDrawable ) { + mFoldDrawable = foldDrawable; +} + +Drawable* UICodeEditor::getFoldedDrawable() const { + return mFoldedDrawable; +} + +void UICodeEditor::setFoldedDrawable( Drawable* foldedDrawable ) { + mFoldedDrawable = foldedDrawable; +} + bool UICodeEditor::isMinimapFileTooLarge() const { return mDocView.getVisibleLinesCount() > 1 && mDocView.getVisibleLinesCount() > diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index fe2eb3387..109822fbb 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -2034,51 +2034,50 @@ std::map App::getDefaultKeybindings() { std::map App::getLocalKeybindings() { return { { { KEY_RETURN, KEYMOD_LALT | KEYMOD_LCTRL }, "fullscreen-toggle" }, - { { KEY_F3, KEYMOD_NONE }, "repeat-find" }, { { KEY_F3, KEYMOD_SHIFT }, "find-prev" }, - { { KEY_F12, KEYMOD_NONE }, "console-toggle" }, - { { KEY_F, KeyMod::getDefaultModifier() }, "find-replace" }, - { { KEY_Q, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "close-app" }, - { { KEY_O, KeyMod::getDefaultModifier() }, "open-file" }, - { { KEY_W, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "download-file-web" }, - { { KEY_O, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-folder" }, - { { KEY_F11, KEYMOD_NONE }, "debug-widget-tree-view" }, - { { KEY_K, KeyMod::getDefaultModifier() }, "open-locatebar" }, - { { KEY_P, KeyMod::getDefaultModifier() }, "open-command-palette" }, - { { KEY_F, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-global-search" }, - { { KEY_L, KeyMod::getDefaultModifier() }, "go-to-line" }, + { { KEY_F3, KEYMOD_NONE }, "repeat-find" }, + { { KEY_F3, KEYMOD_SHIFT }, "find-prev" }, + { { KEY_F12, KEYMOD_NONE }, "console-toggle" }, + { { KEY_F, KeyMod::getDefaultModifier() }, "find-replace" }, + { { KEY_Q, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "close-app" }, + { { KEY_O, KeyMod::getDefaultModifier() }, "open-file" }, + { { KEY_W, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "download-file-web" }, + { { KEY_O, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-folder" }, + { { KEY_F11, KEYMOD_NONE }, "debug-widget-tree-view" }, + { { KEY_K, KeyMod::getDefaultModifier() }, "open-locatebar" }, + { { KEY_P, KeyMod::getDefaultModifier() }, "open-command-palette" }, + { { KEY_F, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-global-search" }, + { { KEY_L, KeyMod::getDefaultModifier() }, "go-to-line" }, #if EE_PLATFORM == EE_PLATFORM_MACOS - { { KEY_M, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "menu-toggle" }, + { { KEY_M, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "menu-toggle" }, #else - { { KEY_M, KeyMod::getDefaultModifier() }, "menu-toggle" }, + { { KEY_M, KeyMod::getDefaultModifier() }, "menu-toggle" }, #endif - { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "save-all" }, - { { KEY_F9, KEYMOD_LALT }, "switch-side-panel" }, - { { KEY_J, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-left" }, - { { KEY_L, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-right" }, - { { KEY_I, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-top" }, - { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-bottom" }, - { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "terminal-split-swap" }, - { { KEY_T, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, - "reopen-closed-tab" }, - { { KEY_1, KEYMOD_LALT }, "toggle-status-locate-bar" }, - { { KEY_2, KEYMOD_LALT }, "toggle-status-global-search-bar" }, - { { KEY_3, KEYMOD_LALT }, "toggle-status-terminal" }, - { { KEY_4, KEYMOD_LALT }, "toggle-status-build-output" }, - { { KEY_5, KEYMOD_LALT }, "toggle-status-app-output" }, - { { KEY_B, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-start" }, - { { KEY_C, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-cancel" }, - { { KEY_F5, KEYMOD_NONE }, "project-build-and-run" }, - { { KEY_O, KEYMOD_LALT | KEYMOD_SHIFT }, "show-open-documents" }, - { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, - "open-workspace-symbol-search" }, - { { KEY_P, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, - "open-document-symbol-search" }, - { { KEY_N, KEYMOD_SHIFT | KEYMOD_LALT }, "create-new-window" }, + { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "save-all" }, + { { KEY_F9, KEYMOD_LALT }, "switch-side-panel" }, + { { KEY_J, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-left" }, + { { KEY_L, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-right" }, + { { KEY_I, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-top" }, + { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-bottom" }, + { { KEY_S, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "terminal-split-swap" }, + { { KEY_T, KeyMod::getDefaultModifier() | KEYMOD_LALT | KEYMOD_SHIFT }, + "reopen-closed-tab" }, + { { KEY_1, KEYMOD_LALT }, "toggle-status-locate-bar" }, + { { KEY_2, KEYMOD_LALT }, "toggle-status-global-search-bar" }, + { { KEY_3, KEYMOD_LALT }, "toggle-status-terminal" }, + { { KEY_4, KEYMOD_LALT }, "toggle-status-build-output" }, + { { KEY_5, KEYMOD_LALT }, "toggle-status-app-output" }, + { { KEY_B, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-start" }, + { { KEY_C, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "project-build-cancel" }, + { { KEY_F5, KEYMOD_NONE }, "project-build-and-run" }, + { { KEY_O, KEYMOD_LALT | KEYMOD_SHIFT }, "show-open-documents" }, + { { KEY_K, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-workspace-symbol-search" }, + { { KEY_P, KeyMod::getDefaultModifier() | KEYMOD_SHIFT }, "open-document-symbol-search" }, + { { KEY_N, KEYMOD_SHIFT | KEYMOD_LALT }, "create-new-window" }, }; } @@ -2087,13 +2086,13 @@ std::map App::getLocalKeybindings() { std::map App::getMigrateKeybindings() { return { { "fullscreen-toggle", "alt+return" }, { "switch-to-tab-1", "alt+1" }, - { "switch-to-tab-2", "alt+2" }, { "switch-to-tab-3", "alt+3" }, - { "switch-to-tab-4", "alt+4" }, { "switch-to-tab-5", "alt+5" }, - { "switch-to-tab-6", "alt+6" }, { "switch-to-tab-7", "alt+7" }, - { "switch-to-tab-8", "alt+8" }, { "switch-to-tab-9", "alt+9" }, - { "switch-to-last-tab", "alt+0" }, + { "switch-to-tab-2", "alt+2" }, { "switch-to-tab-3", "alt+3" }, + { "switch-to-tab-4", "alt+4" }, { "switch-to-tab-5", "alt+5" }, + { "switch-to-tab-6", "alt+6" }, { "switch-to-tab-7", "alt+7" }, + { "switch-to-tab-8", "alt+8" }, { "switch-to-tab-9", "alt+9" }, + { "switch-to-last-tab", "alt+0" }, #if EE_PLATFORM == EE_PLATFORM_MACOS - { "menu-toggle", "mod+shift+m" }, + { "menu-toggle", "mod+shift+m" }, #endif }; } @@ -2522,6 +2521,8 @@ void App::onCodeEditorCreated( UICodeEditor* editor, TextDocument& doc ) { editor->setLineWrapKeepIndentation( config.wrapKeepIndentation ); editor->setLineWrapMode( config.wrapMode ); editor->setLineWrapType( config.wrapType ); + editor->setFoldDrawable( findIcon( "chevron-down", PixelDensity::dpToPxI( 12 ) ) ); + editor->setFoldedDrawable( findIcon( "chevron-right", PixelDensity::dpToPxI( 12 ) ) ); doc.setAutoCloseBrackets( !mConfig.editor.autoCloseBrackets.empty() ); doc.setAutoCloseBracketsPairs( makeAutoClosePairs( mConfig.editor.autoCloseBrackets ) ); diff --git a/src/tools/ecode/iconmanager.cpp b/src/tools/ecode/iconmanager.cpp index 5e7a52a05..910032e8c 100644 --- a/src/tools/ecode/iconmanager.cpp +++ b/src/tools/ecode/iconmanager.cpp @@ -216,6 +216,7 @@ void IconManager::init( UISceneNode* sceneNode, FontTrueType* iconFont, FontTrue { "symbol-key", 0xea93 }, { "symbol-null", 0xea8f }, { "collapse-all", 0xeac5 }, + { "chevron-down", 0xeab4 }, { "chevron-right", 0xeab6 }, { "lightbulb-autofix", 0xeb13 }, { "layout-sidebar-left-off", 0xec02 }, diff --git a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp index f4e56c81d..07aa0616b 100644 --- a/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp +++ b/src/tools/ecode/plugins/lsp/lspdocumentclient.cpp @@ -28,6 +28,7 @@ LSPDocumentClient::LSPDocumentClient( LSPClientServer* server, TextDocument* doc } LSPDocumentClient::~LSPDocumentClient() { + mDoc->getFoldRangeService().setProvider( nullptr ); mDoc = nullptr; UISceneNode* sceneNode = getUISceneNode(); if ( nullptr != sceneNode && 0 != mTag )