Generate actions from a text file
Mostly because I wanted to nest preprocessing. This makes the build more complex and slightly less portable, but the code itself is much cleaner.
This commit is contained in:
parent
66c77c3f8d
commit
4598c45d2f
|
@ -90,8 +90,22 @@ configure_file (${PROJECT_SOURCE_DIR}/config.h.in
|
||||||
${PROJECT_BINARY_DIR}/config.h)
|
${PROJECT_BINARY_DIR}/config.h)
|
||||||
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
|
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
|
||||||
|
|
||||||
|
# Assuming a Unix-compatible system with a standalone preprocessor
|
||||||
|
set (actions ${PROJECT_BINARY_DIR}/nncmpp-actions.h)
|
||||||
|
add_custom_command (OUTPUT ${actions}
|
||||||
|
COMMAND cpp -I${PROJECT_BINARY_DIR} -P ${PROJECT_SOURCE_DIR}/nncmpp.actions
|
||||||
|
| grep . | tr [[\n]] [[\t]] | sed -ne [[y/\t/\n/]] > ${actions}
|
||||||
|
-e [[h; s/,[^\n]*/,/g]] -e [[s/$/COUNT/]]
|
||||||
|
-e [[s/[^\n]*/\tACTION_&/g]] -e [[s/.*/enum action {\n&\n};\n/p]]
|
||||||
|
-e [[g; s/,[^\n]*//g; y/_/-/]] -e [[s/[^\n]\{1,\}/\t"&",/g]]
|
||||||
|
-e [[s/.*/static const char *g_action_names[] = {\n&};\n/p]]
|
||||||
|
-e [[g; s/[^\n]*, //g;]] -e [[s/[^\n]\{1,\}/\t"&",/g]]
|
||||||
|
-e [[s/.*/static const char *g_action_descriptions[] = {\n&};/p]]
|
||||||
|
COMMAND test -s ${actions}
|
||||||
|
DEPENDS ${PROJECT_BINARY_DIR}/config.h VERBATIM)
|
||||||
|
|
||||||
# Build the main executable and link it
|
# Build the main executable and link it
|
||||||
add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c)
|
add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c ${actions})
|
||||||
target_link_libraries (${PROJECT_NAME} ${Unistring_LIBRARIES}
|
target_link_libraries (${PROJECT_NAME} ${Unistring_LIBRARIES}
|
||||||
${Ncursesw_LIBRARIES} termo-static ${curl_LIBRARIES} ${extra_libraries})
|
${Ncursesw_LIBRARIES} termo-static ${curl_LIBRARIES} ${extra_libraries})
|
||||||
add_threads (${PROJECT_NAME})
|
add_threads (${PROJECT_NAME})
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
#ifndef CONFIG_H
|
#ifndef CONFIG_H
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
#define PROGRAM_NAME "${CMAKE_PROJECT_NAME}"
|
#define PROGRAM_NAME "${PROJECT_NAME}"
|
||||||
#define PROGRAM_VERSION "${PROJECT_VERSION}"
|
#define PROGRAM_VERSION "${PROJECT_VERSION}"
|
||||||
|
|
||||||
#cmakedefine HAVE_RESIZETERM
|
#cmakedefine HAVE_RESIZETERM
|
||||||
#cmakedefine WITH_FFTW
|
#cmakedefine WITH_FFTW
|
||||||
#cmakedefine WITH_PULSE
|
#cmakedefine WITH_PULSE
|
||||||
|
|
||||||
#endif // ! CONFIG_H
|
#endif /* ! CONFIG_H */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
NONE, Do nothing
|
||||||
|
|
||||||
|
QUIT, Quit
|
||||||
|
REDRAW, Redraw screen
|
||||||
|
TAB_HELP, Switch to help tab
|
||||||
|
TAB_LAST, Switch to last tab
|
||||||
|
TAB_PREVIOUS, Switch to previous tab
|
||||||
|
TAB_NEXT, Switch to next tab
|
||||||
|
|
||||||
|
MPD_TOGGLE, Toggle play/pause
|
||||||
|
MPD_STOP, Stop playback
|
||||||
|
MPD_PREVIOUS, Previous song
|
||||||
|
MPD_NEXT, Next song
|
||||||
|
MPD_BACKWARD, Seek backwards
|
||||||
|
MPD_FORWARD, Seek forwards
|
||||||
|
MPD_VOLUME_UP, Increase volume
|
||||||
|
MPD_VOLUME_DOWN, Decrease volume
|
||||||
|
|
||||||
|
MPD_SEARCH, Global search
|
||||||
|
MPD_ADD, Add selection to playlist
|
||||||
|
MPD_REPLACE, Replace playlist
|
||||||
|
MPD_REPEAT, Toggle repeat
|
||||||
|
MPD_RANDOM, Toggle random playback
|
||||||
|
MPD_SINGLE, Toggle single song playback
|
||||||
|
MPD_CONSUME, Toggle consume
|
||||||
|
MPD_UPDATE_DB, Update MPD database
|
||||||
|
MPD_COMMAND, Send raw command to MPD
|
||||||
|
|
||||||
|
#ifdef WITH_PULSE
|
||||||
|
PULSE_VOLUME_UP, Increase PulseAudio volume
|
||||||
|
PULSE_VOLUME_DOWN, Decrease PulseAudio volume
|
||||||
|
PULSE_MUTE, Toggle mute of MPD PulseAudio sink
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CHOOSE, Choose item
|
||||||
|
DELETE, Delete item
|
||||||
|
UP, Go up a level
|
||||||
|
MULTISELECT, Toggle multiselect
|
||||||
|
|
||||||
|
SCROLL_UP, Scroll up
|
||||||
|
SCROLL_DOWN, Scroll down
|
||||||
|
MOVE_UP, Move selection up
|
||||||
|
MOVE_DOWN, Move selection down
|
||||||
|
|
||||||
|
GOTO_TOP, Go to top
|
||||||
|
GOTO_BOTTOM, Go to bottom
|
||||||
|
GOTO_ITEM_PREVIOUS, Go to previous item
|
||||||
|
GOTO_ITEM_NEXT, Go to next item
|
||||||
|
GOTO_PAGE_PREVIOUS, Go to previous page
|
||||||
|
GOTO_PAGE_NEXT, Go to next page
|
||||||
|
|
||||||
|
GOTO_VIEW_TOP, Select top item
|
||||||
|
GOTO_VIEW_CENTER, Select center item
|
||||||
|
GOTO_VIEW_BOTTOM, Select bottom item
|
||||||
|
|
||||||
|
EDITOR_CONFIRM, Confirm input
|
||||||
|
|
||||||
|
EDITOR_B_CHAR, Go back a character
|
||||||
|
EDITOR_F_CHAR, Go forward a character
|
||||||
|
EDITOR_B_WORD, Go back a word
|
||||||
|
EDITOR_F_WORD, Go forward a word
|
||||||
|
EDITOR_HOME, Go to start of line
|
||||||
|
EDITOR_END, Go to end of line
|
||||||
|
|
||||||
|
EDITOR_B_DELETE, Delete last character
|
||||||
|
EDITOR_F_DELETE, Delete next character
|
||||||
|
EDITOR_B_KILL_WORD, Delete last word
|
||||||
|
EDITOR_B_KILL_LINE, Delete everything up to BOL
|
||||||
|
EDITOR_F_KILL_LINE, Delete everything up to EOL
|
114
nncmpp.c
114
nncmpp.c
|
@ -2235,117 +2235,14 @@ app_goto_tab (int tab_index)
|
||||||
|
|
||||||
// --- Actions -----------------------------------------------------------------
|
// --- Actions -----------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef WITH_PULSE
|
#include "nncmpp-actions.h"
|
||||||
#define WITH_PULSE_01 1
|
|
||||||
#else
|
|
||||||
#define WITH_PULSE_01 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO: use the C preprocessor and a tool to generate this from nncmpp.actions
|
|
||||||
#define ACTIONS(XX) \
|
|
||||||
XX( 1, NONE, Do nothing ) \
|
|
||||||
\
|
|
||||||
XX( 1, QUIT, Quit ) \
|
|
||||||
XX( 1, REDRAW, Redraw screen ) \
|
|
||||||
XX( 1, TAB_HELP, Switch to help tab ) \
|
|
||||||
XX( 1, TAB_LAST, Switch to last tab ) \
|
|
||||||
XX( 1, TAB_PREVIOUS, Switch to previous tab ) \
|
|
||||||
XX( 1, TAB_NEXT, Switch to next tab ) \
|
|
||||||
\
|
|
||||||
XX( 1, MPD_TOGGLE, Toggle play/pause ) \
|
|
||||||
XX( 1, MPD_STOP, Stop playback ) \
|
|
||||||
XX( 1, MPD_PREVIOUS, Previous song ) \
|
|
||||||
XX( 1, MPD_NEXT, Next song ) \
|
|
||||||
XX( 1, MPD_BACKWARD, Seek backwards ) \
|
|
||||||
XX( 1, MPD_FORWARD, Seek forwards ) \
|
|
||||||
XX( 1, MPD_VOLUME_UP, Increase volume ) \
|
|
||||||
XX( 1, MPD_VOLUME_DOWN, Decrease volume ) \
|
|
||||||
\
|
|
||||||
XX( 1, MPD_SEARCH, Global search ) \
|
|
||||||
XX( 1, MPD_ADD, Add selection to playlist ) \
|
|
||||||
XX( 1, MPD_REPLACE, Replace playlist ) \
|
|
||||||
XX( 1, MPD_REPEAT, Toggle repeat ) \
|
|
||||||
XX( 1, MPD_RANDOM, Toggle random playback ) \
|
|
||||||
XX( 1, MPD_SINGLE, Toggle single song playback ) \
|
|
||||||
XX( 1, MPD_CONSUME, Toggle consume ) \
|
|
||||||
XX( 1, MPD_UPDATE_DB, Update MPD database ) \
|
|
||||||
XX( 1, MPD_COMMAND, Send raw command to MPD ) \
|
|
||||||
\
|
|
||||||
XX( WITH_PULSE_01, PULSE_VOLUME_UP, Increase PulseAudio volume ) \
|
|
||||||
XX( WITH_PULSE_01, PULSE_VOLUME_DOWN, Decrease PulseAudio volume ) \
|
|
||||||
XX( WITH_PULSE_01, PULSE_MUTE, Toggle mute of MPD PulseAudio sink ) \
|
|
||||||
\
|
|
||||||
XX( 1, CHOOSE, Choose item ) \
|
|
||||||
XX( 1, DELETE, Delete item ) \
|
|
||||||
XX( 1, UP, Go up a level ) \
|
|
||||||
XX( 1, MULTISELECT, Toggle multiselect ) \
|
|
||||||
\
|
|
||||||
XX( 1, SCROLL_UP, Scroll up ) \
|
|
||||||
XX( 1, SCROLL_DOWN, Scroll down ) \
|
|
||||||
XX( 1, MOVE_UP, Move selection up ) \
|
|
||||||
XX( 1, MOVE_DOWN, Move selection down ) \
|
|
||||||
\
|
|
||||||
XX( 1, GOTO_TOP, Go to top ) \
|
|
||||||
XX( 1, GOTO_BOTTOM, Go to bottom ) \
|
|
||||||
XX( 1, GOTO_ITEM_PREVIOUS, Go to previous item ) \
|
|
||||||
XX( 1, GOTO_ITEM_NEXT, Go to next item ) \
|
|
||||||
XX( 1, GOTO_PAGE_PREVIOUS, Go to previous page ) \
|
|
||||||
XX( 1, GOTO_PAGE_NEXT, Go to next page ) \
|
|
||||||
\
|
|
||||||
XX( 1, GOTO_VIEW_TOP, Select top item ) \
|
|
||||||
XX( 1, GOTO_VIEW_CENTER, Select center item ) \
|
|
||||||
XX( 1, GOTO_VIEW_BOTTOM, Select bottom item ) \
|
|
||||||
\
|
|
||||||
XX( 1, EDITOR_CONFIRM, Confirm input ) \
|
|
||||||
\
|
|
||||||
XX( 1, EDITOR_B_CHAR, Go back a character ) \
|
|
||||||
XX( 1, EDITOR_F_CHAR, Go forward a character ) \
|
|
||||||
XX( 1, EDITOR_B_WORD, Go back a word ) \
|
|
||||||
XX( 1, EDITOR_F_WORD, Go forward a word ) \
|
|
||||||
XX( 1, EDITOR_HOME, Go to start of line ) \
|
|
||||||
XX( 1, EDITOR_END, Go to end of line ) \
|
|
||||||
\
|
|
||||||
XX( 1, EDITOR_B_DELETE, Delete last character ) \
|
|
||||||
XX( 1, EDITOR_F_DELETE, Delete next character ) \
|
|
||||||
XX( 1, EDITOR_B_KILL_WORD, Delete last word ) \
|
|
||||||
XX( 1, EDITOR_B_KILL_LINE, Delete everything up to BOL ) \
|
|
||||||
XX( 1, EDITOR_F_KILL_LINE, Delete everything up to EOL )
|
|
||||||
|
|
||||||
enum action
|
|
||||||
{
|
|
||||||
#define XX(usable, name, description) ACTION_ ## name,
|
|
||||||
ACTIONS (XX)
|
|
||||||
#undef XX
|
|
||||||
ACTION_COUNT
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct action_info
|
|
||||||
{
|
|
||||||
const char *name; ///< Name for user bindings
|
|
||||||
const char *description; ///< Human-readable description
|
|
||||||
bool usable; ///< Usable?
|
|
||||||
}
|
|
||||||
g_actions[] =
|
|
||||||
{
|
|
||||||
#define XX(usable, name, description) { #name, #description, usable },
|
|
||||||
ACTIONS (XX)
|
|
||||||
#undef XX
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Accept a more human format of action-name instead of ACTION_NAME
|
|
||||||
static int action_toupper (int c) { return c == '-' ? '_' : toupper_ascii (c); }
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
action_resolve (const char *name)
|
action_resolve (const char *name)
|
||||||
{
|
{
|
||||||
const unsigned char *s = (const unsigned char *) name;
|
|
||||||
for (int i = 0; i < ACTION_COUNT; i++)
|
for (int i = 0; i < ACTION_COUNT; i++)
|
||||||
{
|
if (!strcasecmp_ascii (g_action_names[i], name))
|
||||||
const char *target = g_actions[i].name;
|
|
||||||
for (size_t k = 0; action_toupper (s[k]) == target[k]; k++)
|
|
||||||
if (!s[k] && !target[k])
|
|
||||||
return i;
|
return i;
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3943,9 +3840,6 @@ help_tab_group (struct binding *keys, size_t len, struct strv *out,
|
||||||
{
|
{
|
||||||
for (enum action i = 0; i < ACTION_COUNT; i++)
|
for (enum action i = 0; i < ACTION_COUNT; i++)
|
||||||
{
|
{
|
||||||
if (!g_actions[i].usable)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct strv ass = strv_make ();
|
struct strv ass = strv_make ();
|
||||||
for (size_t k = 0; k < len; k++)
|
for (size_t k = 0; k < len; k++)
|
||||||
if (keys[k].action == i)
|
if (keys[k].action == i)
|
||||||
|
@ -3954,7 +3848,7 @@ help_tab_group (struct binding *keys, size_t len, struct strv *out,
|
||||||
{
|
{
|
||||||
char *joined = strv_join (&ass, ", ");
|
char *joined = strv_join (&ass, ", ");
|
||||||
strv_append_owned (out, xstrdup_printf
|
strv_append_owned (out, xstrdup_printf
|
||||||
(" %-30s %s", g_actions[i].description, joined));
|
(" %-30s %s", g_action_descriptions[i], joined));
|
||||||
free (joined);
|
free (joined);
|
||||||
|
|
||||||
bound[i] = true;
|
bound[i] = true;
|
||||||
|
@ -3971,7 +3865,7 @@ help_tab_unbound (struct strv *out, bool bound[ACTION_COUNT])
|
||||||
if (!bound[i])
|
if (!bound[i])
|
||||||
{
|
{
|
||||||
strv_append_owned (out,
|
strv_append_owned (out,
|
||||||
xstrdup_printf (" %-30s", g_actions[i].description));
|
xstrdup_printf (" %-30s", g_action_descriptions[i]));
|
||||||
help_tab_assign_action (i);
|
help_tab_assign_action (i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue