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

let inherit (lib.nix2lua) call; in
{
  fn.lspconfig-eslint-on-attach = {
    args = [ "client" "bufnr" ];
    content = { bufnr, ... }: {
      vim.augroup.eslint-fix = {
        event = "BufWritePre";
        buffer = bufnr;
        command = "silent! EslintFixAll";
      };
    };
  };

  plugins.language-server.lspconfig.serverSettings = {
    # nix
    nil_ls = { };
    # rust
    rust_analyzer = {
      settings.rust-analyzer = {
        "server.path" = "rust-analyzer";
        "updates.prompt" = false;
        "updates.checkOnStartup" = false;
        "checkOnSave.enable" = true;
        "checkOnSave.command" = "clippy";
        "cargo.autoreload" = true;
      };
    };
    # linter for javascript, typescript, vue
    eslint = {
      on_attach = config.fn.lspconfig-eslint-on-attach.lambda;
      flags = {
        allow_incremental_sync = false;
        debounce_text_changes = 1000;
      };
    };
    # vue
    volar = {
      init_options = {
        typescript.tsdk = "./node_modules/typescript/lib";
      };
    };
    # python
    pylsp = { };
    # typescript, javascript
    denols = {
      root_dir = call "${config.plugin.nvim-lspconfig.varName}.util.root_pattern" [ "deno.json" "deno.jsonc" ];
    };
    # java
    jdtls = {
      cmd = [
        "${pkgs.jdt-language-server}/bin/jdtls"
        "--jvm-arg=-javaagent:${pkgs.lombok.out}/share/java/lombok.jar"
        "--jvm-arg=-Xbootclasspath/a:${pkgs.lombok.out}/share/java/lombok.jar"
      ];
    };
    # json
    jsonls = { };
    # css, scss, less
    cssls = { };
    css_variables = {
      lookupFiles = [
        "**/*.scss"
        "**/*.less"
        "**/*.css"
      ];
    };
    # Grammar/Spell Checker
    ltex = {
      language = "en-US";
      languageToolHttpServerUri = "http://localhost:8081";
    };
    # erlang
    erlangls = {
      cmd = [ "${lib.getExe pkgs.erlang-ls}" ];
    };
  };

  plugins.language-server.typescript-tools = {
    enable = true;
    serverSettings = {
      filetypes = [ "javascript" "javascriptreact" "typescript" "typescriptreact" "vue" ];
      settings = {
        tsserver_max_memory = "auto";
        tsserver_plugins = [ "@vue/typescript-plugin" ];
      };
    };
  };

  plugin.lsp_signature-nvim = {
    enable = true;
    name = "lsp_signature";
    setupSettings = {
      floating_window = false;
      hint_enable = true;
      hint_prefix = {
        above = "↙ ";
        current = "← ";
        below = "↖ ";
      };
    };
  };
}