Add option to force kitty images

This commit is contained in:
Nikita Ivanov 2022-06-21 01:08:53 +05:00
parent a3a4312e9a
commit 7d32959bbb
No known key found for this signature in database
GPG Key ID: 6E656AC5B97B5133
11 changed files with 136 additions and 42 deletions

View File

@ -1,7 +1,7 @@
setup_fifo 1
if use_ueberzug; then
printf '{"action": "remove", "identifier": "preview"}\n' > "$fifo"
elif use_kitty; then
if use_kitty; then
kitty +kitten icat --clear --transfer-mode file
elif use_ueberzug; then
printf '{"action": "remove", "identifier": "preview"}\n' > "$fifo"
fi

View File

@ -11,7 +11,7 @@ use_ueberzug() {
}
use_kitty() {
use_ueberzug && return 1
[ -z "$force_kitty" ] && use_ueberzug && return 1
is_kitty
}

View File

@ -17,6 +17,19 @@
#define ACCEPT(x) CHECK_OK(accept(x))
#define NOT_ACCEPT(x) CHECK_NULL(accept(x))
struct Option {
char *name;
enum {
OPTION_BOOL,
OPTION_INT,
OPTION_STR,
} arg_type;
union {
int *i;
char **s;
} arg_val;
};
enum {
STAT_OK,
STAT_ERR,
@ -27,6 +40,10 @@ static Lexer *lexer;
static Token token;
static VectorPreview *previews;
static struct Option options[] = {
{ "forcekitty", OPTION_BOOL, { .i = &ctpv.opts.force_kitty } },
};
static void any_type_null(char **s)
{
if (*s && strcmp(*s, any_type) == 0)
@ -36,6 +53,9 @@ static void any_type_null(char **s)
static void add_preview(char *name, char *script, char *type, char *subtype,
char *ext)
{
if (!previews)
return;
any_type_null(&type);
any_type_null(&subtype);
@ -57,6 +77,9 @@ static void add_preview(char *name, char *script, char *type, char *subtype,
static int add_priority(char *name, int priority)
{
if (!previews)
return OK;
int found = 0;
for (size_t i = 0; i < previews->len; i++) {
@ -72,6 +95,9 @@ static int add_priority(char *name, int priority)
static int remove_preview(char *name)
{
if (!previews)
return OK;
int found = 0;
for (ssize_t i = previews->len - 1; i >= 0; i--) {
@ -151,6 +177,49 @@ static int preview_type(char **type, char **subtype, char **ext)
return preview_type_mime(type, subtype);
}
static struct Option *get_option(char *name)
{
for (size_t i = 0; i < LEN(options); i++) {
if (strcmp(name, options[i].name) == 0)
return options + i;
}
return NULL;
}
static int cmd_set(void)
{
Token name = token;
EXPECT(TOK_STR);
struct Option *opt = get_option(name.val.s);
if (!opt) {
PARSEERROR(name, "option '%s' does not exist", name.val.s);
return STAT_ERR;
}
Token value = token;
switch (opt->arg_type) {
case OPTION_BOOL:
*opt->arg_val.i = accept(TOK_INT) == STAT_OK ? value.val.i : 1;
break;
case OPTION_INT:
EXPECT(TOK_INT);
*opt->arg_val.i = value.val.i;
break;
case OPTION_STR:
EXPECT(TOK_STR);
*opt->arg_val.s = value.val.s;
break;
default:
PRINTINTERR("unknowm type: %d", opt->arg_type);
abort();
}
return STAT_OK;
}
static int cmd_preview(void)
{
Token name = token;
@ -207,7 +276,9 @@ static int command(void)
Token cmd = token;
EXPECT(TOK_STR);
if (strcmp(cmd.val.s, "preview") == 0)
if (strcmp(cmd.val.s, "set") == 0)
return cmd_set();
else if (strcmp(cmd.val.s, "preview") == 0)
return cmd_preview();
else if (strcmp(cmd.val.s, "priority") == 0)
return cmd_priority(cmd);

View File

@ -16,22 +16,12 @@
#include "preview.h"
#include "../previews.h"
struct CTPV ctpv;
const char any_type[] = ANY_TYPE;
static magic_t magic;
static struct {
enum {
MODE_PREVIEW,
MODE_SERVER,
MODE_CLEAR,
MODE_END,
MODE_LIST,
MODE_MIME,
} mode;
char *server_id_s;
} ctpv = { .mode = MODE_PREVIEW };
static VectorPreview *previews;
static void cleanup(void)
@ -75,6 +65,16 @@ static int get_config_file(char *buf, size_t len)
return OK;
}
static int config(int prevs)
{
char config_file[FILENAME_MAX];
get_config_file(config_file, LEN(config_file));
ERRCHK_RET_OK(config_load(prevs ? previews : NULL, config_file));
return OK;
}
static int init_previews(void)
{
/* 20 is some arbitrary number, it's here in order to
@ -82,10 +82,7 @@ static int init_previews(void)
previews = vectorPreview_new(LEN(b_previews) + 20);
vectorPreview_append_arr(previews, b_previews, LEN(b_previews));
char config_file[FILENAME_MAX];
get_config_file(config_file, LEN(config_file));
ERRCHK_RET_OK(config_load(previews, config_file));
ERRCHK_RET_OK(config(1));
previews_init(previews->buf, previews->len);
@ -263,11 +260,13 @@ static int server(void)
static int clear(void)
{
ERRCHK_RET_OK(config(0));
return server_clear(ctpv.server_id_s);
}
static int end(void)
{
ERRCHK_RET_OK(config(0));
return server_end(ctpv.server_id_s);
}

View File

@ -3,6 +3,23 @@
#define ANY_TYPE "*"
struct CTPV {
enum {
MODE_PREVIEW = 0, /* default mode */
MODE_SERVER,
MODE_CLEAR,
MODE_END,
MODE_LIST,
MODE_MIME,
} mode;
char *server_id_s;
struct {
int force_kitty;
} opts;
};
extern struct CTPV ctpv;
extern const char any_type[];
#endif

View File

@ -123,11 +123,8 @@ static int run(Preview *p, int *exitcode, int *signal)
int sp_arg[] = { pipe_fds[0], pipe_fds[1], STDERR_FILENO };
char *script = prepend_helpers(p->script, p->script_len);
char *args[] = SHELL_ARGS(script);
int ret = spawn(args, NULL, exitcode, signal, spawn_redirect, sp_arg);
int ret = run_script(p->script, p->script_len, exitcode, signal, spawn_redirect, sp_arg);
free(script);
close(pipe_fds[1]);
if (*exitcode != FAILED_PREVIEW_EC) {

View File

@ -169,18 +169,9 @@ exit:
return ret;
}
static int run_script(char *script, size_t script_len, char *arg)
static inline int run_server_script(char *script, size_t script_len, char *arg)
{
int ret = OK;
char *s = prepend_helpers(script, script_len);
char *args[] = SHELL_ARGS(s, arg);
int exitcode;
ERRCHK_GOTO_OK(spawn(args, NULL, &exitcode, NULL, NULL, NULL), ret, cleanup);
cleanup:
free(s);
return ret;
return run_script(script, script_len, NULL, NULL, NULL, NULL);
}
int server_set_fifo_var(const char *id_s)
@ -196,12 +187,12 @@ int server_clear(const char *id_s)
{
ERRCHK_RET_OK(server_set_fifo_var(id_s));
return run_script(scr_clear_sh, LEN(scr_clear_sh), (char *)id_s);
return run_server_script(scr_clear_sh, LEN(scr_clear_sh), (char *)id_s);
}
int server_end(const char *id_s)
{
ERRCHK_RET_OK(server_set_fifo_var(id_s));
return run_script(scr_end_sh, LEN(scr_end_sh), (char *)id_s);
return run_server_script(scr_end_sh, LEN(scr_end_sh), (char *)id_s);
}

View File

@ -1,5 +1,6 @@
#include <string.h>
#include "ctpv.h"
#include "shell.h"
#include "error.h"
#include "../gen/helpers.h"
@ -9,7 +10,7 @@
*
* User must call free()
*/
char *prepend_helpers(char *str, size_t len)
static char *prepend_helpers(char *str, size_t len)
{
char *buf, *b;
size_t l, helpers_len = LEN(scr_helpers_sh) - 1;
@ -29,3 +30,17 @@ char *prepend_helpers(char *str, size_t len)
return buf;
}
int run_script(char *script, size_t script_len, int *exitcode, int *signal,
SpawnProg sp, void *sp_arg)
{
ERRCHK_RET_ERN(setenv("force_kitty", ctpv.opts.force_kitty ? "1" : "", 1) == -1);
char *scr = prepend_helpers(script, script_len);
char *args[] = SHELL_ARGS(scr);
int ret = spawn(args, NULL, exitcode, signal, sp, sp_arg);
free(scr);
return ret;
}

View File

@ -6,6 +6,8 @@
#define SHELL_ARGS(script, ...) \
{ "/bin/sh", "-c", script, "/bin/sh", __VA_ARGS__ __VA_OPT__(,) NULL }
char *prepend_helpers(char *str, size_t len);
int run_script(char *script, size_t script_len, int *exitcode, int *signal,
SpawnProg sp, void *sp_arg);
#endif

View File

@ -51,7 +51,7 @@ int spawn_wait(int pid, int *exitcode, int *signal)
*
* cfunc is a function to call when child process is created
*/
int spawn(char *args[], int *cpid, int *exitcode, int *signal, int (*cfunc)(const void *),
int spawn(char *args[], int *cpid, int *exitcode, int *signal, SpawnProg cfunc,
const void *carg)
{
if (exitcode)

View File

@ -21,12 +21,14 @@
va_end(args); \
} while (0)
typedef int (*SpawnProg)(const void *);
extern char *program;
int spawn_redirect(const void *arg);
int spawn_wait(int pid, int *exitcode, int *signal);
int spawn(char *args[], int *cpid, int *exitcode, int *signal,
int (*cfunc)(const void *), const void *carg);
SpawnProg cfunc, const void *carg);
int strcmpnull(const char *s1, const char *s2);
int strlennull(const char *s);