From 3d002678a85f74cd9ecd30728b893ff27192ea31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 1 Oct 2025 00:50:03 -0300 Subject: [PATCH] Added "join-lines" (SpartanJ/ecode#669). Added "move-to-previous-paragraph", "move-to-next-paragraph", "select-paragraph", "delete-paragraph" (SpartanJ/ecode#670). Updated codicon font and changed the AI Assistant main icon. Improved `CommandPalette::build`. --- bin/assets/fonts/codicon.ttf | Bin 82548 -> 90728 bytes include/eepp/ui/doc/textdocument.hpp | 17 +- src/eepp/ui/doc/textdocument.cpp | 86 +++ src/eepp/ui/iconmanager.cpp | 534 +++++++++--------- src/tools/ecode/commandpalette.cpp | 18 +- .../plugins/aiassistant/aiassistantplugin.cpp | 6 +- .../ecode/plugins/aiassistant/chatui.cpp | 15 +- 7 files changed, 393 insertions(+), 283 deletions(-) diff --git a/bin/assets/fonts/codicon.ttf b/bin/assets/fonts/codicon.ttf index f60b260e0402715b055fd642ceac4c8143bb9161..0989abf8ef1af54f0928ae2bbeee9c76cda8394b 100644 GIT binary patch delta 20706 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 diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index 8af0bf724..44527e41f 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -293,7 +293,7 @@ class EE_API TextDocument { std::size_t getLineLength( Int64 ) const; - void safeLineOp( Int64 line, std::function op ); + void safeLineOp( Int64 line, std::function op ); void getLineTextToBuffer( Int64 line, String& buffer ) const; @@ -839,6 +839,21 @@ class EE_API TextDocument { TextRange restrictRange = TextRange() ); void changeFilePath( const std::string& filePath, bool notify ); + + void joinLines(); + + TextPosition findPreviousEmptyLines( size_t selIdx ); + + TextPosition findNextEmptyLines( size_t selIdx ); + + void moveToNextParagraph(); + + void moveToPreviousParagraph(); + + void selectCurrentParagraph(); + + void deleteCurrentParagraph(); + }; struct TextSearchParams { diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index a90667776..dde5c6ee4 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -4132,6 +4132,87 @@ void TextDocument::trimTrailingWhitespace() { } } +void TextDocument::joinLines() { + if ( linesCount() < 2 ) + return; + + BoolScopedOp op( mDoingTextInput, true ); + for ( size_t cursorIdx = mSelection.size() - 1; cursorIdx != (size_t)-1; --cursorIdx ) { + auto range = getSelectionIndex( cursorIdx ).normalized(); + Int64 startLine = range.start().line(); + Int64 endLine = range.hasSelection() ? range.end().line() : startLine; + Int64 joinTo = endLine + ( range.hasSelection() ? 0 : 1 ); + if ( joinTo >= (Int64)linesCount() || startLine >= joinTo ) + continue; + + String joined; + for ( Int64 ln = startLine; ln <= joinTo; ln++ ) { + String part = getLineTextWithoutNewLine( ln ); + if ( ln > startLine ) { + size_t lpos = part.find_first_not_of( " \t" ); + part = lpos != String::InvalidPos ? part.substr( lpos ) : String(); + } + if ( ln < joinTo ) { + size_t rpos = part.find_last_not_of( " \t" ); + part = rpos != String::InvalidPos ? part.substr( 0, rpos + 1 ) : String(); + } + if ( !joined.empty() ) + joined += String( " " ); + joined += part; + } + + TextRange repRange( { startLine, 0 }, { joinTo, (Int64)( getLineLength( joinTo ) - 1 ) } ); + remove( cursorIdx, repRange ); + setSelection( cursorIdx, insert( cursorIdx, { startLine, 0 }, joined ) ); + } + mergeSelection(); +} + +TextPosition TextDocument::findPreviousEmptyLines( size_t selIdx ) { + Int64 startLine = mSelection[selIdx].normalized().start().line() - 1; + bool found = false; + for ( ; startLine >= 0; --startLine ) { + if ( getLineLength( startLine ) == 1 ) { + found = true; + break; + } + } + return found ? TextPosition{ startLine, static_cast( getLineLength( startLine ) ) } + : startOfDoc(); +} + +TextPosition TextDocument::findNextEmptyLines( size_t selIdx ) { + Int64 startLine = mSelection[selIdx].normalized().end().line() + 1; + bool found = false; + for ( ; startLine < static_cast( linesCount() ); ++startLine ) { + if ( getLineLength( startLine ) == 1 ) { + found = true; + break; + } + } + return found ? TextPosition{ startLine, 0 } : endOfDoc(); +} + +void TextDocument::moveToPreviousParagraph() { + for ( size_t i = 0; i < mSelection.size(); ++i ) + setSelection( i, findPreviousEmptyLines( i ) ); +} + +void TextDocument::moveToNextParagraph() { + for ( size_t i = 0; i < mSelection.size(); ++i ) + setSelection( i, findNextEmptyLines( i ) ); +} + +void TextDocument::selectCurrentParagraph() { + for ( size_t i = 0; i < mSelection.size(); ++i ) + setSelection( i, { findPreviousEmptyLines( i ), findNextEmptyLines( i ) } ); +} + +void TextDocument::deleteCurrentParagraph() { + selectCurrentParagraph(); + deleteToNextChar(); +} + void TextDocument::initializeCommands() { mCommands["reset"] = [this] { reset(); }; mCommands["save"] = [this] { save(); }; @@ -4144,6 +4225,7 @@ void TextDocument::initializeCommands() { mCommands["delete-to-end-of-line"] = [this] { deleteToEndOfLine(); }; mCommands["delete-selection"] = [this] { deleteSelection(); }; mCommands["delete-word"] = [this] { deleteWord(); }; + mCommands["delete-paragraph"] = [this] { deleteCurrentParagraph(); }; mCommands["move-to-previous-char"] = [this] { moveToPreviousChar(); }; mCommands["move-to-previous-word"] = [this] { moveToPreviousWord(); }; mCommands["move-to-next-char"] = [this] { moveToNextChar(); }; @@ -4157,6 +4239,8 @@ void TextDocument::initializeCommands() { mCommands["move-to-start-of-line"] = [this] { moveToStartOfLine(); }; mCommands["move-to-end-of-line"] = [this] { moveToEndOfLine(); }; mCommands["move-to-start-of-content"] = [this] { moveToStartOfContent(); }; + mCommands["move-to-previous-paragraph"] = [this] { moveToPreviousParagraph(); }; + mCommands["move-to-next-paragraph"] = [this] { moveToNextParagraph(); }; mCommands["move-lines-up"] = [this] { moveLinesUp(); }; mCommands["move-lines-down"] = [this] { moveLinesDown(); }; mCommands["select-to-previous-char"] = [this] { selectToPreviousChar(); }; @@ -4176,6 +4260,7 @@ void TextDocument::initializeCommands() { mCommands["select-to-end-of-doc"] = [this] { selectToEndOfDoc(); }; mCommands["select-to-previous-page"] = [this] { selectToPreviousPage( mPageSize ); }; mCommands["select-to-next-page"] = [this] { selectToNextPage( mPageSize ); }; + mCommands["select-paragraph"] = [this] { selectCurrentParagraph(); }; mCommands["select-all"] = [this] { selectAll(); }; mCommands["new-line"] = [this] { newLine(); }; mCommands["new-line-above"] = [this] { newLineAbove(); }; @@ -4197,6 +4282,7 @@ void TextDocument::initializeCommands() { mCommands["to-base64"] = [this] { toBase64(); }; mCommands["from-base64"] = [this] { fromBase64(); }; mCommands["trim-trailing-whitespace"] = [this] { trimTrailingWhitespace(); }; + mCommands["join-lines"] = [this] { joinLines(); }; if ( TEXT_DOCUMENT_COMMANDS.empty() ) { for ( const auto& [cmd, _] : mCommands ) diff --git a/src/eepp/ui/iconmanager.cpp b/src/eepp/ui/iconmanager.cpp index a294fd66e..7a30fb703 100644 --- a/src/eepp/ui/iconmanager.cpp +++ b/src/eepp/ui/iconmanager.cpp @@ -4,6 +4,8 @@ namespace EE { namespace UI { +using IconPair = std::pair; + UIIconTheme* IconManager::init( const std::string& iconThemeName, FontTrueType* remixIconFont, FontTrueType* noniconFont, FontTrueType* codIconFont ) { @@ -11,288 +13,290 @@ UIIconTheme* IconManager::init( const std::string& iconThemeName, FontTrueType* if ( remixIconFont && remixIconFont->loaded() ) { remixIconFont->setIsEmojiFont( true ); - std::unordered_map icons = { - { "document-new", 0xecc3 }, - { "document-open", 0xed70 }, - { "document-save", 0xf0b3 }, - { "document-save-as", 0xf0b3 }, - { "document-close", 0xeb99 }, - { "quit", 0xeb97 }, - { "undo", 0xea58 }, - { "redo", 0xea5a }, - { "cut", 0xf0c1 }, - { "copy", 0xecd5 }, - { "paste", 0xeb91 }, - { "edit", 0xec86 }, - { "split-horizontal", 0xf17a }, - { "split-vertical", 0xf17b }, - { "find-replace", 0xed2b }, - { "folder-add", 0xed5a }, - { "file-add", 0xecc9 }, - { "file-copy", 0xecd3 }, - { "file-code", 0xecd1 }, - { "file-edit", 0xecdb }, - { "font-size", 0xed8d }, - { "delete-bin", 0xec1e }, - { "delete-text", 0xec1e }, - { "zoom-in", 0xf2db }, - { "zoom-out", 0xf2dd }, - { "zoom-reset", 0xeb47 }, - { "fullscreen", 0xed9c }, - { "keybindings", 0xee75 }, - { "search", 0xf0d1 }, - { "go-up", 0xea78 }, - { "ok", 0xeb7a }, - { "cancel", 0xeb98 }, - { "color-picker", 0xf13d }, - { "pixel-density", 0xed8c }, - { "go-to-line", 0xf1f8 }, - { "table-view", 0xf1de }, - { "list-view", 0xecf1 }, - { "menu-unfold", 0xef40 }, - { "menu-fold", 0xef3d }, - { "download-cloud", 0xec58 }, - { "layout-left", 0xee94 }, - { "layout-right", 0xee9b }, - { "color-scheme", 0xebd4 }, - { "global-settings", 0xedcf }, - { "folder-user", 0xed84 }, - { "help", 0xf045 }, - { "terminal", 0xf1f6 }, - { "earth", 0xec7a }, - { "arrow-down", 0xea4c }, - { "arrow-up", 0xea76 }, - { "arrow-down-s", 0xea4e }, - { "arrow-up-s", 0xea78 }, - { "arrow-right-s", 0xea6e }, - { "match-case", 0xed8d }, - { "palette", 0xefc5 }, - { "file-code", 0xecd1 }, - { "cursor-pointer", 0xec09 }, - { "drive", 0xedf8 }, - { "refresh", 0xf064 }, - { "hearth-pulse", 0xee10 }, - { "add", 0xea12 }, - { "hammer", 0xedee }, - { "eraser", 0xec9e }, - { "file-search", 0xed05 }, - { "window", 0xf2c4 }, - { "file-lock-fill", 0xecf2 }, - { "filetype-svg", 0xF3C5 }, - { "filetype-png", 0xF3C5 }, - { "filetype-jpg", 0xF3C5 }, - { "filetype-jpeg", 0xF3C5 }, - { "filetype-tga", 0xF3C5 }, - { "filetype-dds", 0xF3C5 }, - { "filetype-qoi", 0xF3C5 }, - { "filetype-bmp", 0xF3C5 }, - { "filetype-gif", 0xF3C5 }, - { "filetype-psd", 0xF3C5 }, - { "filetype-hdr", 0xF3C5 }, - { "filetype-pic", 0xF3C5 }, - { "filetype-pvr", 0xF3C5 }, - { "filetype-pkm", 0xF3C5 }, - { "filetype-mp3", 0xEF83 }, - { "filetype-ogg", 0xEF83 }, - { "filetype-wav", 0xEF83 }, - { "filetype-flac", 0xEF83 }, - { "settings", 0xF0E3 }, - { "stop", 0xF1A0 }, - { "text-wrap", 0xF200 }, - { "play-filled", 0xF00A }, - { "code-ai", 0xF56F }, - { "robot-2", 0xF3D9 }, - { "chat-history", 0xEB61 }, - { "chat-private", 0xEB69 }, - { "loader-2", 0xEEC2 }, - { "more-fill", 0xEF78 }, - { "volume-up-fill", 0xF2A1 }, - { "volume-down-fill", 0xF29B }, - { "volume-mute-fill", 0xF29D }, - { "pause-fill", 0xEFD7 }, - }; + for ( const auto& icon : std::initializer_list{ - for ( const auto& icon : icons ) + { "document-new", 0xecc3 }, + { "document-open", 0xed70 }, + { "document-save", 0xf0b3 }, + { "document-save-as", 0xf0b3 }, + { "document-close", 0xeb99 }, + { "quit", 0xeb97 }, + { "undo", 0xea58 }, + { "redo", 0xea5a }, + { "cut", 0xf0c1 }, + { "copy", 0xecd5 }, + { "paste", 0xeb91 }, + { "edit", 0xec86 }, + { "split-horizontal", 0xf17a }, + { "split-vertical", 0xf17b }, + { "find-replace", 0xed2b }, + { "folder-add", 0xed5a }, + { "file-add", 0xecc9 }, + { "file-copy", 0xecd3 }, + { "file-code", 0xecd1 }, + { "file-edit", 0xecdb }, + { "font-size", 0xed8d }, + { "delete-bin", 0xec1e }, + { "delete-text", 0xec1e }, + { "zoom-in", 0xf2db }, + { "zoom-out", 0xf2dd }, + { "zoom-reset", 0xeb47 }, + { "fullscreen", 0xed9c }, + { "keybindings", 0xee75 }, + { "search", 0xf0d1 }, + { "go-up", 0xea78 }, + { "ok", 0xeb7a }, + { "cancel", 0xeb98 }, + { "color-picker", 0xf13d }, + { "pixel-density", 0xed8c }, + { "go-to-line", 0xf1f8 }, + { "table-view", 0xf1de }, + { "list-view", 0xecf1 }, + { "menu-unfold", 0xef40 }, + { "menu-fold", 0xef3d }, + { "download-cloud", 0xec58 }, + { "layout-left", 0xee94 }, + { "layout-right", 0xee9b }, + { "color-scheme", 0xebd4 }, + { "global-settings", 0xedcf }, + { "folder-user", 0xed84 }, + { "help", 0xf045 }, + { "terminal", 0xf1f6 }, + { "earth", 0xec7a }, + { "arrow-down", 0xea4c }, + { "arrow-up", 0xea76 }, + { "arrow-down-s", 0xea4e }, + { "arrow-up-s", 0xea78 }, + { "arrow-right-s", 0xea6e }, + { "match-case", 0xed8d }, + { "palette", 0xefc5 }, + { "file-code", 0xecd1 }, + { "cursor-pointer", 0xec09 }, + { "drive", 0xedf8 }, + { "refresh", 0xf064 }, + { "hearth-pulse", 0xee10 }, + { "add", 0xea12 }, + { "hammer", 0xedee }, + { "eraser", 0xec9e }, + { "file-search", 0xed05 }, + { "window", 0xf2c4 }, + { "file-lock-fill", 0xecf2 }, + { "filetype-svg", 0xF3C5 }, + { "filetype-png", 0xF3C5 }, + { "filetype-jpg", 0xF3C5 }, + { "filetype-jpeg", 0xF3C5 }, + { "filetype-tga", 0xF3C5 }, + { "filetype-dds", 0xF3C5 }, + { "filetype-qoi", 0xF3C5 }, + { "filetype-bmp", 0xF3C5 }, + { "filetype-gif", 0xF3C5 }, + { "filetype-psd", 0xF3C5 }, + { "filetype-hdr", 0xF3C5 }, + { "filetype-pic", 0xF3C5 }, + { "filetype-pvr", 0xF3C5 }, + { "filetype-pkm", 0xF3C5 }, + { "filetype-mp3", 0xEF83 }, + { "filetype-ogg", 0xEF83 }, + { "filetype-wav", 0xEF83 }, + { "filetype-flac", 0xEF83 }, + { "settings", 0xF0E3 }, + { "stop", 0xF1A0 }, + { "text-wrap", 0xF200 }, + { "play-filled", 0xF00A }, + { "code-ai", 0xF56F }, + { "robot-2", 0xF3D9 }, + { "chat-history", 0xEB61 }, + { "chat-private", 0xEB69 }, + { "loader-2", 0xEEC2 }, + { "more-fill", 0xEF78 }, + { "volume-up-fill", 0xF2A1 }, + { "volume-down-fill", 0xF29B }, + { "volume-mute-fill", 0xF29D }, + { "pause-fill", 0xEFD7 }, + } ) { iconTheme->add( UIGlyphIcon::New( icon.first, remixIconFont, icon.second ) ); + } } if ( noniconFont && noniconFont->loaded() ) { noniconFont->setIsEmojiFont( true ); - std::unordered_map mimeIcons = - { { "filetype-lua", 61826 }, - { "filetype-c", 61718 }, - { "filetype-h", 61792 }, - { "filetype-cs", 61720 }, - { "filetype-cpp", 61719 }, - { "filetype-hpp", 61719 }, - { "filetype-css", 61743 }, - { "filetype-conf", 61781 }, - { "filetype-cfg", 61781 }, - { "filetype-desktop", 61781 }, - { "filetype-service", 61781 }, - { "filetype-env", 61781 }, - { "filetype-properties", 61781 }, - { "filetype-ini", 61781 }, - { "filetype-dart", 61744 }, - { "filetype-diff", 61752 }, - { "filetype-zip", 61775 }, - { "filetype-go", 61789 }, - { "filetype-htm", 61799 }, - { "filetype-html", 61799 }, - { "filetype-java", 61809 }, - { "filetype-js", 61810 }, - { "filetype-json", 61811 }, - { "filetype-kt", 61814 }, - { "filetype-md", 61829 }, - { "filetype-perl", 61853 }, - { "filetype-php", 61855 }, - { "filetype-py", 61863 }, - { "filetype-pyc", 61863 }, - { "filetype-pyd", 61863 }, - { "filetype-swift", 61906 }, - { "filetype-rb", 61880 }, - { "filetype-rs", 61881 }, - { "filetype-ts", 61923 }, - { "filetype-jsx", 0xf1ab }, - { "filetype-tsx", 0xf1ab }, - { "filetype-yaml", 61945 }, - { "filetype-yml", 61945 }, - { "filetype-jpg", 61801 }, - { "filetype-png", 61801 }, - { "filetype-jpeg", 61801 }, - { "filetype-bmp", 61801 }, - { "filetype-tga", 61801 }, - { "filetype-sh", 61911 }, - { "filetype-bash", 61911 }, - { "filetype-fish", 61911 }, - { "filetype-scala", 61882 }, - { "filetype-r", 61866 }, - { "filetype-rake", 61880 }, - { "filetype-rss", 61879 }, - { "filetype-sql", 61746 }, - { "filetype-elm", 61763 }, - { "filetype-ex", 61971 }, - { "filetype-exs", 61971 }, - { "filetype-awk", 61971 }, - { "filetype-nim", 61734 }, - { "filetype-xml", 61769 }, - { "filetype-dockerfile", 61758 }, - { "filetype-scala", 61882 }, - { "filetype-sc", 61882 }, - { "filetype-perl", 61853 }, - { "filetype-vue", 0xf1f4 }, - { "file", 61766 }, - { "file-symlink", 61774 }, - { "folder", 0xF23B }, - { "folder-open", 0xF23C }, - { "tree-expanded", 0xF11E }, - { "tree-contracted", 0xF120 }, - { "github", 0xF184 }, - { "package", 61846 }, - { "tab-close", 61944 } }; + for ( const auto& icon : std::initializer_list - for ( const auto& icon : mimeIcons ) + { { "filetype-lua", 61826 }, + { "filetype-c", 61718 }, + { "filetype-h", 61792 }, + { "filetype-cs", 61720 }, + { "filetype-cpp", 61719 }, + { "filetype-hpp", 61719 }, + { "filetype-css", 61743 }, + { "filetype-conf", 61781 }, + { "filetype-cfg", 61781 }, + { "filetype-desktop", 61781 }, + { "filetype-service", 61781 }, + { "filetype-env", 61781 }, + { "filetype-properties", 61781 }, + { "filetype-ini", 61781 }, + { "filetype-dart", 61744 }, + { "filetype-diff", 61752 }, + { "filetype-zip", 61775 }, + { "filetype-go", 61789 }, + { "filetype-htm", 61799 }, + { "filetype-html", 61799 }, + { "filetype-java", 61809 }, + { "filetype-js", 61810 }, + { "filetype-json", 61811 }, + { "filetype-kt", 61814 }, + { "filetype-md", 61829 }, + { "filetype-perl", 61853 }, + { "filetype-php", 61855 }, + { "filetype-py", 61863 }, + { "filetype-pyc", 61863 }, + { "filetype-pyd", 61863 }, + { "filetype-swift", 61906 }, + { "filetype-rb", 61880 }, + { "filetype-rs", 61881 }, + { "filetype-ts", 61923 }, + { "filetype-jsx", 0xf1ab }, + { "filetype-tsx", 0xf1ab }, + { "filetype-yaml", 61945 }, + { "filetype-yml", 61945 }, + { "filetype-jpg", 61801 }, + { "filetype-png", 61801 }, + { "filetype-jpeg", 61801 }, + { "filetype-bmp", 61801 }, + { "filetype-tga", 61801 }, + { "filetype-sh", 61911 }, + { "filetype-bash", 61911 }, + { "filetype-fish", 61911 }, + { "filetype-scala", 61882 }, + { "filetype-r", 61866 }, + { "filetype-rake", 61880 }, + { "filetype-rss", 61879 }, + { "filetype-sql", 61746 }, + { "filetype-elm", 61763 }, + { "filetype-ex", 61971 }, + { "filetype-exs", 61971 }, + { "filetype-awk", 61971 }, + { "filetype-nim", 61734 }, + { "filetype-xml", 61769 }, + { "filetype-dockerfile", 61758 }, + { "filetype-scala", 61882 }, + { "filetype-sc", 61882 }, + { "filetype-perl", 61853 }, + { "filetype-vue", 0xf1f4 }, + { "file", 61766 }, + { "file-symlink", 61774 }, + { "folder", 0xF23B }, + { "folder-open", 0xF23C }, + { "tree-expanded", 0xF11E }, + { "tree-contracted", 0xF120 }, + { "github", 0xF184 }, + { "package", 61846 }, + { "tab-close", 61944 } } ) { iconTheme->add( UIGlyphIcon::New( icon.first, noniconFont, icon.second ) ); + } } if ( codIconFont && codIconFont->loaded() ) { codIconFont->setIsEmojiFont( true ); - std::unordered_map codIcons = { - { "symbol-text", 0xea93 }, - { "symbol-method", 0xea8c }, - { "symbol-function", 0xea8c }, - { "symbol-constructor", 0xea8c }, - { "symbol-field", 0xeb5f }, - { "symbol-variable", 0xea88 }, - { "symbol-class", 0xeb5b }, - { "symbol-interface", 0xeb61 }, - { "symbol-module", 0xea8b }, - { "symbol-property", 0xeb65 }, - { "symbol-unit", 0xea96 }, - { "symbol-value", 0xea95 }, - { "symbol-enum", 0xea95 }, - { "symbol-keyword", 0xeb62 }, - { "symbol-snippet", 0xeb66 }, - { "symbol-color", 0xeb5c }, - { "symbol-file", 0xeb60 }, - { "symbol-reference", 0xea94 }, - { "symbol-folder", 0xea83 }, - { "symbol-enum-member", 0xeb5e }, - { "symbol-constant", 0xeb5d }, - { "symbol-struct", 0xea91 }, - { "symbol-event", 0xea86 }, - { "symbol-operator", 0xeb64 }, - { "symbol-type-parameter", 0xea92 }, - { "expand-all", 0xeb95 }, - { "symbol-namespace", 0xea8b }, - { "symbol-package", 0xea8b }, - { "symbol-string", 0xeb8d }, - { "symbol-number", 0xea90 }, - { "symbol-boolean", 0xea8f }, - { "symbol-array", 0xea8a }, - { "symbol-object", 0xea8b }, - { "symbol-key", 0xea93 }, - { "symbol-null", 0xea8f }, - { "collapse-all", 0xeac5 }, - { "chevron-down", 0xeab4 }, - { "chevron-right", 0xeab6 }, - { "lightbulb-autofix", 0xeb13 }, - { "layout-sidebar-left-off", 0xec02 }, - { "layout-sidebar-left", 0xebf3 }, - { "warning", 0xea6c }, - { "error", 0xea87 }, - { "search-fuzzy", 0xec0d }, - { "source-control", 0xea68 }, - { "repo", 0xea62 }, - { "repo-pull", 0xeb40 }, - { "repo-push", 0xeb41 }, - { "repo-forked", 0xea63 }, - { "repo-fetch", 0xec1d }, - { "git-fetch", 0xf101 }, - { "git-commit", 0xeafc }, - { "git-stash", 0xec26 }, - { "git-stash-apply", 0xec27 }, - { "git-stash-pop", 0xec28 }, - { "git-merge", 0xeafe }, - { "diff-single", 0xec22 }, - { "remove", 0xeb3b }, - { "tag", 0xea66 }, - { "globe", 0xeb01 }, - { "circle-filled", 0xea71 }, - { "circle", 0xeabc }, - { "diff-multiple", 0xec23 }, - { "extensions", 0xeae6 }, - { "window-opt", 0xeb7f }, - { "tools", 0xeb6d }, - { "play", 0xeb2c }, - { "output", 0xeb9d }, - { "fold", 0xeaf5 }, - { "bug", 0xeaaf }, - { "debug", 0xead8 }, - { "debug-alt", 0xeb91 }, - { "debug-continue", 0xeacf }, - { "debug-disconnect", 0xead0 }, - { "debug-pause", 0xead1 }, - { "debug-restart", 0xead2 }, - { "debug-start", 0xead3 }, - { "debug-step-into", 0xead4 }, - { "debug-step-out", 0xead5 }, - { "debug-step-over", 0xead6 }, - { "debug-stop", 0xead7 }, - { "chrome-close", 0xeab8 }, - { "diff-added", 0xeadc }, - { "diff-removed", 0xeadf }, - { "eye", 0xea70 }, - { "eye-closed", 0xeae7 }, - { "settings-alt", 0xeb52 }, - { "attach", 0xec34 }, - }; + for ( const auto& icon : std::initializer_list{ - for ( const auto& icon : codIcons ) + { "symbol-text", 0xea93 }, + { "symbol-method", 0xea8c }, + { "symbol-function", 0xea8c }, + { "symbol-constructor", 0xea8c }, + { "symbol-field", 0xeb5f }, + { "symbol-variable", 0xea88 }, + { "symbol-class", 0xeb5b }, + { "symbol-interface", 0xeb61 }, + { "symbol-module", 0xea8b }, + { "symbol-property", 0xeb65 }, + { "symbol-unit", 0xea96 }, + { "symbol-value", 0xea95 }, + { "symbol-enum", 0xea95 }, + { "symbol-keyword", 0xeb62 }, + { "symbol-snippet", 0xeb66 }, + { "symbol-color", 0xeb5c }, + { "symbol-file", 0xeb60 }, + { "symbol-reference", 0xea94 }, + { "symbol-folder", 0xea83 }, + { "symbol-enum-member", 0xeb5e }, + { "symbol-constant", 0xeb5d }, + { "symbol-struct", 0xea91 }, + { "symbol-event", 0xea86 }, + { "symbol-operator", 0xeb64 }, + { "symbol-type-parameter", 0xea92 }, + { "expand-all", 0xeb95 }, + { "symbol-namespace", 0xea8b }, + { "symbol-package", 0xea8b }, + { "symbol-string", 0xeb8d }, + { "symbol-number", 0xea90 }, + { "symbol-boolean", 0xea8f }, + { "symbol-array", 0xea8a }, + { "symbol-object", 0xea8b }, + { "symbol-key", 0xea93 }, + { "symbol-null", 0xea8f }, + { "collapse-all", 0xeac5 }, + { "chevron-down", 0xeab4 }, + { "chevron-right", 0xeab6 }, + { "lightbulb-autofix", 0xeb13 }, + { "layout-sidebar-left-off", 0xec02 }, + { "layout-sidebar-left", 0xebf3 }, + { "warning", 0xea6c }, + { "error", 0xea87 }, + { "search-fuzzy", 0xec0d }, + { "source-control", 0xea68 }, + { "repo", 0xea62 }, + { "repo-pull", 0xeb40 }, + { "repo-push", 0xeb41 }, + { "repo-forked", 0xea63 }, + { "repo-fetch", 0xec1d }, + { "git-fetch", 0xf101 }, + { "git-commit", 0xeafc }, + { "git-stash", 0xec26 }, + { "git-stash-apply", 0xec27 }, + { "git-stash-pop", 0xec28 }, + { "git-merge", 0xeafe }, + { "diff-single", 0xec22 }, + { "remove", 0xeb3b }, + { "tag", 0xea66 }, + { "globe", 0xeb01 }, + { "circle-filled", 0xea71 }, + { "circle", 0xeabc }, + { "diff-multiple", 0xec23 }, + { "extensions", 0xeae6 }, + { "window-opt", 0xeb7f }, + { "tools", 0xeb6d }, + { "play", 0xeb2c }, + { "output", 0xeb9d }, + { "fold", 0xeaf5 }, + { "bug", 0xeaaf }, + { "debug", 0xead8 }, + { "debug-alt", 0xeb91 }, + { "debug-continue", 0xeacf }, + { "debug-disconnect", 0xead0 }, + { "debug-pause", 0xead1 }, + { "debug-restart", 0xead2 }, + { "debug-start", 0xead3 }, + { "debug-step-into", 0xead4 }, + { "debug-step-out", 0xead5 }, + { "debug-step-over", 0xead6 }, + { "debug-stop", 0xead7 }, + { "chrome-close", 0xeab8 }, + { "diff-added", 0xeadc }, + { "diff-removed", 0xeadf }, + { "eye", 0xea70 }, + { "eye-closed", 0xeae7 }, + { "settings-alt", 0xeb52 }, + { "attach", 0xec34 }, + { "chat-sparkle", 0xEC4F }, + + } ) { iconTheme->add( UIGlyphIcon::New( icon.first, codIconFont, icon.second ) ); + } } iconTheme->add( UISVGIcon::New( diff --git a/src/tools/ecode/commandpalette.cpp b/src/tools/ecode/commandpalette.cpp index 912d51e48..b4dd078d2 100644 --- a/src/tools/ecode/commandpalette.cpp +++ b/src/tools/ecode/commandpalette.cpp @@ -6,14 +6,18 @@ std::vector> CommandPalette::build( const std::vector& commandList, const EE::UI::KeyBindings& keybindings ) { std::vector> ret; + std::unordered_set processedCommands; + ret.reserve( commandList.size() ); + processedCommands.reserve( commandList.size() ); for ( const auto& cmd : commandList ) { - if ( std::find_if( ret.begin(), ret.end(), - [&cmd]( const auto& other ) { return other[2] == cmd; } ) != ret.end() ) - continue; - std::string cmdName( cmd ); - String::capitalizeInPlace( cmdName ); - String::replaceAll( cmdName, "-", " " ); - ret.push_back( { cmdName, keybindings.getCommandKeybindString( cmd ), cmd } ); + if ( processedCommands.insert( cmd ).second ) { + std::string cmdName( cmd ); + String::capitalizeInPlace( cmdName ); + String::replaceAll( cmdName, "-", " " ); + + ret.push_back( + { std::move( cmdName ), keybindings.getCommandKeybindString( cmd ), cmd } ); + } } return ret; } diff --git a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp index 59d4466e9..a65323c69 100644 --- a/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp +++ b/src/tools/ecode/plugins/aiassistant/aiassistantplugin.cpp @@ -240,7 +240,7 @@ void AIAssistantPlugin::load( PluginManager* pluginManager ) { } ); } - return TabWidgetData{ chatUI, getPluginContext()->findIcon( "code-ai" ), + return TabWidgetData{ chatUI, getPluginContext()->findIcon( "chat-sparkle" ), i18n( "ai_assistant", "AI Assistant" ) }; }; config.onSave = []( UIWidget* widget ) { @@ -415,7 +415,7 @@ LLMChatUI* AIAssistantPlugin::newAIAssistant() { if ( !splitter->hasSplit() ) tabWidget = splitter->splitTabWidget( SplitDirection::Right, tabWidget ); auto [tab, _] = splitter->createWidgetInTabWidget( tabWidget, chatUI, tabName ); - auto icon = getPluginContext()->findIcon( "code-ai" ); + auto icon = getPluginContext()->findIcon( "chat-sparkle" ); if ( icon ) tab->setIcon( icon ); return chatUI; @@ -479,7 +479,7 @@ void AIAssistantPlugin::initUI() { mStatusButton->setParent( mStatusBar ); mStatusButton->setId( "ai_assistant_but" ); mStatusButton->setClass( "status_but" ); - mStatusButton->setIcon( iconDrawable( "code-ai", 14 ) ); + mStatusButton->setIcon( iconDrawable( "chat-sparkle", 14 ) ); mStatusButton->setTooltipText( i18n( "ai_assistant", "AI Assistant" ) ); mStatusButton->on( Event::MouseClick, [this]( const Event* ) { newAIAssistant()->setFocus(); } ); diff --git a/src/tools/ecode/plugins/aiassistant/chatui.cpp b/src/tools/ecode/plugins/aiassistant/chatui.cpp index 7c6325e99..f1d99362c 100644 --- a/src/tools/ecode/plugins/aiassistant/chatui.cpp +++ b/src/tools/ecode/plugins/aiassistant/chatui.cpp @@ -392,13 +392,14 @@ LLMChatUI::LLMChatUI( PluginManager* manager ) : setCmd( "ai-show-menu", [this] { UIPopUpMenu* menu = UIPopUpMenu::New(); - menu->add( i18n( "new_conversation", "New Conversation" ), - getUISceneNode()->findIconDrawable( "code-ai", PixelDensity::dpToPxI( 12 ) ), - getPlugin() - ->getPluginContext() - ->getMainLayout() - ->getKeyBindings() - .getCommandKeybindString( "new-ai-assistant" ) ) + menu->add( + i18n( "new_conversation", "New Conversation" ), + getUISceneNode()->findIconDrawable( "chat-sparkle", PixelDensity::dpToPxI( 12 ) ), + getPlugin() + ->getPluginContext() + ->getMainLayout() + ->getKeyBindings() + .getCommandKeybindString( "new-ai-assistant" ) ) ->setId( "new-ai-assistant" ); menu->add(