Files
fastfetch/src/detection/editor/editor.c
T

161 lines
5.1 KiB
C
Raw Normal View History

2024-05-22 16:13:36 +08:00
#include "editor.h"
2026-01-06 09:48:38 +08:00
#include "common/processing.h"
#include "common/library.h"
#include "common/stringUtils.h"
#include "common/path.h"
#include "common/binary.h"
2024-05-22 16:13:36 +08:00
#include <stdlib.h>
2026-04-09 16:20:59 +08:00
static bool extractNvimVersionFromBinary(const char* str, FF_A_UNUSED uint32_t len, void* userdata) {
2026-03-29 09:28:49 +08:00
if (!ffStrStartsWith(str, "NVIM v")) {
return true;
}
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
return false;
}
2026-04-09 16:20:59 +08:00
static bool extractVimVersionFromBinary(const char* str, FF_A_UNUSED uint32_t len, void* userdata) {
2026-03-29 09:28:49 +08:00
if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) {
return true;
}
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved "));
ffStrbufSubstrBeforeFirstC(userdata, ' ');
return false;
}
2026-04-09 16:20:59 +08:00
static bool extractNanoVersionFromBinary(const char* str, FF_A_UNUSED uint32_t len, void* userdata) {
2026-03-29 09:28:49 +08:00
if (!ffStrStartsWith(str, "GNU nano ")) {
return true;
}
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
return false;
}
2026-03-29 09:28:49 +08:00
const char* ffDetectEditor(FFEditorResult* result) {
2024-05-22 16:13:36 +08:00
ffStrbufSetS(&result->name, getenv("VISUAL"));
2026-03-29 09:28:49 +08:00
if (result->name.length) {
2024-05-27 16:41:37 +08:00
result->type = "Visual";
2026-03-29 09:28:49 +08:00
} else {
2024-05-22 16:13:36 +08:00
ffStrbufSetS(&result->name, getenv("EDITOR"));
2026-03-29 09:28:49 +08:00
if (result->name.length) {
2024-05-27 16:41:37 +08:00
result->type = "Editor";
2026-03-29 09:28:49 +08:00
} else {
2024-05-27 16:41:37 +08:00
return "$VISUAL or $EDITOR not set";
2026-03-29 09:28:49 +08:00
}
2024-05-27 16:41:37 +08:00
}
2024-05-22 16:13:36 +08:00
2026-03-29 09:28:49 +08:00
if (ffIsAbsolutePath(result->name.chars)) {
ffStrbufSet(&result->path, &result->name);
2026-03-29 09:28:49 +08:00
} else {
const char* error = ffFindExecutableInPath(result->name.chars, &result->path);
2026-03-29 09:28:49 +08:00
if (error) {
return NULL;
}
}
2024-08-23 10:17:06 +08:00
{
char buf[PATH_MAX + 1];
2026-03-29 09:28:49 +08:00
if (!realpath(result->path.chars, buf)) {
2024-08-23 10:17:06 +08:00
return NULL;
2026-03-29 09:28:49 +08:00
}
2024-05-22 16:13:36 +08:00
2024-08-23 10:17:06 +08:00
// WIN32: Should we handle scoop shim exe here?
2024-08-22 16:41:06 +08:00
2026-03-29 09:28:49 +08:00
#ifdef __linux__
2024-08-23 10:17:06 +08:00
if (!ffStrEndsWith(buf, "/snap"))
2026-03-29 09:28:49 +08:00
#endif
2024-08-23 10:17:06 +08:00
ffStrbufSetS(&result->path, buf);
}
{
uint32_t index = ffStrbufLastIndexC(&result->path,
2026-03-29 09:28:49 +08:00
#ifndef _WIN32
'/'
2026-03-29 09:28:49 +08:00
#else
'\\'
2026-03-29 09:28:49 +08:00
#endif
);
2026-03-29 09:28:49 +08:00
if (index == result->path.length) {
return NULL;
2026-03-29 09:28:49 +08:00
}
ffStrbufSetS(&result->exe, &result->path.chars[index + 1]);
2026-03-29 09:28:49 +08:00
if (!result->exe.length) {
return NULL;
2026-03-29 09:28:49 +08:00
}
2026-03-29 09:28:49 +08:00
#ifdef _WIN32
if (ffStrbufEndsWithS(&result->exe, ".exe")) {
ffStrbufSubstrBefore(&result->exe, result->exe.length - 4);
2026-03-29 09:28:49 +08:00
}
#endif
}
2024-05-22 16:13:36 +08:00
2026-03-29 09:28:49 +08:00
if (!instance.config.general.detectVersion) {
return NULL;
}
2024-08-22 16:41:06 +08:00
2026-03-29 09:28:49 +08:00
if (ffStrbufEqualS(&result->exe, "nvim")) {
2024-08-27 16:19:05 +08:00
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version, (uint32_t) strlen("NVIM v0.0.0"));
2026-03-29 09:28:49 +08:00
} else if (ffStrbufEqualS(&result->exe, "vim") || ffStrbufStartsWithS(&result->exe, "vim.")) {
2024-08-27 16:19:05 +08:00
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
2026-03-29 09:28:49 +08:00
} else if (ffStrbufEqualS(&result->exe, "nano")) {
2024-08-27 16:19:05 +08:00
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
2026-03-29 09:28:49 +08:00
}
2026-03-29 09:28:49 +08:00
if (result->version.length > 0) {
return NULL;
}
2024-05-22 16:13:36 +08:00
const char* param = NULL;
if (
ffStrbufEqualS(&result->exe, "nano") ||
ffStrbufEqualS(&result->exe, "vim") ||
ffStrbufStartsWithS(&result->exe, "vim.") || // vim.basic/vim.tiny
ffStrbufEqualS(&result->exe, "nvim") ||
ffStrbufEqualS(&result->exe, "micro") ||
ffStrbufEqualS(&result->exe, "emacs") ||
ffStrbufStartsWithS(&result->exe, "emacs-") || // emacs-29.3
ffStrbufEqualS(&result->exe, "hx") ||
ffStrbufEqualS(&result->exe, "code") ||
2024-06-17 12:37:32 +08:00
ffStrbufEqualS(&result->exe, "pluma") ||
ffStrbufEqualS(&result->exe, "sublime_text") ||
2026-03-29 09:28:49 +08:00
ffStrbufEqualS(&result->exe, "zeditor")) {
param = "--version";
} else if (
ffStrbufEqualS(&result->exe, "kak") ||
2026-03-29 09:28:49 +08:00
ffStrbufEqualS(&result->exe, "pico")) {
param = "-version";
} else if (
ffStrbufEqualS(&result->exe, "ne")) {
param = "-h";
} else {
return NULL;
}
ffProcessAppendStdOut(&result->version, (char* const[]) {
result->path.chars,
(char*) param,
NULL,
});
if (result->version.length == 0) {
2024-05-22 16:13:36 +08:00
return NULL;
2026-03-29 09:28:49 +08:00
}
2024-05-22 16:13:36 +08:00
ffStrbufSubstrBeforeFirstC(&result->version, '\n');
const char* versionStart = strpbrk(result->version.chars, "0123456789");
if (versionStart != NULL) {
const char* versionEnd = strpbrk(versionStart, " \t\v\f\r");
2026-03-29 09:28:49 +08:00
if (versionEnd != NULL) {
ffStrbufSubstrBefore(&result->version, (uint32_t) (versionEnd - result->version.chars));
}
2026-03-29 09:28:49 +08:00
if (versionStart != result->version.chars) {
ffStrbufSubstrAfter(&result->version, (uint32_t) (versionStart - result->version.chars - 1));
}
2024-05-22 16:13:36 +08:00
}
return NULL;
}