This commit is contained in:
Squibid 2025-11-23 17:31:47 -05:00
parent 8537a9a127
commit 1a764d6a14
Signed by: squibid
GPG key ID: BECE5684D3C4005D
9 changed files with 332 additions and 329 deletions

View file

@ -1,22 +1,22 @@
#compdef wom
_arguments \
'1:flag:->flags' \
'*:: :->args'
'1:flag:->flags' \
'*:: :->args'
case "$state" in
flags)
local -a opts
opts=(
'-c:Path to config file'
'-v:Show version and exit'
'-h:Show help text'
flags)
local -a opts
opts=(
'-c:Path to config file'
'-v:Show version and exit'
'-h:Show help text'
$(wom subcmds)
)
_describe 'flags' opts
;;
)
_describe 'flags' opts
;;
args)
case $line[1] in
-c) _files ;;
esac
case $line[1] in
-c) _files ;;
esac
esac

View file

@ -12,17 +12,17 @@ ds_sll_t *subcmds;
int
register_subcmd(char *name, void (*cb)(void *, int argc, char *argv[]), void *data)
{
char *c;
char *c;
ds_sll_t *newnode = calloc(1, sizeof(ds_sll_t));
wom_subcmd_t *newsubcmd = calloc(1, sizeof(wom_subcmd_t));
/* make sure the subcmd name doesn't contain a space */
for (c = name; *c != '\0'; c++) {
if (isspace(*c)) {
log_fatal("subcmd '%s' can't contain any whitespace characters", name);
return 1;
}
}
/* make sure the subcmd name doesn't contain a space */
for (c = name; *c != '\0'; c++) {
if (isspace(*c)) {
log_fatal("subcmd '%s' can't contain any whitespace characters", name);
return 1;
}
}
/* setup data */
newsubcmd->name = name;
@ -38,12 +38,12 @@ register_subcmd(char *name, void (*cb)(void *, int argc, char *argv[]), void *da
}
/* otherwise append the node to the end of the current nodes */
ds_ll_foreach(ds_sll_t, subcmds) {
ds_ll_foreach(ds_sll_t, subcmds) {
if (!cur->next) {
cur->next = newnode;
break;
}
}
}
return 0;
}
@ -83,12 +83,12 @@ run_subcmds(int argc, char *argv[])
/* check for subcommands to run */
for (i = 1; i < argc; i++) {
ds_ll_foreach(ds_sll_t, subcmds) {
ds_ll_foreach(ds_sll_t, subcmds) {
subcmd = cur->data;
if (strcmp(argv[i], subcmd->name) == 0) {
goto args;
}
}
}
}
return;

View file

@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -12,18 +13,18 @@ char
config_path = NULL;
if ((path = getenv("XDG_CONFIG_HOME"))) {
config_path = calloc(
strlen(path) + strlen("/wom/init.lua") + 1,
sizeof(char)
);
config_path = strcat(path, "/wom/init.lua");
} else if ((path = getenv("HOME"))) {
config_path = calloc(
strlen(path) + strlen("/.config/wom/init.lua") + 1,
sizeof(char)
);
config_path = strcat(path, "/.config/wom/init.lua");
if ((path = strdup(getenv("XDG_CONFIG_HOME")))) {
size_t len = strlen(path) + strlen("/wom/init.lua") + 1;
config_path = calloc(len, sizeof(char));
if (config_path) {
snprintf(config_path, len, "%s%s", path, "/wom/init.lua");
}
} else if ((path = strdup(getenv("HOME")))) {
size_t len = strlen(path) + strlen("/.config/wom/init.lua") + 1;
config_path = calloc(len, sizeof(char));
if (config_path) {
snprintf(config_path, len, "%s%s", path, "/wom/init.lua");
}
}
return config_path;

View file

@ -54,9 +54,9 @@ wom_register_subcmd(lua_State *L)
l = L;
ret = register_subcmd(name, wrapper_func, cb);
if (ret != 0) {
lua_error(L);
}
if (ret != 0) {
lua_error(L);
}
lua_pushinteger(L, ret);

View file

@ -53,8 +53,8 @@ wom_fs_dir(lua_State *L)
/* set its metatable */
lua_newtable(L);
lua_pushcfunction(L, dir_gc);
lua_setfield(L, -2, "__gc");
lua_pushcfunction(L, dir_gc);
lua_setfield(L, -2, "__gc");
lua_setmetatable(L, -2);

View file

@ -9,6 +9,7 @@
#include <cargs.h>
#include "conf.h"
#include "log.h"
#include "lua/wom.h"
#include "lua/wom_fs.h"
#include "subcmds.h"
@ -16,11 +17,11 @@
static struct cag_option options[] = {
{
.identifier = 'v',
.access_letters = "v",
.access_name = "version",
.description = "get the version of womblic",
},
.identifier = 'v',
.access_letters = "v",
.access_name = "version",
.description = "get the version of womblic",
},
{
.identifier = 'c',
.access_letters = "c",
@ -67,8 +68,8 @@ int
main(int argc, char *argv[])
{
int l;
lua_State *L;
const char *cag_path;
lua_State *L;
const char *cag_path;
char *config_path = { 0 };
cag_option_context context;
@ -81,12 +82,12 @@ main(int argc, char *argv[])
l = strlen(cag_path);
config_path = calloc(l + 1, sizeof(char));
strncpy(config_path, cag_path, l);
break;
break;
case 'v': printf("%s-%s\n", argv[0], VERSION); break;
case 'h':
printf("Usage: wom [OPTION]...\n");
cag_option_print(options, CAG_ARRAY_SIZE(options), stdout);
exit(0);
exit(0);
case '?':
cag_option_print_error(&context, stdout);
break;

View file

@ -23,16 +23,16 @@
#define set_str_len(u, us, hu) str_len += (u > 0) ? (numlen(u) + 1 + (u > 1 ? strlen(us"s") : strlen(us)) + ((hu > 0) ? 1 : 0)) : 0
#define write_str(u, us) do { \
if (u > 0) { \
if (str[0] != '\0') { \
strcat(str, " "); \
} \
size_t sz = numlen(u) + (u > 1 ? strlen(us"s") : strlen(us)) + 2; \
tmp = calloc(sz, sizeof(char)); \
snprintf(tmp, sz, "%d %s", u, u > 1 ? us"s" : us); \
strcat(str, tmp); \
free(tmp); \
} \
if (u > 0) { \
if (str[0] != '\0') { \
strcat(str, " "); \
} \
size_t sz = numlen(u) + (u > 1 ? strlen(us"s") : strlen(us)) + 2; \
tmp = calloc(sz, sizeof(char)); \
snprintf(tmp, sz, "%d %s", u, u > 1 ? us"s" : us); \
strcat(str, tmp); \
free(tmp); \
} \
} while (0)
int i, total_delay_s, up = 0;
@ -41,17 +41,17 @@ struct termios oldt;
static void
termios_noecho(void)
{
struct termios newt;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
struct termios newt;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
}
static void
termios_restore(void)
{
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
}
/**
@ -70,44 +70,44 @@ termios_restore(void)
static char
*sec2str(int sec)
{
int days, hours, minutes, seconds, str_len;
char *str, *tmp;
int days, hours, minutes, seconds, str_len;
char *str, *tmp;
if (sec < 0) {
return 0;
}
if (sec < 0) {
return 0;
}
for (str_len = days = hours = minutes = seconds = 0; sec > 0;) {
if (sec >= 60 * 60 * 24) {
sec -= 60 * 60 * 24;
days++;
} else if (sec >= 60 * 60) {
sec -= 60 * 60;
hours++;
} else if (sec >= 60) {
sec -= 60;
minutes++;
} else if (sec >= 1) {
sec -= 1;
seconds++;
}
}
for (str_len = days = hours = minutes = seconds = 0; sec > 0;) {
if (sec >= 60 * 60 * 24) {
sec -= 60 * 60 * 24;
days++;
} else if (sec >= 60 * 60) {
sec -= 60 * 60;
hours++;
} else if (sec >= 60) {
sec -= 60;
minutes++;
} else if (sec >= 1) {
sec -= 1;
seconds++;
}
}
set_str_len(days, "day", 0);
set_str_len(hours, "hour", days);
set_str_len(minutes, "minute", hours);
set_str_len(seconds, "second", minutes);
str_len += 1;
set_str_len(days, "day", 0);
set_str_len(hours, "hour", days);
set_str_len(minutes, "minute", hours);
set_str_len(seconds, "second", minutes);
str_len += 1;
str = malloc(str_len * sizeof(char));
str[0] = '\0';
str = malloc(str_len * sizeof(char));
str[0] = '\0';
write_str(days, "day");
write_str(hours, "hour");
write_str(minutes, "minute");
write_str(seconds, "second");
write_str(days, "day");
write_str(hours, "hour");
write_str(minutes, "minute");
write_str(seconds, "second");
return str;
return str;
}
/**
@ -126,77 +126,77 @@ static char
static int
str2sec(char *str)
{
char *time_buffer;
int i, si, ei, ste, temp_total, total;
char *time_buffer;
int i, si, ei, ste, temp_total, total;
for (total = si = ei = i = 0; i < strlen(str); i++, temp_total = 0) {
/**
* if the char is not a number we need to take all the previous numbers
* and attempt to convert this to a proper time
*/
if (str[i] < '0' || str[i] > '9') {
ei = i - 1;
ste = ei - si + 1;
time_buffer = malloc((ste * sizeof(char)) + 1);
memcpy(time_buffer, str + si, ste);
time_buffer[ste] = '\0';
temp_total += strtol(time_buffer, NULL, 10);
free(time_buffer);
for (total = si = ei = i = 0; i < strlen(str); i++, temp_total = 0) {
/**
* if the char is not a number we need to take all the previous numbers
* and attempt to convert this to a proper time
*/
if (str[i] < '0' || str[i] > '9') {
ei = i - 1;
ste = ei - si + 1;
time_buffer = malloc((ste * sizeof(char)) + 1);
memcpy(time_buffer, str + si, ste);
time_buffer[ste] = '\0';
temp_total += strtol(time_buffer, NULL, 10);
free(time_buffer);
switch (str[i]) {
default: case 's': break;
case 'm': temp_total *= 60; break;
case 'h': temp_total *= 60 * 60; break;
case 'd': temp_total *= 60 * 60 * 24; break;
}
switch (str[i]) {
default: case 's': break;
case 'm': temp_total *= 60; break;
case 'h': temp_total *= 60 * 60; break;
case 'd': temp_total *= 60 * 60 * 24; break;
}
total += temp_total;
si = i + 1;
}
}
total += temp_total;
si = i + 1;
}
}
return total;
return total;
}
static void
timer_exit(void)
{
char *time_str;
time_t t;
struct tm tm;
char *time_str;
time_t t;
struct tm tm;
printf("\033[?25h");
printf("\033[?25h");
time_str = sec2str(total_delay_s - i);
time_str = sec2str(total_delay_s - i);
t = time(NULL);
tm = *localtime(&t);
printf(
"\033[3A\033[43;30;1m wom timer \033[0m %s elapsed at %d/%02d/%02d %02d:%02d:%02d\n",
time_str,
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec
);
free(time_str);
printf(
"\033[3A\033[43;30;1m wom timer \033[0m %s elapsed at %d/%02d/%02d %02d:%02d:%02d\n",
time_str,
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec
);
free(time_str);
}
static void
timer_sig_exit(int sig)
{
puts("\n");
timer_exit();
exit(sig);
puts("\n");
timer_exit();
exit(sig);
}
void
timer_subcmd(void *, int argc, char *argv[])
{
bool first;
bool first;
int j, slp, sec, rollover, wi, tick, sub;
char *pb_elapsed, *pb_left, *time_str;
char *pb_elapsed, *pb_left, *time_str;
for (i = 1, total_delay_s = 0; i < argc; i++) {
total_delay_s += str2sec(argv[i]);
@ -206,62 +206,62 @@ timer_subcmd(void *, int argc, char *argv[])
exit(1);
}
/* create the progress bar */
pb_left = calloc(strlen(PB_FULL), sizeof(char) + 1);
strcpy(pb_left, PB_FULL);
pb_elapsed = calloc(strlen(PB_FULL), sizeof(char) + 1);
/* create the progress bar */
pb_left = calloc(strlen(PB_FULL), sizeof(char) + 1);
strcpy(pb_left, PB_FULL);
pb_elapsed = calloc(strlen(PB_FULL), sizeof(char) + 1);
/* render ui */
printf("\033[?25l");
atexit(timer_exit);
signal(SIGINT, timer_sig_exit);
puts("");
rollover = 0;
first = true;
tick = (total_delay_s / (float)PB_LEN) * S_AS_MSEC;
/* render ui */
printf("\033[?25l");
atexit(timer_exit);
signal(SIGINT, timer_sig_exit);
puts("");
rollover = 0;
first = true;
tick = (total_delay_s / (float)PB_LEN) * S_AS_MSEC;
for (sub = j = 0, i = total_delay_s; i > 0; i--) {
/* sub second handler */
for (sec = S_AS_MSEC; sec > 0;) {
if (!first) {
printf("\033[2A");
}
first = false;
for (sub = j = 0, i = total_delay_s; i > 0; i--) {
/* sub second handler */
for (sec = S_AS_MSEC; sec > 0;) {
if (!first) {
printf("\033[2A");
}
first = false;
if (rollover > 0) {
sub = rollover;
rollover = 0;
} else {
sub = tick;
}
if (sec - sub < 0) {
slp = sec;
rollover = fabs((float)sec - sub);
sec = 0;
} else {
sec -= sub;
slp = sub;
}
if (rollover > 0) {
sub = rollover;
rollover = 0;
} else {
sub = tick;
}
if (sec - sub < 0) {
slp = sec;
rollover = fabs((float)sec - sub);
sec = 0;
} else {
sec -= sub;
slp = sub;
}
printf("\033[2K\033[43;30;1m wom timer \033[0m \033[33m%s\033[30m%s\033[0m\n", pb_left, pb_elapsed);
time_str = sec2str(i);
printf("\033[2K\033[90m %s\033[0m\n", time_str);
free(time_str);
printf("\033[2K\033[43;30;1m wom timer \033[0m \033[33m%s\033[30m%s\033[0m\n", pb_left, pb_elapsed);
time_str = sec2str(i);
printf("\033[2K\033[90m %s\033[0m\n", time_str);
free(time_str);
/* change the progress bar */
if (rollover == 0) {
wi = strlen(PB_FULL) - (j * strlen("")) - strlen("");
strncat(pb_elapsed, "", strlen(PB_FULL));
pb_left[wi] = '\0';
j++;
}
/* change the progress bar */
if (rollover == 0) {
wi = strlen(PB_FULL) - (j * strlen("")) - strlen("");
strncat(pb_elapsed, "", strlen(PB_FULL));
pb_left[wi] = '\0';
j++;
}
usleep(slp);
}
}
usleep(slp);
}
}
free(pb_left);
free(pb_elapsed);
free(pb_left);
free(pb_elapsed);
return;
}
@ -269,122 +269,122 @@ timer_subcmd(void *, int argc, char *argv[])
static void
stopwatch_exit(void)
{
char *time_str;
time_t t;
struct tm tm;
char *time_str;
time_t t;
struct tm tm;
termios_restore();
printf("\033[?25h");
termios_restore();
printf("\033[?25h");
time_str = sec2str(i);
time_str = sec2str(i);
t = time(NULL);
tm = *localtime(&t);
printf(
"\033[%dA\033[43;30;1m wom stopwatch \033[0m %s elapsed at %d/%02d/%02d %02d:%02d:%02d\n",
3 + up,
time_str,
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec
);
free(time_str);
printf(
"\033[%dA\033[43;30;1m wom stopwatch \033[0m %s elapsed at %d/%02d/%02d %02d:%02d:%02d\n",
3 + up,
time_str,
tm.tm_year + 1900,
tm.tm_mon + 1,
tm.tm_mday,
tm.tm_hour,
tm.tm_min,
tm.tm_sec
);
free(time_str);
}
static void
stopwatch_sig_exit(int sig)
{
puts("\n");
stopwatch_exit();
exit(sig);
puts("\n");
stopwatch_exit();
exit(sig);
}
void
stopwatch_subcmd(void *, int argc, char *argv[])
{
int j, k, wi, pl;
char *pb_elapsed, *pb_left, *time_str, buf[PATH_MAX];
ds_dll_t *laps;
struct pollfd pfd = {
.fd = stdin->_fileno,
.events = POLLIN,
.revents = 0
};
char *pb_elapsed, *pb_left, *time_str, buf[PATH_MAX];
ds_dll_t *laps;
struct pollfd pfd = {
.fd = stdin->_fileno,
.events = POLLIN,
.revents = 0
};
/* disable terminal echoing */
termios_noecho();
atexit(stopwatch_exit);
signal(SIGINT, stopwatch_sig_exit);
/* disable terminal echoing */
termios_noecho();
atexit(stopwatch_exit);
signal(SIGINT, stopwatch_sig_exit);
/* create the progress bar */
pb_left = calloc(strlen(PB_FULL), sizeof(char) + 1);
strcpy(pb_left, PB_FULL);
pb_elapsed = calloc(strlen(PB_FULL), sizeof(char) + 1);
/* create the progress bar */
pb_left = calloc(strlen(PB_FULL), sizeof(char) + 1);
strcpy(pb_left, PB_FULL);
pb_elapsed = calloc(strlen(PB_FULL), sizeof(char) + 1);
/* initalizie the linked list */
laps = ds_dll_init();
/* initalizie the linked list */
laps = ds_dll_init();
/* render ui */
printf("\033[?25l");
puts("");
/* render ui */
printf("\033[?25l");
puts("");
for (j = i = 0;; i++) {
pl = poll(&pfd, 1, 0);
if (pl < 0) {
log_trace("pl: %d", pl);
/* TODO: error */
exit(1);
}
for (j = i = 0;; i++) {
pl = poll(&pfd, 1, 0);
if (pl < 0) {
log_trace("pl: %d", pl);
/* TODO: error */
exit(1);
}
if (i != 0) {
printf("\033[%dA", 2 + (up > 0 ? up + 1 : 0));
}
if (i != 0) {
printf("\033[%dA", 2 + (up > 0 ? up + 1 : 0));
}
if (pfd.revents & POLLIN) {
read(pfd.fd, buf, PATH_MAX);
ds_dll_insert(laps, (void *)(long)i);
up++;
}
if (pfd.revents & POLLIN) {
read(pfd.fd, buf, PATH_MAX);
ds_dll_insert(laps, (void *)(long)i);
up++;
}
printf("\033[2K\033[43;30;1m wom stopwatch \033[0m \033[33m%s\033[30m%s\033[0m\n", pb_elapsed, pb_left);
time_str = sec2str(i);
printf("\033[2K\033[90m %s\033[0m\n", time_str);
free(time_str);
printf("\033[2K\033[43;30;1m wom stopwatch \033[0m \033[33m%s\033[30m%s\033[0m\n", pb_elapsed, pb_left);
time_str = sec2str(i);
printf("\033[2K\033[90m %s\033[0m\n", time_str);
free(time_str);
if (up) {
printf("\033[2K\033[0m lap time\033[0m\n");
}
k = 1;
for (ds_dll_t *cur = laps; cur; cur = cur->next, k++) {
if ((int)(long)cur->data) {
time_str = sec2str((int)(long)cur->data);
printf("\033[2K\033[0m %03d %s\033[0m\n", k, time_str);
free(time_str);
}
}
if (up) {
printf("\033[2K\033[0m lap time\033[0m\n");
}
k = 1;
for (ds_dll_t *cur = laps; cur; cur = cur->next, k++) {
if ((int)(long)cur->data) {
time_str = sec2str((int)(long)cur->data);
printf("\033[2K\033[0m %03d %s\033[0m\n", k, time_str);
free(time_str);
}
}
/* change the progress bar */
if (i % 2 == 1) {
if (i % 60 == 1) {
strcpy(pb_left, PB_FULL);
bzero(pb_elapsed, strlen(PB_FULL));
j = 0;
}
wi = strlen(PB_FULL) - (j * strlen("")) - strlen("");
strncat(pb_elapsed, "", strlen(PB_FULL));
pb_left[wi] = '\0';
j++;
}
/* change the progress bar */
if (i % 2 == 1) {
if (i % 60 == 1) {
strcpy(pb_left, PB_FULL);
bzero(pb_elapsed, strlen(PB_FULL));
j = 0;
}
wi = strlen(PB_FULL) - (j * strlen("")) - strlen("");
strncat(pb_elapsed, "", strlen(PB_FULL));
pb_left[wi] = '\0';
j++;
}
sleep(1);
}
sleep(1);
}
printf("\033[?25h");
printf("\033[?25h");
free(pb_left);
free(pb_elapsed);
free(pb_left);
free(pb_elapsed);
return;
}

View file

@ -58,48 +58,49 @@ void
subcmds_dev(void *, int argc, char *argv[])
{
char cwd[PATH_MAX];
char *wpath, *editor;
char *wpath, *editor;
if (argc > 1) {
if (strcmp(argv[1], "add") == 0) {
if (argc > 2) {
/* if the directory doesn't exist, then make it */
if (!opendir(conf_state_path())) {
if (errno == ENOENT) {
if (mkdir(conf_state_path(), 0755) < 0) {
printf("Failed to create state path: %s\n", conf_state_path());
exit(1);
}
}
}
if (argc > 1) {
if (strcmp(argv[1], "add") == 0) {
if (argc > 2) {
/* if the directory doesn't exist, then make it */
if (!opendir(conf_state_path())) {
if (errno == ENOENT) {
if (mkdir(conf_state_path(), 0755) < 0) {
printf("Failed to create state path: %s\n", conf_state_path());
exit(1);
}
}
}
/* add the directory to the path */
add(argv[2]);
} else {
if (getcwd(cwd, PATH_MAX) == NULL) {
exit(1);
}
/* add the directory to the path */
add(argv[2]);
} else {
if (getcwd(cwd, PATH_MAX) == NULL) {
exit(1);
}
/* add the directory to the path */
add(cwd);
}
} else if (strcmp(argv[1], "edit") == 0) {
wpath = calloc(strlen(conf_state_path()) + 4, sizeof(char));
strcpy(wpath, conf_state_path());
strcat(wpath, "dev");
/* add the directory to the path */
add(cwd);
}
} else if (strcmp(argv[1], "edit") == 0) {
wpath = calloc(strlen(conf_state_path()) + 4, sizeof(char));
strcpy(wpath, conf_state_path());
strcat(wpath, "dev");
editor = getenv("EDITOR");
if (editor) {
execvp(editor, (char *[]){ editor, wpath, NULL });
goto free_stuff;
}
printf("Failed to open editor\n");
free_stuff:
free(editor);
free(wpath);
} else if (strcmp(argv[1], "help") == 0 || strcmp(argv[1], "h") == 0) {
printf("Help text\n");
} else {
}
}
editor = getenv("EDITOR");
puts(getenv("XDG_CONFIG_DIR"));
return;
if (editor) {
execvp(editor, (char *[]){ editor, wpath, NULL });
goto free_stuff;
}
printf("Failed to open editor\n");
free_stuff:
free(wpath);
} else if (strcmp(argv[1], "help") == 0 || strcmp(argv[1], "h") == 0) {
printf("Help text\n");
} else {
}
}
}

View file

@ -1,9 +1,9 @@
wom.register_subcmd("helloworld", function()
print("hello world")
for i in wom.fs.dir(".") do
if wom.fs.type(i) == "directory" then
print(i)
end
end
for i in wom.fs.dir(".") do
if wom.fs.type(i) == "directory" then
print(i)
end
end
end)