diff --git a/bin/assets/fonts/codicon.ttf b/bin/assets/fonts/codicon.ttf index f60b260e0..0989abf8e 100644 Binary files a/bin/assets/fonts/codicon.ttf and b/bin/assets/fonts/codicon.ttf differ 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(