diff --git a/CHANGELOG.md b/CHANGELOG.md index 097671066..dcbc706da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Notable Changes: * fastfetch no longer creates a sample config file silently. Use `--gen-config` to generate one. * fastfetch now search for user config file in the order of `fastfetch --list-config-paths` +* Unknown disks are hidden by default. Features: * `--logo-padding-top` option (@CarterLi, #372) @@ -16,6 +17,9 @@ Features: * Add `--disk-show-unknown` option for Disk module * Add `--gpu-hide-integrated` option (#379) * Add `--gpu-hide-discrete` option (#379) +* Detect terminal version when available +* Support `WezTerm` terminal font detection (requires [`wezterm` executable](https://wezfurlong.org/wezterm/cli/general.html) being available) +* Add `--shell-version` and `--terminal-version` options to disable shell / terminal version detection Logos: * Raspbian (@IamNoRobot, #373) @@ -23,6 +27,7 @@ Logos: Bugfixes: * `--logo-type` now does accept `iterm` too (@CarterLi, #374) * Fix mintty terminal font detection +* Fix bug that line buffering doesn't work properly (Windows) Other: * Fixed a Typo in iterm error message (@jessebot, #376) diff --git a/CMakeLists.txt b/CMakeLists.txt index 586b0b305..fc0451893 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wconversion") if(WIN32) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wconversion -fno-exceptions -fno-rtti") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--tsaware -Wl,--build-id -Wl,--subsystem,console:6.1,--major-os-version,6,--minor-os-version,1") endif() # Used for dlopen finding dylibs installed by homebrew @@ -644,7 +645,6 @@ if(ENABLE_THREADS) endif() endif() - if(ENABLE_BUFFER) target_compile_definitions(libfastfetch PRIVATE FF_ENABLE_BUFFER) endif() @@ -719,6 +719,11 @@ target_link_libraries(flashfetch PRIVATE libfastfetch ) +if(ENABLE_BUFFER) # FF_ENABLE_BUFFER is used in fastfetch.c + target_compile_definitions(fastfetch PRIVATE FF_ENABLE_BUFFER) + target_compile_definitions(flashfetch PRIVATE FF_ENABLE_BUFFER) +endif() + if(WIN32) set(TARGET_NAME fastfetch) target_sources(fastfetch diff --git a/README.md b/README.md index 78312f6a8..ed848668c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Fastfetch -Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written in pure c, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported. +Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying them in a pretty way. It is written mainly in C, with performance and customizability in mind. Currently, Linux, Android, FreeBSD, MacOS and Windows 7+ are supported. @@ -112,7 +112,7 @@ KDE Plasma, Gnome, Cinnamon, Mate, XFCE4, LXQt ##### Terminal fonts ``` -Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, Kitty, LXTerminal, Deepin Terminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu +Konsole, Gnome Terminal, Tilix, XFCE4 Terminal, Alacritty, Kitty, LXTerminal, Deepin Terminal, iTerm2, Apple Terminal, Warp, TTY, Windows Terminal, Termux, mintty, ConEmu, WezTerm ``` ## Building @@ -132,12 +132,13 @@ If the build process fails to find the headers for a library listed in [dependen Currently GCC or clang is required (MSVC is not supported). MSYS2 with CLANG64 subsystem (or CLANGARM64 if needed) is suggested (and tested) to build fastfetch. If you need Windows 7 / 8.x support, using MINGW64 is suggested. 1. Install [MSYS2](https://www.msys2.org/#installation) -1. Open `MSYS2 CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime) +1. Open `MSYS2 / CLANG64` (not `MSYS2 / MSYS`, which targets cygwin C runtime) 1. Install dependencies ```bash pacman -Syu mingw-w64-clang-x86_64-cmake mingw-w64-clang-x86_64-pkgconf mingw-w64-clang-x86_64-clang mingw-w64-clang-x86_64-cjson mingw-w64-clang-x86_64-vulkan-loader mingw-w64-clang-x86_64-opencl-icd ``` -1. Follow building instructions of Linux + +Follow the building instructions of Linux next. ## Packaging diff --git a/completions/bash b/completions/bash index d71e6c83b..66649337a 100644 --- a/completions/bash +++ b/completions/bash @@ -189,10 +189,14 @@ __fastfetch_completion() "--pipe" "--title-fqdn" "--escape-bedrock" + "--shell-version" + "--terminal-version" + "--disk-folders" "--disk-show-removable" "--disk-show-hidden" "--gpu-hide-integrated" "--gpu-hide-discrete" + "--disk-show-unknown" ) local FF_OPTIONS_STRING=( diff --git a/src/common/init.c b/src/common/init.c index 85ef35668..97184f345 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -318,6 +318,9 @@ static void defaultConfig(FFinstance* instance) instance->config.gpuHideIntegrated = false; instance->config.gpuHideDiscrete = false; + instance->config.shellVersion = true; + instance->config.terminalVersion = true; + instance->config.titleFQDN = false; ffStrbufInitA(&instance->config.diskFolders, 0); diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 30e515734..736c121b3 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -4,7 +4,6 @@ #define WIN32_LEAN_AND_MEAN 1 #include -//We can't use this native version yet because we still use POSIX path ( eg /usr/bin/fish ) at a lot of places. const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) { SECURITY_ATTRIBUTES saAttr = { diff --git a/src/data/config_user.txt b/src/data/config_user.txt index 859267bcc..b68b845ca 100644 --- a/src/data/config_user.txt +++ b/src/data/config_user.txt @@ -219,6 +219,18 @@ #--gpu-hide-integrated #--gpu-hide-discrete +# Shell option +# Sets if shell version should be detected and printed +# Must be either true or false +# Default is true. +#--shell-version true + +# Terminal option +# Sets if terminal version should be detected and printed +# Must be either true or false +# Default is true. +#--terminal-version true + # Disk option # Sets if removable volume should be printed # Must be either true or false diff --git a/src/data/help.txt b/src/data/help.txt index 9cd91fd9f..c83dec794 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -103,6 +103,8 @@ Module specific options: --title-fqdn : Set if the title should use fully qualified domain name. Default is false --separator-string : Set the string printed by the separator module --os-file : Set the path to the file containing OS information + --shell-version : Set if shell version should be detected and printed + --terminal-version : Set if terminal version should be detected and printed --disk-folders : A colon (semicolon on Windows) separated list of folder paths for the disk output. Default is "/:/home" ("C:\\;D:\\ ..." on Windows) --disk-show-removable : Set if removable volume should be printed. Default is true --disk-show-hidden : Set if hidden volumes should be printed. Default is false diff --git a/src/detection/battery/battery_bsd.c b/src/detection/battery/battery_bsd.c index 17ce47a2f..2cfbe4b7b 100644 --- a/src/detection/battery/battery_bsd.c +++ b/src/detection/battery/battery_bsd.c @@ -6,8 +6,11 @@ #include #include -const char* ffDetectBatteryImpl(FF_UNUSED_PARAM FFinstance* instance, FFlist* results) +const char* ffDetectBatteryImpl(FF_MAYBE_UNUSED FFinstance* instance, FFlist* results) { + //https://www.freebsd.org/cgi/man.cgi?acpi_battery(4) + //https://gitlab.xfce.org/panel-plugins/xfce4-battery-plugin/-/blob/master/panel-plugin/libacpi.c + int acpifd = open("/dev/acpi", O_RDONLY); if(acpifd < 0) return "open(\"/dev/acpi\", O_RDONLY) failed"; diff --git a/src/detection/brightness/brightness_linux.c b/src/detection/brightness/brightness_linux.c index 31e346062..0f2a9d5fd 100644 --- a/src/detection/brightness/brightness_linux.c +++ b/src/detection/brightness/brightness_linux.c @@ -3,7 +3,7 @@ #include -const char* ffDetectBrightness(FF_UNUSED_PARAM FFlist* result) +const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) { //https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-backlight const char* backlightDirPath = "/sys/class/backlight/"; diff --git a/src/detection/brightness/brightness_nosupport.c b/src/detection/brightness/brightness_nosupport.c index 5661c180f..4bd83c4de 100644 --- a/src/detection/brightness/brightness_nosupport.c +++ b/src/detection/brightness/brightness_nosupport.c @@ -1,6 +1,6 @@ #include "brightness.h" -const char* ffDetectBrightness(FF_UNUSED_PARAM FFlist* result) +const char* ffDetectBrightness(FF_MAYBE_UNUSED FFlist* result) { return "Not supported on this platform"; } diff --git a/src/detection/terminalfont/terminalfont.c b/src/detection/terminalfont/terminalfont.c index 5716b720d..41ff5428b 100644 --- a/src/detection/terminalfont/terminalfont.c +++ b/src/detection/terminalfont/terminalfont.c @@ -37,7 +37,7 @@ static void detectAlacritty(const FFinstance* instance, FFTerminalFontResult* te ffStrbufDestroy(&fontSize); } -static void detectTTY(FFTerminalFontResult* terminalFont) +FF_MAYBE_UNUSED static void detectTTY(FFTerminalFontResult* terminalFont) { FFstrbuf fontName; ffStrbufInit(&fontName); @@ -291,7 +291,7 @@ static void detectFromWindowsTeriminal(const FFinstance* instance, const FFstrbu #endif #endif //defined(_WIN32) || defined(__linux__) -static bool detectKitty(const FFinstance* instance, FFTerminalFontResult* result) +FF_MAYBE_UNUSED static bool detectKitty(const FFinstance* instance, FFTerminalFontResult* result) { FFstrbuf fontName; ffStrbufInit(&fontName); @@ -320,21 +320,54 @@ static bool detectKitty(const FFinstance* instance, FFTerminalFontResult* result return true; } +static bool detectWezterm(FF_MAYBE_UNUSED const FFinstance* instance, FFTerminalFontResult* result) +{ + FF_STRBUF_AUTO_DESTROY fontName; + ffStrbufInit(&fontName); + + ffStrbufSetS(&result->error, ffProcessAppendStdOut(&fontName, (char* const[]){ + "wezterm", + "ls-fonts", + "--text", + "a", + NULL + })); + if(result->error.length) + return false; + + //LeftToRight + // 0 a \u{61} x_adv=7 cells=1 glyph=a,180 wezterm.font("JetBrains Mono", {weight="Regular", stretch="Normal", style="Normal"}) + // , BuiltIn + ffStrbufSubstrAfterFirstC(&fontName, '"'); + ffStrbufSubstrBeforeFirstC(&fontName, '"'); + + if(!fontName.length) + return false; + + ffFontInitCopy(&result->font, fontName.chars); + return true; +} + void ffDetectTerminalFontPlatform(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont); static bool detectTerminalFontCommon(const FFinstance* instance, const FFTerminalShellResult* terminalShell, FFTerminalFontResult* terminalFont) { - if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "alacritty") == 0) + if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "alacritty")) detectAlacritty(instance, terminalFont); - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "kitty") == 0) + else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalProcessName, "wezterm-gui")) + detectWezterm(instance, terminalFont); + + #ifndef _WIN32 + else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "kitty")) detectKitty(instance, terminalFont); else if(ffStrbufStartsWithIgnCaseS(&terminalShell->terminalExe, "/dev/tty")) detectTTY(terminalFont); + #endif #if defined(_WIN32) || defined(__linux__) //Used by both Linux (WSL) and Windows - else if(ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "Windows Terminal") == 0 || - ffStrbufIgnCaseCompS(&terminalShell->terminalProcessName, "WindowsTerminal.exe") == 0) + else if(ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "Windows Terminal") || + ffStrbufIgnCaseEqualS(&terminalShell->terminalProcessName, "WindowsTerminal.exe")) detectFromWindowsTeriminal(instance, &terminalShell->terminalExe, terminalFont); #endif diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index a99c498e4..aa9d221f3 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -1,5 +1,7 @@ #include "fastfetch.h" +#include "common/io.h" #include "common/processing.h" +#include "common/properties.h" #ifdef _WIN32 @@ -36,122 +38,252 @@ static bool getFileVersion(const char* exePath, FFstrbuf* version) #endif -static void getShellVersionBash(FFstrbuf* exe, FFstrbuf* version) +static bool getExeVersionRaw(FFstrbuf* exe, FFstrbuf* version) { - ffProcessAppendStdOut(version, (char* const[]) { + return ffProcessAppendStdOut(version, (char* const[]) { exe->chars, "--version", NULL - }); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)\nCopyright... + }) == NULL; +} + +static bool getExeVersionGeneral(FFstrbuf* exe, FFstrbuf* version) +{ + if(!getExeVersionRaw(exe, version)) + return false; + + ffStrbufSubstrAfterFirstC(version, ' '); + ffStrbufSubstrBeforeFirstC(version, ' '); + return true; +} + +static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* version) +{ + if(!getExeVersionRaw(exe, version)) + return false; + + // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)\nCopyright... ffStrbufSubstrBeforeFirstC(version, '\n'); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys) ffStrbufSubstrBeforeLastC(version, ' '); // GNU bash, version 5.1.16(1)-release ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16(1)-release ffStrbufSubstrBeforeFirstC(version, '('); // 5.1.16 + return true; } -static void getShellVersionZsh(FFstrbuf* exe, FFstrbuf* version) +static bool getShellVersionFish(FFstrbuf* exe, FFstrbuf* version) { - ffProcessAppendStdOut(version, (char* const[]) { - exe->chars, - "--version", - NULL - }); - ffStrbufSubstrBeforeLastC(version, ' '); - ffStrbufSubstrAfterFirstC(version, ' '); -} + if(!getExeVersionRaw(exe, version)) + return false; -static void getShellVersionFish(FFstrbuf* exe, FFstrbuf* version) -{ - ffProcessAppendStdOut(version, (char* const[]) { - exe->chars, - "--version", - NULL - }); + //fish, version 3.6.0 ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); + return true; } -static void getShellVersionTcsh(FFstrbuf* exe, FFstrbuf* version) -{ - ffProcessAppendStdOut(version, (char* const[]) { - exe->chars, - "--version", - NULL - }); // tcsh 6.24.01 (Astron) 2022-05-12 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec - ffStrbufSubstrAfterFirstC(version, ' '); // 6.24.01 (Astron) 2022-05-12 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec - ffStrbufSubstrBeforeFirstC(version, ' '); // 6.24.01 -} - -static void getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version) +static bool getShellVersionPwsh(FFstrbuf* exe, FFstrbuf* version) { #ifdef _WIN32 if(getFileVersion(exe->chars, version)) - return; + { + ffStrbufSubstrBeforeLastC(version, '.'); + return true; + } #endif - ffProcessAppendStdOut(version, (char* const[]) { - exe->chars, - "--version", - NULL - }); + if(!getExeVersionRaw(exe, version)) + return false; + ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); + return true; } #ifdef _WIN32 -static void getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) +static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version) { - ffProcessAppendStdOut(version, (char* const[]) { + if(ffProcessAppendStdOut(version, (char* const[]) { exe->chars, "-NoLogo", "-NoProfile", "-Command", "$PSVersionTable.PSVersion.ToString()", NULL - }); + })) return false; + ffStrbufTrimRight(version, '\n'); ffStrbufSubstrAfterLastC(version, ' '); + return true; } -static void getShellVersionCmd(FFstrbuf* exe, FFstrbuf* version) +static bool getShellVersionCmd(FFstrbuf* exe, FFstrbuf* version) { - getFileVersion(exe->chars, version); + return getFileVersion(exe->chars, version); } #endif -static void getShellVersionNu(FFstrbuf* exe, FFstrbuf* version) -{ - ffProcessAppendStdOut(version, (char* const[]) { - exe->chars, - "--version", - NULL - }); -} - bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version) { - bool ok = true; if(strcasecmp(exeName, "bash") == 0 || strcasecmp(exeName, "sh") == 0) - getShellVersionBash(exe, version); - else if(strcasecmp(exeName, "zsh") == 0) - getShellVersionZsh(exe, version); - else if(strcasecmp(exeName, "fish") == 0) - getShellVersionFish(exe, version); - else if(strcasecmp(exeName, "pwsh") == 0) - getShellVersionPwsh(exe, version); - else if(strcasecmp(exeName, "csh") == 0 || strcasecmp(exeName, "tcsh") == 0) - getShellVersionTcsh(exe, version); - else if(strcasecmp(exeName, "nu") == 0) - getShellVersionNu(exe, version); + return getShellVersionBash(exe, version); + if(strcasecmp(exeName, "zsh") == 0) + return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0) + if(strcasecmp(exeName, "fish") == 0) + return getShellVersionFish(exe, version); + if(strcasecmp(exeName, "pwsh") == 0) + return getShellVersionPwsh(exe, version); + if(strcasecmp(exeName, "csh") == 0 || strcasecmp(exeName, "tcsh") == 0) + return getExeVersionGeneral(exe, version); //tcsh 6.24.07 (Astron) 2022-12-21 (aarch64-apple-darwin) options wide,nls,dl,al,kan,sm,rh,color,filec + if(strcasecmp(exeName, "nu") == 0) + return getExeVersionRaw(exe, version); //0.73.0 #ifdef _WIN32 - else if(strcasecmp(exeName, "powershell") == 0 || strcasecmp(exeName, "powershell_ise") == 0) - getShellVersionWinPowerShell(exe, version); - else if(strcasecmp(exeName, "cmd") == 0) - getShellVersionCmd(exe, version); + if(strcasecmp(exeName, "powershell") == 0 || strcasecmp(exeName, "powershell_ise") == 0) + return getShellVersionWinPowerShell(exe, version); + if(strcasecmp(exeName, "cmd") == 0) + return getShellVersionCmd(exe, version); #endif - else - ok = false; - return ok; + return false; +} + +FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version) +{ + ffStrbufSetS(version, getenv("TERMUX_VERSION")); + return version->length > 0; +} + +FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version) +{ + if(ffProcessAppendStdOut(version, (char* const[]){ + "gnome-terminal", + "--version", + NULL + })) return false; + + //# GNOME Terminal 3.46.7 using VTE 0.70.2 +BIDI +GNUTLS +ICU +SYSTEMD + ffStrbufSubstrAfterFirstS(version, "Terminal "); + ffStrbufSubstrBeforeFirstC(version, ' '); + return true; +} + +FF_MAYBE_UNUSED static bool getTerminalVersionKonsole(FFstrbuf* exe, FFstrbuf* version) +{ + const char* konsoleVersion = getenv("KONSOLE_VERSION"); + if(konsoleVersion) + { + //221201 + long major = strtol(konsoleVersion, NULL, 10); + if (major >= 0) + { + long patch = major % 100; + major /= 100; + long minor = major % 100; + major /= 100; + ffStrbufSetF(version, "%ld.%ld.%ld", major, minor, patch); + return true; + } + } + + return getExeVersionGeneral(exe, version); +} + +#ifdef _WIN32 + +static bool getTerminalVersionWindowsTerminal(FFstrbuf* exe, FFstrbuf* version) +{ + FF_STRBUF_AUTO_DESTROY buildInfoPath; + ffStrbufInitNS(&buildInfoPath, ffStrbufLastIndexC(exe, '\\') + 1, exe->chars); + ffStrbufAppendS(&buildInfoPath, "BuildInfo.xml"); + + if(ffParsePropFile(buildInfoPath.chars, "StoreVersion=\"", version)) + { + ffStrbufTrimRight(version, '"'); + return true; + } + + return getFileVersion(exe->chars, version); +} + +static bool getTerminalVersionConEmu(FFstrbuf* exe, FFstrbuf* version) +{ + ffStrbufSetS(version, getenv("ConEmuBuild")); + + if(version->length) + return true; + + return getFileVersion(exe->chars, version); +} + +#endif + +bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe, FFstrbuf* version) +{ + #ifdef __ANDROID__ + + if(ffStrbufEqualS(processName, "Termux")) + return getTerminalVersionTermux(version); + + #endif + + #if defined(__linux__) || defined(__FreeBSD__) + + if(ffStrbufIgnCaseEqualS(processName, "gnome-terminal-")) + return getTerminalVersionGnome(version); + + if(ffStrbufIgnCaseEqualS(processName, "konsole")) + return getTerminalVersionKonsole(exe, version); + + if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal")) + return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)... + + if(ffStrbufIgnCaseEqualS(processName, "deepin-terminal")) + return getExeVersionGeneral(exe, version);//deepin-terminal 5.4.36 + + #endif + + #ifdef _WIN32 + + if(ffStrbufIgnCaseEqualS(processName, "WindowsTerminal.exe")) + return getTerminalVersionWindowsTerminal(exe, version); + + if(ffStrbufStartsWithIgnCaseS(processName, "ConEmuC")) + return getTerminalVersionConEmu(exe, version); + + #endif + + #ifndef _WIN32 + + if(ffStrbufIgnCaseEqualS(processName, "kitty")) + return getExeVersionGeneral(exe, version); //kitty 0.21.2 created by Kovid Goyal + + #endif + + if(ffStrbufStartsWithIgnCaseS(processName, "alacritty")) + return getExeVersionGeneral(exe, version); + + const char* termProgramVersion = getenv("TERM_PROGRAM_VERSION"); + if(termProgramVersion) + { + const char* termProgram = getenv("TERM_PROGRAM"); + if(termProgram) + { + if(ffStrbufStartsWithIgnCaseS(processName, termProgram) || // processName ends with `.exe` on Windows + (strcmp(termProgram, "vscode") == 0 && ffStrbufStartsWithIgnCaseS(processName, "code")) + ) { + ffStrbufSetS(version, termProgramVersion); + return true; + } + } + } + + #ifdef _WIN32 + + return getFileVersion(exe->chars, version); + + #else + + return false; + + #endif } diff --git a/src/detection/terminalshell/terminalshell.h b/src/detection/terminalshell/terminalshell.h index 8783e3410..a2a1f4200 100644 --- a/src/detection/terminalshell/terminalshell.h +++ b/src/detection/terminalshell/terminalshell.h @@ -17,6 +17,7 @@ typedef struct FFTerminalShellResult FFstrbuf terminalExe; FFstrbuf terminalPrettyName; const char* terminalExeName; //pointer to a char in terminalExe + FFstrbuf terminalVersion; FFstrbuf userShellExe; const char* userShellExeName; //pointer to a char in userShellExe diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 80c0d93d1..07b902dac 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -310,6 +310,8 @@ static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* versio getShellVersionGeneric(exe, exeName, version); } +bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version); + const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { FF_UNUSED(instance); @@ -350,12 +352,17 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) getTerminalFromEnv(&result); getUserShellFromEnv(instance, &result); - getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion); - if(strcasecmp(result.shellExeName, result.userShellExeName) != 0) - getShellVersion(&result.userShellExe, result.userShellExeName, &result.userShellVersion); - else - ffStrbufSet(&result.userShellVersion, &result.shellVersion); + ffStrbufClear(&result.shellVersion); + if(instance->config.shellVersion) + { + getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion); + + if(strcasecmp(result.shellExeName, result.userShellExeName) != 0) + getShellVersion(&result.userShellExe, result.userShellExeName, &result.userShellVersion); + else + ffStrbufSet(&result.userShellVersion, &result.shellVersion); + } if(ffStrbufEqualS(&result.shellProcessName, "pwsh")) ffStrbufInitS(&result.shellPrettyName, "PowerShell"); @@ -373,11 +380,18 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) ffStrbufInitS(&result.terminalPrettyName, "Apple Terminal"); else if(ffStrbufEqualS(&result.terminalProcessName, "WarpTerminal")) ffStrbufInitS(&result.terminalPrettyName, "Warp"); + else if(ffStrbufEqualS(&result.terminalProcessName, "wezterm-gui")) + ffStrbufInitS(&result.terminalPrettyName, "WezTerm"); else if(strncmp(result.terminalExeName, result.terminalProcessName.chars, result.terminalProcessName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName ffStrbufInitS(&result.terminalPrettyName, result.terminalExeName); else ffStrbufInitCopy(&result.terminalPrettyName, &result.terminalProcessName); + ffStrbufInit(&result.terminalVersion); + + if(instance->config.terminalVersion) + fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); + ffThreadMutexUnlock(&mutex); return &result; } diff --git a/src/detection/terminalshell/terminalshell_windows.cpp b/src/detection/terminalshell/terminalshell_windows.cpp index cb2da1ca4..b800228fa 100644 --- a/src/detection/terminalshell/terminalshell_windows.cpp +++ b/src/detection/terminalshell/terminalshell_windows.cpp @@ -99,7 +99,7 @@ static bool getProcessInfo(uint32_t pid, uint32_t* ppid, FFstrbuf* pname, FFstrb extern "C" bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version); -static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) +static uint32_t getShellInfo(const FFinstance* instance, FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; @@ -128,11 +128,12 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufClear(&result->shellPrettyName); ffStrbufClear(&result->shellExe); result->shellExeName = nullptr; - return getShellInfo(result, ppid); + return getShellInfo(instance, result, ppid); } ffStrbufClear(&result->shellVersion); - fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion); + if(instance->config.shellVersion) + fftsGetShellVersion(&result->shellExe, result->shellPrettyName.chars, &result->shellVersion); if(ffStrbufIgnCaseEqualS(&result->shellPrettyName, "pwsh")) ffStrbufSetS(&result->shellPrettyName, "PowerShell"); @@ -175,7 +176,7 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) return ppid; } -static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) +static uint32_t getTerminalInfo(const FFinstance* instance, FFTerminalShellResult* result, uint32_t pid) { uint32_t ppid; @@ -201,7 +202,7 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufClear(&result->terminalPrettyName); ffStrbufClear(&result->terminalExe); result->terminalExeName = ""; - return getTerminalInfo(result, ppid); + return getTerminalInfo(instance, result, ppid); } if(ffStrbufIgnCaseEqualS(&result->terminalPrettyName, "WindowsTerminal")) @@ -217,6 +218,8 @@ static uint32_t getTerminalInfo(FFTerminalShellResult* result, uint32_t pid) ffStrbufSetS(&result->terminalPrettyName, "Windows Explorer"); else if(ffStrbufStartsWithIgnCaseS(&result->terminalPrettyName, "ConEmuC")) ffStrbufSetS(&result->terminalPrettyName, "ConEmu"); + else if(ffStrbufEqualS(&result->terminalPrettyName, "wezterm-gui")) + ffStrbufInitS(&result->terminalPrettyName, "WezTerm"); return ppid; } @@ -263,6 +266,8 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) } } +extern "C" bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version); + const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) { FF_UNUSED(instance); @@ -297,11 +302,15 @@ const FFTerminalShellResult* ffDetectTerminalShell(const FFinstance* instance) if(!getProcessInfo(0, &ppid, nullptr, nullptr, nullptr)) goto exit; - ppid = getShellInfo(&result, ppid); - getTerminalInfo(&result, ppid); + ppid = getShellInfo(instance, &result, ppid); + getTerminalInfo(instance, &result, ppid); if(result.terminalProcessName.length == 0) getTerminalFromEnv(&result); + ffStrbufInit(&result.terminalVersion); + if(instance->config.terminalVersion) + fftsGetTerminalVersion(&result.terminalProcessName, &result.terminalExe, &result.terminalVersion); + exit: ffThreadMutexUnlock(&mutex); return &result; diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c index 92322440f..a972939d7 100644 --- a/src/detection/wifi/wifi_windows.c +++ b/src/detection/wifi/wifi_windows.c @@ -40,7 +40,7 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result) } } -const char* ffDetectWifi(FF_UNUSED_PARAM const FFinstance* instance, FFlist* result) +const char* ffDetectWifi(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* result) { FF_LIBRARY_LOAD(wlanapi, NULL, "dlopen wlanapi"FF_LIBRARY_EXTENSION" failed", "wlanapi"FF_LIBRARY_EXTENSION, 1) FF_LIBRARY_LOAD_SYMBOL_MESSAGE(wlanapi, WlanOpenHandle) diff --git a/src/fastfetch.c b/src/fastfetch.c index 543aea831..a18e3256e 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1253,6 +1253,10 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con instance->config.gpuHideDiscrete = optionParseBoolean(value); else if(strcasecmp(key, "--title-fqdn") == 0) instance->config.titleFQDN = optionParseBoolean(value); + else if(strcasecmp(key, "--shell-version") == 0) + instance->config.shellVersion = optionParseBoolean(value); + else if(strcasecmp(key, "--terminal-version") == 0) + instance->config.terminalVersion = optionParseBoolean(value); else if(strcasecmp(key, "--disk-folders") == 0) optionParseString(key, value, &instance->config.diskFolders); else if(strcasecmp(key, "--disk-show-removable") == 0) @@ -1483,6 +1487,10 @@ int main(int argc, const char** argv) ffStart(&instance); + #if defined(_WIN32) && defined(FF_ENABLE_BUFFER) + fflush(stdout); + #endif + //Parse the structure and call the modules uint32_t startIndex = 0; while (startIndex < data.structure.length) diff --git a/src/fastfetch.h b/src/fastfetch.h index 1c6316957..8ee5cd356 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -21,7 +21,7 @@ static inline void ffUnused(int dummy, ...) { (void) dummy; } #define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); -#define FF_UNUSED_PARAM __attribute__ ((__unused__)) +#define FF_MAYBE_UNUSED __attribute__ ((__unused__)) #define FASTFETCH_LOGO_MAX_COLORS 9 //two digits would make parsing much more complicated (index 1 - 9) @@ -180,6 +180,9 @@ typedef struct FFconfig bool titleFQDN; + bool shellVersion; + bool terminalVersion; + FFstrbuf diskFolders; bool diskShowRemovable; bool diskShowHidden; diff --git a/src/modules/terminal.c b/src/modules/terminal.c index 469ece23b..28e8d14a5 100644 --- a/src/modules/terminal.c +++ b/src/modules/terminal.c @@ -20,7 +20,11 @@ void ffPrintTerminal(FFinstance* instance) if(instance->config.terminal.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_TERMINAL_MODULE_NAME, 0, &instance->config.terminal.key); - ffStrbufPutTo(&result->terminalPrettyName, stdout); + + if(result->terminalVersion.length) + printf("%s %s\n", result->terminalPrettyName.chars, result->terminalVersion.chars); + else + ffStrbufPutTo(&result->terminalPrettyName, stdout); } else { diff --git a/src/util/FFlist.h b/src/util/FFlist.h index 86b20bc5c..e65180d3a 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -51,8 +51,6 @@ static inline void ffListSort(FFlist* list, int(*compar)(const void*, const void itemVarName - (itemType*)(listVar).data < (listVar).length; \ ++itemVarName) -#if defined(_WIN32) || defined(__APPLE__) - #define FF_LIST_AUTO_DESTROY FFlist __attribute__((__cleanup__(ffListDestroy))) -#endif +#define FF_LIST_AUTO_DESTROY FFlist __attribute__((__cleanup__(ffListDestroy))) #endif diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 94adc6b03..7755225a7 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -310,8 +310,6 @@ static inline FF_C_NODISCARD bool ffStrbufEndsWithIgnCase(const FFstrbuf* strbuf return ffStrbufEndsWithIgnCaseNS(strbuf, end->length, end->chars); } -#if defined(_WIN32) || defined(__APPLE__) - #define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy))) -#endif +#define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy))) #endif diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c index a1f68021d..c21389f19 100644 --- a/src/util/windows/utsname.c +++ b/src/util/windows/utsname.c @@ -13,7 +13,7 @@ static int detectSysname(struct utsname *name) static int detectNodename(struct utsname *name) { DWORD bufSize = UTSNAME_MAXLENGTH - 1; - if(!GetComputerNameA(name->nodename, &bufSize)) + if(!GetComputerNameExA(ComputerNameDnsFullyQualified, name->nodename, &bufSize)) return 1; name->nodename[bufSize] = '\0'; return 0;