mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
TerminalShell: split terminal and shell detection code further
This commit is contained in:
@@ -118,7 +118,7 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static pid_t getShellInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
static pid_t getShellInfo(FFShellResult* result, pid_t pid)
|
||||
{
|
||||
char name[256];
|
||||
name[0] = '\0';
|
||||
@@ -148,13 +148,14 @@ static pid_t getShellInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
)
|
||||
return getShellInfo(result, ppid);
|
||||
|
||||
result->shellPid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->shellProcessName, name);
|
||||
getProcessInformation(pid, &result->shellProcessName, &result->shellExe, &result->shellExeName);
|
||||
result->pid = (uint32_t) pid;
|
||||
result->ppid = (uint32_t) ppid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
return ppid;
|
||||
}
|
||||
|
||||
static pid_t getTerminalInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
static pid_t getTerminalInfo(FFTerminalResult* result, pid_t pid)
|
||||
{
|
||||
char name[256];
|
||||
name[0] = '\0';
|
||||
@@ -191,29 +192,29 @@ static pid_t getTerminalInfo(FFTerminalShellResult* result, pid_t pid)
|
||||
getProcessNameAndPpid(ppid, name, &ppid);
|
||||
#endif
|
||||
|
||||
result->terminalPid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->terminalProcessName, name);
|
||||
getProcessInformation(pid, &result->terminalProcessName, &result->terminalExe, &result->terminalExeName);
|
||||
result->pid = (uint32_t) pid;
|
||||
ffStrbufSetS(&result->processName, name);
|
||||
getProcessInformation(pid, &result->processName, &result->exe, &result->exeName);
|
||||
return ppid;
|
||||
}
|
||||
|
||||
static void getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
static void getTerminalFromEnv(FFTerminalResult* result)
|
||||
{
|
||||
if(
|
||||
result->terminalProcessName.length > 0 &&
|
||||
!ffStrbufStartsWithIgnCaseS(&result->terminalProcessName, "login") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "(login)") &&
|
||||
result->processName.length > 0 &&
|
||||
!ffStrbufStartsWithIgnCaseS(&result->processName, "login") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "(login)") &&
|
||||
|
||||
#ifdef __APPLE__
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "launchd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "stable") && //for WarpTerminal
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "launchd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "stable") && //for WarpTerminal
|
||||
#else
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "systemd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "init") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->terminalProcessName, "(init)") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "systemd") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "init") &&
|
||||
!ffStrbufIgnCaseEqualS(&result->processName, "(init)") &&
|
||||
#endif
|
||||
|
||||
ffStrbufIgnCaseCompS(&result->terminalProcessName, "0") != 0
|
||||
ffStrbufIgnCaseCompS(&result->processName, "0") != 0
|
||||
) return;
|
||||
|
||||
const char* term = NULL;
|
||||
@@ -274,20 +275,20 @@ static void getTerminalFromEnv(FFTerminalShellResult* result)
|
||||
|
||||
if(ffStrSet(term))
|
||||
{
|
||||
ffStrbufSetS(&result->terminalProcessName, term);
|
||||
ffStrbufSetS(&result->terminalExe, term);
|
||||
setExeName(&result->terminalExe, &result->terminalExeName);
|
||||
ffStrbufSetS(&result->processName, term);
|
||||
ffStrbufSetS(&result->exe, term);
|
||||
setExeName(&result->exe, &result->exeName);
|
||||
}
|
||||
}
|
||||
|
||||
static void getUserShellFromEnv(FFTerminalShellResult* result)
|
||||
static void getUserShellFromEnv(FFShellResult* result)
|
||||
{
|
||||
//If shell detection via processes failed
|
||||
if(result->shellProcessName.length == 0 && instance.state.platform.userShell.length > 0)
|
||||
if(result->processName.length == 0 && instance.state.platform.userShell.length > 0)
|
||||
{
|
||||
ffStrbufSet(&result->shellExe, &instance.state.platform.userShell);
|
||||
setExeName(&result->shellExe, &result->shellExeName);
|
||||
ffStrbufAppendS(&result->shellProcessName, result->shellExeName);
|
||||
ffStrbufSet(&result->exe, &instance.state.platform.userShell);
|
||||
setExeName(&result->exe, &result->exeName);
|
||||
ffStrbufAppendS(&result->processName, result->exeName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,114 +296,129 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
||||
|
||||
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
|
||||
|
||||
static void setShellInfoDetails(FFTerminalShellResult* result)
|
||||
static void setShellInfoDetails(FFShellResult* result)
|
||||
{
|
||||
ffStrbufClear(&result->shellVersion);
|
||||
fftsGetShellVersion(&result->shellExe, result->shellExeName, &result->shellVersion);
|
||||
ffStrbufClear(&result->version);
|
||||
fftsGetShellVersion(&result->exe, result->exeName, &result->version);
|
||||
|
||||
if(ffStrbufEqualS(&result->shellProcessName, "pwsh"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "PowerShell");
|
||||
else if(ffStrbufEqualS(&result->shellProcessName, "nu"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "nushell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellProcessName, "python") && getenv("XONSH_VERSION"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "xonsh");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->shellProcessName, "oil.ovm"))
|
||||
ffStrbufInitStatic(&result->shellPrettyName, "Oils");
|
||||
if(ffStrbufEqualS(&result->processName, "pwsh"))
|
||||
ffStrbufInitStatic(&result->prettyName, "PowerShell");
|
||||
else if(ffStrbufEqualS(&result->processName, "nu"))
|
||||
ffStrbufInitStatic(&result->prettyName, "nushell");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->processName, "python") && getenv("XONSH_VERSION"))
|
||||
ffStrbufInitStatic(&result->prettyName, "xonsh");
|
||||
else if(ffStrbufIgnCaseEqualS(&result->processName, "oil.ovm"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Oils");
|
||||
else
|
||||
{
|
||||
// https://github.com/fastfetch-cli/fastfetch/discussions/280#discussioncomment-3831734
|
||||
ffStrbufInitS(&result->shellPrettyName, result->shellExeName);
|
||||
ffStrbufInitS(&result->prettyName, result->exeName);
|
||||
}
|
||||
}
|
||||
|
||||
static void setTerminalInfoDetails(FFTerminalShellResult* result)
|
||||
static void setTerminalInfoDetails(FFTerminalResult* result)
|
||||
{
|
||||
if(result->terminalExeName[0] == '.' && ffStrEndsWith(result->terminalExeName, "-wrapped"))
|
||||
if(result->exeName[0] == '.' && ffStrEndsWith(result->exeName, "-wrapped"))
|
||||
{
|
||||
// For NixOS. Ref: #510 and https://github.com/NixOS/nixpkgs/pull/249428
|
||||
// We use terminalProcessName when detecting version and font, overriding it for simplification
|
||||
// We use processName when detecting version and font, overriding it for simplification
|
||||
ffStrbufSetNS(
|
||||
&result->terminalProcessName,
|
||||
(uint32_t) (strlen(result->terminalExeName) - strlen(".-wrapped")),
|
||||
result->terminalExeName + 1);
|
||||
&result->processName,
|
||||
(uint32_t) (strlen(result->exeName) - strlen(".-wrapped")),
|
||||
result->exeName + 1);
|
||||
}
|
||||
|
||||
if(ffStrbufEqualS(&result->terminalProcessName, "wezterm-gui"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "WezTerm");
|
||||
if(ffStrbufStartsWithS(&result->terminalProcessName, "tmux:"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "tmux");
|
||||
if(ffStrbufEqualS(&result->processName, "wezterm-gui"))
|
||||
ffStrbufInitStatic(&result->prettyName, "WezTerm");
|
||||
if(ffStrbufStartsWithS(&result->processName, "tmux:"))
|
||||
ffStrbufInitStatic(&result->prettyName, "tmux");
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "com.termux"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "Termux");
|
||||
else if(ffStrbufEqualS(&result->processName, "com.termux"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Termux");
|
||||
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
|
||||
else if(ffStrbufStartsWithS(&result->terminalProcessName, "gnome-terminal-"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "GNOME Terminal");
|
||||
else if(ffStrbufStartsWithS(&result->terminalProcessName, "kgx"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "GNOME Console");
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "urxvt") ||
|
||||
ffStrbufEqualS(&result->terminalProcessName, "urxvtd") ||
|
||||
ffStrbufEqualS(&result->terminalProcessName, "rxvt")
|
||||
else if(ffStrbufStartsWithS(&result->processName, "gnome-terminal-"))
|
||||
ffStrbufInitStatic(&result->prettyName, "GNOME Terminal");
|
||||
else if(ffStrbufStartsWithS(&result->processName, "kgx"))
|
||||
ffStrbufInitStatic(&result->prettyName, "GNOME Console");
|
||||
else if(ffStrbufEqualS(&result->processName, "urxvt") ||
|
||||
ffStrbufEqualS(&result->processName, "urxvtd") ||
|
||||
ffStrbufEqualS(&result->processName, "rxvt")
|
||||
)
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "rxvt-unicode");
|
||||
ffStrbufInitStatic(&result->prettyName, "rxvt-unicode");
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "iTerm.app") || ffStrbufStartsWithS(&result->terminalProcessName, "iTermServer-"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "iTerm");
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "Apple_Terminal"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "Apple Terminal");
|
||||
else if(ffStrbufEqualS(&result->terminalProcessName, "WarpTerminal"))
|
||||
ffStrbufInitStatic(&result->terminalPrettyName, "Warp");
|
||||
else if(ffStrbufEqualS(&result->processName, "iTerm.app") || ffStrbufStartsWithS(&result->processName, "iTermServer-"))
|
||||
ffStrbufInitStatic(&result->prettyName, "iTerm");
|
||||
else if(ffStrbufEqualS(&result->processName, "Apple_Terminal"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Apple Terminal");
|
||||
else if(ffStrbufEqualS(&result->processName, "WarpTerminal"))
|
||||
ffStrbufInitStatic(&result->prettyName, "Warp");
|
||||
|
||||
#endif
|
||||
|
||||
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 if(strncmp(result->exeName, result->processName.chars, result->processName.length) == 0) // if exeName starts with processName, print it. Otherwise print processName
|
||||
ffStrbufInitS(&result->prettyName, result->exeName);
|
||||
else
|
||||
ffStrbufInitCopy(&result->terminalPrettyName, &result->terminalProcessName);
|
||||
ffStrbufInitCopy(&result->prettyName, &result->processName);
|
||||
|
||||
ffStrbufInit(&result->terminalVersion);
|
||||
fftsGetTerminalVersion(&result->terminalProcessName, &result->terminalExe, &result->terminalVersion);
|
||||
ffStrbufInit(&result->version);
|
||||
fftsGetTerminalVersion(&result->processName, &result->exe, &result->version);
|
||||
}
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell()
|
||||
#ifdef __APPLE__
|
||||
#define FF_EXE_PATH_LEN PROC_PIDPATHINFO_MAXSIZE
|
||||
#elif defined(MAXPATH)
|
||||
#define FF_EXE_PATH_LEN MAXPATH
|
||||
#elif defined(PATH_MAX)
|
||||
#define FF_EXE_PATH_LEN PATH_MAX
|
||||
#else
|
||||
#define FF_EXE_PATH_LEN 260
|
||||
#endif
|
||||
|
||||
const FFShellResult* ffDetectShell()
|
||||
{
|
||||
static FFTerminalShellResult result;
|
||||
static FFShellResult result;
|
||||
static bool init = false;
|
||||
if(init)
|
||||
return &result;
|
||||
init = true;
|
||||
|
||||
#ifdef __APPLE__
|
||||
const uint32_t exePathLen = PROC_PIDPATHINFO_MAXSIZE;
|
||||
#elif defined(MAXPATH)
|
||||
const uint32_t exePathLen = MAXPATH;
|
||||
#elif defined(PATH_MAX)
|
||||
const uint32_t exePathLen = PATH_MAX;
|
||||
#else
|
||||
const uint32_t exePathLen = 260;
|
||||
#endif
|
||||
|
||||
ffStrbufInit(&result.shellProcessName);
|
||||
ffStrbufInitA(&result.shellExe, exePathLen);
|
||||
result.shellExeName = result.shellExe.chars;
|
||||
ffStrbufInit(&result.shellVersion);
|
||||
result.shellPid = 0;
|
||||
|
||||
ffStrbufInit(&result.terminalProcessName);
|
||||
ffStrbufInitA(&result.terminalExe, exePathLen);
|
||||
result.terminalExeName = result.terminalExe.chars;
|
||||
result.terminalPid = 0;
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, FF_EXE_PATH_LEN);
|
||||
result.exeName = result.exe.chars;
|
||||
ffStrbufInit(&result.version);
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
|
||||
pid_t ppid = getppid();
|
||||
ppid = getShellInfo(&result, ppid);
|
||||
getUserShellFromEnv(&result);
|
||||
setShellInfoDetails(&result);
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
const FFTerminalResult* ffDetectTerminal()
|
||||
{
|
||||
static FFTerminalResult result;
|
||||
static bool init = false;
|
||||
if(init)
|
||||
return &result;
|
||||
init = true;
|
||||
|
||||
ffStrbufInit(&result.processName);
|
||||
ffStrbufInitA(&result.exe, FF_EXE_PATH_LEN);
|
||||
result.exeName = result.exe.chars;
|
||||
result.pid = 0;
|
||||
result.ppid = 0;
|
||||
|
||||
pid_t ppid = (pid_t) ffDetectShell()->ppid;
|
||||
|
||||
if (ppid)
|
||||
ppid = getTerminalInfo(&result, ppid);
|
||||
getTerminalFromEnv(&result);
|
||||
|
||||
Reference in New Issue
Block a user