#
# Visual Studio Code + Dance (kakoune mode) Experiments
#
{
  pkgs,
  deprekages,
  lib,
  nil,
  ...
}:
let
  # Simple helper to de-stringify invalid tokens.
  author = name: pkgs.vscode-extensions.${name};

  # Forces a package to be marked as having linux-aarch64 support.
  forceArmLinux =
    pkg:
    pkg.overrideAttrs (prev: {
      meta.platforms = prev.meta.platforms ++ [ "aarch64-linux" ];
    });
in
{
  programs.vscode = {
    enable = true;

    package = pkgs.vscode.override {};

    #
    # Extensions to include with vscode.
    #
    extensions = with (pkgs.vscode-extensions // deprekages.vscode-extensions); [
      # Requires a qualified name due to the leading '1'.
      #(author "1Password").op-vscode

      # appearance
      oderwat.indent-rainbow
      brandonkirbyson.solarized-palenight

      # behavior
      usernamehw.errorlens
      asvetliakov.vscode-neovim
      editorconfig.editorconfig

      # general add-ons
      adpyke.codesnap
      ms-toolsai.jupyter
      ms-vscode.hexeditor
      ms-vscode.cmake-tools
      #ms-vscode.makefile-tools
      streetsidesoftware.code-spell-checker

      # nix
      jnoortheen.nix-ide
      arrterian.nix-env-selector
      brettm12345.nixfmt-vscode

      # rust
      fill-labs.dependi
#rust-lang.rust-analyzer
      njpwerner.autodocstring

      # python
#(forceArmLinux ms-python.python)

      # c/c++
      ms-vscode.cpptools

      # misc languages
      golang.go
      graphql.vscode-graphql
      graphql.vscode-graphql-syntax

      # accessibility / talon, for when our neuro condition is wonk
      pokey.talon
      pokey.cursorless
      pokey.parse-tree
      pokey.command-server

    ];

    #
    # Keybindings.
    #
    keybindings = [
      {
        key = "shift shift";
        command = "workbench.action.quickOpen";
      }
      {
        key = "alt alt";
        command = "workbench.action.quickOpen";
      }
      {
        key = "ctrl ctrl";
        command = "workbench.action.showCommands";
      }
    ];

    #
    # VSCode settings; runtime settings are immutable.
    #
    userSettings = {

      # Theming.
      "workbench.colorTheme" = lib.mkForce "Solarized-Palenight";

      # Default to formatting on save.
      "editor.formatOnSave" = true;

      # Curosrless: don't show decorations until asked.
      "cursorless.showOnStart" = false;

      # We have our own accessibility tech -- the VSCode option
      # mostly focuses around folks using screen readers.
      "editor.accessibilitySupport" = "off";

      #
      # Rust
      #
      "rust-analyzer.checkOnSave.command" = "clippy";

      #
      # Nix
      #
      "nix.enableLanguageServer" = true;
      "nix.serverPath" = "${nil.nil}/bin/nil";
      "nix.formatterPath" = "${pkgs.nixfmt-rfc-style}/bin/nixfmt";
      "[nix]"."editor.defaultFormatter" = "brettm12345.nixfmt-vscode";

      #
      # Neovim.
      #

      # Make it so the plugin is performant.
      "extensions.experimental.affinity" = {
        "asvetliakov.vscode-neovim" = 1;
      };

      #
      # Spell Checking
      #
      "cSpell.userWords" = [
        "serdes"
        "ktemkin"
        "kadkins"
        "deprekated"
        "unpoison"
        "poisonable"
        "hieratika"
      ];

    };

    #
    # For now, let Nix manage everything.
    #
    enableUpdateCheck = false;
    enableExtensionUpdateCheck = false;
    mutableExtensionsDir = false;

  };

}
