{ pkgs, ... }:
{
  programs.kakoune = {
    enable = true;
    defaultEditor = true;
    plugins = with pkgs.kakounePlugins;
      [ kak-fzf byline-kak kakboard auto-pairs-kak ];
    config = {
      colorScheme = "tomorrow-night";
      numberLines = {
        enable = true;
        highlightCursor = true;
      };
      showMatching = true;
      tabStop = 2;
      indentWidth = 2;
      hooks = [
          {
            name = "WinCreate";
            commands = "kakboard-enable";
            option = ".*";
          }
          {
            name = "BufCreate";
            commands = "set buffer filetype typst";
            option = ".*\.typ";
          }
          # {
          #   # When the filetype=latex option is set in a buffer context (automatically), add a new hook to build the latex file on write
          #   name = "BufSetOption";
          #   option = "filetype=latex";
          #   commands = "hook buffer BufWritePost .* %{ texlab-build }";
          # }
          {
            name = "BufSetOption";
            option = "filetype=markdown";
            commands = "add-highlighter buffer/ wrap -word -indent -width 79";
          }
          {
            name = "BufSetOption";
            option = "filetype=latex";
            commands = "add-highlighter buffer/ wrap -word -indent -width 79";
          }
					{
            name = "BufSetOption";
            option = "filetype=markdown";
            commands = "hook buffer BufWritePost .* %{ echo %sh{ pandoc -o \"\${kak_buffile%.md}.pdf\" \"$kak_buffile\" 2>&1 } }";
          }
          {
            name = "BufCreate";
            option = ".*\.Rmd";
            commands = "hook buffer BufWritePost .* %{ nop %sh{ Rscript -e \"rmarkdown::render(\\\"$kak_buffile\\\", 'pdf_document')\" } }";
          }
          {
            name = "BufCreate";
            option = ".*\.qmd";
            commands = "hook buffer BufWritePost .* %{ echo %sh{ quarto render $kak_buffile --to pdf } }";
          }
      ];
      keyMappings = [
        # Define select all
        {
          key = "a";
          mode = "user";
          effect = "*%s<ret>";
          docstring = "Select all";
        }
      ];
    };
    extraConfig =
    ''
      # highlight trailing whitespace
      add-highlighter global/trailing-whitespace regex '\h+$' 0:Error

      # highlight FIXME/TODO/NOTE
      add-highlighter global/ regex \b(TODO|FIXME|NOTE)\b 0:default+rb

      # don't remove trailing indent
      set global disabled_hooks .*-trim-indent
      source ${pkgs.writeText "kakoune-divider.kak" (builtins.readFile ./kakoune/divider.kak)}
      set-option global divider_face LineNumbers
      divider-on 80

      # byline enables extending selection with x
      require-module byline

      eval %sh{kak-lsp --kakoune -s $kak_session}
      lsp-enable
    ''
    +
    ''
      map global user l ':enter-user-mode lsp<ret>' -docstring 'LSP mode'
      map global insert <tab> '<a-;>:try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks <lt>tab> }<ret>' -docstring 'Select next snippet placeholder'
      map global object a '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
      map global object <a-a> '<a-semicolon>lsp-object<ret>' -docstring 'LSP any symbol'
      map global object f '<a-semicolon>lsp-object Function Method<ret>' -docstring 'LSP function or method'
      map global object t '<a-semicolon>lsp-object Class Interface Struct<ret>' -docstring 'LSP class interface or struct'
      map global object d '<a-semicolon>lsp-diagnostic-object --include-warnings<ret>' -docstring 'LSP errors and warnings'
      map global object D '<a-semicolon>lsp-diagnostic-object<ret>' -docstring 'LSP errors'
    '' # LSP mappings
    +
    "";
  };

  home.packages = with pkgs; [ kak-lsp ];
  xdg.configFile."kak-lsp/kak-lsp.toml".source =
    ./kakoune/kak-lsp.toml;

  xdg.desktopEntries.kakoune = {
    name = "Kakoune";
    genericName = "Text Editor";
    comment = "Edit text files";
    icon = "kak";
    exec = "kak %F";
    terminal = true;
    mimeType = [
      "text/english"
      "text/plain"
      "text/x-makefile"
      "text/x-c++hdr"
      "text/x-c++src"
      "text/x-chdr"
      "text/x-csrc"
      "text/x-java"
      "text/x-moc"
      "text/x-pascal"
      "text/x-tcl"
      "text/x-tex"
      "application/x-shellscript"
      "text/x-c"
      "text/x-c++"
      "text/x-devicetree-source"
    ];
    categories = [ "Utility" "TextEditor" ];
  };
}
