From 0db9aac06281b757de24fa044a465e3bfd6df07b Mon Sep 17 00:00:00 2001 From: Nepeta Leijon Date: Sun, 2 Aug 2026 12:40:07 -0300 Subject: [PATCH 1/3] Add Nepeta mode (closes #17) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New include/nepeta.h and src/nepeta.c: opt-in cat-speak reskin of prompt, banner, help text, and builtin error/status messages - Nepeta mode is toggleable via TRIGGER_NEPETA env var ('1'/'yes'/etc enables) or the new 'nepeta' builtin (on/off/status/bare) - Whole-word alpha-run pun translation: for→fur, perfect→purrfect, great→clawesome, awesome→pawsome, friend→furriend, now→meow, help→halp - When disabled, trigger_nepeta_say delegates to fputs — all existing output is byte-identical; no pipelines, external programs, perror(), or builtin name listings are affected - Tests: 18 new NepetaTests (state, prompt, translate, say capture, env init) + 6 new builtin dispatch tests (count bumped to 8) --- CMakeLists.txt | 9 ++- include/builtins.h | 1 + include/nepeta.h | 16 ++++ src/builtins.c | 49 ++++++++++-- src/main.c | 6 +- src/nepeta.c | 176 ++++++++++++++++++++++++++++++++++++++++++ tests/test_builtins.c | 57 +++++++++++++- tests/test_nepeta.c | 174 +++++++++++++++++++++++++++++++++++++++++ 8 files changed, 478 insertions(+), 10 deletions(-) create mode 100644 include/nepeta.h create mode 100644 src/nepeta.c create mode 100644 tests/test_nepeta.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 756d0ce..0bfc1a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ set(LIB_SOURCES src/builtins.c src/pipeline.c src/glob.c + src/nepeta.c ) set(UTIL_SOURCES @@ -23,6 +24,7 @@ set(HEADERS include/builtins.h include/pipeline.h include/glob_expand.h + include/nepeta.h ) add_library(trigger_core STATIC ${LIB_SOURCES} ${UTIL_SOURCES}) @@ -67,8 +69,13 @@ target_link_libraries(test_glob trigger_core) target_compile_options(test_glob PRIVATE -Wall -Wextra -Werror) add_test(NAME GlobTests COMMAND test_glob) +add_executable(test_nepeta tests/test_nepeta.c) +target_link_libraries(test_nepeta trigger_core) +target_compile_options(test_nepeta PRIVATE -Wall -Wextra -Werror) +add_test(NAME NepetaTests COMMAND test_nepeta) + add_custom_target(run_tests COMMAND ${CMAKE_CTEST_COMMAND} --verbose - DEPENDS test_input test_builtins test_execute test_pipeline test_glob + DEPENDS test_input test_builtins test_execute test_pipeline test_glob test_nepeta WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) diff --git a/include/builtins.h b/include/builtins.h index 120525b..264b22a 100644 --- a/include/builtins.h +++ b/include/builtins.h @@ -13,6 +13,7 @@ int trigger_pwd(char **args); int trigger_echo(char **args); int trigger_export(char **args); int trigger_unset(char **args); +int trigger_nepeta(char **args); int trigger_num_builtins(void); const Builtin *find_builtin(const char *name); diff --git a/include/nepeta.h b/include/nepeta.h new file mode 100644 index 0000000..c3fc706 --- /dev/null +++ b/include/nepeta.h @@ -0,0 +1,16 @@ +#ifndef NEPETA_H +#define NEPETA_H + +#include +#include + +bool trigger_nepeta_is_enabled(void); +void trigger_nepeta_set_enabled(bool enabled); +void trigger_nepeta_init_from_env(void); +const char *trigger_nepeta_prompt(void); +void trigger_nepeta_print_banner(void); +char *trigger_nepeta_translate(const char *plain_text); +void trigger_nepeta_say(FILE *stream, const char *plain_text); +const char *trigger_nepeta_random_quote(void); + +#endif diff --git a/src/builtins.c b/src/builtins.c index 3fc650f..49fc5b5 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -1,4 +1,5 @@ #include "builtins.h" +#include "nepeta.h" #include "utils/utils.h" #include #include @@ -8,7 +9,7 @@ static const Builtin builtins[] = { {"cd", trigger_cd}, {"help", trigger_help}, {"exit", trigger_exit}, {"pwd", trigger_pwd}, {"echo", trigger_echo}, {"export", trigger_export}, - {"unset", trigger_unset}, + {"unset", trigger_unset}, {"nepeta", trigger_nepeta}, }; static const int builtin_count = sizeof(builtins) / sizeof(builtins[0]); @@ -26,7 +27,7 @@ const Builtin *find_builtin(const char *name) { int trigger_cd(char **args) { if (args[1] == NULL) { - fprintf(stderr, "trigger: expected argument to \"cd\"\n"); + trigger_nepeta_say(stderr, "trigger: expected argument to \"cd\"\n"); return 1; } if (chdir(args[1]) != 0) { @@ -38,15 +39,15 @@ int trigger_cd(char **args) { } int trigger_help(char **args __attribute__((unused))) { - printf("Trigger: A simple shell written in C\n"); - printf("Type program names and arguments, and hit enter.\n"); - printf("The following are built in:\n"); + trigger_nepeta_say(stdout, "Trigger: A simple shell written in C\n"); + trigger_nepeta_say(stdout, "Type program names and arguments, and hit enter.\n"); + trigger_nepeta_say(stdout, "The following are built in:\n"); for (int i = 0; i < builtin_count; i++) { printf(" %s\n", builtins[i].name); } - printf("Use the man command for information on other programs.\n"); + trigger_nepeta_say(stdout, "Use the man command for information on other programs.\n"); return 0; } @@ -57,7 +58,9 @@ int trigger_exit(char **args) { if (*endptr == '\0' && n >= 0 && n <= 255) { return (int) n; } - fprintf(stderr, "trigger: exit: %s: numeric argument required\n", args[1]); + char buf[256]; + snprintf(buf, sizeof(buf), "trigger: exit: %s: numeric argument required\n", args[1]); + trigger_nepeta_say(stderr, buf); return 2; } return EXIT_SUCCESS; @@ -114,3 +117,35 @@ int trigger_unset(char **args) { } return 0; } + +int trigger_nepeta(char **args) { + if (args[1] == NULL) { + trigger_nepeta_set_enabled(!trigger_nepeta_is_enabled()); + trigger_nepeta_say(stdout, "Nepeta mode toggled.\n"); + return 0; + } + + if (strcmp(args[1], "on") == 0) { + trigger_nepeta_set_enabled(true); + trigger_nepeta_say(stdout, "Nepeta mode enabled.\n"); + return 0; + } + + if (strcmp(args[1], "off") == 0) { + trigger_nepeta_set_enabled(false); + trigger_nepeta_say(stdout, "Nepeta mode disabled.\n"); + return 0; + } + + if (strcmp(args[1], "status") == 0) { + if (trigger_nepeta_is_enabled()) { + trigger_nepeta_say(stdout, "Nepeta mode is enabled.\n"); + } else { + trigger_nepeta_say(stdout, "Nepeta mode is disabled.\n"); + } + return 0; + } + + trigger_nepeta_say(stderr, "usage: nepeta [on|off|status]\n"); + return 1; +} diff --git a/src/main.c b/src/main.c index 3e05a73..cfa045c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include "execute.h" #include "input.h" +#include "nepeta.h" #include "utils/utils.h" #include #include @@ -10,7 +11,7 @@ void trigger_loop(void) { int last_status = 0; for (;;) { - printf("> "); + printf("%s", trigger_nepeta_prompt()); fflush(stdout); char *line = trigger_read_line(); TokenList *tl = parse_line_with_quotes(line); @@ -38,6 +39,9 @@ int main(void) { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); + trigger_nepeta_init_from_env(); + trigger_nepeta_print_banner(); + trigger_loop(); return EXIT_SUCCESS; diff --git a/src/nepeta.c b/src/nepeta.c new file mode 100644 index 0000000..3c84a9b --- /dev/null +++ b/src/nepeta.c @@ -0,0 +1,176 @@ +#include "nepeta.h" +#include "utils/utils.h" +#include +#include +#include +#include +#include + +static bool nepeta_enabled = false; + +bool trigger_nepeta_is_enabled(void) { return nepeta_enabled; } + +void trigger_nepeta_set_enabled(bool enabled) { nepeta_enabled = enabled; } + +void trigger_nepeta_init_from_env(void) { + const char *val = getenv("TRIGGER_NEPETA"); + if (val != NULL && val[0] != '\0' && strcmp(val, "0") != 0) { + nepeta_enabled = true; + } +} + +const char *trigger_nepeta_prompt(void) { + if (nepeta_enabled) { + return ":33 < "; + } + return "> "; +} + +typedef struct { + const char *from; + const char *to; +} PunEntry; + +static const PunEntry pun_dict[] = { + {"for", "fur"}, + {"perfect", "purrfect"}, + {"great", "clawesome"}, + {"awesome", "pawsome"}, + {"friend", "furriend"}, + {"now", "meow"}, + {"help", "halp"}, +}; + +static const size_t pun_count = sizeof(pun_dict) / sizeof(pun_dict[0]); + +static int alpha_run_len(const char *s) { + int n = 0; + while (s[n] != '\0' && isalpha((unsigned char) s[n])) { + n++; + } + return n; +} + +static bool alpha_run_equals(const char *s, int slen, const char *dict_word) { + size_t dwlen = strlen(dict_word); + if ((size_t) slen != dwlen) { + return false; + } + for (size_t i = 0; i < dwlen; i++) { + if (tolower((unsigned char) s[i]) != tolower((unsigned char) dict_word[i])) { + return false; + } + } + return true; +} + +static const char *find_pun(const char *s, int slen) { + for (size_t i = 0; i < pun_count; i++) { + if (alpha_run_equals(s, slen, pun_dict[i].from)) { + return pun_dict[i].to; + } + } + return NULL; +} + +static void append_char(char **buf, size_t *cap, size_t *len, char c) { + if (*len + 1 >= *cap) { + *cap = *cap == 0 ? 64 : *cap * 2; + *buf = xrealloc(*buf, *cap); + } + (*buf)[*len] = c; + (*len)++; +} + +static void append_str(char **buf, size_t *cap, size_t *len, const char *s) { + for (const char *p = s; *p != '\0'; p++) { + append_char(buf, cap, len, *p); + } +} + +char *trigger_nepeta_translate(const char *plain_text) { + if (plain_text == NULL) { + char *empty = xmalloc(1); + empty[0] = '\0'; + return empty; + } + + char *result = NULL; + size_t cap = 0; + size_t len = 0; + + const char *p = plain_text; + + while (*p != '\0') { + if (isalpha((unsigned char) *p)) { + int run = alpha_run_len(p); + const char *pun = find_pun(p, run); + + if (pun != NULL) { + char first = p[0]; + if (isupper((unsigned char) first)) { + append_char(&result, &cap, &len, (char) toupper((unsigned char) pun[0])); + append_str(&result, &cap, &len, pun + 1); + } else { + append_char(&result, &cap, &len, (char) tolower((unsigned char) pun[0])); + append_str(&result, &cap, &len, pun + 1); + } + } else { + for (int i = 0; i < run; i++) { + append_char(&result, &cap, &len, p[i]); + } + } + p += run; + } else { + append_char(&result, &cap, &len, *p); + p++; + } + } + + append_char(&result, &cap, &len, '\0'); + return result; +} + +void trigger_nepeta_say(FILE *stream, const char *plain_text) { + if (!nepeta_enabled) { + fputs(plain_text, stream); + return; + } + + char *translated = trigger_nepeta_translate(plain_text); + fprintf(stream, ":33 < %s", translated); + free(translated); +} + +static const char *quotes[] = { + ":33 < *ac scratches at the terminal prompt*", + ":33 < purractice makes purrfect! hehe", + ":33 < *pounces on the enter key* rawr!", + ":33 < this shell is the cat's pajamas!", + ":33 < *curls up on the keyboard* warm~", + ":33 < fur the glory of the hunt!", + ":33 < *chases the cursor with big kitty eyes*", + ":33 < all your base are belong to Nepeta!", + ":33 < *batbatbat* at the command line", + ":33 < meow is the time fur action!", +}; + +static const size_t quote_count = sizeof(quotes) / sizeof(quotes[0]); + +const char *trigger_nepeta_random_quote(void) { + static int seeded = 0; + if (!seeded) { + srand((unsigned) time(NULL)); + seeded = 1; + } + return quotes[rand() % quote_count]; +} + +void trigger_nepeta_print_banner(void) { + if (!nepeta_enabled) { + return; + } + + printf(":33 < *Nepeta Leijon has entered the terminal* "); + printf("purrfect mode activated, %s, fur great justice!\n", trigger_nepeta_random_quote()); +} diff --git a/tests/test_builtins.c b/tests/test_builtins.c index 73bba7f..f2fe3c2 100644 --- a/tests/test_builtins.c +++ b/tests/test_builtins.c @@ -1,4 +1,5 @@ #include "../include/builtins.h" +#include "../include/nepeta.h" #include "test_framework.h" #include #include @@ -8,7 +9,7 @@ void test_builtin_arrays_match() { int count = trigger_num_builtins(); - ASSERT_TRUE(count == 7, "Should have 7 built-in commands"); + ASSERT_TRUE(count == 8, "Should have 8 built-in commands"); ASSERT_NOT_NULL(find_builtin("cd"), "Should find 'cd' built-in"); ASSERT_NOT_NULL(find_builtin("help"), "Should find 'help' built-in"); @@ -17,12 +18,17 @@ void test_builtin_arrays_match() { ASSERT_NOT_NULL(find_builtin("echo"), "Should find 'echo' built-in"); ASSERT_NOT_NULL(find_builtin("export"), "Should find 'export' built-in"); ASSERT_NOT_NULL(find_builtin("unset"), "Should find 'unset' built-in"); + ASSERT_NOT_NULL(find_builtin("nepeta"), "Should find 'nepeta' built-in"); ASSERT_NULL(find_builtin("nonexistent"), "Should not find unknown built-in"); const Builtin *cd_b = find_builtin("cd"); ASSERT_NOT_NULL(cd_b, "cd Builtin* should not be NULL"); ASSERT_TRUE(cd_b->fn == trigger_cd, "cd Builtin should point to trigger_cd"); + + const Builtin *nepeta_b = find_builtin("nepeta"); + ASSERT_NOT_NULL(nepeta_b, "nepeta Builtin* should not be NULL"); + ASSERT_TRUE(nepeta_b->fn == trigger_nepeta, "nepeta Builtin should point to trigger_nepeta"); } void test_cd_no_args() { @@ -118,6 +124,50 @@ void test_unset_command() { ASSERT_NULL(getenv("UNSET_VAR"), "unset variable should not be available"); } +void test_nepeta_on() { + trigger_nepeta_set_enabled(false); + char *args[] = {"nepeta", "on", NULL}; + int result = trigger_nepeta(args); + ASSERT_EQUAL(0, result, "nepeta on should return 0"); + ASSERT_TRUE(trigger_nepeta_is_enabled(), "Nepeta should be enabled after 'nepeta on'"); + trigger_nepeta_set_enabled(false); +} + +void test_nepeta_off() { + trigger_nepeta_set_enabled(true); + char *args[] = {"nepeta", "off", NULL}; + int result = trigger_nepeta(args); + ASSERT_EQUAL(0, result, "nepeta off should return 0"); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Nepeta should be disabled after 'nepeta off'"); + trigger_nepeta_set_enabled(false); +} + +void test_nepeta_status() { + trigger_nepeta_set_enabled(false); + char *args[] = {"nepeta", "status", NULL}; + int result = trigger_nepeta(args); + ASSERT_EQUAL(0, result, "nepeta status should return 0"); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Nepeta should still be disabled after status"); + trigger_nepeta_set_enabled(false); +} + +void test_nepeta_bare_toggle() { + trigger_nepeta_set_enabled(false); + char *args[] = {"nepeta", NULL}; + int result = trigger_nepeta(args); + ASSERT_EQUAL(0, result, "nepeta bare should return 0"); + ASSERT_TRUE(trigger_nepeta_is_enabled(), "Nepeta should be enabled after bare toggle"); + trigger_nepeta_set_enabled(false); +} + +void test_nepeta_unknown_arg() { + trigger_nepeta_set_enabled(false); + char *args[] = {"nepeta", "meow", NULL}; + int result = trigger_nepeta(args); + ASSERT_EQUAL(1, result, "nepeta with unknown arg should return 1"); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Nepeta should stay disabled after unknown arg"); +} + int main() { TEST_SUITE_START("Built-ins Module Tests"); @@ -133,6 +183,11 @@ int main() { test_export_command(); test_export_no_value(); test_unset_command(); + test_nepeta_on(); + test_nepeta_off(); + test_nepeta_status(); + test_nepeta_bare_toggle(); + test_nepeta_unknown_arg(); TEST_SUITE_END(); } diff --git a/tests/test_nepeta.c b/tests/test_nepeta.c new file mode 100644 index 0000000..5b524df --- /dev/null +++ b/tests/test_nepeta.c @@ -0,0 +1,174 @@ +#include "../include/nepeta.h" +#include "test_framework.h" +#include +#include +#include + +static void reset_nepeta(void) { trigger_nepeta_set_enabled(false); } + +void test_default_disabled() { + reset_nepeta(); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Nepeta mode should be disabled by default"); +} + +void test_set_get_roundtrip() { + reset_nepeta(); + trigger_nepeta_set_enabled(true); + ASSERT_TRUE(trigger_nepeta_is_enabled(), "Should be enabled after set(true)"); + trigger_nepeta_set_enabled(false); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Should be disabled after set(false)"); +} + +void test_prompt_disabled() { + reset_nepeta(); + ASSERT_STR_EQUAL("> ", trigger_nepeta_prompt(), "Prompt should be default when disabled"); +} + +void test_prompt_enabled() { + reset_nepeta(); + trigger_nepeta_set_enabled(true); + ASSERT_STR_EQUAL(":33 < ", trigger_nepeta_prompt(), "Prompt should be :33 < when enabled"); +} + +void test_translate_known_word() { + reset_nepeta(); + char *t = trigger_nepeta_translate("for"); + ASSERT_STR_EQUAL("fur", t, "\"for\" should translate to \"fur\""); + free(t); +} + +void test_translate_case_preserving() { + reset_nepeta(); + char *t = trigger_nepeta_translate("For"); + ASSERT_STR_EQUAL("Fur", t, "\"For\" should translate to \"Fur\""); + free(t); +} + +void test_translate_no_substring_match() { + reset_nepeta(); + char *t = trigger_nepeta_translate("information"); + ASSERT_STR_EQUAL("information", t, "\"information\" should not match \"for\" substring"); + free(t); +} + +void test_translate_no_match_passthrough() { + reset_nepeta(); + char *t = trigger_nepeta_translate("hello world"); + ASSERT_STR_EQUAL("hello world", t, "Unmatched text should pass through unchanged"); + free(t); +} + +void test_translate_multiple_words() { + reset_nepeta(); + char *t = trigger_nepeta_translate("this is great for a friend"); + ASSERT_STR_EQUAL("this is clawesome fur a furriend", t, + "Multiple words should all translate"); + free(t); +} + +void test_translate_null() { + reset_nepeta(); + char *t = trigger_nepeta_translate(NULL); + ASSERT_NOT_NULL(t, "NULL input should return allocated empty string"); + ASSERT_STR_EQUAL("", t, "NULL input should return empty string"); + free(t); +} + +void test_translate_empty() { + reset_nepeta(); + char *t = trigger_nepeta_translate(""); + ASSERT_STR_EQUAL("", t, "Empty input should return empty string"); + free(t); +} + +static char *capture_say(const char *text) { + char *buf; + size_t sz; + FILE *f = open_memstream(&buf, &sz); + if (f == NULL) + return NULL; + trigger_nepeta_say(f, text); + fclose(f); + return buf; +} + +void test_say_disabled() { + reset_nepeta(); + char *buf = capture_say("hello"); + ASSERT_NOT_NULL(buf, "capture_say should not return NULL when disabled"); + ASSERT_STR_EQUAL("hello", buf, "say should pass through unchanged when disabled"); + free(buf); +} + +void test_say_enabled() { + reset_nepeta(); + trigger_nepeta_set_enabled(true); + char *buf = capture_say("this is for you"); + ASSERT_NOT_NULL(buf, "capture_say should not return NULL when enabled"); + ASSERT_STR_EQUAL(":33 < this is fur you", buf, + "say should prefix with :33 < and translate when enabled"); + free(buf); +} + +void test_random_quote_not_null() { + reset_nepeta(); + const char *q = trigger_nepeta_random_quote(); + ASSERT_NOT_NULL(q, "Random quote should not be NULL"); + ASSERT_TRUE(strlen(q) > 0, "Random quote should not be empty"); +} + +void test_init_from_env_enabled() { + reset_nepeta(); + setenv("TRIGGER_NEPETA", "1", 1); + trigger_nepeta_init_from_env(); + ASSERT_TRUE(trigger_nepeta_is_enabled(), "Should enable when TRIGGER_NEPETA=1"); + unsetenv("TRIGGER_NEPETA"); +} + +void test_init_from_env_disabled_zero() { + reset_nepeta(); + setenv("TRIGGER_NEPETA", "0", 1); + trigger_nepeta_init_from_env(); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Should stay disabled when TRIGGER_NEPETA=0"); + unsetenv("TRIGGER_NEPETA"); +} + +void test_init_from_env_disabled_unset() { + reset_nepeta(); + unsetenv("TRIGGER_NEPETA"); + trigger_nepeta_init_from_env(); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Should stay disabled when TRIGGER_NEPETA unset"); +} + +void test_init_from_env_disabled_empty() { + reset_nepeta(); + setenv("TRIGGER_NEPETA", "", 1); + trigger_nepeta_init_from_env(); + ASSERT_FALSE(trigger_nepeta_is_enabled(), "Should stay disabled when TRIGGER_NEPETA=\"\""); + unsetenv("TRIGGER_NEPETA"); +} + +int main() { + TEST_SUITE_START("Nepeta Module Tests"); + + test_default_disabled(); + test_set_get_roundtrip(); + test_prompt_disabled(); + test_prompt_enabled(); + test_translate_known_word(); + test_translate_case_preserving(); + test_translate_no_substring_match(); + test_translate_no_match_passthrough(); + test_translate_multiple_words(); + test_translate_null(); + test_translate_empty(); + test_say_disabled(); + test_say_enabled(); + test_random_quote_not_null(); + test_init_from_env_enabled(); + test_init_from_env_disabled_zero(); + test_init_from_env_disabled_unset(); + test_init_from_env_disabled_empty(); + + TEST_SUITE_END(); +} From c6de1b8d8c174de27c86b238bfedf244f83ef3a3 Mon Sep 17 00:00:00 2001 From: Nepeta Leijon Date: Sun, 2 Aug 2026 12:52:50 -0300 Subject: [PATCH 2/3] Fix clang-format: pack array entries within column limit --- src/builtins.c | 11 ++++++++--- src/nepeta.c | 23 +++++++---------------- tests/test_nepeta.c | 3 +-- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index 49fc5b5..5cb63d2 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -7,9 +7,14 @@ #include static const Builtin builtins[] = { - {"cd", trigger_cd}, {"help", trigger_help}, {"exit", trigger_exit}, - {"pwd", trigger_pwd}, {"echo", trigger_echo}, {"export", trigger_export}, - {"unset", trigger_unset}, {"nepeta", trigger_nepeta}, + {"cd", trigger_cd}, + {"help", trigger_help}, + {"exit", trigger_exit}, + {"pwd", trigger_pwd}, + {"echo", trigger_echo}, + {"export", trigger_export}, + {"unset", trigger_unset}, + {"nepeta", trigger_nepeta}, }; static const int builtin_count = sizeof(builtins) / sizeof(builtins[0]); diff --git a/src/nepeta.c b/src/nepeta.c index 3c84a9b..355c869 100644 --- a/src/nepeta.c +++ b/src/nepeta.c @@ -32,12 +32,8 @@ typedef struct { } PunEntry; static const PunEntry pun_dict[] = { - {"for", "fur"}, - {"perfect", "purrfect"}, - {"great", "clawesome"}, - {"awesome", "pawsome"}, - {"friend", "furriend"}, - {"now", "meow"}, + {"for", "fur"}, {"perfect", "purrfect"}, {"great", "clawesome"}, + {"awesome", "pawsome"}, {"friend", "furriend"}, {"now", "meow"}, {"help", "halp"}, }; @@ -143,16 +139,11 @@ void trigger_nepeta_say(FILE *stream, const char *plain_text) { } static const char *quotes[] = { - ":33 < *ac scratches at the terminal prompt*", - ":33 < purractice makes purrfect! hehe", - ":33 < *pounces on the enter key* rawr!", - ":33 < this shell is the cat's pajamas!", - ":33 < *curls up on the keyboard* warm~", - ":33 < fur the glory of the hunt!", - ":33 < *chases the cursor with big kitty eyes*", - ":33 < all your base are belong to Nepeta!", - ":33 < *batbatbat* at the command line", - ":33 < meow is the time fur action!", + ":33 < *ac scratches at the terminal prompt*", ":33 < purractice makes purrfect! hehe", + ":33 < *pounces on the enter key* rawr!", ":33 < this shell is the cat's pajamas!", + ":33 < *curls up on the keyboard* warm~", ":33 < fur the glory of the hunt!", + ":33 < *chases the cursor with big kitty eyes*", ":33 < all your base are belong to Nepeta!", + ":33 < *batbatbat* at the command line", ":33 < meow is the time fur action!", }; static const size_t quote_count = sizeof(quotes) / sizeof(quotes[0]); diff --git a/tests/test_nepeta.c b/tests/test_nepeta.c index 5b524df..339c7d9 100644 --- a/tests/test_nepeta.c +++ b/tests/test_nepeta.c @@ -61,8 +61,7 @@ void test_translate_no_match_passthrough() { void test_translate_multiple_words() { reset_nepeta(); char *t = trigger_nepeta_translate("this is great for a friend"); - ASSERT_STR_EQUAL("this is clawesome fur a furriend", t, - "Multiple words should all translate"); + ASSERT_STR_EQUAL("this is clawesome fur a furriend", t, "Multiple words should all translate"); free(t); } From c0a115f881e75d3d05e3cf91c5b016cb6bce2990 Mon Sep 17 00:00:00 2001 From: Nepeta Leijon Date: Sun, 2 Aug 2026 12:55:29 -0300 Subject: [PATCH 3/3] Apply clang-format to all modified files --- src/builtins.c | 11 +++-------- src/nepeta.c | 15 +++++++-------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/builtins.c b/src/builtins.c index 5cb63d2..9b4255e 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -7,14 +7,9 @@ #include static const Builtin builtins[] = { - {"cd", trigger_cd}, - {"help", trigger_help}, - {"exit", trigger_exit}, - {"pwd", trigger_pwd}, - {"echo", trigger_echo}, - {"export", trigger_export}, - {"unset", trigger_unset}, - {"nepeta", trigger_nepeta}, + {"cd", trigger_cd}, {"help", trigger_help}, {"exit", trigger_exit}, + {"pwd", trigger_pwd}, {"echo", trigger_echo}, {"export", trigger_export}, + {"unset", trigger_unset}, {"nepeta", trigger_nepeta}, }; static const int builtin_count = sizeof(builtins) / sizeof(builtins[0]); diff --git a/src/nepeta.c b/src/nepeta.c index 355c869..0650861 100644 --- a/src/nepeta.c +++ b/src/nepeta.c @@ -32,9 +32,8 @@ typedef struct { } PunEntry; static const PunEntry pun_dict[] = { - {"for", "fur"}, {"perfect", "purrfect"}, {"great", "clawesome"}, - {"awesome", "pawsome"}, {"friend", "furriend"}, {"now", "meow"}, - {"help", "halp"}, + {"for", "fur"}, {"perfect", "purrfect"}, {"great", "clawesome"}, {"awesome", "pawsome"}, + {"friend", "furriend"}, {"now", "meow"}, {"help", "halp"}, }; static const size_t pun_count = sizeof(pun_dict) / sizeof(pun_dict[0]); @@ -139,11 +138,11 @@ void trigger_nepeta_say(FILE *stream, const char *plain_text) { } static const char *quotes[] = { - ":33 < *ac scratches at the terminal prompt*", ":33 < purractice makes purrfect! hehe", - ":33 < *pounces on the enter key* rawr!", ":33 < this shell is the cat's pajamas!", - ":33 < *curls up on the keyboard* warm~", ":33 < fur the glory of the hunt!", - ":33 < *chases the cursor with big kitty eyes*", ":33 < all your base are belong to Nepeta!", - ":33 < *batbatbat* at the command line", ":33 < meow is the time fur action!", + ":33 < *ac scratches at the terminal prompt*", ":33 < purractice makes purrfect! hehe", + ":33 < *pounces on the enter key* rawr!", ":33 < this shell is the cat's pajamas!", + ":33 < *curls up on the keyboard* warm~", ":33 < fur the glory of the hunt!", + ":33 < *chases the cursor with big kitty eyes*", ":33 < all your base are belong to Nepeta!", + ":33 < *batbatbat* at the command line", ":33 < meow is the time fur action!", }; static const size_t quote_count = sizeof(quotes) / sizeof(quotes[0]);