How to configure addons installed with "anki.withAddons"

I’ve been trying to declaratively configure anki for a while now but I can’t figure out how to find available configuration options:

{ config, lib, pkgs, pkgs-unstable, ... }:
{
  home.packages = with pkgs-unstable; [
    (anki.withAddons (with ankiAddons; [
      anki-connect
      yomichan-forvo-server
      passfail2
      # https://github.com/AnKing-VIP/AnkiRecolor/blob/main/src/addon/config.py#L35
      recolor.withConfig {

        get_theme_css = { colors_config = "nord.json"; };

      } # Eventually pair this with stylix
    ]))
  ];

#  home.file."${pkgs-unstable.ankiAddons.recolor}/share/anki/addons/recolor/theme/TokyoNight.json".source = ./TokyoNight.json;
#  home.file."${pkgs-unstable.ankiAddons.recolor}/share/anki/addons/recolor/theme/RosepineMoon.json".source = ./RosepineMoon.json;
}

Ideally this would be paired with the theme generated by stylix, I figured one way to do that would be to create a ./stylix.json, have that file be installed into “${pkgs-unstable.ankiAddons.recolor}/share/anki/addons/recolor/themes” but I can’t even seem to figure out how to enable the already installed nord theme.

Can someone help me to understand how to parse github pages so I know how to solve these issues on my own? I want to learn nix so even just a link to an article on the topic would help a lot.

Any help would be appreciated.

1 Like

You don’t actually always have to look at the code. Since Nix is normally just used to generate the apps config file, you can configure the app how you want without Nix and then create your Nix config based on the config file the app generated.
Anki add-ons store user config in the meta.json file under the config key. Everything you put in .withConfig {} gets translated to JSON and put there in meta.json. This is also what Anki does when you edit an add-on’s config from within the UI. The JSON you type in gets put in meta.json under the config key.
If you look at the meta.json for ReColor when not using Nix, it probably looks something like this:

{
    "human_version": "3.0",
    "name": "ReColor",
    "mod": 1709430312,
    "min_point_version": 55,
    "max_point_version": 55,
    "branch_index": 1,
    "disabled": false,
    "config": {
        "colors": {
            "ACCENT_CARD": [
                "Card mode",
                "#cba6f7",
                "#cba6f7",
                "--accent-card"
            ],
            "ACCENT_DANGER": [
                "Danger",
                "#f38ba8",
                "#f38ba8",
                "--accent-danger"
            ],
            "ACCENT_NOTE": [
                "Note mode",
                "#a6e3a1",
                "#a6e3a1",
                "--accent-note"
            ],
            "BORDER": [
                "Border",
                "#45475a",
                "#45475a",
                "--border"
            ],
            "BORDER_FOCUS": [
                "Border (focused input)",
                "#f5e0dc",
                "#f5e0dc",
                "--border-focus"
            ],
            "BORDER_STRONG": [
                "Border (strong)",
                "#585b70",
                "#585b70",
                "--border-strong"
            ],
            "BORDER_SUBTLE": [
                "Border (subtle)",
                "#313244",
                "#313244",
                "--border-subtle"
            ],
            "BUTTON_BG": [
                "Button background",
                "#313244",
                "#313244",
                "--button-bg"
            ],
            "BUTTON_DISABLED": [
                "Button background (disabled)",
                "#313244",
                "#313244",
                "--button-disabled"
            ],
            "BUTTON_HOVER": [
                "Button background (hover)",
                "#45475a",
                "#45475a",
                [
                    "--button-gradient-start",
                    "--button-gradient-end"
                ]
            ],
            "BUTTON_HOVER_BORDER": [
                "Button border (hover)",
                "#585b70",
                "#585b70",
                "--button-hover-border"
            ],
            "BUTTON_PRIMARY_BG": [
                "Button Primary Bg",
                "#2f67e1",
                "#2f67e1",
                "--button-primary-bg"
            ],
            "BUTTON_PRIMARY_DISABLED": [
                "Button Primary Disabled",
                "#4484ed",
                "#4484ed",
                "--button-primary-disabled"
            ],
            "BUTTON_PRIMARY_GRADIENT_END": [
                "Button Primary Gradient End",
                "#2544a8",
                "#2544a8",
                "--button-primary-gradient-end"
            ],
            "BUTTON_PRIMARY_GRADIENT_START": [
                "Button Primary Gradient Start",
                "#2f67e1",
                "#2f67e1",
                "--button-primary-gradient-start"
            ],
            "CANVAS": [
                "Background",
                "#1e1e2e",
                "#1e1e2e",
                [
                    "--canvas",
                    "--bs-body-bg"
                ]
            ],
            "CANVAS_CODE": [
                "Code editor background",
                "#181825",
                "#181825",
                "--canvas-code"
            ],
            "CANVAS_ELEVATED": [
                "Review",
                "#181825",
                "#181825",
                "--canvas-elevated"
            ],
            "CANVAS_GLASS": [
                "Background (transparent text surface)",
                "#18182566",
                "#18182566",
                "--canvas-glass"
            ],
            "CANVAS_INSET": [
                "Background (inset)",
                "#11111b",
                "#11111b",
                "--canvas-inset"
            ],
            "CANVAS_OVERLAY": [
                "Background (menu & tooltip)",
                "#181825",
                "#181825",
                "--canvas-overlay"
            ],
            "FG": [
                "Text",
                "#cdd6f4",
                "#cdd6f4",
                [
                    "--fg",
                    "--bs-body-color"
                ]
            ],
            "FG_DISABLED": [
                "Text (disabled)",
                "#a6adc6",
                "#a6adc6",
                "--fg-disabled"
            ],
            "FG_FAINT": [
                "Text (faint)",
                "#9399b2",
                "#9399b2",
                "--fg-faint"
            ],
            "FG_LINK": [
                "Text (link)",
                "#f5e0dc",
                "#f5e0dc",
                "--fg-link"
            ],
            "FG_SUBTLE": [
                "Text (subtle)",
                "#bac2de",
                "#bac2de",
                "--fg-subtle"
            ],
            "FLAG_1": [
                "Flag 1",
                "#f38ba8",
                "#f38ba8",
                "--flag-1"
            ],
            "FLAG_2": [
                "Flag 2",
                "#fab387",
                "#fab387",
                "--flag-2"
            ],
            "FLAG_3": [
                "Flag 3",
                "#a6e3a1",
                "#a6e3a1",
                "--flag-3"
            ],
            "FLAG_4": [
                "Flag 4",
                "#89b4fa",
                "#89b4fa",
                "--flag-4"
            ],
            "FLAG_5": [
                "Flag 5",
                "#cba6f7",
                "#cba6f7",
                "--flag-5"
            ],
            "FLAG_6": [
                "Flag 6",
                "#89dceb",
                "#89dceb",
                "--flag-6"
            ],
            "FLAG_7": [
                "Flag 7",
                "#c9cbff",
                "#c9cbff",
                "--flag-7"
            ],
            "HIGHLIGHT_BG": [
                "Highlight background",
                "#313244",
                "#313244",
                "--highlight-bg"
            ],
            "HIGHLIGHT_FG": [
                "Highlight text",
                "#f5e0dc",
                "#f5e0dc",
                "--highlight-fg"
            ],
            "SCROLLBAR_BG": [
                "Scrollbar background",
                "#1e1e2e",
                "#1e1e2e",
                "--scrollbar-bg"
            ],
            "SCROLLBAR_BG_ACTIVE": [
                "Scrollbar background (active)",
                "#313244",
                "#313244",
                "--scrollbar-bg-active"
            ],
            "SCROLLBAR_BG_HOVER": [
                "Scrollbar background (hover)",
                "#1e1e2e",
                "#1e1e2e",
                "--scrollbar-bg-hover"
            ],
            "SELECTED_BG": [
                "Selected Bg",
                "#313244",
                "#313244",
                "--selected-bg"
            ],
            "SELECTED_FG": [
                "Selected Fg",
                "#f5e0dc",
                "#f5e0dc",
                "--selected-fg"
            ],
            "SHADOW": [
                "Shadow",
                "#1e1e2e",
                "#1e1e2e",
                "--shadow"
            ],
            "SHADOW_FOCUS": [
                "Shadow (focused input)",
                "#fab387",
                "#fab387",
                "--shadow-focus"
            ],
            "SHADOW_INSET": [
                "Shadow (inset)",
                "#11111b",
                "#11111b",
                "--shadow-inset"
            ],
            "SHADOW_SUBTLE": [
                "Shadow (subtle)",
                "#181825",
                "#181825",
                "--shadow-subtle"
            ],
            "STATE_BURIED": [
                "Buried",
                "#7f849c",
                "#7f849c",
                "--state-buried"
            ],
            "STATE_LEARN": [
                "Learn",
                "#f38ba8",
                "#f38ba8",
                "--state-learn"
            ],
            "STATE_MARKED": [
                "Marked",
                "#FAE3B0",
                "#FAE3B0",
                "--state-marked"
            ],
            "STATE_NEW": [
                "New",
                "#96cdfb",
                "#96cdfb",
                "--state-new"
            ],
            "STATE_REVIEW": [
                "Review",
                "#a6e3a1",
                "#a6e3a1",
                "--state-review"
            ],
            "STATE_SUSPENDED": [
                "Suspended",
                "#a6adc8",
                "#a6adc8",
                "--state-suspended"
            ]
        },
        "version": {
            "major": 3,
            "minor": 0
        }
    },
    "conflicts": [],
    "update_enabled": true
}

Look familiar? Everything under config is the same format as the files you found in themes/. So, clearly what you need to configure in withConfig isn’t which theme file to load but rather, the theme itself. When manually selecting a theme in ReColor, what it actually does is load one of those presets in themes/ and then put its contents under config in meta.json.
Knowing this, it should be pretty easy to translate to Nix. Here’s what that looks like:

pkgs.ankiAddons.recolor.withConfig {
  config = {
    colors = {
      ACCENT_CARD = [
        "Card mode"
        "#cba6f7"
        "#cba6f7"
        "--accent-card"
      ];
      ACCENT_DANGER = [
        "Danger"
        "#f38ba8"
        "#f38ba8"
        "--accent-danger"
      ];
      ACCENT_NOTE = [
        "Note mode"
        "#a6e3a1"
        "#a6e3a1"
        "--accent-note"
      ];
      BORDER = [
        "Border"
        "#45475a"
        "#45475a"
        "--border"
      ];
      BORDER_FOCUS = [
        "Border (focused input)"
        "#f5e0dc"
        "#f5e0dc"
        "--border-focus"
      ];
      BORDER_STRONG = [
        "Border (strong)"
        "#585b70"
        "#585b70"
        "--border-strong"
      ];
      BORDER_SUBTLE = [
        "Border (subtle)"
        "#313244"
        "#313244"
        "--border-subtle"
      ];
      BUTTON_BG = [
        "Button background"
        "#313244"
        "#313244"
        "--button-bg"
      ];
      BUTTON_DISABLED = [
        "Button background (disabled)"
        "#313244"
        "#313244"
        "--button-disabled"
      ];
      BUTTON_HOVER = [
        "Button background (hover)"
        "#45475a"
        "#45475a"
        [
          "--button-gradient-start"
          "--button-gradient-end"
        ]
      ];
      BUTTON_HOVER_BORDER = [
        "Button border (hover)"
        "#585b70"
        "#585b70"
        "--button-hover-border"
      ];
      BUTTON_PRIMARY_BG = [
        "Button Primary Bg"
        "#2f67e1"
        "#2f67e1"
        "--button-primary-bg"
      ];
      BUTTON_PRIMARY_DISABLED = [
        "Button Primary Disabled"
        "#4484ed"
        "#4484ed"
        "--button-primary-disabled"
      ];
      BUTTON_PRIMARY_GRADIENT_END = [
        "Button Primary Gradient End"
        "#2544a8"
        "#2544a8"
        "--button-primary-gradient-end"
      ];
      BUTTON_PRIMARY_GRADIENT_START = [
        "Button Primary Gradient Start"
        "#2f67e1"
        "#2f67e1"
        "--button-primary-gradient-start"
      ];
      CANVAS = [
        "Background"
        "#1e1e2e"
        "#1e1e2e"
        [
          "--canvas"
          "--bs-body-bg"
        ]
      ];
      CANVAS_CODE = [
        "Code editor background"
        "#181825"
        "#181825"
        "--canvas-code"
      ];
      CANVAS_ELEVATED = [
        "Review"
        "#181825"
        "#181825"
        "--canvas-elevated"
      ];
      CANVAS_GLASS = [
        "Background (transparent text surface)"
        "#18182566"
        "#18182566"
        "--canvas-glass"
      ];
      CANVAS_INSET = [
        "Background (inset)"
        "#11111b"
        "#11111b"
        "--canvas-inset"
      ];
      CANVAS_OVERLAY = [
        "Background (menu & tooltip)"
        "#181825"
        "#181825"
        "--canvas-overlay"
      ];
      FG = [
        "Text"
        "#cdd6f4"
        "#cdd6f4"
        [
          "--fg"
          "--bs-body-color"
        ]
      ];
      FG_DISABLED = [
        "Text (disabled)"
        "#a6adc6"
        "#a6adc6"
        "--fg-disabled"
      ];
      FG_FAINT = [
        "Text (faint)"
        "#9399b2"
        "#9399b2"
        "--fg-faint"
      ];
      FG_LINK = [
        "Text (link)"
        "#f5e0dc"
        "#f5e0dc"
        "--fg-link"
      ];
      FG_SUBTLE = [
        "Text (subtle)"
        "#bac2de"
        "#bac2de"
        "--fg-subtle"
      ];
      FLAG_1 = [
        "Flag 1"
        "#f38ba8"
        "#f38ba8"
        "--flag-1"
      ];
      FLAG_2 = [
        "Flag 2"
        "#fab387"
        "#fab387"
        "--flag-2"
      ];
      FLAG_3 = [
        "Flag 3"
        "#a6e3a1"
        "#a6e3a1"
        "--flag-3"
      ];
      FLAG_4 = [
        "Flag 4"
        "#89b4fa"
        "#89b4fa"
        "--flag-4"
      ];
      FLAG_5 = [
        "Flag 5"
        "#cba6f7"
        "#cba6f7"
        "--flag-5"
      ];
      FLAG_6 = [
        "Flag 6"
        "#89dceb"
        "#89dceb"
        "--flag-6"
      ];
      FLAG_7 = [
        "Flag 7"
        "#c9cbff"
        "#c9cbff"
        "--flag-7"
      ];
      HIGHLIGHT_BG = [
        "Highlight background"
        "#313244"
        "#313244"
        "--highlight-bg"
      ];
      HIGHLIGHT_FG = [
        "Highlight text"
        "#f5e0dc"
        "#f5e0dc"
        "--highlight-fg"
      ];
      SCROLLBAR_BG = [
        "Scrollbar background"
        "#1e1e2e"
        "#1e1e2e"
        "--scrollbar-bg"
      ];
      SCROLLBAR_BG_ACTIVE = [
        "Scrollbar background (active)"
        "#313244"
        "#313244"
        "--scrollbar-bg-active"
      ];
      SCROLLBAR_BG_HOVER = [
        "Scrollbar background (hover)"
        "#1e1e2e"
        "#1e1e2e"
        "--scrollbar-bg-hover"
      ];
      SELECTED_BG = [
        "Selected Bg"
        "#313244"
        "#313244"
        "--selected-bg"
      ];
      SELECTED_FG = [
        "Selected Fg"
        "#f5e0dc"
        "#f5e0dc"
        "--selected-fg"
      ];
      SHADOW = [
        "Shadow"
        "#1e1e2e"
        "#1e1e2e"
        "--shadow"
      ];
      SHADOW_FOCUS = [
        "Shadow (focused input)"
        "#fab387"
        "#fab387"
        "--shadow-focus"
      ];
      SHADOW_INSET = [
        "Shadow (inset)"
        "#11111b"
        "#11111b"
        "--shadow-inset"
      ];
      SHADOW_SUBTLE = [
        "Shadow (subtle)"
        "#181825"
        "#181825"
        "--shadow-subtle"
      ];
      STATE_BURIED = [
        "Buried"
        "#7f849c"
        "#7f849c"
        "--state-buried"
      ];
      STATE_LEARN = [
        "Learn"
        "#f38ba8"
        "#f38ba8"
        "--state-learn"
      ];
      STATE_MARKED = [
        "Marked"
        "#FAE3B0"
        "#FAE3B0"
        "--state-marked"
      ];
      STATE_NEW = [
        "New"
        "#96cdfb"
        "#96cdfb"
        "--state-new"
      ];
      STATE_REVIEW = [
        "Review"
        "#a6e3a1"
        "#a6e3a1"
        "--state-review"
      ];
      STATE_SUSPENDED = [
        "Suspended"
        "#a6adc8"
        "#a6adc8"
        "--state-suspended"
      ];
    };
    version = {
      major = 3;
      minor = 1;
    };
  };
}

To convert this to use Stylix, all you have to do is replace the color strings like “#45475a” with the color variables Stylix provides.

For the question of “how to find available configuration options”, you probably already did most of the steps but I’ll summarize all of them:

  1. Look at the Nix documentation. Sometimes, not every option you need is exposed as a Nix option. In those cases, you usually use something like extraConfig that gets translated directly into the app’s native config format. With Anki add-ons, the function withConfig is being used instead of the NixOS module system. What gets passed to withConfig acts the same as an extraConfig option would.
  2. Look at the app’s documentation. It will usually explain how to use its config file.
  3. Look at the config file generated by the app. If the app’s documentation won’t tell you anything then let the app tell you itself!
  4. Look at other people’s Nix configs. In this case, you could try searching “recolor .withConfig” on GitHub.
  5. Finally, like you started to do, you can look at the app’s source code. This can be difficult if you aren’t a programmer, since an app could be written in any number of programming languages. I’ll try to explain a general approach to this next.

The key to finding what you want in the source code is tracing the logic. You find something you recognize like how you found the file that deals with “config” stuff, and then trace the logic to what you’re looking for. In this case, the config options.
Almost every programming language is just a list of instructions for the computer that are read in order. Most of those instructions/lines of code are just telling the computer to go run some other code before going to the next instruction. Those are called function calls and in most languages look like name_of_function_with_code_to_run(). The key here is the parenthesis. If you see someTextWithoutSpaces followed directly by parenthesis, it’s probably a function a call. The parenthesis may or may not have other text inside them.
If all code did was follow some instructions in order, apps would be like a movie, the same every time with no interactivity. The missing piece here is the actual logic. That logic usually uses the terms if and else. The code version of “Give me ice cream if it’s Wednesday, otherwise I’ll have salad” might look like

if current_day == "Wednesday":
    buy_ice_cream()
else:
    buy_salad()

in Python, the language ReColor is coded in.

You found a starting point earlier of that manager.py file. To get to the configuration options from there you’d have to first look at what it does. The file is full of functions for saving and loading config files. each def something is a function that will be called from other parts of the code. One of those functions is called get. It’s used to get values from the config. Logically, whatever calls that function must know what config options to look for, so why not search for get() in the code base? If you do you’ll find this: conf.get(f"colors.{conf_key}.0"). It looks like this function call has something to do with colors. Promising, but there’s not a specific option really. What calls the function this line was in? It turns out a few places do, but they all have code like:

conf_keys = [
    "FG",
    "FG_SUBTLE",
    "FG_DISABLED",
    "FG_FAINT",
    "FG_LINK",
    "CANVAS",
    "CANVAS_ELEVATED",
    "CANVAS_INSET",
    "CANVAS_OVERLAY",
    "CANVAS_CODE",
    "BORDER",
    "BORDER_SUBTLE",
    "BORDER_STRONG",
    "BORDER_FOCUS",
]

There’s your config keys!

You might notice that Nix code seems kind of different from what I was describing and most code you’ll see. That’s because Nix is different. Some of those differences are because it’s what’s called a “functional” programming language and that it’s made specifically for NixOS use cases rather than general use. In the end, it does work the same, though. You just have to understand how.
Understanding how it all works is a long, maybe never ending journey but a great one to start on. I don’t have great resources for this but the first step is learning the Nix language syntax like you may have already done. Nix Language - Nix 2.28.5 Reference Manual
One thing that makes Nix tricky is that so much of what you interact with are interfaces from nixpkgs that go well beyond the base Nix language. In the end, it’s all Nix, though (and a lot Bash to be fair). Beyond pure Nix, the NixOS module system is a great thing to read up on. For documentation on all the stuff people use from nixpkgs in their Nix code, the nixpkgs manual is great.

This should have at least solved your Anki problem. Hopefully the rest was helpful in some way as well.

Good luck learning!

1 Like

Thank you so much for your help!!

I’m still having some trouble though as trying to build any addon with any config seems to not be working.

Even the example configuration you wrote for passfail2 doesn’t seem to be working for me, the semicolon after the ending curly bracket of the withConfig function gives an “unexpected ;” error, removing that only gives another error:

yuki% homeup
> Building Home-Manager configuration
error:
       … while calling the 'derivationStrict' builtin
         at <nix/derivation-internal.nix>:37:12:
           36|
           37|   strict = derivationStrict drvAttrs;
             |            ^
           38|

       … while evaluating derivation 'home-manager-generation'
         whose name attribute is located at /nix/store/rzpdp2vaaxaddl6gcg4wfyczvcg0yc7f-source/pkgs/stdenv/generic/make-derivation.nix:480:13

       … while evaluating attribute 'buildCommand' of derivation 'home-manager-generation'
         at /nix/store/rzpdp2vaaxaddl6gcg4wfyczvcg0yc7f-source/pkgs/build-support/trivial-builders/default.nix:80:17:
           79|         enableParallelBuilding = true;
           80|         inherit buildCommand name;
             |                 ^
           81|         passAsFile = [ "buildCommand" ] ++ (derivationArgs.passAsFile or [ ]);

       … while evaluating the option `home.activation.installPackages.data':

       … while evaluating definitions from `/nix/store/j9vi4cb7v9g8bsvwxz2v26gxhypr1isr-source/modules/home-environment.nix':

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: cannot coerce a function to a string: «lambda withConfig @ /nix/store/h2bn031b0fj0ymv9v7bv5rcdjx58y2l9-source/pkgs/games/anki/addons/anki-utils.nix:65:13»
┏━ 1 Errors: 
┃ error:
┃        … while calling the 'derivationStrict' builtin
┃          at <nix/derivation-internal.nix>:37:12:
┃            36|
┃            37|   strict = derivationStrict drvAttrs;
┃              |            ^
┃            38|
┃ 
┃        … while evaluating derivation 'home-manager-generation'
┃          whose name attribute is located at /nix/store/rzpdp2vaaxaddl6gcg4wfyczvcg0yc7f-source/pkgs/stdenv/generic/make-derivation.nix:480:13
┃ 
┃        … while evaluating attribute 'buildCommand' of derivation 'home-manager-generation'
┃          at /nix/store/rzpdp2vaaxaddl6gcg4wfyczvcg0yc7f-source/pkgs/build-support/trivial-builders/default.nix:80:17:
┃            79|         enableParallelBuilding = true;
┃            80|         inherit buildCommand name;
┃              |                 ^
┃            81|         passAsFile = [ "buildCommand" ] ++ (derivationArgs.passAsFile or [ ]);
┃ 
┃        … while evaluating the option `home.activation.installPackages.data':
┃ 
┃        … while evaluating definitions from `/nix/store/j9vi4cb7v9g8bsvwxz2v26gxhypr1isr-source/modules/home-environment.nix':
┃ 
┃        (stack trace truncated; use '--show-trace' to show the full, detailed trace)
┃ 
┃        error: cannot coerce a function to a string: «lambda withConfig @ /nix/store/h2bn031b0fj0ymv9v7bv5rcdjx58y2l9-source/pkgs/games/anki/addons/anki-utils.nix…
┣━━━                                                             
┗━ ∑ ⚠ Exited with 1 errors reported by nix at 20:02:47 after 17s
Error: 
   0: Command exited with status Exited(1)

Location:
   src/commands.rs:261

with this configuration:

{ config, lib, pkgs, pkgs-unstable, ... }:
{

#  imports = [
#    ./recolor.nix
#  ];

  home.packages = with pkgs-unstable; [
    (anki.withAddons (with ankiAddons; [
      anki-connect
      yomichan-forvo-server
      passfail2.withConfig {
          config = {
            again_button_name = "not quite";
            good_button_name = "excellent";
          };
        }
    ]))
  ];
}

Do you have any idea why this might be happening?

If its necessary, my entire config can be found on codeberg

This looks like a classic annoying thing. List items are separated by spaces so its like passfail2.withConfig (a function as the error points out) and { config = ... } are separate items. You need parenthesis around them.

That works! recolors config is very clearly impacting anki.

For some reason though I get two seperate popups each time I open up anki:

Failed to listen on port 8765. 
Make sure it is available and not in use.
The add-on module: "recolor" tried to update its config.
See [github.com/NixOS/nixpkgs/tree/master/pkgs/games/anki/with-addons.nix](https://github.com/NixOS/nixpkgs/tree/master/pkgs/games/anki/with-addons.nix) for how to configure add-ons managed by NixOS.

I have no idea why changing recolor’s config would suddenly stop anki-connect from working but thats easily the most important addon to me so I definitely want to fix this issue.

Weirdly enough, this does not happen when I try and use the passfail2’s example config, instead that doesn’t even seem to be working as the pass fail buttons remain “pass” and “fail” (I honestly don’t care about configuring that but I figure we should probably a dress why it isn’t doing anything for me)

Current config on codeberg

Can you click the show details button to see what config recolor was trying to change?

Also, you don’t need builtins.readfile for what you want. Just import, though you’ll need to make it a valid Nix file. (Right now it’s trying to use recolor.withConfig, but there’s no recolor in that file’s scope.)

Also, also, for passfail2 try adding toggle_names_textcolors = 1 to the config.

Have you made sure that no other instances of Anki are running? The error suggests that the most likely, issue is something already running on that port.

outside of a codeblock so its not one massive line:

details

{“colors”: {“ACCENT_CARD”: [“Card mode”, “#89b4fa”, “#89b4fa”, “–accent-card”], “ACCENT_DANGER”: [“Danger”, “#f38ba8”, “#f38ba8”, “–accent-danger”], “ACCENT_NOTE”: [“Note mode”, “#a6e3a1”, “#a6e3a1”, “–accent-note”], “BORDER”: [“Border”, “#45475a”, “#45475a”, “–border”], “BORDER_FOCUS”: [“Border (focused input)”, “#f5e0dc”, “#f5e0dc”, “–border-focus”], “BORDER_STRONG”: [“Border (strong)”, “#585b70”, “#585b70”, “–border-strong”], “BORDER_SUBTLE”: [“Border (subtle)”, “#313244”, “#313244”, “–border-subtle”], “BUTTON_BG”: [“Button background”, “#313244”, “#313244”, “–button-bg”], “BUTTON_DISABLED”: [“Button background (disabled)”, “#313244”, “#313244”, “–button-disabled”], “BUTTON_HOVER”: [“Button background (hover)”, “#45475a”, “#45475a”, [“–button-gradient-start”, “–button-gradient-end”]], “BUTTON_HOVER_BORDER”: [“Button border (hover)”, “#585b70”, “#585b70”, “–button-hover-border”], “BUTTON_PRIMARY_BG”: [“Button Primary Bg”, “#2f67e1”, “#2f67e1”, “–button-primary-bg”], “BUTTON_PRIMARY_DISABLED”: [“Button Primary Disabled”, “#4484ed”, “#4484ed”, “–button-primary-disabled”], “BUTTON_PRIMARY_GRADIENT_END”: [“Button Primary Gradient End”, “#2544a8”, “#2544a8”, “–button-primary-gradient-end”], “BUTTON_PRIMARY_GRADIENT_START”: [“Button Primary Gradient Start”, “#2f67e1”, “#2f67e1”, “–button-primary-gradient-start”], “CANVAS”: [“Background”, “#232136”, “#232136”, [“–canvas”, “–bs-body-bg”]], “CANVAS_CODE”: [“Code editor background”, “#2a273f”, “#2a273f”, “–canvas-code”], “CANVAS_ELEVATED”: [“Review”, “#2a273f”, “#2a273f”, “–canvas-elevated”], “CANVAS_GLASS”: [“Background (transparent text surface)”, “#2a273f66”, “#2a273f66”, “–canvas-glass”], “CANVAS_INSET”: [“Background (inset)”, “#393552”, “#393552”, “–canvas-inset”], “CANVAS_OVERLAY”: [“Background (menu & tooltip)”, “#6e6a86”, “#6e6a86”, “–canvas-overlay”], “FG”: [“Text”, “#56526e”, “#56526e”, [“–fg”, “–bs-body-color”]], “FG_DISABLED”: [“Text (disabled)”, “#56526e”, “#a6adc6”, “–fg-disabled”], “FG_FAINT”: [“Text (faint)”, “#9399b2”, “#9399b2”, “–fg-faint”], “FG_LINK”: [“Text (link)”, “#f5e0dc”, “#f5e0dc”, “–fg-link”], “FG_SUBTLE”: [“Text (subtle)”, “#bac2de”, “#bac2de”, “–fg-subtle”], “FLAG_1”: [“Flag 1”, “#f38ba8”, “#f38ba8”, “–flag-1”], “FLAG_2”: [“Flag 2”, “#fab387”, “#fab387”, “–flag-2”], “FLAG_3”: [“Flag 3”, “#a6e3a1”, “#a6e3a1”, “–flag-3”], “FLAG_4”: [“Flag 4”, “#89b4fa”, “#89b4fa”, “–flag-4”], “FLAG_5”: [“Flag 5”, “#cba6f7”, “#cba6f7”, “–flag-5”], “FLAG_6”: [“Flag 6”, “#89dceb”, “#89dceb”, “–flag-6”], “FLAG_7”: [“Flag 7”, “#c9cbff”, “#c9cbff”, “–flag-7”], “HIGHLIGHT_BG”: [“Highlight background”, “#313244”, “#313244”, “–highlight-bg”], “HIGHLIGHT_FG”: [“Highlight text”, “#f5e0dc”, “#f5e0dc”, “–highlight-fg”], “SCROLLBAR_BG”: [“Scrollbar background”, “#1e1e2e”, “#1e1e2e”, “–scrollbar-bg”], “SCROLLBAR_BG_ACTIVE”: [“Scrollbar background (active)”, “#313244”, “#313244”, “–scrollbar-bg-active”], “SCROLLBAR_BG_HOVER”: [“Scrollbar background (hover)”, “#1e1e2e”, “#1e1e2e”, “–scrollbar-bg-hover”], “SELECTED_BG”: [“Selected Bg”, “#313244”, “#313244”, “–selected-bg”], “SELECTED_FG”: [“Selected Fg”, “#f5e0dc”, “#f5e0dc”, “–selected-fg”], “SHADOW”: [“Shadow”, “#1e1e2e”, “#1e1e2e”, “–shadow”], “SHADOW_FOCUS”: [“Shadow =focused input)”, “#fab387”, “#fab387”, “–shadow-focus”], “SHADOW_INSET”: [“Shadow (inset)”, “#11111b”, “#11111b”, “–shadow-inset”], “SHADOW_SUBTLE”: [“Shadow (subtle)”, “#181825”, “#181825”, “–shadow-subtle”], “STATE_BURIED”: [“Buried”, “#7f849c”, “#7f849c”, “–state-buried”], “STATE_LEARN”: [“Learn”, “#f38ba8”, “#f38ba8”, “–state-learn”], “STATE_MARKED”: [“Marked”, “#FAE3B0”, “#FAE3B0”, “–state-marked”], “STATE_NEW”: [“New”, “#96cdfb”, “#96cdfb”, “–state-new”], “STATE_REVIEW”: [“Review”, “#a6e3a1”, “#a6e3a1”, “–state-review”], “STATE_SUSPENDED”: [“Suspended”, “#a6adc8”, “#a6adc8”, “–state-suspended”]}, “version”: {“major”: 3, “minor”: 1}}

The ankiconnect thing was on me, it works just fine

even with toggle_name_textcolors = 1; the addon seems to not be changing its config

Passfail’s config does seem to be changing it just doesn’t seem to be giving any effect

yuki% cat /nix/store/lqh3ma8n3hdxvja304aglinb3vyd0j2q-anki-addon-passfail2-with-config-0.3.0-unstable-2024-10-17/share/anki/addons/passfail2/meta.json
{
  "config": {
    "again_button_name": "not quite",
    "good_button_name": "excellent",
    "toggle_name_textcolors": 1
  }
}

yet:

You need to add

version = {
  major = 3;
  minor = 1;
};

after the colors part so like colors = {...}; version = {...};

You missed an “s”. It’s “toggle_names_textcolors”

IT WORKS!!!

fixing the typo and adding the version to both of the addon’s configs fixed all of the issues.

Thank you so much for your help.

For anybody curious the final config with a rather slightly sloppy stylix theme (definitely will edit it as I continue to use it) is as follows:

{ config, lib, pkgs, pkgs-unstable, ... }:
{

  home.packages = with pkgs-unstable; [
    (anki.withAddons (with ankiAddons; [
      anki-connect
      (passfail2.withConfig {
          config = {
            again_button_name = "ヘッポコ";
            good_button_name = "日本語上手";
            toggle_names_textcolors = 1;
          };

      })
      (recolor.withConfig {

          config = {
              colors = {
            ACCENT_CARD = [
                "Card mode"
                "#${config.lib.stylix.colors.base0B}"
                "#${config.lib.stylix.colors.base0B}"
                "--accent-card"
            ];
            ACCENT_DANGER = [
                "Danger"
                "#${config.lib.stylix.colors.base08}"
                "#${config.lib.stylix.colors.base08}"
                "--accent-danger"
            ];
            ACCENT_NOTE = [
                "Note mode"
                "#${config.lib.stylix.colors.base0C}"
                "#${config.lib.stylix.colors.base0C}"
                "--accent-note"
            ];
            BORDER = [
                "Border"
                "#45475a"
                "#45475a"
                "--border"
            ];
            BORDER_FOCUS = [
                "Border (focused input)"
                "#${config.lib.stylix.colors.base0D}"
                "#${config.lib.stylix.colors.base0D}"
                "--border-focus"
            ];
            BORDER_STRONG = [
                "Border (strong)"
                "#585b70"
                "#585b70"
                "--border-strong"
            ];
            BORDER_SUBTLE = [
                "Border (subtle)"
                "#313244"
                "#313244"
                "--border-subtle"
            ];
            BUTTON_BG = [
                "Button background"
                "#313244"
                "#313244"
                "--button-bg"
            ];
            BUTTON_DISABLED = [
                "Button background (disabled)"
                "#313244"
                "#313244"
                "--button-disabled"
            ];
            BUTTON_HOVER = [
                "Button background (hover)"
                "#45475a"
                "#45475a"
                [
                    "--button-gradient-start"
                    "--button-gradient-end"
                ]
            ];
            BUTTON_HOVER_BORDER = [
                "Button border (hover)"
                "#585b70"
                "#585b70"
                "--button-hover-border"
            ];
            BUTTON_PRIMARY_BG = [
                "Button Primary Bg"
                "#2f67e1"
                "#2f67e1"
                "--button-primary-bg"
            ];
            BUTTON_PRIMARY_DISABLED = [
                "Button Primary Disabled"
                "#4484ed"
                "#4484ed"
                "--button-primary-disabled"
            ];
            BUTTON_PRIMARY_GRADIENT_END = [
                "Button Primary Gradient End"
                "#2544a8"
                "#2544a8"
                "--button-primary-gradient-end"
            ];
            BUTTON_PRIMARY_GRADIENT_START = [
                "Button Primary Gradient Start"
                "#2f67e1"
                "#2f67e1"
                "--button-primary-gradient-start"
            ];
            CANVAS = [
                "Background"
                "#${config.lib.stylix.colors.base00}"
                "#${config.lib.stylix.colors.base00}"
                [
                    "--canvas"
                    "--bs-body-bg"
                ]
            ];
            CANVAS_CODE = [
                "Code editor background"
                "#${config.lib.stylix.colors.base01}"
                "#${config.lib.stylix.colors.base01}"
                "--canvas-code"
            ];
            CANVAS_ELEVATED = [
                "Review"
                "#${config.lib.stylix.colors.base01}"
                "#${config.lib.stylix.colors.base01}"
                "--canvas-elevated"
            ];
            CANVAS_GLASS = [
                "Background (transparent text surface)"
                "#${config.lib.stylix.colors.base01}66"
                "#${config.lib.stylix.colors.base01}66"
                "--canvas-glass"
            ];
            CANVAS_INSET = [
                "Background (inset)"
                "#${config.lib.stylix.colors.base02}"
                "#${config.lib.stylix.colors.base02}"
                "--canvas-inset"
            ];
            CANVAS_OVERLAY = [
                "Background (menu & tooltip)"
                "#${config.lib.stylix.colors.base02}"
                "#${config.lib.stylix.colors.base02}"
                "--canvas-overlay"
            ];
            FG = [
                "Text"
                "#${config.lib.stylix.colors.base06}"
                "#${config.lib.stylix.colors.base06}"
                [
                    "--fg"
                    "--bs-body-color"
                ]
            ];
            FG_DISABLED = [
                "Text (disabled)"
                "#${config.lib.stylix.colors.base05}"
                "#${config.lib.stylix.colors.base05}"
                "--fg-disabled"
            ];
            FG_FAINT = [
                "Text (faint)"
                "#${config.lib.stylix.colors.base04}"
                "#${config.lib.stylix.colors.base04}"
                "--fg-faint"
            ];
            FG_LINK = [
                "Text (link)"
                "#${config.lib.stylix.colors.base0D}"
                "#${config.lib.stylix.colors.base0D}"
                "--fg-link"
            ];
            FG_SUBTLE = [
                "Text (subtle)"
                "#${config.lib.stylix.colors.base03}"
                "#${config.lib.stylix.colors.base03}"
                "--fg-subtle"
            ];
            FLAG_1 = [
                "Flag 1"
                "#${config.lib.stylix.colors.base08}"
                "#${config.lib.stylix.colors.base08}"
                "--flag-1"
            ];
            FLAG_2 = [
                "Flag 2"
                "#${config.lib.stylix.colors.base09}"
                "#${config.lib.stylix.colors.base09}"
                "--flag-2"
            ];
            FLAG_3 = [
                "Flag 3"
                "#${config.lib.stylix.colors.base0A}"
                "#${config.lib.stylix.colors.base0A}"
                "--flag-3"
            ];
            FLAG_4 = [
                "Flag 4"
                "#${config.lib.stylix.colors.base0B}"
                "#${config.lib.stylix.colors.base0B}"
                "--flag-4"
            ];
            FLAG_5 = [
                "Flag 5"
                "#${config.lib.stylix.colors.base0D}"
                "#${config.lib.stylix.colors.base0D}"
                "--flag-5"
            ];
            FLAG_6 = [
                "Flag 6"
                "#${config.lib.stylix.colors.base0C}"
                "#${config.lib.stylix.colors.base0C}"
                "--flag-6"
            ];
            FLAG_7 = [
                "Flag 7"
                "#c9cbff"
                "#c9cbff"
                "--flag-7"
            ];
            HIGHLIGHT_BG = [
                "Highlight background"
                "#${config.lib.stylix.colors.base0F}"
                "#${config.lib.stylix.colors.base0F}"
                "--highlight-bg"
            ];
            HIGHLIGHT_FG = [
                "Highlight text"
                "#${config.lib.stylix.colors.base0D}"
                "#${config.lib.stylix.colors.base0D}"
                "--highlight-fg"
            ];
            SCROLLBAR_BG = [
                "Scrollbar background"
                "#1e1e2e"
                "#1e1e2e"
                "--scrollbar-bg"
            ];
            SCROLLBAR_BG_ACTIVE = [
                "Scrollbar background (active)"
                "#313244"
                "#313244"
                "--scrollbar-bg-active"
            ];
            SCROLLBAR_BG_HOVER = [
                "Scrollbar background (hover)"
                "#${config.lib.stylix.colors.base00}"
                "#${config.lib.stylix.colors.base00}"
                "--scrollbar-bg-hover"
            ];
            SELECTED_BG = [
                "Selected Bg"
                "#313244"
                "#313244"
                "--selected-bg"
            ];
            SELECTED_FG = [
                "Selected Fg"
                "#${config.lib.stylix.colors.base0A}"
                "#${config.lib.stylix.colors.base0A}"
                "--selected-fg"
            ];
            SHADOW = [
                "Shadow"
                "#1e1e2e"
                "#1e1e2e"
                "--shadow"
            ];
            SHADOW_FOCUS = [
                "Shadow  =focused input)"
                "#${config.lib.stylix.colors.base0D}"
                "#${config.lib.stylix.colors.base0D}"
                "--shadow-focus"
            ];
            SHADOW_INSET = [
                "Shadow (inset)"
                "#11111b"
                "#11111b"
                "--shadow-inset"
            ];
            SHADOW_SUBTLE = [
                "Shadow (subtle)"
                "#181825"
                "#181825"
                "--shadow-subtle"
            ];
            STATE_BURIED = [
                "Buried"
                "#7f849c"
                "#7f849c"
                "--state-buried"
            ];
            STATE_LEARN = [
                "Learn"
                "#${config.lib.stylix.colors.base08}"
                "#${config.lib.stylix.colors.base08}"
                "--state-learn"
            ];
            STATE_MARKED = [
                "Marked"
                "#${config.lib.stylix.colors.base09}"
                "#${config.lib.stylix.colors.base09}"
                "--state-marked"
            ];
            STATE_NEW = [
                "New"
                "#${config.lib.stylix.colors.base0C}"
                "#${config.lib.stylix.colors.base0C}"
                "--state-new"
            ];
            STATE_REVIEW = [
                "Review"
                "#${config.lib.stylix.colors.base0D}"
                "#${config.lib.stylix.colors.base0D}"
                "--state-review"
            ];
            STATE_SUSPENDED = [
                "Suspended"
                "#${config.lib.stylix.colors.base06}"
                "#${config.lib.stylix.colors.base06}"
                "--state-suspended"
            ];
        };
            version = {
                major = 3;
                minor = 1;
            };
          };
      })
    ]))
  ];
}

1 Like

minor thing. The version = stuff is specific to recolor, so passfail2 doesn’t need it.

thank you for telling me, it’s fixed.