{ config, lib, pkgs, ... }: let kakCmd = "kak"; strPalette = with pkgs.rice; palette.toRgbShortHex colorPalette; rustPlugins = with pkgs; [ cargo cargo-watch clippy rust-analyzer rustc rustfmt ]; bashPlugins = with pkgs; [ nodePackages.bash-language-server ]; cppPlugins = with pkgs; [ clang-tools ]; latexPlugins = with pkgs; [ texlab ]; pythonPlugins = with pkgs.python38Packages; [ black pyls-black pyls-isort pyls-mypy python-language-server ]; javascriptPlugins = with pkgs; [ flow ]; nixPlugins = with pkgs; [ rnix-lsp ]; spellingPlugins = with pkgs; [ aspell aspellDicts.en aspellDicts.en-computers aspellDicts.en-science aspellDicts.it ]; dataFormats = with pkgs; [ yaml-language-server nodePackages.vscode-langservers-extracted ]; in { home.sessionVariables = { EDITOR = kakCmd; VISUAL = kakCmd; }; programs.bash.shellAliases = { k = kakCmd; }; programs.zsh.shellAliases = { k = kakCmd; }; programs.kakoune = { enable = true; config = { colorScheme = "nord"; tabStop = 2; indentWidth = 2; alignWithTabs = true; scrollOff = { lines = 5; columns = 3; }; ui = { setTitle = true; changeColors = true; enableMouse = true; }; wrapLines = { enable = true; word = true; }; numberLines = { enable = true; highlightCursor = true; }; keyMappings = [ { mode = "normal"; docstring = "Edit file"; key = ""; effect = ":edit"; } { mode = "user"; docstring = "Code actions"; key = "a"; effect = ":lsp-code-actions"; } { mode = "user"; docstring = "Comment block"; key = "b"; effect = ":comment-block"; } { mode = "user"; docstring = "Comment line"; key = "l"; effect = ":comment-line"; } { mode = "user"; docstring = "Copy to clipboard"; key = "y"; effect = "${pkgs.xclip}/bin/xclip -i -selection clipboard"; } { mode = "user"; docstring = "Format code"; key = "F"; effect = ":lsp-formatting-sync"; } { mode = "user"; docstring = "Jump to definition"; key = "d"; effect = ":lsp-definition"; } { mode = "user"; docstring = "Jump to type definition"; key = "t"; effect = ":lsp-type-definition"; } { mode = "user"; docstring = "List project diagnostics"; key = "i"; effect = ":lsp-diagnostics"; } { mode = "user"; docstring = "Paste from clipboard (after)"; key = "P"; effect = "${pkgs.xclip}/bin/xclip -selection clipboard -o"; } { mode = "user"; docstring = "Paste from clipboard (before)"; key = "p"; effect = "!${pkgs.xclip}/bin/xclip -selection clipboard -o"; } { mode = "user"; docstring = "Show hover info"; key = "q"; effect = ":lsp-hover"; } { mode = "user"; docstring = "Spellcheck English"; key = "S"; effect = ":spell en"; } { mode = "user"; docstring = "Spellcheck"; key = "s"; effect = ":spell "; } { mode = "normal"; docstring = "Try next snippet placeholder"; key = ""; effect = ": insert-c-n"; } ]; hooks = [ { name = "BufCreate"; option = ".*"; commands = "editorconfig-load"; } { name = "ModuleLoaded"; option = "auto-pairs"; commands = "auto-pairs-enable"; } { name = "ModuleLoaded"; option = "powerline"; commands = builtins.concatStringsSep "\n" [ "powerline-enable" ]; } { name = "WinSetOption"; option = "filetype=(rust|python|c|cpp|latex|javascript|go|nix)"; commands = builtins.concatStringsSep "\n" [ "lsp-enable-window" ]; } ]; }; extraConfig = builtins.concatStringsSep "\n" [ "# Custom commands" "define-command -docstring 'save and quit' x 'write-all; quit' # Save and quit with 'x'" "add-highlighter global/ regex \\h+$ 0:Error # Highlight trailing spaces" "eval %sh{kak-lsp --kakoune -s \$kak_session} # Start kak-lsp" # Kak-lsp snippet support '' def -hidden insert-c-n %{ try %{ lsp-snippets-select-next-placeholders exec 'd' } catch %{ exec -with-hooks '' } } '' "require-module prelude" #"require-module auto-pairs" "require-module connect" "require-module connect-broot" "require-module connect-lf" "require-module connect-rofi" "require-module powerline" ]; plugins = ( with pkgs; [ broot lf editorconfig-core-c # kakounePlugins.auto-pairs-kak kakounePlugins.kak-lsp kakounePlugins.powerline-kak kakounePlugins.prelude-kak kakounePlugins.connect-kak ] ) ++ rustPlugins ++ bashPlugins ++ cppPlugins ++ pythonPlugins ++ javascriptPlugins ++ latexPlugins ++ nixPlugins ++ spellingPlugins ++ dataFormats; }; xdg.configFile."kak/colors/nord.kak".text = with strPalette; '' set-face global value rgb:${normal.magenta},default set-face global type rgb:${bright.white},default set-face global identifier rgb:${normal.cyan},default set-face global string rgb:${normal.green},default set-face global error rgb:${normal.red},default set-face global keyword rgb:${normal.blue},default set-face global operator rgb:${normal.blue},default set-face global attribute rgb:${bright.blue},default set-face global comment rgb:${bright.blue},default set-face global meta rgb:${normal.yellow},default set-face global Default rgb:${normal.white},default set-face global PrimarySelection rgb:${normal.black},rgb:${dark.yellow} set-face global SecondarySelection rgb:${normal.black},rgb:${dark.white} set-face global PrimaryCursor rgb:${normal.black},rgb:${normal.yellow} set-face global SecondaryCursor rgb:${normal.black},rgb:${normal.white} set-face global MenuForeground rgb:${normal.white},rgb:${bright.black} set-face global MenuBackground default,rgb:${normal.black} set-face global MenuInfo default,rgb:${normal.black} set-face global Information rgb:${dark.black},rgb:${normal.cyan} set-face global StatusLine rgb:${normal.white},rgb:${normal.black} set-face global StatusLineMode rgb:${normal.blue},rgb:${normal.black} set-face global StatusLineInfo rgb:${normal.blue},rgb:${normal.black} set-face global StatusLineValue rgb:${normal.blue},rgb:${normal.black} set-face global StatusCursor rgb:${dark.black},rgb:${normal.yellow} set-face global Prompt rgb:${normal.cyan},rgb:${normal.black} set-face global BufferPadding default,default ''; xdg.configFile."kak-lsp/kak-lsp.toml".text = '' snippet_support = false verbosity = 2 [server] timeout = 1800 # seconds = 30 minutes [language.bash] filetypes = ["sh"] roots = [".git", ".hg"] command = "${pkgs.nodePackages.bash-language-server}/bin/bash-language-server" args = ["start"] [language.c_cpp] filetypes = ["c", "cpp"] roots = ["compile_commands.json", ".clangd"] command = "${pkgs.clang-tools}/bin/clangd" offset_encoding = "utf-8" # [language.crystal] # filetypes = ["crystal"] # roots = ["shard.yml"] # command = "scry" [language.css] filetypes = ["css"] roots = ["package.json", ".git"] command = "${pkgs.nodePackages.vscode-langservers-extracted}/bin/vscode-css-language-server" args = ["--stdio"] [language.less] filetypes = ["less"] roots = ["package.json", ".git"] command = "css-languageserver" args = ["--stdio"] [language.scss] filetypes = ["scss"] roots = ["package.json", ".git"] command = "${pkgs.nodePackages.vscode-langservers-extracted}/bin/vscode-css-language-server" args = ["--stdio"] # [language.d] # filetypes = ["d", "di"] # roots = [".git", "dub.sdl", "dub.json"] # command = "dls" # [language.dart] # # start shell to find path to dart analysis server source # filetypes = ["dart"] # roots = ["pubspec.yaml", ".git"] # command = "sh" # args = ["-c", "dart $(dirname $(command -v dart))/snapshots/analysis_server.dart.snapshot --lsp"] # [language.elixir] # filetypes = ["elixir"] # roots = ["mix.exs"] # command = "elixir-ls" # settings_section = "elixirLS" # [language.elixir.settings.elixirLS] # # See https://github.com/elixir-lsp/elixir-ls/blob/master/apps/language_server/lib/language_server/server.ex # # dialyzerEnable = true # [language.elm] # filetypes = ["elm"] # roots = ["elm.json"] # command = "elm-language-server" # args = ["--stdio"] # settings_section = "elmLS" # [language.elm.settings.elmLS] # # See https://github.com/elm-tooling/elm-language-server#server-settings # runtime = "node" # elmPath = "elm" # elmFormatPath = "elm-format" # elmTestPath = "elm-test" # [language.go] # filetypes = ["go"] # roots = ["Gopkg.toml", "go.mod", ".git", ".hg"] # command = "gopls" # offset_encoding = "utf-8" # settings_section = "gopls" # [language.go.settings.gopls] # # See https://github.com/golang/tools/blob/master/gopls/doc/settings.md # # "build.buildFlags" = [] # [language.haskell] # filetypes = ["haskell"] # roots = ["Setup.hs", "stack.yaml", "*.cabal"] # command = "haskell-language-server-wrapper" # args = ["--lsp"] # settings_section = "haskell" # [language.haskell.settings.haskell] # # See https://github.com/latex-lsp/texlab/blob/e1ee8495b0f54b4411a1ffacf787efa621d8f826/src/options.rs # # formattingProvider = "ormolu" [language.html] filetypes = ["html"] roots = ["package.json"] command = "${pkgs.nodePackages.vscode-langservers-extracted}/bin/vscode-html-language-server" args = ["--stdio"] # # Commented out by default because you still need to set the paths in the JDT # # Language Server arguments below before this can become a valid configuration. # [language.java] # filetypes = ["java"] # roots = [".git", "mvnw", "gradlew"] # command = "java" # args = [ # "-Declipse.application=org.eclipse.jdt.ls.core.id1", # "-Dosgi.bundles.defaultStartLevel=4", # "-Declipse.product=org.eclipse.jdt.ls.core.product", # "-Dlog.level=ALL", # "-Dfile.encoding=utf-8", # "--add-modules=ALL-SYSTEM", # "--add-opens", # "java.base/java.util=ALL-UNNAMED", # "--add-opens", # "java.base/java.lang=ALL-UNNAMED", # "-noverify", # "-Xmx1G", # "-jar", # "/path/to/eclipse.jdt.ls/repository/plugins/org.eclipse.equinox.launcher_1.6.100.v20201223-0822.jar", # "-configuration", # "/path/to/eclipse.jdt.ls/repository/config_linux", # "-data", # "/path/to/eclipse-workspace", # ] # [language.java.settings] # # See https://github.dev/eclipse/eclipse.jdt.ls # # "java.format.insertSpaces" = true [language.javascript] filetypes = ["javascript"] roots = [".flowconfig"] command = "${pkgs.flow}/bin/flow" args = ["lsp"] [language.json] filetypes = ["json"] roots = ["package.json"] command = "${pkgs.nodePackages.vscode-langservers-extracted}/bin/vscode-json-language-server" args = ["--stdio"] # # Requires Julia packages "LanguageServer", "StaticLint" and "SymbolServer" # [language.julia] # filetypes = ["julia"] # roots = ["Project.toml", ".git"] # command = "julia" # args = [ # "--startup-file=no", # "--history-file=no", # "-e", # """ # using LanguageServer; # using Pkg; # import StaticLint; # import SymbolServer; # import REPL; # env_path = dirname(Pkg.Types.Context().env.project_file); # server = LanguageServer.LanguageServerInstance(stdin, stdout, env_path, ""); # server.runlinter = true; # run(server); # """, # ] # [language.julia.settings] # # See https://github.com/julia-vscode/LanguageServer.jl/blob/master/src/requests/workspace.jl # # Format options. See https://github.com/julia-vscode/DocumentFormat.jl/blob/master/src/DocumentFormat.jl # # "julia.format.indent" = 4 # # Lint options. See https://github.com/julia-vscode/StaticLint.jl/blob/master/src/linting/checks.jl # # "julia.lint.call" = true # # Other options, see https://github.com/julia-vscode/LanguageServer.jl/blob/master/src/requests/workspace.jl # # "julia.lint.run" = "true" [language.latex] filetypes = ["latex"] roots = [".git"] command = "${pkgs.texlab}/bin/texlab" settings_section = "texlab" [language.latex.settings.texlab] # See https://github.com/latex-lsp/texlab/blob/master/src/options.rs bibtexFormatter = "texlab" # [language.lua] # filetypes = ["lua"] # roots = [".git"] # command = "lua-language-server" # [language.lua.settings.Lua] # # See https://github.com/sumneko/vscode-lua/blob/master/setting/schema.json # # diagnostics.enable = true # [language.nim] # filetypes = ["nim"] # roots = ["*.nimble", ".git"] # command = "nimlsp" [language.nix] filetypes = ["nix"] roots = ["flake.nix", "shell.nix", ".git"] command = "${pkgs.rnix-lsp}/bin/rnix-lsp" # [language.ocaml] # filetypes = ["ocaml"] # roots = ["Makefile", "opam", "*.opam", "dune"] # command = "ocamllsp" # [language.php] # filetypes = ["php"] # roots = [".htaccess", "composer.json"] # command = "intelephense" # args = ["--stdio"] # settings_section = "intelephense" # [language.php.settings] # intelephense.storagePath = "/tmp/intelephense" [language.python] filetypes = ["python"] roots = ["requirements.txt", "setup.py", ".git", ".hg"] command = "${pkgs.python-language-server}/bin/python-language-server" offset_encoding = "utf-8" [language.python.settings] # See https://github.com/palantir/python-language-server#configuration # and https://github.com/palantir/python-language-server/blob/develop/vscode-client/package.json # "pyls.configurationSources" = ["flake8"] # [language.reason] # filetypes = ["reason"] # roots = ["package.json", "Makefile", ".git", ".hg"] # command = "ocamllsp" # [language.ruby] # filetypes = ["ruby"] # roots = ["Gemfile"] # command = "solargraph" # args = ["stdio"] # [language.ruby.settings] # # See https://github.com/castwide/solargraph/blob/master/lib/solargraph/language_server/host.rb # # "solargraph.completion" = true # [language.rust] # filetypes = ["rust"] # roots = ["Cargo.toml"] # command = "sh" # args = [ # "-c", # """ # if path=$(rustup which rls 2>/dev/null); then # "$path" # else # rls # fi # """, # ] # [language.rust.settings.rust] # # See https://github.com/rust-lang/rls#configuration # # features = [] [language.rust] filetypes = ["rust"] roots = ["Cargo.toml"] command = "${pkgs.rust-analyzer}/bin/rust-analyzer" settings_section = "rust-analyzer" [language.rust.settings.rust-analyzer] hoverActions.enable = false # kak-lsp doesn't support this at the moment # cargo.features = [] # See https://rust-analyzer.github.io/manual.html#configuration # If you get 'unresolved proc macro' warnings, you have two options # 1. The safe choice is two disable the warning: diagnostics.disabled = ["unresolved-proc-macro"] # 2. Or you can opt-in for proc macro support procMacro.enable = true cargo.loadOutDirsFromCheck = true # See https://github.com/rust-analyzer/rust-analyzer/issues/6448 # [language.terraform] # filetypes = ["terraform"] # roots = ["*.tf"] # command = "terraform-ls" # args = ["serve"] # [language.terraform.settings.terraform-ls] # # See https://github.com/hashicorp/terraform-ls/blob/main/docs/SETTINGS.md # # rootModulePaths = [] [language.yaml] filetypes = ["yaml"] roots = [".git"] command = "${pkgs.yaml-language-server}/bin/yaml-language-server" args = ["--stdio"] [language.yaml.settings] # See https://github.com/redhat-developer/yaml-language-server#language-server-settings # Defaults are at https://github.com/redhat-developer/yaml-language-server/blob/master/src/yamlSettings.ts yaml.format.enable = true # [language.zig] # filetypes = ["zig"] # roots = ["build.zig"] # command = "zls" # Semantic tokens support # See https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_semanticTokens # for the default list of tokens and modifiers. # However, many language servers implement their own values. # Make sure to check the output of `lsp-capabilities` and each server's documentation and source code as well. # Examples: # - TypeScript: https://github.com/microsoft/vscode-languageserver-node/blob/2645fb54ea1e764aff71dee0ecc8aceff3aabf56/client/src/common/semanticTokens.ts#L58 # - Rust Analyzer: https://github.com/rust-analyzer/rust-analyzer/blob/f6da603c7fe56c19a275dc7bab1f30fe1ad39707/crates/ide/src/syntax_highlighting.rs#L42 [[semantic_tokens]] token = "comment" face = "documentation" modifiers = ["documentation"] [[semantic_tokens]] token = "comment" face = "comment" [[semantic_tokens]] token = "function" face = "function" [[semantic_tokens]] token = "keyword" face = "keyword" [[semantic_tokens]] token = "namespace" face = "module" [[semantic_tokens]] token = "operator" face = "operator" [[semantic_tokens]] token = "string" face = "string" [[semantic_tokens]] token = "type" face = "type" [[semantic_tokens]] token = "variable" face = "default+d" modifiers = ["readonly"] [[semantic_tokens]] token = "variable" face = "default+d" modifiers = ["constant"] [[semantic_tokens]] token = "variable" face = "variable" ''; xdg.dataFile."applications/kakoune.desktop".source = let desktopItem = pkgs.makeDesktopItem { name = "kakoune"; type = "Application"; exec = "${kakCmd} %U"; icon = "kakoune"; desktopName = "Kakoune"; comment = "Kakoune text editor"; terminal = true; categories = "Development;Office;"; mimeType = "text/plain;text/*"; }; in builtins.toPath "${desktopItem}/share/applications/kakoune.desktop"; }