Nix "distribution" of kakoune?

Hello, I’m sure some of you are using nix, and I’m guessing you’ve put together a bunch of config. Does anyone have good configs to share?

There’s already the home-manager module but it’s quite bare bones so far as I’m concerned. What I’m looking for is a full-blown kak-lsp + formatcmd + tree-sitter (which has this: GitHub - igor-ramazanov/kak-tree-sitter-helix: Generate kak-tree-sitter grammars, queries and themes using Helix. that I’m trying out).

Here’s what I’m envisioning:

programs.kakoune = {
  enable = true;
  languages = {
   nix.enable = true;
   typescript.enable = true;
   typescript.lsp.enable = true;
   typescript.tree-sitter.enable = true;
   typescript.lint.enable = true;
   typescript.format.enable = true;
   typescript.format.package = "biome"; # would configure 'formatcmd'
  };
  autopairs.enable = true;
  autopairs.package = pkgs.one-of-the-autopairs-plugins;
};

You get the gist of it, that’s just a random example. Just anything to speed up the initial setup

Is there any interest from anyone in partaking such a thing (using/contributing)? I’m considering starting off a flake but my nix-fu is very low, so I’m not looking to start complicating my config for zero users.

If not a “nix” distribution, I didn’t find any “distributions” with a quick google search. I haven’t used kakoune in a couple of years, but am looking to try again

1 Like

Talking to myself here, but I think I am right on this. I’ve seen a few nix configs for kakoune already, and I believe a good bootstrapped config isn’t impossible.

I’ve only done thought-work and drive-by research toward it for now, though. There’s lots of inspiration in nix configs on github, in people’s dotfiles. E.g.

Here’s my current kakoune.nix, it ain’t pretty but maybe it’ll get someone a running start. I was hoping to one day extract all the pieces into options that could be turned on/off, kakoune.language.clojure.formatter.enable = true; or something.

kakoune.nix (as part of home-manager)
{
  config,
  lib,
  pkgs,
  ...
}:
{
  home.packages = [
    (pkgs.rustPlatform.buildRustPackage {
      pname = "kakoune-lsp";
      src = pkgs.fetchFromGitHub {
        owner = "kakoune-lsp";
        repo = "kakoune-lsp";
        rev = "d11fb25fa20ab121c816ddcd8fa5f35ee170cee7";
        sha256 = "sha256-NYDNUsvlphKdrqVLel9U+5PlBsGtyv+KPUOCTj3t1xo=";
      };
      version = "git-2024-10-27";
      cargoHash = "sha256-CRgKtDIxu6AZ0+M2N9wx/Ar0Kn1zjBGa0dLpVgHud5Q=";
    })
    # pkgs.kakoune-lsp
    pkgs.editorconfig-core-c
    pkgs.bash-language-server
  ];

  programs.kak-tree-sitter-helix.enable = true;

  programs.kakoune = {
    enable = true;
    defaultEditor = true;
    extraConfig = builtins.readFile ./kakrc.kak;
    package = pkgs.kakoune-unwrapped.overrideAttrs {
      src = pkgs.fetchFromGitHub {
        owner = "mawww";
        repo = "kakoune";
        rev = "b96e500ddb27f78f2478e69836d6502d4fdbe9c0";
        sha256 = "sha256-VsKpvWUFyxlbGh50FRegIpLrnglNCZi8RZTZ9RFDdPc=";
      };
      # Update lsp too.
      version = "git-2024-10-27";
    };
    plugins =
      let
        exe = lib.getExe;
        writePlugin =
          { pname, text }:
          pkgs.writeTextFile (rec {
            inherit text;
            name = "${pname}.kak";
            destination = "/share/kak/autoload/${name}";
          });
        sudo-write = pkgs.kakouneUtils.buildKakounePluginFrom2Nix {
          pname = "sudo-write";
          version = "v2024-08-23";
          src = pkgs.fetchFromGitHub {
            owner = "occivink";
            repo = "kakoune-sudo-write";
            rev = "ec0d6d26ceaadd93d6824630ba587b31e442214d";
            sha256 = "sha256-O+yw8upyYnQThDoWKnFbjrjthPTCm6EaBUoJNqpUPLA=";
          };
          meta.homepage = "https://github.com/occivink/kakoune-sudo-write/";
        };
        luar = pkgs.kakouneUtils.buildKakounePluginFrom2Nix {
          pname = "luar";
          version = "v2024-10-29";
          src = pkgs.fetchFromGitHub {
            owner = "gustavo-hms";
            repo = "luar";
            rev = "2f430316f8fc4d35db6c93165e2e77dc9f3d0450";
            sha256 = "sha256-vHn/V3sfzaxaxF8OpA5jPEuPstOVwOiQrogdSGtT6X4=";
          };
        };
        peneira = pkgs.kakouneUtils.buildKakounePluginFrom2Nix {
          pname = "peneira";
          version = "v2024-10-29";
          src = pkgs.fetchFromGitHub {
            owner = "gustavo-hms";
            repo = "peneira";
            rev = "cd47a790f3cfce9e9dfeb7a1c4ed85433c906158";
            sha256 = "sha256-sEyxtNu1VEsU7Txi02ZVJirwYL7GKBh2VI7SbyVht6c=";
          };
          #patches = [
          # I have a change here to fix a crash bc I don't use number-lines.
          #  ./peneira.patch
          #];
        };
      in
      [
        (pkgs.writeTextFile (rec {
          text =
            let
              themeFile = config.lib.stylix.colors {
                template = ./colors/my-termcolors.kak;
                extension = ".kak";
              };
            in
            builtins.readFile themeFile;
          name = "my-termcolors.kak";
          destination = "/share/kak/colors/${name}";
        }))
        (writePlugin ({
          pname = "kak-tree-sitter";
          # https://github.com/igor-ramazanov/kak-tree-sitter-helix
          text = ''
            try %{ evaluate-commands %sh{ kak-tree-sitter -dks --init "$kak_session" }}
          '';
        }))
        (writePlugin ({
          pname = "formatter";
          text = ''
            define-command -hidden formatter-lsp-or-format %{
              try %{ lsp-formatting-sync } catch %{ format }
            }
            define-command -hidden -params 3 formatter-hook-filetype %{
              hook -group "%arg{1}-formatter-%arg{2}" window "%arg{2}" .* "%arg{3}"
              hook -once -always window WinSetOption filetype=.* %{ remove-hooks window "%arg{1}-formatter-%arg{2}" }
            }

            # Nix
            hook -group formatter-nix global WinSetOption filetype=nix %{
              set-option buffer formatcmd 'nix fmt -- -'
              # formatter-hook-filetype nix BufWritePre format-buffer
            }

            # Clj
            hook -group formatter-clj global WinSetOption filetype=clojure %{
              set-option buffer formatcmd '${exe pkgs.cljfmt} fix -'
              formatter-hook-filetype nix BufWritePre formatter-lsp-or-format
            }

            # Shell
            hook -group formatter-sh global WinSetOption filetype=(sh|shell|bash|zsh) %{
              set-option buffer formatcmd '${exe pkgs.shfmt} -'
              set-option buffer lintcmd '${exe pkgs.shellcheck} -fgcc -Cnever'
              formatter-hook-filetype nix BufWritePre formatter-lsp-or-format
              formatter-hook-filetype nix BufWritePost lint-buffer
            }
          '';
        }))
        (writePlugin ({
          pname = "kakoune-lsp";
          text = ''
            eval %sh{kak-lsp --kakoune --session "$kak_session"}
            lsp-enable
            lsp-inlay-hints-enable global
            # lsp-inlay-diagnostics-enable global
            lsp-auto-signature-help-enable
            hook global -group semantic-tokens BufReload .* lsp-semantic-tokens
            hook global -group semantic-tokens NormalIdle .* lsp-semantic-tokens
            hook global -group semantic-tokens InsertIdle .* lsp-semantic-tokens
            set-option global lsp_hover_anchor true
            set-option global lsp_auto_highlight_references true
            set-option global lsp_hover_max_lines 50

            # define-command lsp-restart -docstring "Restart lsp session" %{ lsp-stop; lsp-start }
          '';
        }))
        sudo-write
        luar
        peneira
        (writePlugin ({
          pname = "peneira-on";
          text = ''
            hook -once global KakBegin .* %{
              set-option global luar_interpreter ${lib.getExe' pkgs.lua "lua"}
              require-module luar
              require-module peneira
            }
          '';
        }))
        # (pkgs.kakounePlugins.rep.overrideAttrs {
        #   src = pkgs.fetchFromGitHub {
        #     owner = "eraserhd";
        #     repo = "rep";
        #     rev = "1b5321ef5628270cb391fc7dd3c19259f5931c03";
        #     sha256 = "sha256-4TXNHN2ytFx4jJZe/TLy1dQcuD1twnDLzsXkGzsxboc=";
        #   };
        #   version = "git";
        # })
        # pkgs.kakounePlugins.auto-pairs-kak
        # (writePlugin ({
        #   pname = "auto-pairs";
        #   text = ''
        #     enable-auto-pairs
        #   '';
        # }))
        # pkgs.kakounePlugins.active-window-kak
      ];

  };
}

That’s a nice idea. Something akin to GitHub - nix-community/nixvim: Configure Neovim with Nix! [maintainers=@GaetanLepage, @traxys, @mattsturgeon, @khaneliman] or Neovim Flake by Gabriel Volpe.

The existing home-manager’s module is nice, but fairly low-level.

1 Like

Yes exactly. Setting up LSPs/formatters/linters/tree-sitter would be a huge win, and it could give ez access to all kinds of plugins with a <plugin>.enable = true; config, and that’s as nice as it gets.