feat: add fzf-based file/plugin/port selection and update build system
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -Wall -Wextra -Wpedantic -std=c11 -Isrc
|
CFLAGS = -Wall -Wextra -Wpedantic -std=gnu11 -Isrc -I../engine/src
|
||||||
CARLA_INC = -I/usr/include/carla -I/usr/include/carla/includes
|
CARLA_INC = -I/usr/include/carla -I/usr/include/carla/includes
|
||||||
CARLA_LIB = -L/usr/lib/carla -Wl,-rpath,/usr/lib/carla -lcarla_standalone2
|
CARLA_LIB = -L/usr/lib/carla -Wl,-rpath,/usr/lib/carla -lcarla_standalone2
|
||||||
|
|
||||||
@@ -22,20 +22,20 @@ all: looper-client test_status_parse
|
|||||||
looper-client: src/main.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ)
|
looper-client: src/main.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ)
|
||||||
$(CC) $(CFLAGS) $(CARLA_INC) -o $@ $^ $(CARLA_LIB) -ljack -lncurses
|
$(CC) $(CFLAGS) $(CARLA_INC) -o $@ $^ $(CARLA_LIB) -ljack -lncurses
|
||||||
|
|
||||||
test_status_parse: tests/test_status_parse.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ)
|
test_status_parse: tests/test_status_parse.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ)
|
||||||
$(CC) $(CFLAGS) $(CARLA_INC) -o test_status_parse tests/test_status_parse.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(CARLA_LIB) -ljack -lncurses
|
$(CC) $(CFLAGS) $(CARLA_INC) -o test_status_parse tests/test_status_parse.c src/tui.c $(PLUGINS_OBJ) $(CARLA_OBJ) $(CLIENT_CMD_OBJ) $(SCRIPT_OBJ) $(LOG_OBJ) $(CARLA_LIB) -ljack -lncurses
|
||||||
|
|
||||||
# --- Plugin stubs (now real) ---
|
# --- Plugin stubs (now real) ---
|
||||||
$(PLUGINS_OBJ): src/plugins.c src/plugins.h
|
$(PLUGINS_OBJ): src/plugins.c src/plugins.h
|
||||||
$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<
|
$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<
|
||||||
|
|
||||||
$(CARLA_OBJ): src/carla_host.c src/carla_host.h
|
$(CARLA_OBJ): src/carla_host.c src/carla_host.h
|
||||||
$(CC) -Wall -Wextra -std=c11 -Isrc $(CARLA_INC) -c -o $@ $<
|
$(CC) -Wall -Wextra -std=gnu11 -Isrc -I../engine/src $(CARLA_INC) -c -o $@ $<
|
||||||
|
|
||||||
CARLA_TEST_OBJ = src/carla_host_test.o
|
CARLA_TEST_OBJ = src/carla_host_test.o
|
||||||
|
|
||||||
$(CARLA_TEST_OBJ): src/carla_host.c src/carla_host.h
|
$(CARLA_TEST_OBJ): src/carla_host.c src/carla_host.h
|
||||||
$(CC) -Wall -Wextra -std=c11 -Isrc $(CARLA_INC) -DTESTING -c -o $@ $<
|
$(CC) -Wall -Wextra -std=gnu11 -Isrc -I../engine/src $(CARLA_INC) -DTESTING -c -o $@ $<
|
||||||
|
|
||||||
$(CLIENT_CMD_OBJ): src/client_cmd.c src/client_cmd.h
|
$(CLIENT_CMD_OBJ): src/client_cmd.c src/client_cmd.h
|
||||||
$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<
|
$(CC) $(CFLAGS) $(CARLA_INC) -c -o $@ $<
|
||||||
@@ -51,8 +51,17 @@ TEST_SCRIPT_OBJ = tests/test_script.o
|
|||||||
$(TEST_SCRIPT_OBJ): tests/test_script.c src/script.h
|
$(TEST_SCRIPT_OBJ): tests/test_script.c src/script.h
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
$(TEST_SCRIPT_BIN): $(TEST_SCRIPT_OBJ) $(SCRIPT_OBJ)
|
TEST_TUI_STUB_OBJ = tests/test_tui_stub.o
|
||||||
$(CC) $(CFLAGS) -o $@ $^
|
|
||||||
|
tests/test_tui_stub.c:
|
||||||
|
mkdir -p tests
|
||||||
|
@printf '%s\n' '#include "tui.h"' '' 'char *tui_fzf_select(const char *const items[], size_t count, const char *prompt){(void)items;(void)count;(void)prompt;return NULL;}' '' 'void tui_cleanup(void){}' > $@
|
||||||
|
|
||||||
|
$(TEST_TUI_STUB_OBJ): tests/test_tui_stub.c
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
$(TEST_SCRIPT_BIN): $(TEST_SCRIPT_OBJ) $(SCRIPT_OBJ) $(PLUGINS_OBJ) $(CLIENT_CMD_OBJ) $(CARLA_OBJ) $(TEST_TUI_STUB_OBJ)
|
||||||
|
$(CC) $(CFLAGS) $(CARLA_INC) -o $@ $^ $(CARLA_LIB) -ljack -lncurses
|
||||||
|
|
||||||
$(LOG_OBJ): src/log.c
|
$(LOG_OBJ): src/log.c
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
@@ -101,7 +110,7 @@ TEST_CARLA_MOCK_BIN = test_carla_host_mock
|
|||||||
CARLA_MOCK_OBJ = src/carla_host_mock.o
|
CARLA_MOCK_OBJ = src/carla_host_mock.o
|
||||||
|
|
||||||
$(CARLA_MOCK_OBJ): src/carla_host.c src/carla_host.h
|
$(CARLA_MOCK_OBJ): src/carla_host.c src/carla_host.h
|
||||||
$(CC) -Wall -Wextra -std=c11 -Isrc $(CARLA_INC) -DTESTING -DMOCK_JACK -c -o $@ $<
|
$(CC) -Wall -Wextra -std=gnu11 -Isrc -I../engine/src $(CARLA_INC) -DTESTING -DMOCK_JACK -c -o $@ $<
|
||||||
|
|
||||||
$(TEST_CARLA_MOCK_BIN): tests/test_carla_host_mock.c $(CARLA_MOCK_OBJ)
|
$(TEST_CARLA_MOCK_BIN): tests/test_carla_host_mock.c $(CARLA_MOCK_OBJ)
|
||||||
$(CC) $(CFLAGS) $(CARLA_INC) -DTESTING -DMOCK_JACK -o $@ $^ $(CARLA_LIB) -ljack
|
$(CC) $(CFLAGS) $(CARLA_INC) -DTESTING -DMOCK_JACK -o $@ $^ $(CARLA_LIB) -ljack
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdlib.h>
|
||||||
#include <CarlaHost.h>
|
#include <CarlaHost.h>
|
||||||
#include <CarlaBackend.h>
|
#include <CarlaBackend.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -206,6 +208,48 @@ int carla_disconnect_plugin(int id) {
|
|||||||
return any ? 0 : -1; // return -1 if no connections were found (harmless)
|
return any ? 0 : -1; // return -1 if no connections were found (harmless)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOCK_JACK
|
||||||
|
/* Mock: return a few fake port names */
|
||||||
|
int carla_get_ports(const char *type, char ***ports, int *count) {
|
||||||
|
(void)type;
|
||||||
|
static const char *fake[] = {"system:capture_1", "system:capture_2", "system:playback_1", "system:playback_2"};
|
||||||
|
*count = 4;
|
||||||
|
*ports = malloc(*count * sizeof(char*));
|
||||||
|
if (!*ports) { *count = 0; return -1; }
|
||||||
|
for (int i = 0; i < *count; i++)
|
||||||
|
(*ports)[i] = strdup(fake[i]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include <jack/jack.h>
|
||||||
|
int carla_get_ports(const char *type, char ***ports, int *count) {
|
||||||
|
(void)type;
|
||||||
|
if (!jack_client) {
|
||||||
|
*ports = NULL;
|
||||||
|
*count = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
const char **jports = jack_get_ports(jack_client, NULL, NULL, 0);
|
||||||
|
if (!jports) {
|
||||||
|
*ports = NULL;
|
||||||
|
*count = 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int n = 0;
|
||||||
|
while (jports[n]) n++;
|
||||||
|
*count = n;
|
||||||
|
*ports = malloc(n * sizeof(char*));
|
||||||
|
if (!*ports) {
|
||||||
|
jack_free(jports);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
(*ports)[i] = strdup(jports[i]);
|
||||||
|
jack_free(jports);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
int carla_test_connection_count(void) {
|
int carla_test_connection_count(void) {
|
||||||
return conn_count;
|
return conn_count;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
#include "../engine/src/log.c"
|
#include "../../engine/src/log.c"
|
||||||
|
|||||||
@@ -4,10 +4,16 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
/* Forward declarations for functions used from carla_host.c */
|
||||||
|
int carla_load(const char *binary, const char *plugin_id, int *out_id);
|
||||||
|
int carla_get_ports(const char *type, char ***ports, int *count);
|
||||||
|
#include "tui.h"
|
||||||
|
#include <glob.h>
|
||||||
|
|
||||||
#define MAX_NOTES 128
|
#define MAX_NOTES 128
|
||||||
|
|
||||||
static char *note_actions[MAX_NOTES] = {0};
|
static char *note_actions[MAX_NOTES] = {0};
|
||||||
|
char g_selected_port[256] = {0};
|
||||||
|
|
||||||
int script_load(const char *path) {
|
int script_load(const char *path) {
|
||||||
FILE *fp = fopen(path, "r");
|
FILE *fp = fopen(path, "r");
|
||||||
@@ -45,6 +51,100 @@ int script_load(const char *path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int script_handle_fzf_command(const char *type) {
|
||||||
|
if (!type) return -1;
|
||||||
|
|
||||||
|
if (strcmp(type, "sample") == 0) {
|
||||||
|
// Get sample directory from env or home
|
||||||
|
const char *dir = getenv("LOOPER_SAMPLE_DIR");
|
||||||
|
if (!dir) dir = getenv("HOME");
|
||||||
|
if (!dir) dir = ".";
|
||||||
|
char pattern[1024];
|
||||||
|
snprintf(pattern, sizeof(pattern), "%s/**/*.wav", dir);
|
||||||
|
glob_t g;
|
||||||
|
if (glob(pattern, GLOB_TILDE, NULL, &g) != 0) {
|
||||||
|
// Try without wildcard
|
||||||
|
snprintf(pattern, sizeof(pattern), "%s/*.wav", dir);
|
||||||
|
if (glob(pattern, GLOB_TILDE, NULL, &g) != 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
const char **items = malloc((g.gl_pathc + 1) * sizeof(char*));
|
||||||
|
if (!items) { globfree(&g); return -1; }
|
||||||
|
for (size_t i = 0; i < g.gl_pathc; i++)
|
||||||
|
items[i] = g.gl_pathv[i];
|
||||||
|
items[g.gl_pathc] = NULL;
|
||||||
|
|
||||||
|
char *selected = tui_fzf_select(items, g.gl_pathc, "Load sample: ");
|
||||||
|
if (selected) {
|
||||||
|
int out_id;
|
||||||
|
carla_load(selected, "", &out_id);
|
||||||
|
free(selected);
|
||||||
|
}
|
||||||
|
free(items);
|
||||||
|
globfree(&g);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type, "plugin") == 0) {
|
||||||
|
// List .so files in common paths
|
||||||
|
const char *dirs[] = {
|
||||||
|
getenv("VST_PATH") ? getenv("VST_PATH") : "/usr/lib/vst",
|
||||||
|
getenv("HOME"),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
char **paths = NULL;
|
||||||
|
size_t count = 0;
|
||||||
|
for (int d = 0; dirs[d]; d++) {
|
||||||
|
char pattern[1024];
|
||||||
|
snprintf(pattern, sizeof(pattern), "%s/**/*.so", dirs[d]);
|
||||||
|
glob_t g;
|
||||||
|
if (glob(pattern, GLOB_TILDE, NULL, &g) == 0) {
|
||||||
|
for (size_t i = 0; i < g.gl_pathc; i++) {
|
||||||
|
paths = realloc(paths, (count+1) * sizeof(char*));
|
||||||
|
paths[count] = strdup(g.gl_pathv[i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
globfree(&g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count == 0) return -1;
|
||||||
|
const char **items = malloc(count * sizeof(char*));
|
||||||
|
for (size_t i = 0; i < count; i++) items[i] = paths[i];
|
||||||
|
|
||||||
|
char *selected = tui_fzf_select(items, count, "Load plugin: ");
|
||||||
|
if (selected) {
|
||||||
|
int out_id;
|
||||||
|
carla_load(selected, "", &out_id);
|
||||||
|
free(selected);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < count; i++) free(paths[i]);
|
||||||
|
free(paths);
|
||||||
|
free(items);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(type, "from") == 0 || strcmp(type, "to") == 0) {
|
||||||
|
char **ports;
|
||||||
|
int count;
|
||||||
|
// For "to" we need input ports (where output will go), for "from" we need output ports
|
||||||
|
if (carla_get_ports("audio", &ports, &count) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
char *selected = tui_fzf_select((const char**)ports, count,
|
||||||
|
(strcmp(type,"to")==0) ? "Select plugin input port: " : "Select looper output port: ");
|
||||||
|
if (selected) {
|
||||||
|
strncpy(g_selected_port, selected, sizeof(g_selected_port)-1);
|
||||||
|
g_selected_port[sizeof(g_selected_port)-1] = '\0';
|
||||||
|
free(selected);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < count; i++) free(ports[i]);
|
||||||
|
free(ports);
|
||||||
|
return (selected ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void script_cleanup(void) {
|
void script_cleanup(void) {
|
||||||
for (int i = 0; i < MAX_NOTES; i++) {
|
for (int i = 0; i < MAX_NOTES; i++) {
|
||||||
free(note_actions[i]);
|
free(note_actions[i]);
|
||||||
|
|||||||
@@ -4,5 +4,7 @@
|
|||||||
int script_load(const char *path);
|
int script_load(const char *path);
|
||||||
void script_handle_note(int note);
|
void script_handle_note(int note);
|
||||||
void script_cleanup(void);
|
void script_cleanup(void);
|
||||||
|
int script_handle_fzf_command(const char *type);
|
||||||
|
extern char g_selected_port[256];
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@@ -350,6 +351,18 @@ void tui_run(void) {
|
|||||||
rack_mode = !rack_mode;
|
rack_mode = !rack_mode;
|
||||||
rack_selected = 0;
|
rack_selected = 0;
|
||||||
break;
|
break;
|
||||||
|
case KEY_F(5):
|
||||||
|
script_handle_fzf_command("sample");
|
||||||
|
draw_grid();
|
||||||
|
break;
|
||||||
|
case KEY_F(6):
|
||||||
|
script_handle_fzf_command("plugin");
|
||||||
|
draw_grid();
|
||||||
|
break;
|
||||||
|
case KEY_F(7):
|
||||||
|
script_handle_fzf_command("from");
|
||||||
|
draw_grid();
|
||||||
|
break;
|
||||||
case 27: case 'Q':
|
case 27: case 'Q':
|
||||||
if (rack_mode) {
|
if (rack_mode) {
|
||||||
rack_mode = false;
|
rack_mode = false;
|
||||||
@@ -396,6 +409,69 @@ void tui_run(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* tui_fzf_select(const char *const items[], size_t count, const char *prompt) {
|
||||||
|
if (!items || count == 0) return NULL;
|
||||||
|
|
||||||
|
// Save ncurses state
|
||||||
|
def_prog_mode();
|
||||||
|
endwin();
|
||||||
|
|
||||||
|
// Build a temporary file with the items list
|
||||||
|
char tmpfile[] = "/tmp/tui_fzf_XXXXXX";
|
||||||
|
int fd = mkstemp(tmpfile);
|
||||||
|
if (fd == -1) {
|
||||||
|
reset_prog_mode();
|
||||||
|
refresh();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
FILE *tmp = fdopen(fd, "w");
|
||||||
|
if (!tmp) {
|
||||||
|
close(fd);
|
||||||
|
unlink(tmpfile);
|
||||||
|
reset_prog_mode();
|
||||||
|
refresh();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (items[i])
|
||||||
|
fprintf(tmp, "%s\n", items[i]);
|
||||||
|
}
|
||||||
|
fclose(tmp);
|
||||||
|
|
||||||
|
// Build fzf command reading from the temporary file
|
||||||
|
char cmd[8192];
|
||||||
|
snprintf(cmd, sizeof(cmd),
|
||||||
|
"fzf --prompt='%s' < %s",
|
||||||
|
prompt ? prompt : "Select: ",
|
||||||
|
tmpfile);
|
||||||
|
|
||||||
|
FILE *result = popen(cmd, "r");
|
||||||
|
if (!result) {
|
||||||
|
unlink(tmpfile);
|
||||||
|
reset_prog_mode();
|
||||||
|
refresh();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char selected[4096] = {0};
|
||||||
|
if (fgets(selected, sizeof(selected), result) != NULL) {
|
||||||
|
size_t len = strlen(selected);
|
||||||
|
if (len > 0 && selected[len-1] == '\n')
|
||||||
|
selected[len-1] = '\0';
|
||||||
|
}
|
||||||
|
pclose(result);
|
||||||
|
unlink(tmpfile);
|
||||||
|
|
||||||
|
// Restore ncurses
|
||||||
|
reset_prog_mode();
|
||||||
|
refresh();
|
||||||
|
|
||||||
|
if (selected[0] == '\0')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return strdup(selected);
|
||||||
|
}
|
||||||
|
|
||||||
void tui_cleanup(void) {
|
void tui_cleanup(void) {
|
||||||
if (yank_buffer.clip_indices) free(yank_buffer.clip_indices);
|
if (yank_buffer.clip_indices) free(yank_buffer.clip_indices);
|
||||||
/* free script note allocations */
|
/* free script note allocations */
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#ifndef TUI_H
|
#ifndef TUI_H
|
||||||
#define TUI_H
|
#define TUI_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
void tui_init(void);
|
void tui_init(void);
|
||||||
void tui_run(void);
|
void tui_run(void);
|
||||||
void tui_cleanup(void);
|
void tui_cleanup(void);
|
||||||
int send_command(const char *cmd);
|
int send_command(const char *cmd);
|
||||||
|
char* tui_fzf_select(const char *const items[], size_t count, const char *prompt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
5
client/tests/test_tui_stub.c
Normal file
5
client/tests/test_tui_stub.c
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#include "tui.h"
|
||||||
|
|
||||||
|
char *tui_fzf_select(const char *const items[], size_t count, const char *prompt){(void)items;(void)count;(void)prompt;return NULL;}
|
||||||
|
|
||||||
|
void tui_cleanup(void){}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|||||||
32
tests/test_tui_stub.c
Normal file
32
tests/test_tui_stub.c
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* Stub for tui functions used by script.c in test builds */
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "tui.h"
|
||||||
|
|
||||||
|
char *tui_fzf_select(const char *const items[], size_t count, const char *prompt) {
|
||||||
|
(void)items;
|
||||||
|
(void)count;
|
||||||
|
(void)prompt;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tui_cleanup(void) {
|
||||||
|
/* no operation */
|
||||||
|
}
|
||||||
|
/* Stub for tui functions used by script.c in test builds */
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "tui.h"
|
||||||
|
|
||||||
|
char *tui_fzf_select(const char *const items[], size_t count, const char *prompt) {
|
||||||
|
(void)items;
|
||||||
|
(void)count;
|
||||||
|
(void)prompt;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tui_cleanup(void) {
|
||||||
|
/* no operation */
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user