diff --git a/doc/json_schema.json b/doc/json_schema.json index a6e0bca2b..c7786dcea 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -357,9 +357,17 @@ "additionalProperties": false, "properties": { "stat": { - "type": "boolean", - "description": "Show time usage (in ms) for individual modules", - "default": false + "description": "Show time usage (in ms) for individual modules with optional threshold", + "oneOf": [ + { + "type": "boolean", + "default": false + }, + { + "type": "integer", + "minimum": 1 + } + ] }, "pipe": { "type": "boolean", diff --git a/src/common/commandoption.c b/src/common/commandoption.c index a54b57ce7..b71ef2bf4 100644 --- a/src/common/commandoption.c +++ b/src/common/commandoption.c @@ -1,4 +1,5 @@ #include "commandoption.h" +#include "common/color.h" #include "common/printing.h" #include "common/time.h" #include "common/jsonconfig.h" @@ -105,6 +106,7 @@ static void parseStructureCommand( void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc) { //Parse the structure and call the modules + uint32_t thres = (uint32_t) instance.config.display.stat; uint32_t startIndex = 0; while (startIndex < data->structure.length) { @@ -112,12 +114,12 @@ void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc) data->structure.chars[colonIndex] = '\0'; double ms = 0; - if(instance.config.display.stat) + if(thres >= 0) ms = ffTimeGetTick(); parseStructureCommand(data->structure.chars + startIndex, genJsonResult, jsonDoc); - if(instance.config.display.stat) + if(thres >= 0) { ms = ffTimeGetTick() - ms; @@ -128,9 +130,11 @@ void ffPrintCommandOption(FFdata* data, yyjson_mut_doc* jsonDoc) } else { - char str[32]; + char str[64]; int len = snprintf(str, sizeof str, "%.3fms", ms); - printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load + if (thres > 0) + snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms); + printf("\e[s\e[1A\e[9999999C\e[%dD%s\e[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load } } diff --git a/src/common/jsonconfig.c b/src/common/jsonconfig.c index 537607641..673047b2d 100644 --- a/src/common/jsonconfig.c +++ b/src/common/jsonconfig.c @@ -1,4 +1,5 @@ #include "fastfetch.h" +#include "common/color.h" #include "common/jsonconfig.h" #include "common/printing.h" #include "common/io/io.h" @@ -181,12 +182,13 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc) if (!modules) return NULL; if (!yyjson_is_arr(modules)) return "Property 'modules' must be an array of strings or objects"; + uint32_t thres = (uint32_t) instance.config.display.stat; yyjson_val* item; size_t idx, max; yyjson_arr_foreach(modules, idx, max, item) { double ms = 0; - if(!prepare && instance.config.display.stat) + if(!prepare && thres >= 0) ms = ffTimeGetTick(); yyjson_val* module = item; @@ -208,7 +210,7 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc) else if(!parseModuleJsonObject(type, module, jsonDoc)) return "Unknown module type"; - if(!prepare && instance.config.display.stat) + if(!prepare && thres >= 0) { ms = ffTimeGetTick() - ms; if (jsonDoc) @@ -218,9 +220,11 @@ static const char* printJsonConfig(bool prepare, yyjson_mut_doc* jsonDoc) } else { - char str[32]; + char str[64]; int len = snprintf(str, sizeof str, "%.3fms", ms); - printf("\033[s\033[1A\033[9999999C\033[%dD%s\033[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load + if (thres > 0) + snprintf(str, sizeof str, "\e[%sm%.3fms\e[m", (ms <= thres ? FF_COLOR_FG_GREEN : ms <= 2 * thres ? FF_COLOR_FG_YELLOW : FF_COLOR_FG_RED), ms); + printf("\e[s\e[1A\e[9999999C\e[%dD%s\e[u", len, str); // Save; Up 1; Right 9999999; Left ; Print ; Load } } diff --git a/src/common/time.h b/src/common/time.h index 1b0fba635..588ba7847 100644 --- a/src/common/time.h +++ b/src/common/time.h @@ -9,7 +9,7 @@ #include #endif -static inline double ffTimeGetTick() //In msec +static inline double ffTimeGetTick(void) //In msec { #ifdef _WIN32 LARGE_INTEGER frequency; @@ -24,7 +24,7 @@ static inline double ffTimeGetTick() //In msec #endif } -static inline uint64_t ffTimeGetNow() +static inline uint64_t ffTimeGetNow(void) { #ifdef _WIN32 uint64_t timeNow; diff --git a/src/options/display.c b/src/options/display.c index cc844b08f..0dc0ad6a9 100644 --- a/src/options/display.c +++ b/src/options/display.c @@ -20,8 +20,23 @@ const char* ffOptionsParseDisplayJsonConfig(FFOptionsDisplay* options, yyjson_va if (ffStrEqualsIgnCase(key, "stat")) { - if ((options->stat = yyjson_get_bool(val))) + if (yyjson_is_bool(val)) + { + if (yyjson_get_bool(val)) + { + options->stat = 0; + options->showErrors = true; + } + else + options->stat = -1; + } + else if (yyjson_is_uint(val)) + { + options->stat = (int) yyjson_get_uint(val); options->showErrors = true; + } + else + return "display.stat must be a boolean or a positive integer"; } else if (ffStrEqualsIgnCase(key, "pipe")) options->pipe = yyjson_get_bool(val); @@ -271,8 +286,25 @@ bool ffOptionsParseDisplayCommandLine(FFOptionsDisplay* options, const char* key { if(ffStrEqualsIgnCase(key, "--stat")) { - if((options->stat = ffOptionParseBoolean(value))) + if(ffOptionParseBoolean(value)) + { + options->stat = 0; options->showErrors = true; + } + else if (value) + { + char* end; + uint32_t num = (uint32_t) strtoul(value, &end, 10); + if (*end == '\0') + { + options->stat = (int32_t) num; + options->showErrors = true; + } + else + options->stat = -1; + } + else + options->stat = -1; } else if(ffStrEqualsIgnCase(key, "--pipe")) options->pipe = ffOptionParseBoolean(value); @@ -470,7 +502,7 @@ void ffOptionsInitDisplay(FFOptionsDisplay* options) options->sizeBinaryPrefix = FF_SIZE_BINARY_PREFIX_TYPE_IEC; options->sizeNdigits = 2; options->sizeMaxPrefix = UINT8_MAX; - options->stat = false; + options->stat = -1; options->noBuffer = false; options->keyWidth = 0; options->keyPaddingLeft = 0; @@ -519,7 +551,12 @@ void ffOptionsGenerateDisplayJsonConfig(FFOptionsDisplay* options, yyjson_mut_do yyjson_mut_val* obj = yyjson_mut_obj(doc); if (options->stat != defaultOptions.stat) - yyjson_mut_obj_add_bool(doc, obj, "stat", options->stat); + { + if (options->stat <= 0) + yyjson_mut_obj_add_bool(doc, obj, "stat", options->stat == 0); + else + yyjson_mut_obj_add_int(doc, obj, "stat", options->stat); + } if (options->pipe != defaultOptions.pipe) yyjson_mut_obj_add_bool(doc, obj, "pipe", options->pipe); diff --git a/src/options/display.h b/src/options/display.h index 934c2cac1..fe1f0ba5d 100644 --- a/src/options/display.h +++ b/src/options/display.h @@ -28,7 +28,7 @@ typedef struct FFOptionsDisplay FFstrbuf keyValueSeparator; - bool stat; + int32_t stat; // <0: disable stat; 0: no threshold; >0: threshold in ms bool pipe; //disables all escape sequences bool showErrors; bool disableLinewrap;