{ pkgs, ... }@all: with all;
{
  home = {
    packages = with pkgs; [
      # nixfmt-classic # nix formater
      # nil # nix language server
      # nixd # specified in nixd.nix
      gopls
      delve
      jdt-language-server
      lldb # debugger for llvm stuff
      yaml-language-server # yaml
      marksman # markdown
      vale-ls # style-checker lsp (needs vale)
      ltex-ls # Ltex (language tool)
      vscode-langservers-extracted
      bash-language-server
    ];
    sessionVariables = {
      EDITOR = "hx";
      VISUAL = "hx";
    };
  };
  programs.helix = {
    enable = true;
    defaultEditor = true;
    package = pkgs.unstable.helix;
    settings = {
      # theme = "base16_terminal";
      theme = "base16";
      editor = {
        scrolloff = 5;
        mouse = true;
        # default-yank-register = "\"";
        middle-click-paste = false;
        scroll-lines = 3;
        shell = ["sh" "-c"];
        line-number = "relative";
        cursorline = true;
        cursorcolumn = true;
        # continue-comments = false;
        auto-completion = true;
        # path-completion = true;
        auto-format = false;
        idle-timeout = 250;
        completion-timeout = 5;
        preview-completion-insert = true;
        completion-trigger-len = 1;
        auto-info = true;
        true-color = true; # is detected automatically if set to false 
        undercurl = false; # is detected automatically if set to false 
        rulers = [];
        bufferline = "always";
        color-modes = true;
        text-width = 120;
        workspace-lsp-roots = [];
        default-line-ending = "native";
        insert-final-newline = false;
        popup-border = "all"; 
        indent-heuristic = "hybrid";
        jump-label-alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        # clip-board-provider = # selected automatically
        # end-of-line-diagnostics = "hint";
        statusline = {
          left   = [ "mode"
            "spinner"
            "file-name"
            "read-only-indicator"
            "file-type"
            "version-control"
          ];
          center = [
            "position-percentage"
            "total-line-numbers"
            "register"
          ];
          right  = [
            "spinner"
            "diagnostics"
            "selections"
            "primary-selection-length"
            "register"
            "position"
            "file-encoding"
          ];
          # separator = " ";
          mode = {
            normal = "NORMAL";
            insert = "INSERT";
            select = "SELECT";
          };
        };
        lsp = {
          enable = true;
          display-messages = false;
          auto-signature-help = true;
          display-inlay-hints = true;
        };
        cursor-shape = {
          normal = "block";
          insert = "bar";
          select = "underline";
        };
        file-picker = {
          hidden = false; # Enables ignoring hidden files	
          follow-symlinks = true; # Follow symlinks instead of ignoring them
          deduplicate-links = true; # Ignore symlinks that point at files already shown in the picker
          parents = true; # Enables reading ignore files from parent directories
          ignore = true; # Enables reading .ignore files
          git-ignore = true; # Enables reading .gitignore files
          git-global = true; # Enables reading global .gitignore, whose path is specified in git's config: core.excludesfile option
          git-exclude = true; # Enables reading .git/info/exclude files
          # max-depth unset = ; # Set with an integer value for maximum depth to recurse
        };
        auto-pairs = {
          "(" = ")";
          "{" = "}";
          "[" = "]";
          "\"" = "\"";
          "`" = "`";
          "<" = ">";
          # "/* " = " */";
        };
        auto-save = {
          focus-lost = false;
          after-delay = {
            enable = false; 
            timeout = 3000;
          };
        };
        search = {
          smart-case = true;
          wrap-around = true;
        };
        whitespace = {
          render = {
            skip-levels = "none";
            space = "none";
            nbsp = "none";
            nnbsp = "none";
            tab = "none";
            newline = "none";
            tabpad = "none";
          };
          characters = {
            skip-levels = 1;
            space = "·";
            nbsp = "⍽";
            nnbsp = "␣";
            tab = "→";
            newline = "⏎";
            tabpad = "·";
          };
        };
        indent-guides = {
          render = true;
          character = "╎";
          skip-levels = 0;
        };
        gutters = [
          "diagnostics"
          "spacer"
          "line-numbers"
          "spacer"
          "diff"
        ];
          # line-numbers = {};
          # layout.minwidth = 3;
          # diagnostics = {};
          # diff = {};
          # spacer = {};
        soft-wrap = {
          enable = true;
          max-wrap = 20;
          max-indent-retain = 40;
          wrap-indicator = "↪";
          wrap-at-text-width = false;
        };
        smart-tab = {
          enable = false;
          supersede-menu = false;
        };
        inline-diagnostics = {
          cursor-line = "warning";
          other-lines = "disable";
          prefix-len = 1;
          # max-wrap = set above
          max-diagnostics = 20;
        };
      };
      keys = {
        normal = {
          "C-g" = [ ":new" ":insert-output lazygit" ":buffer-close!" ":redraw" ];
          "C-i" = [ ":pipe fgl" "toggle_comments" ];
          "A-`" = [ "no_op" ];
          "`"   = [ "no_op" ];
          "ö" = { "s" = [ "switch_case" ]; "u" = [ "switch_to_uppercase" ]; "l" = [ "switch_to_lowercase" ]; };
        };
        select = {
          "ö" = { "s" = [ "switch_case" ]; "u" = [ "switch_to_uppercase" ]; "l" = [ "switch_to_lowercase" ]; }; 
        };
      };
    };
    languages = {
      language = [
        {
          name = "nix";
          language-servers = [
            "nixd"
            # "llm"
          ]; 
        }
        {
          name = "latex";
          language-servers = [ "texlab" "language-tool" ]; 
        }
        {
          name = "markdown";
          # language-servers = [ "marksman" "style-check" "language-tool" ];
          language-servers = [ "language-tool" "marksman" ];
          file-types = [ "md" "MD" ];
          scope = "text.<name>";
        }
        {
          name = "python";
          language-servers = [ "pyright" "ruff" ];
          formatter = {
            command = "ruff";
            args = [
              "format"
              "--line-length"
              "120"
              "-"
            ];
          };
          debugger = {
            name = "debugpy";
            transport = "stdio";
            command = "python";
            args = [ "-m" "debugpy.adapter" ];
            templates = [{
              name = "source";
              request = "launch";
              completion = [{
                name = "entrypoint";
                completion = "filename";
                default = ".";
              }];
              args = {
                mode = "debug";
                program = "{0}";
              };
            }];
          };
        }
        {
          name = "go";
          language-servers = [ 
            "gopls"
            # "llm"
          ];
          # formatter = {
          #   command = "gofmt";
          # };
        }
      ];
      language-server = {
        "nixd" = {
          command = "nixd";
        };
        "style-check" = {
          command = lib.getExe pkgs.vale-ls; 
        };
        "language-tool" = {
          command = "${pkgs.ltex-ls}/bin/ltex-ls";
        };
        "ruff" = {
          command = "ruff-lsp";
          config.settings.args = [
            # Set line length
            "--line-length"
            "240"
            # Enable custom ruff rules
            # "--select" lib.concatStringsSep [ ]
          ];
        };
        "llm" = {
          command = lib.getExe pkgs.helix-gpt; 
          args = [
            "--handler"
            "ollama"
            "--ollamaModel"
            "codellama:7b"
          ];
        };
      };
    };
    themes = {
      base16 = with rice.color; {
        "attributes" = foreground; 
        "comment" = {
          fg = black.bright;
          modifiers = [ "italic" ];
        };
        "constant" = accent.bright; 
        "constant.character.escape" = special.bright;
        "constant.numeric" = foreground; 
        "constructor" = weird.base;
        "debug" = yellow.base;
        "diagnostic.modifiers" = [ "underline" ];
        "diff.delta" = blue.bright; 
        "diff.minus" = negative.bright; 
        "diff.plus" = positive.bright; 
        "error" = red.base; 
        "function" = secondary.bright; 
        "hint" = tertiary.bright;
        "info" = foreground; 
        "keyword" = special.base;
        "keyword.modifiers" = [ "italic" ];
        "label" = foreground;
        "namespace" = weird.bright;
        "operator" = foreground;
        "special" = special.base; 
        "string" = secondary.bright; 
        "type" = red.base; 
        "variable" = accent.base; 
        "variableother.member" = foreground; 
        "warning" = red.base; 

        "markup.heading" = accent.base; 
        "markup.bold" = {
          fg = tertiary.bright; 
          modifiers = [ "bold" ];
        };
        "italic" = {
          fg = secondary.bright;
          modifiers = [ "italic" ];
        };
        "markup.linktext" = accent.base; 
        "markup.linkurl" = {
          fg = tertiary.dark; 
          modifiers = [ "underlined" ];
        };
        "markup.list" = accent.bright; 
        "markup.quote" = weird.bright; 
        "markup.raw" = special.bright; 
        "markup.strikethrough".modifiers = [ "crossed_out" ];

        "diagnostic.hint".underline.style = "curl";
        "diagnostic.info".underline.style = "curl";
        "diagnostic.warning".underline.style = "curl";
        "diagnostic.error".underline.style = "curl";

        "ui.background" = { # general background of the editor window
          # bg = background;
        };
        "ui.bufferline" = { # the top line ("tab"-line)
          fg = accent.base;
          bg = black.base;
        };
        "ui.bufferline.active" = { # the active "tab"
          fg = background;
          bg = accent.base;
          modifiers = [ "bold" ];
        }; 
        "ui.cursor" = { # the cursor in Normal mode
          fg = foreground;
          modifiers = [ "reversed" ];
        };
        "ui.cursorline.primary" = { # the line on which the cursor is on
          bg = black.base;
        };
        "ui.cursor.match" = { # Matching bracket etc.
          bg = green.dark;
          modifiers = [ ];
        };
        "ui.gutter" = {
          bg = black.base;
        };
        "ui.help" = {
          fg = green.base;
          bg = black.base;
        };
        "ui.linenr" = {
          fg = white.dark;
          bg = black.base;
        };
        "ui.linenr.selected" = {
          fg = accent.bright;
          modifiers = [ "bold" ];
        };
        "ui.menu" = {
          fg = accent.base;
          bg = black.base;
        };
        "ui.menu.scroll" = {
          fg = yellow.dark;
          bg = background;
        };
        "ui.menu.selected" = {
          fg = red.base;
          bg = blue.dark;
        };
        "ui.popup" = {
          bg = black.base;
        };
        "ui.selection" = {
          bg = white.dark;
        };
        "ui.selection.primary" = {
          bg = black.bright;
        };
        "ui.statusline" = {
          fg = blue.bright;
          bg = black.base;
        };
        "ui.statusline.inactive" = {
          fg = red.bright;
          bg = red.dark;
        };
        "ui.statusline.insert" = {
          fg = green.bright;
          bg = green.dark;
        };
        "ui.statusline.normal" = {
          fg = yellow.bright;
          bg = yellow.dark;
        };
        "ui.statusline.select" = {
          fg = cyan.bright;
          bg = cyan.dark;
        };
        "ui.text" = foreground;
        "ui.text.focus" = accent.base;
        "ui.virtual.indent-guide" = {
          fg = black.bright;
        };
        "ui.virtual.inlay-hint" = {
          fg = background;
          bg = tertiary.dark;
        };
        "ui.virtual.ruler" = {
          bg = background;
        };
        "ui.virtual.jump-label" = {
          fg = special.base;
          underline = {
            style = "dotted";
          }; 
        };
        "ui.window" = {
          bg = black.base;
        };
      };
    };
  };
}
