#include "editor.h" #include "common/processing.h" #include "util/stringUtils.h" #include #ifdef _WIN32 #include static inline char* realpath(const char* restrict file_name, char* restrict resolved_name) { return _fullpath(resolved_name, file_name, _MAX_PATH); } #endif const char* ffDetectEditor(FFEditorResult* result) { ffStrbufSetS(&result->name, getenv("VISUAL")); if (result->name.length) result->type = "Visual"; else { ffStrbufSetS(&result->name, getenv("EDITOR")); if (result->name.length) result->type = "Editor"; else return "$VISUAL or $EDITOR not set"; } if (!instance.config.general.detectVersion) return NULL; #ifndef _WIN32 if (result->name.chars[0] != '/') { if (ffProcessAppendStdOut(&result->path, (char* const[]){ FASTFETCH_TARGET_DIR_USR "/bin/which", result->name.chars, NULL, }) != NULL || result->path.length == 0) return NULL; } #else if (!(result->name.length > 3 && ffCharIsEnglishAlphabet(result->name.chars[0]) && result->name.chars[1] == ':' && result->name.chars[2] == '\\')) { char buf[32]; uint32_t len = GetSystemDirectoryA(buf, sizeof(buf)); if (len < strlen("C:\\WINDOWS\\system32")) return NULL; strncpy(buf + len, "\\where.exe", sizeof(buf) - len); if (ffProcessAppendStdOut(&result->path, (char* const[]){ buf, result->name.chars, NULL, }) != NULL || result->path.length == 0) return NULL; } #endif else ffStrbufSet(&result->path, &result->name); char buf[PATH_MAX + 1]; if (!realpath(result->path.chars, buf)) return NULL; ffStrbufSetS(&result->path, buf); { uint32_t index = ffStrbufLastIndexC(&result->path, #ifndef _WIN32 '/' #else '\\' #endif ); if (index == result->path.length) return NULL; ffStrbufSetS(&result->exe, &result->path.chars[index + 1]); if (!result->exe.length) return NULL; #ifdef _WIN32 if (ffStrbufEndsWithS(&result->exe, ".exe")) ffStrbufSubstrBefore(&result->exe, result->exe.length - 4); #endif } const char* param = NULL; if ( ffStrbufEqualS(&result->exe, "nano") || ffStrbufEqualS(&result->exe, "vim") || 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") || ffStrbufEqualS(&result->exe, "pluma") || ffStrbufEqualS(&result->exe, "sublime_text") ) param = "--version"; else if ( ffStrbufEqualS(&result->exe, "kak") || 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) return NULL; ffStrbufSubstrBeforeFirstC(&result->version, '\n'); for (uint32_t iStart = 0; iStart < result->version.length; ++iStart) { char c = result->version.chars[iStart]; if (ffCharIsDigit(c)) { for (uint32_t iEnd = iStart + 1; iEnd < result->version.length; ++iEnd) { char c = result->version.chars[iEnd]; if (isspace(c)) { ffStrbufSubstrBefore(&result->version, iEnd); break; } } if (iStart > 0) ffStrbufSubstrAfter(&result->version, iStart - 1); break; } } return NULL; }