diff --git a/src/eepp/system/time.cpp b/src/eepp/system/time.cpp index c77cbc6e9..fdecf0b8f 100644 --- a/src/eepp/system/time.cpp +++ b/src/eepp/system/time.cpp @@ -20,35 +20,42 @@ bool Time::isValid( const std::string& str ) { } Time Time::fromString( const std::string& str ) { - bool isMilliseconds = String::endsWith( str, "ms" ); - bool isSeconds = false; - bool isMinutes = false; - if ( isMilliseconds || ( isSeconds = String::endsWith( str, "s" ) ) || - ( isMinutes = String::endsWith( str, "m" ) ) || - ( isSeconds = String::isNumber( str, true ) ) ) { - size_t to = str.find_first_of( "sm" ); - if ( to == std::string::npos ) - to = str.size(); - std::string number; - for ( size_t pos = 0; pos < to; pos++ ) { - if ( String::isNumber( str[pos], true ) ) { - number += str[pos]; - } else { - return Time::Zero; + auto timePart = String::split( str, " " ); + Time time = Time::Zero; + for ( auto& part : timePart ) { + String::trimInPlace( part ); + if ( part.empty() ) + continue; + bool isMilliseconds = String::endsWith( part, "ms" ); + bool isSeconds = false; + bool isMinutes = false; + if ( isMilliseconds || ( isSeconds = String::endsWith( part, "s" ) ) || + ( isMinutes = String::endsWith( part, "m" ) ) || + ( isSeconds = String::isNumber( part, true ) ) ) { + size_t to = part.find_first_of( "sm" ); + if ( to == std::string::npos ) + to = part.size(); + std::string number; + for ( size_t pos = 0; pos < to; pos++ ) { + if ( String::isNumber( part[pos], true ) ) { + number += part[pos]; + } else { + return Time::Zero; + } } - } - double val; - if ( String::fromString( val, number ) ) { - if ( isSeconds ) { - return Seconds( val ); - } else if ( isMinutes ) { - return Minutes( val ); - } else { - return Milliseconds( val ); + double val; + if ( String::fromString( val, number ) ) { + if ( isSeconds ) { + time += Seconds( val ); + } else if ( isMinutes ) { + time += Minutes( val ); + } else { + time += Milliseconds( val ); + } } } } - return Time::Zero; + return time; } Time::Time() : mMicroseconds( 0 ) {} @@ -71,7 +78,9 @@ std::string Time::toString() const { Uint64 totalSeconds = asSeconds(); if ( asSeconds() < 1 ) { - return String::format( "%4.2fms", asMilliseconds() ); + if ( asMilliseconds() == static_cast( (Int64)asMilliseconds() ) ) + return String::format( "%.fms", asMilliseconds() ); + return String::format( "%.2fms", asMilliseconds() ); } else if ( totalSeconds < 60 ) { return String::format( "%lus", static_cast( totalSeconds ) ); } @@ -80,11 +89,15 @@ std::string Time::toString() const { long secondsLeft = totalSeconds - minutesLeft * 60; if ( minutesLeft < 60 ) { - return String::format( "%02ldm %02lds", minutesLeft, secondsLeft ); + if ( secondsLeft == 0 ) + return String::format( "%ldm", minutesLeft ); + return String::format( "%ldm %lds", minutesLeft, secondsLeft ); } else { long hoursLeft = minutesLeft / 60; minutesLeft = minutesLeft - hoursLeft * 60; - return String::format( "%02ldh %02ldm %02lds", hoursLeft, minutesLeft, secondsLeft ); + if ( secondsLeft == 0 ) + return String::format( "%ldh %ldm", hoursLeft, minutesLeft ); + return String::format( "%ldh %ldm %lds", hoursLeft, minutesLeft, secondsLeft ); } } diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.cpp b/src/tools/ecode/plugins/formatter/formatterplugin.cpp index 7dcf6908f..7c44cf7c6 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.cpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.cpp @@ -59,7 +59,8 @@ void FormatterPlugin::onRegister( UICodeEditor* editor ) { mEditors.insert( editor ); for ( auto& kb : mKeyBindings ) { - editor->getKeyBindings().addKeybindString( kb.second, kb.first ); + if ( !kb.first.empty() ) + editor->getKeyBindings().addKeybindString( kb.second, kb.first ); } if ( editor->hasDocument() ) @@ -125,7 +126,7 @@ size_t FormatterPlugin::formatterFilePatternPosition( const std::vector() ); + else if ( updateConfigFile ) + config["auto_format_on_save"] = getAutoFormatOnSave(); } if ( mKeyBindings.empty() ) mKeyBindings["format-doc"] = "alt+f"; if ( j.contains( "keybindings" ) && j["keybindings"].contains( "format-doc" ) ) mKeyBindings["format-doc"] = j["keybindings"]["format-doc"]; + else if ( updateConfigFile ) + j["keybindings"]["format-doc"] = mKeyBindings["format-doc"]; + + if ( updateConfigFile ) { + FileSystem::fileWrite( path, j.dump( 2 ) ); + } if ( !j.contains( "formatters" ) ) return; @@ -210,7 +219,7 @@ void FormatterPlugin::load( PluginManager* pluginManager ) { return; for ( const auto& path : paths ) { try { - loadFormatterConfig( path ); + loadFormatterConfig( path, mConfigPath == path ); } catch ( const json::exception& e ) { Log::error( "Parsing formatter \"%s\" failed:\n%s", path.c_str(), e.what() ); } diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.hpp b/src/tools/ecode/plugins/formatter/formatterplugin.hpp index 473ad4757..be260a2c8 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.hpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.hpp @@ -92,7 +92,7 @@ class FormatterPlugin : public UICodeEditorPlugin { void load( PluginManager* pluginManager ); - void loadFormatterConfig( const std::string& path ); + void loadFormatterConfig( const std::string& path, bool updateConfigFile ); void formatDoc( UICodeEditor* editor ); diff --git a/src/tools/ecode/plugins/linter/linterplugin.cpp b/src/tools/ecode/plugins/linter/linterplugin.cpp index ac437f0f8..442d44859 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.cpp +++ b/src/tools/ecode/plugins/linter/linterplugin.cpp @@ -72,7 +72,7 @@ size_t LinterPlugin::linterFilePatternPosition( const std::vector& return std::string::npos; } -void LinterPlugin::loadLinterConfig( const std::string& path ) { +void LinterPlugin::loadLinterConfig( const std::string& path, bool updateConfigFile ) { std::string data; if ( !FileSystem::fileGet( path, data ) ) return; @@ -90,11 +90,20 @@ void LinterPlugin::loadLinterConfig( const std::string& path ) { auto& config = j["config"]; if ( config.contains( "delay_time" ) ) setDelayTime( Time::fromString( config["delay_time"].get() ) ); + else if ( updateConfigFile ) + config["delay_time"] = getDelayTime().toString(); + if ( config.contains( "enable_lsp_diagnostics" ) && config["enable_lsp_diagnostics"].is_boolean() ) setEnableLSPDiagnostics( config["enable_lsp_diagnostics"].get() ); + else if ( updateConfigFile ) + config["enable_lsp_diagnostics"] = getEnableLSPDiagnostics(); + if ( config.contains( "enable_error_lens" ) && config["enable_error_lens"].is_boolean() ) setErrorLens( config["enable_error_lens"].get() ); + else if ( updateConfigFile ) + config["enable_error_lens"] = getErrorLens(); + if ( config.contains( "disable_lsp_languages" ) && config["disable_lsp_languages"].is_array() ) { const auto& langs = config["disable_lsp_languages"]; @@ -112,7 +121,10 @@ void LinterPlugin::loadLinterConfig( const std::string& path ) { "LinterPlugin::loadLinterConfig: Error parsing disable_lsp_languages: %s", e.what() ); } + } else if ( updateConfigFile ) { + config["disable_lsp_languages"] = json::array(); } + if ( config.contains( "disable_languages" ) && config["disable_languages"].is_array() ) { const auto& langs = config["disable_languages"]; try { @@ -128,9 +140,15 @@ void LinterPlugin::loadLinterConfig( const std::string& path ) { Log::debug( "LinterPlugin::loadLinterConfig: Error parsing disable_languages: %s", e.what() ); } + } else if ( updateConfigFile ) { + config["disable_languages"] = json::array(); } } + if ( updateConfigFile ) { + FileSystem::fileWrite( path, j.dump( 2 ) ); + } + if ( !j.contains( "linters" ) ) return; @@ -321,7 +339,7 @@ void LinterPlugin::load( PluginManager* pluginManager ) { return; for ( const auto& path : paths ) { try { - loadLinterConfig( path ); + loadLinterConfig( path, mConfigPath == path ); } catch ( const json::exception& e ) { Log::error( "Parsing linter \"%s\" failed:\n%s", path.c_str(), e.what() ); } diff --git a/src/tools/ecode/plugins/linter/linterplugin.hpp b/src/tools/ecode/plugins/linter/linterplugin.hpp index 53d43e6cd..345e1c612 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.hpp +++ b/src/tools/ecode/plugins/linter/linterplugin.hpp @@ -143,7 +143,7 @@ class LinterPlugin : public UICodeEditorPlugin { std::string getMatchString( const LinterType& type ); - void loadLinterConfig( const std::string& path ); + void loadLinterConfig( const std::string& path, bool updateConfigFile ); size_t linterFilePatternPosition( const std::vector& patterns ); diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index 7e8e5d6ea..5a665e1ea 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -185,7 +185,7 @@ void LSPClientPlugin::load( PluginManager* pluginManager ) { for ( const auto& path : paths ) { try { - loadLSPConfig( lsps, path ); + loadLSPConfig( lsps, path, mConfigPath == path ); } catch ( const json::exception& e ) { Log::error( "Parsing LSP \"%s\" failed:\n%s", path.c_str(), e.what() ); } @@ -202,7 +202,8 @@ void LSPClientPlugin::load( PluginManager* pluginManager ) { fireReadyCbs(); } -void LSPClientPlugin::loadLSPConfig( std::vector& lsps, const std::string& path ) { +void LSPClientPlugin::loadLSPConfig( std::vector& lsps, const std::string& path, + bool updateConfigFile ) { std::string data; if ( !FileSystem::fileGet( path, data ) ) return; @@ -220,10 +221,14 @@ void LSPClientPlugin::loadLSPConfig( std::vector& lsps, const std auto& config = j["config"]; if ( config.contains( "hover_delay" ) ) setHoverDelay( Time::fromString( config["hover_delay"].get() ) ); + else if ( updateConfigFile ) + config["hover_delay"] = getHoverDelay().toString(); if ( config.contains( "server_close_after_idle_time" ) ) mClientManager.setLSPDecayTime( Time::fromString( config["server_close_after_idle_time"].get() ) ); + else if ( updateConfigFile ) + config["server_close_after_idle_time"] = mClientManager.getLSPDecayTime().toString(); } if ( mKeyBindings.empty() ) { @@ -232,16 +237,21 @@ void LSPClientPlugin::loadLSPConfig( std::vector& lsps, const std } if ( j.contains( "keybindings" ) ) { - auto kb = j["keybindings"]; - auto bindKey = [this, kb]( const std::string& key ) { - if ( kb.contains( key ) ) - mKeyBindings[key] = kb[key]; - }; + auto& kb = j["keybindings"]; auto list = { "lsp-go-to-definition", "lsp-go-to-declaration", "lsp-go-to-implementation", "lsp-go-to-type-definition", "lsp-switch-header-source", "lsp-symbol-info" }; - for ( const auto& key : list ) - bindKey( key ); + for ( const auto& key : list ) { + if ( kb.contains( key ) ) { + if ( !kb[key].empty() ) + mKeyBindings[key] = kb[key]; + } else if ( updateConfigFile ) + kb[key] = mKeyBindings[key]; + } + } + + if ( updateConfigFile ) { + FileSystem::fileWrite( path, j.dump( 2 ) ); } if ( !j.contains( "servers" ) ) @@ -355,7 +365,8 @@ void LSPClientPlugin::onRegister( UICodeEditor* editor ) { mDocs.insert( editor->getDocumentRef().get() ); for ( auto& kb : mKeyBindings ) { - editor->getKeyBindings().addKeybindString( kb.second, kb.first ); + if ( !kb.second.empty() ) + editor->getKeyBindings().addKeybindString( kb.second, kb.first ); } if ( editor->hasDocument() ) { diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp index adc8191ee..7eb9bcb75 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.hpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.hpp @@ -98,7 +98,8 @@ class LSPClientPlugin : public UICodeEditorPlugin { void load( PluginManager* pluginManager ); - void loadLSPConfig( std::vector& lsps, const std::string& path ); + void loadLSPConfig( std::vector& lsps, const std::string& path, + bool updateConfigFile ); size_t lspFilePatternPosition( const std::vector& lsps, const std::vector& patterns );