Editor: add new module

Fix #430
This commit is contained in:
李通洲 2024-05-22 16:13:36 +08:00
parent 92136370bb
commit 30a5dd52b1
No known key found for this signature in database
GPG Key ID: 269AD4F5325A22A3
17 changed files with 302 additions and 3 deletions

View File

@ -1,3 +1,8 @@
# 2.13.2
Features:
* Add new module `Editor` which prints information of the default editor, i.e. $VISUAL or $EDITOR (Editor)
# 2.13.1
Fix a regression introduced in v2.13.0

View File

@ -291,6 +291,7 @@ set(LIBFASTFETCH_SRC
src/detection/disk/disk.c
src/detection/diskio/diskio.c
src/detection/displayserver/displayserver.c
src/detection/editor/editor.c
src/detection/font/font.c
src/detection/gpu/gpu.c
src/detection/media/media.c
@ -330,6 +331,7 @@ set(LIBFASTFETCH_SRC
src/modules/de/de.c
src/modules/disk/disk.c
src/modules/diskio/diskio.c
src/modules/editor/editor.c
src/modules/font/font.c
src/modules/gpu/gpu.c
src/modules/host/host.c

View File

@ -695,6 +695,7 @@
"disk",
"diskio",
"de",
"editor",
"font",
"gamepad",
"gpu",
@ -795,6 +796,10 @@
"const": "datetime",
"description": "Print current date and time"
},
{
"const": "editor",
"description": "Print information of the default editor ($VISUAL or $EDITOR)"
},
{
"const": "font",
"description": "Print system font name"

View File

@ -15,6 +15,7 @@
"processes",
"packages",
"shell",
"editor",
"display",
"brightness",
"monitor",

View File

@ -22,6 +22,7 @@
"processes",
"packages",
"shell",
"editor",
"display",
"brightness",
"monitor",

View File

@ -37,6 +37,7 @@ static FFModuleBaseInfo* D[] = {
};
static FFModuleBaseInfo* E[] = {
(void*) &instance.config.modules.editor,
NULL,
};

View File

@ -0,0 +1,112 @@
#include "editor.h"
#include "common/processing.h"
#include "util/stringUtils.h"
#include <stdlib.h>
#if 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
#ifdef _WIN32
static inline char* realpath(const char* restrict file_name, char* restrict resolved_name)
{
char* result = _fullpath(resolved_name, file_name, _MAX_PATH);
if(result)
{
resolved_name[1] = resolved_name[0]; // Drive Name
resolved_name[0] = '/';
}
return result;
}
#endif
const char* ffDetectEditor(FFEditorResult* result)
{
ffStrbufSetS(&result->name, getenv("VISUAL"));
if (result->name.length == 0)
ffStrbufSetS(&result->name, getenv("EDITOR"));
if (result->name.length == 0)
return "$VISUAL or $EDITOR not set";
#ifndef _WIN32
if (result->name.chars[0] != '/')
{
if (ffProcessAppendStdOut(&result->path, (char* const[]){
"/usr/bin/which",
result->name.chars,
NULL,
}) != NULL || result->path.length == 0)
return NULL;
}
else
ffStrbufSet(&result->path, &result->name);
char buf[FF_EXE_PATH_LEN];
if (!realpath(result->path.chars, buf))
return NULL;
ffStrbufSetS(&result->path, buf);
const char* exe = &result->path.chars[ffStrbufLastIndexC(&result->path, '/')];
if (!*exe) return NULL;
++exe;
result->exe = exe;
const char* param = NULL;
if (
ffStrEquals(exe, "nano") ||
ffStrEquals(exe, "vim") ||
ffStrEquals(exe, "nvim") ||
ffStrEquals(exe, "micro") ||
ffStrEquals(exe, "emacs") ||
ffStrStartsWith(exe, "emacs-") || // emacs-29.3
ffStrEquals(exe, "hx") ||
ffStrEquals(exe, "code") ||
ffStrEquals(exe, "sublime_text")
) param = "--version";
else if (
ffStrEquals(exe, "kak") ||
ffStrEquals(exe, "pico")
) param = "-version";
else if (
ffStrEquals(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 (c >= '0' && c <= '9')
{
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;
}
}
#endif
return NULL;
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "fastfetch.h"
typedef struct FFEditorResult
{
FFstrbuf name;
const char* exe;
FFstrbuf path;
FFstrbuf version;
} FFEditorResult;
const char* ffDetectEditor(FFEditorResult* result);

134
src/modules/editor/editor.c Normal file
View File

@ -0,0 +1,134 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "detection/libc/libc.h"
#include "detection/editor/editor.h"
#include "modules/editor/editor.h"
#include "util/stringUtils.h"
#define FF_EDITOR_NUM_FORMAT_ARGS 4
void ffPrintEditor(FFEditorOptions* options)
{
FFEditorResult result = {
.name = ffStrbufCreate(),
.path = ffStrbufCreate(),
.version = ffStrbufCreate(),
};
const char* error = ffDetectEditor(&result);
if (error)
{
ffPrintError(FF_EDITOR_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
return;
}
ffPrintLogoAndKey(FF_EDITOR_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
if (result.exe)
{
fputs(result.exe, stdout);
if (result.version.length)
printf(" (%s)", result.version.chars);
}
else
{
ffStrbufWriteTo(&result.name, stdout);
}
putchar('\n');
ffStrbufDestroy(&result.name);
ffStrbufDestroy(&result.path);
ffStrbufDestroy(&result.version);
}
bool ffParseEditorCommandOptions(FFEditorOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_EDITOR_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
return false;
}
void ffParseEditorJsonObject(FFEditorOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
ffPrintError(FF_EDITOR_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
void ffGenerateEditorJsonConfig(FFEditorOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyEditorOptions))) FFEditorOptions defaultOptions;
ffInitEditorOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
}
void ffGenerateEditorJsonResult(FF_MAYBE_UNUSED FFEditorOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FFEditorResult result = {
.name = ffStrbufCreate(),
.path = ffStrbufCreate(),
.version = ffStrbufCreate(),
};
const char* error = ffDetectEditor(&result);
if (error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
yyjson_mut_obj_add_strbuf(doc, obj, "name", &result.name);
yyjson_mut_obj_add_strcpy(doc, obj, "exe", result.exe);
yyjson_mut_obj_add_strbuf(doc, obj, "path", &result.path);
yyjson_mut_obj_add_strbuf(doc, obj, "version", &result.version);
ffStrbufDestroy(&result.name);
ffStrbufDestroy(&result.path);
ffStrbufDestroy(&result.version);
}
void ffPrintEditorHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_EDITOR_MODULE_NAME, "{2} ({4})", FF_EDITOR_NUM_FORMAT_ARGS, ((const char* []) {
"Name",
"Exe name",
"Full path",
"Version",
}));
}
void ffInitEditorOptions(FFEditorOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_EDITOR_MODULE_NAME,
"Print information of the default editor ($VISUAL or $EDITOR)",
ffParseEditorCommandOptions,
ffParseEditorJsonObject,
ffPrintEditor,
ffGenerateEditorJsonResult,
ffPrintEditorHelpFormat,
ffGenerateEditorJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs);
}
void ffDestroyEditorOptions(FFEditorOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}

View File

@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_EDITOR_MODULE_NAME "Editor"
void ffPrintEditor(FFEditorOptions* options);
void ffInitEditorOptions(FFEditorOptions* options);
void ffDestroyEditorOptions(FFEditorOptions* options);

View File

@ -0,0 +1,11 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFEditorOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
} FFEditorOptions;

View File

@ -22,6 +22,7 @@
#include "modules/diskio/diskio.h"
#include "modules/display/display.h"
#include "modules/de/de.h"
#include "modules/editor/editor.h"
#include "modules/font/font.h"
#include "modules/gamepad/gamepad.h"
#include "modules/gpu/gpu.h"

View File

@ -22,6 +22,7 @@
#include "modules/disk/option.h"
#include "modules/diskio/option.h"
#include "modules/display/option.h"
#include "modules/editor/option.h"
#include "modules/font/option.h"
#include "modules/host/option.h"
#include "modules/gamepad/option.h"

View File

@ -23,6 +23,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitDiskOptions(&options->disk);
ffInitDiskIOOptions(&options->diskIo);
ffInitDisplayOptions(&options->display);
ffInitEditorOptions(&options->editor);
ffInitFontOptions(&options->font);
ffInitGPUOptions(&options->gpu);
ffInitGamepadOptions(&options->gamepad);
@ -90,6 +91,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyDiskOptions(&options->disk);
ffDestroyDiskIOOptions(&options->diskIo);
ffDestroyDisplayOptions(&options->display);
ffDestroyEditorOptions(&options->editor);
ffDestroyFontOptions(&options->font);
ffDestroyGPUOptions(&options->gpu);
ffDestroyGamepadOptions(&options->gamepad);

View File

@ -24,6 +24,7 @@ typedef struct FFOptionsModules
FFDiskOptions disk;
FFDiskIOOptions diskIo;
FFDisplayOptions display;
FFEditorOptions editor;
FFFontOptions font;
FFGPUOptions gpu;
FFGamepadOptions gamepad;

View File

@ -389,8 +389,8 @@ void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index)
if(strbuf->allocated == 0)
{
//static string
strbuf->length -= index;
strbuf->chars += index;
strbuf->length -= index + 1;
strbuf->chars += index + 1;
return;
}

View File

@ -68,7 +68,7 @@ FF_C_NODISCARD uint32_t ffStrbufPreviousIndexC(const FFstrbuf* strbuf, uint32_t
void ffStrbufReplaceAllC(FFstrbuf* strbuf, char find, char replace);
void ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index);
void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index);
void ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index); // Not including the index
void ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c);
void ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str);
void ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c);