diff --git a/include/eepp/ui/doc/syntaxdefinitionmanager.hpp b/include/eepp/ui/doc/syntaxdefinitionmanager.hpp index bf9e3bde6..ff8e8a330 100644 --- a/include/eepp/ui/doc/syntaxdefinitionmanager.hpp +++ b/include/eepp/ui/doc/syntaxdefinitionmanager.hpp @@ -55,6 +55,9 @@ class EE_API SyntaxDefinitionManager { const std::vector& getDefinitions() const; + /* empty = all */ + bool save( const std::string& path, const std::vector& def = {} ); + protected: SyntaxDefinitionManager(); diff --git a/src/eepp/system/sys.cpp b/src/eepp/system/sys.cpp index 41126fe67..15156e6e7 100644 --- a/src/eepp/system/sys.cpp +++ b/src/eepp/system/sys.cpp @@ -1101,7 +1101,7 @@ static ULONG_PTR GetParentProcessId() { } static bool isWineRunning() { - HMODULE hntdll = GetModuleHandle( "ntdll.dll" ); + HMODULE hntdll = GetModuleHandle( TEXT( "ntdll.dll" ) ); if ( !hntdll ) return false; void* pwine_get_version = (void*)GetProcAddress( hntdll, "wine_get_version" ); diff --git a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp index 848bbbf20..8bc34bb3d 100644 --- a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp +++ b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp @@ -137,6 +137,69 @@ const std::vector& SyntaxDefinitionManager::getDefinitions() c return mDefinitions; } +static json toJson( const SyntaxDefinition& def ) { + json j; + j["name"] = def.getLanguageName(); + if ( def.getLSPName() != String::toLower( def.getLanguageName() ) ) + j["lsp_name"] = def.getLSPName(); + j["files"] = def.getFiles(); + if ( !def.getComment().empty() ) + j["comment"] = def.getComment(); + if ( !def.getPatterns().empty() ) { + j["patterns"] = json::array(); + for ( const auto& ptrn : def.getPatterns() ) { + json pattern; + if ( ptrn.patterns.size() == 1 ) { + pattern["pattern"] = ptrn.patterns[0]; + } else { + pattern["pattern"] = ptrn.patterns; + } + if ( ptrn.types.size() == 1 ) { + pattern["type"] = ptrn.types[0]; + } else { + pattern["type"] = ptrn.types; + } + if ( !ptrn.syntax.empty() ) + pattern["syntax"] = ptrn.syntax; + j["patterns"].emplace_back( std::move( pattern ) ); + } + } + if ( !def.getSymbols().empty() ) { + j["symbols"] = json::array(); + for ( const auto& sym : def.getSymbols() ) + j["symbols"].emplace_back( json{ json{ sym.first, sym.second } } ); + } + + if ( !def.getHeaders().empty() ) + j["headers"] = def.getHeaders(); + + if ( def.getAutoCloseXMLTags() ) + j["auto_close_xml_tags"] = true; + + if ( !def.isVisible() ) + j["visible"] = false; + + return j; +} + +bool SyntaxDefinitionManager::save( const std::string& path, + const std::vector& def ) { + if ( def.size() == 1 ) { + return FileSystem::fileWrite( path, toJson( def[0] ).dump( 2 ) ); + } else if ( !def.empty() ) { + json j = json::array(); + for ( const auto& d : def ) + j.emplace_back( toJson( d ) ); + return FileSystem::fileWrite( path, j.dump( 2 ) ); + } else { + json j = json::array(); + for ( const auto& d : mDefinitions ) + j.emplace_back( toJson( d ) ); + return FileSystem::fileWrite( path, j.dump( 2 ) ); + } + return false; +} + void SyntaxDefinitionManager::addPlainText() { add( { "Plain Text", { "%.txt$" }, {}, {}, "", {}, "plaintext" } ); } @@ -4020,7 +4083,19 @@ static SyntaxDefinition loadLanguage( const nlohmann::json& json ) { if ( json.contains( "patterns" ) && json["patterns"].is_array() ) { const auto& patterns = json["patterns"]; for ( const auto& pattern : patterns ) { - auto type = pattern.value( "type", "normal" ); + std::vector type; + if ( pattern.contains( "type" ) ) { + if ( pattern["type"].is_array() ) { + for ( const auto& t : pattern["type"] ) { + if ( t.is_string() ) + type.push_back( t.get() ); + } + } else if ( pattern["type"].is_string() ) { + type.push_back( pattern["type"] ); + } + } else { + type.push_back( "normal" ); + } auto syntax = pattern.value( "syntax", "" ); std::vector ptrns; if ( pattern.contains( "pattern" ) ) { diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 577054151..2bcf186b8 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -2446,7 +2446,7 @@ static std::string getCurrentProcessPath() { #else char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; pid_t pid = getpid(); - int ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf)); + int ret = proc_pidpath( pid, pathbuf, sizeof( pathbuf ) ); if ( ret >= 0 ) return std::string( pathbuf ); auto path( Sys::getProcessPath() ); @@ -3249,6 +3249,34 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe } } +static void exportLanguages( const std::string& path, const std::string& langs ) { + SyntaxDefinitionManager* sdm = SyntaxDefinitionManager::instance(); + std::vector defs; + + if ( !langs.empty() ) { + auto langss = String::split( langs, ',' ); + for ( const auto& l : langss ) { + const auto& sd = sdm->getByLSPName( l ); + + if ( !sd.getLanguageName().empty() ) { + defs.push_back( sd ); + continue; + } + + const auto& sd2 = sdm->getByLanguageName( l ); + + if ( !sd2.getLanguageName().empty() ) + defs.push_back( sd2 ); + } + } + + if ( sdm->save( path, defs ) ) { + std::cout << "Language definitions exported!\n"; + } else { + std::cout << "Could not write the file\n"; + } +} + } // namespace ecode using namespace ecode; @@ -3308,6 +3336,16 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { "Sets the health format report (accepted values: terminal, markdown, ascii, asciidoc)", { "health-format" }, FeaturesHealth::getMapFlag(), FeaturesHealth::getDefaultOutputFormat() ); + args::ValueFlag exportLangPath( + parser, "export-lang-path", + "Export language definitions to the file path. If no \"export-lang\" is defined it will " + "export all languages available.", + { "export-lang-path" }, "" ); + args::ValueFlag exportLang( + parser, "export-lang", + "Comma separated language names to export its language definitions. \"export-lang-path\" " + "must be defined. Retrieved with \"--health\" command.", + { "export-lang" }, "" ); try { parser.ParseCLI( Sys::parseArguments( argc, argv ) ); @@ -3327,6 +3365,12 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { return EXIT_FAILURE; } + if ( exportLangPath && !exportLangPath.Get().empty() ) { + Sys::windowAttachConsole(); + exportLanguages( exportLangPath.Get(), exportLang.Get() ); + return EXIT_SUCCESS; + } + if ( version.Get() ) { Sys::windowAttachConsole(); std::cout << ecode::Version::getVersionFullName() << '\n';