summaryrefslogtreecommitdiffstats
path: root/src/common/impl/printing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/impl/printing.c')
-rw-r--r--src/common/impl/printing.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/common/impl/printing.c b/src/common/impl/printing.c
new file mode 100644
index 0000000..9f372d9
--- /dev/null
+++ b/src/common/impl/printing.c
@@ -0,0 +1,156 @@
+#include "fastfetch.h"
+#include "common/printing.h"
+#include "common/textModifier.h"
+#include "logo/logo.h"
+
+void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType) {
+ ffLogoPrintLine();
+
+ // This is used by --set-keyless, in this case we want neither the module name nor the separator
+ if (moduleName == NULL) {
+ return;
+ }
+
+ // This is used as a magic value for hiding keys
+ if (!(moduleArgs && ffStrbufEqualS(&moduleArgs->key, " ")) && instance.config.display.keyType != FF_MODULE_KEY_TYPE_NONE) {
+ ffPrintCharTimes(' ', instance.config.display.keyPaddingLeft);
+
+ if (!instance.config.display.pipe) {
+ fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ if (instance.config.display.brightColor) {
+ fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout);
+ }
+
+ if (moduleArgs && !(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_COLOR) && moduleArgs->keyColor.length > 0) {
+ ffPrintColor(&moduleArgs->keyColor);
+ } else {
+ ffPrintColor(&instance.config.display.colorKeys);
+ }
+ }
+
+ if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_ICON && moduleArgs && moduleArgs->keyIcon.length > 0) {
+ ffStrbufWriteTo(&moduleArgs->keyIcon, stdout);
+ }
+
+ if (instance.config.display.keyType & FF_MODULE_KEY_TYPE_STRING) {
+ ffPrintCharTimes(' ', instance.config.display.keyType >> FF_MODULE_KEY_TYPE_SPACE_SHIFT);
+
+ // NULL check is required for modules with custom keys, e.g. disk with the folder path
+ if ((printType & FF_PRINT_TYPE_NO_CUSTOM_KEY) || !moduleArgs || moduleArgs->key.length == 0) {
+ fputs(moduleName, stdout);
+
+ if (moduleIndex > 0) {
+ printf(" %hhu", moduleIndex);
+ }
+ } else {
+ FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
+ FF_PARSE_FORMAT_STRING_CHECKED(&key, &moduleArgs->key, ((FFformatarg[]) {
+ FF_ARG(moduleIndex, "index"),
+ FF_ARG(moduleArgs->keyIcon, "icon"),
+ }));
+ ffStrbufWriteTo(&key, stdout);
+ }
+ }
+
+ if (!instance.config.display.pipe) {
+ fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ ffPrintColor(&instance.config.display.colorSeparator);
+ }
+
+ ffStrbufWriteTo(&instance.config.display.keyValueSeparator, stdout);
+
+ if (!instance.config.display.pipe && instance.config.display.colorSeparator.length) {
+ fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ }
+
+ if (!(printType & FF_PRINT_TYPE_NO_CUSTOM_KEY_WIDTH)) {
+ uint32_t keyWidth = moduleArgs && moduleArgs->keyWidth > 0 ? moduleArgs->keyWidth : instance.config.display.keyWidth;
+ if (keyWidth > 0) {
+ printf("\e[%uG", (unsigned) (keyWidth + instance.state.logoWidth));
+ }
+ }
+ }
+
+ if (!instance.config.display.pipe) {
+ fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ if (moduleArgs && moduleArgs->outputColor.length) {
+ ffPrintColor(&moduleArgs->outputColor);
+ } else if (instance.config.display.colorOutput.length) {
+ ffPrintColor(&instance.config.display.colorOutput);
+ }
+ }
+}
+
+bool ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
+ FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
+ bool success;
+ if (__builtin_expect(moduleArgs != NULL, 1)) {
+ success = ffParseFormatString(&buffer, &moduleArgs->outputFormat, numArgs, arguments);
+ } else {
+ ffStrbufSetStatic(&buffer, "undefined format");
+ success = false;
+ }
+
+ if (success) {
+ ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
+ ffStrbufPutTo(&buffer, stdout);
+ } else {
+ ffPrintError(moduleName, moduleIndex, moduleArgs, printType, "%s", buffer.chars);
+ }
+
+ return success;
+}
+
+void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...) {
+ if (!instance.config.display.showErrors) {
+ return;
+ }
+
+ ffPrintLogoAndKey(moduleName, moduleIndex, moduleArgs, printType);
+
+ if (!instance.config.display.pipe) {
+ fputs(FASTFETCH_TEXT_MODIFIER_ERROR, stdout);
+ }
+
+ va_list arguments;
+ va_start(arguments, message);
+ vprintf(message, arguments);
+ va_end(arguments);
+
+ if (!instance.config.display.pipe) {
+ fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout);
+ }
+
+ putchar('\n');
+}
+
+void ffPrintColor(const FFstrbuf* colorValue) {
+ // If the color is not set, this would reset in \033[m, which resets everything.
+ // So we only print it, if the main color is at least one char.
+ if (colorValue->length == 0) {
+ return;
+ }
+
+ printf("\e[%sm", colorValue->chars);
+}
+
+void ffPrintCharTimes(char c, uint32_t times) {
+ if (times == 0) {
+ return;
+ }
+
+ if (times == 1) {
+ putchar(c);
+ return;
+ }
+
+ char str[32];
+ memset(str, c, sizeof(str)); // 2 instructions when compiling with AVX2 enabled
+ for (uint32_t i = sizeof(str); i <= times; i += (uint32_t) sizeof(str)) {
+ fwrite(str, 1, sizeof(str), stdout);
+ }
+ uint32_t remaining = times % sizeof(str);
+ if (remaining > 0) {
+ fwrite(str, 1, remaining, stdout);
+ }
+}