diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index 91bee978e..4ce4caa60 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -656,6 +656,14 @@ class EE_API TextDocument { bool isHuge() const; + void escape(); + + void unescape(); + + void toBase64(); + + void fromBase64(); + protected: friend class TextUndoStack; friend class FoldRangeServive; diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 6f0af1b49..87c6c27bf 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -1,6 +1,6 @@ -#include -#include +#include #include +#include #include #include #include @@ -3588,6 +3588,123 @@ void TextDocument::notifiyDocumenLineMove( const Int64& fromLine, const Int64& t } } +void TextDocument::escape() { + BoolScopedOpOptional op( !mDoingTextInput, mDoingTextInput, true ); + + if ( hasSelection() ) { + for ( size_t i = 0; i < mSelection.size(); ++i ) { + if ( !mSelection[i].hasSelection() ) + continue; + String escapedSelectedText( String::escape( getText( mSelection[i] ) ) ); + deleteTo( i, 0 ); + setSelection( i, insert( i, getSelectionIndex( i ).start(), escapedSelectedText ) ); + } + } else { + auto prevSels = getSelections(); + + resetCursor(); + + size_t linesCount = mLines.size(); + for ( size_t i = 0; i < linesCount; i++ ) { + Int64 lineIdx = static_cast( i ); + String newText( String::escape( mLines[i].getTextWithoutNewLine() ) ); + setSelection( 0, { { lineIdx, 0 }, { lineIdx, (Int64)line( i ).size() - 1 } } ); + deleteTo( 0, 0 ); + setSelection( 0, insert( 0, getSelectionIndex( 0 ).start(), newText ) ); + } + + setSelection( prevSels ); + } +} + +void TextDocument::unescape() { + BoolScopedOpOptional op( !mDoingTextInput, mDoingTextInput, true ); + + if ( hasSelection() ) { + for ( size_t i = 0; i < mSelection.size(); ++i ) { + if ( !mSelection[i].hasSelection() ) + continue; + String unescapedSelectedText( String::unescape( getText( mSelection[i] ) ) ); + deleteTo( i, 0 ); + setSelection( i, insert( i, getSelectionIndex( i ).start(), unescapedSelectedText ) ); + } + } else { + auto prevSels = getSelections(); + + resetCursor(); + + size_t linesCount = mLines.size(); + for ( size_t i = 0; i < linesCount; i++ ) { + Int64 lineIdx = static_cast( i ); + String newText( String::unescape( mLines[i].getTextWithoutNewLine() ) ); + setSelection( 0, { { lineIdx, 0 }, { lineIdx, (Int64)line( i ).size() - 1 } } ); + deleteTo( 0, 0 ); + setSelection( 0, insert( 0, getSelectionIndex( 0 ).start(), newText ) ); + } + + setSelection( prevSels ); + } +} + +void TextDocument::toBase64() { + BoolScopedOpOptional op( !mDoingTextInput, mDoingTextInput, true ); + + if ( hasSelection() ) { + for ( size_t i = 0; i < mSelection.size(); ++i ) { + if ( !mSelection[i].hasSelection() ) + continue; + std::string text( getText( mSelection[i] ).toUtf8() ); + std::string newText; + Base64::encode( text, newText ); + + deleteTo( i, 0 ); + setSelection( + i, insert( i, getSelectionIndex( i ).start(), String::fromUtf8( newText ) ) ); + } + } else { + auto prevSels = getSelections(); + + resetCursor(); + selectAll(); + const auto fullDoc = getText().toUtf8(); + std::string newDoc; + Base64::encode( fullDoc, newDoc ); + textInput( String::fromUtf8( newDoc ) ); + + setSelection( prevSels ); + } +} + +void TextDocument::fromBase64() { + BoolScopedOpOptional op( !mDoingTextInput, mDoingTextInput, true ); + + if ( hasSelection() ) { + for ( size_t i = 0; i < mSelection.size(); ++i ) { + if ( !mSelection[i].hasSelection() ) + continue; + + std::string text( getText( mSelection[i] ).toUtf8() ); + std::string newText; + Base64::decode( text, newText ); + + deleteTo( i, 0 ); + setSelection( + i, insert( i, getSelectionIndex( i ).start(), String::fromUtf8( newText ) ) ); + } + } else { + auto prevSels = getSelections(); + + resetCursor(); + selectAll(); + const auto fullDoc = getText().toUtf8(); + std::string newDoc; + Base64::decode( fullDoc, newDoc ); + textInput( String::fromUtf8( newDoc ) ); + + setSelection( prevSels ); + } +} + void TextDocument::initializeCommands() { mCommands["reset"] = [this] { reset(); }; mCommands["save"] = [this] { save(); }; @@ -3646,6 +3763,10 @@ void TextDocument::initializeCommands() { mCommands["add-cursor-below"] = [this] { addCursorBelow(); }; mCommands["cursor-undo"] = [this] { cursorUndo(); }; mCommands["select-all-matches"] = [this] { selectAllMatches(); }; + mCommands["escape"] = [this] { escape(); }; + mCommands["unescape"] = [this] { unescape(); }; + mCommands["to-base64"] = [this] { toBase64(); }; + mCommands["from-base64"] = [this] { fromBase64(); }; } TextRange TextDocument::getTopMostCursor() { diff --git a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/typescript.cpp b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/typescript.cpp index d295e70f6..3215f05e3 100644 --- a/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/typescript.cpp +++ b/src/modules/languages-syntax-highlighting/src/eepp/ui/doc/languages/typescript.cpp @@ -63,7 +63,7 @@ void addTypeScript() { { "readonly", "keyword" }, { "case", "keyword" }, { "export", "keyword" }, { "interface", "keyword" }, { "protected", "keyword" }, { "do", "keyword" }, - { "type", "keyword2" }, + { "type", "keyword2" }, { "is", "keyword" }, }, "//", diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp index bd32ecf63..75228f1d1 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp @@ -70,30 +70,6 @@ static constexpr auto KEY_DEFAULT_BUILD_TASK = "${defaultBuildTask}"; static constexpr auto KEY_PATH_SEPARATOR = "${pathSeparator}"; static constexpr auto KEY_PATH_SEPARATOR_ABBR = "${/}"; -/* - -- **${userHome}** - the path of the user's home folder -- **${workspaceFolder}** - the path of the folder opened in VS Code -- **${workspaceFolderBasename}** - the name of the folder opened in VS Code without any slashes (/) -- **${file}** - the current opened file -- **${fileWorkspaceFolder}** - the current opened file's workspace folder -- **${relativeFile}** - the current opened file relative to `workspaceFolder` -- **${relativeFileDirname}** - the current opened file's dirname relative to `workspaceFolder` -- **${fileBasename}** - the current opened file's basename -- **${fileBasenameNoExtension}** - the current opened file's basename with no file extension -- **${fileExtname}** - the current opened file's extension -- **${fileDirname}** - the current opened file's folder path -- **${fileDirnameBasename}** - the current opened file's folder name -- **${cwd}** - the task runner's current working directory upon the startup of VS Code -- **${lineNumber}** - the current selected line number in the active file -- **${selectedText}** - the current selected text in the active file -- **${execPath}** - the path to the running VS Code executable -- **${defaultBuildTask}** - the name of the default build task -- **${pathSeparator}** - the character used by the operating system to separate components in file -paths -- **${/}** - shorthand for **${pathSeparator}** - -*/ Plugin* DebuggerPlugin::New( PluginManager* pluginManager ) { return eeNew( DebuggerPlugin, ( pluginManager, false ) ); }