{ config, lib, pkgs, ... }: let strPalette = with pkgs.rice; palette.toRgbShortHex colorPalette; packages = with pkgs; [ (pkgs.makeDesktopItem { name = "kakoune"; exec = "kak %U"; icon = "kakoune"; desktopName = "Kakoune"; comment = "Kakoune text editor"; terminal = true; categories = [ "Development" ]; }) ] ++ [ # editorconfig-core-c python3.pkgs.editorconfig ] ++ ( lib.optionals (pkgs.devEnvironment.enableCpp) [ clang-tools ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableData) [ yaml-language-server nodePackages.vscode-langservers-extracted ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableHtml) [ nodePackages.vscode-langservers-extracted ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableJavascript) [ flow ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableLatex) [ texlab ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableNix) [ rnix-lsp ] ) ++ ( with python3.pkgs; lib.optionals (pkgs.devEnvironment.enablePython) [ black # pyls-black pyls-flake8 pyls-isort # pyls-mypy python-lsp-server ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableRust) [ cargo cargo-watch clippy rust-analyzer rustc rustfmt ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableShell) [ nodePackages.bash-language-server ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableSpelling) [ aspell aspellDicts.en aspellDicts.en-computers aspellDicts.en-science aspellDicts.it ] ); plugins = with pkgs; [ kakounePlugins.prelude-kak kakounePlugins.kak-lsp kakounePlugins.auto-pairs-kak kakounePlugins.powerline-kak kakounePlugins.connect-kak ]; in { home.sessionVariables = { EDITOR = "kak"; VISUAL = "kak"; }; programs.bash.shellAliases = { k = "kak"; }; programs.zsh.shellAliases = { k = "kak"; }; home.packages = packages; 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 = with pkgs; [ { 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 = "${xclip}/bin/xclip -i -selection clipboard"; } { mode = "user"; docstring = "Format code with formatter"; key = "f"; effect = ":format"; } { mode = "user"; docstring = "Format code with LSP"; key = "F"; effect = ":lsp-formatting-sync"; } { mode = "user"; docstring = "Jump to definition"; key = "d"; effect = ":lsp-definition"; } { mode = "user"; docstring = "Rename object"; key = "r"; effect = ":lsp-rename-prompt"; } { 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 = "${xclip}/bin/xclip -selection clipboard -o"; } { mode = "user"; docstring = "Paste from clipboard (before)"; key = "p"; effect = "!${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"; } # { # mode = "normal"; # docstring = "Search"; # key = "/"; # effect = "/(?i)"; # } # { # mode = "normal"; # docstring = "Reverse search"; # key = ""; # effect = "(?i)"; # } ]; hooks = with pkgs; [ { 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" ]; } ] ++ ( lib.optionals (pkgs.devEnvironment.enableLatex) [ { name = "BufSetOption"; option = "filetype=latex"; commands = "set-option buffer formatcmd ${texlive.bin.latexindent}/bin/latexindent"; } ] ) ++ ( lib.optionals (pkgs.devEnvironment.enablePython) [ { name = "BufSetOption"; option = "filetype=python"; commands = "set-option buffer formatcmd '${python3.pkgs.black}/bin/black -'"; } ] ) ++ ( lib.optionals (pkgs.devEnvironment.enableData) [ { name = "BufSetOption"; option = "filetype=(markdown|html|json|yaml|css|scss|less)"; commands = "set-option buffer formatcmd ${nodePackages.prettier}/bin/prettier"; } ] ); # TODO add more formatters from https://github.com/mawww/kakoune/wiki/Format }; extraConfig = builtins.concatStringsSep "\n" [ "# Custom commands" "add-highlighter global/ regex \\h+$ 0:Error # Highlight trailing spaces" "eval %sh{kak-lsp --kakoune -s $kak_session}" "lsp-enable" '' def -hidden insert-c-n %{ try %{ lsp-snippets-select-next-placeholders exec 'd' } catch %{ exec -with-hooks '' } } '' "require-module powerline" "powerline-start" "require-module connect-broot" "require-module connect-lf" "require-module connect-rofi" ]; plugins = plugins; }; 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 = with pkgs; builtins.concatStringsSep "\n" ( [ '' snippet_support = false verbosity = 2 [server] timeout = 1800 # seconds = 30 minutes '' ] ++ ( lib.optional (pkgs.devEnvironment.enableCpp) '' [language.c_cpp] filetypes = ["c", "cpp"] roots = ["compile_commands.json", ".clangd"] command = "${clang-tools}/bin/clangd" offset_encoding = "utf-8" '' ) ++ ( lib.optional (pkgs.devEnvironment.enableData) '' [language.json] filetypes = ["json"] roots = ["package.json"] command = "${nodePackages.vscode-langservers-extracted}/bin/vscode-json-language-server" args = ["--stdio"] [language.yaml] filetypes = ["yaml"] roots = [".git"] command = "${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 '' ) ++ ( lib.optional (pkgs.devEnvironment.enableGo) '' [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" = [] '' ) ++ ( lib.optional (pkgs.devEnvironment.enableHtml) '' [language.html] filetypes = ["html"] roots = ["package.json"] command = "${nodePackages.vscode-langservers-extracted}/bin/vscode-html-language-server" args = ["--stdio"] [language.css] filetypes = ["css"] roots = ["package.json", ".git"] command = "${nodePackages.vscode-langservers-extracted}/bin/vscode-css-language-server" args = ["--stdio"] [language.less] filetypes = ["less"] roots = ["package.json", ".git"] command = "${nodePackages.vscode-langservers-extracted}/bin/vscode-css-language-server" args = ["--stdio"] [language.scss] filetypes = ["scss"] roots = ["package.json", ".git"] command = "${nodePackages.vscode-langservers-extracted}/bin/vscode-css-language-server" args = ["--stdio"] '' ) ++ ( lib.optional (pkgs.devEnvironment.enableJavascript) '' [language.javascript] filetypes = ["javascript"] roots = [".flowconfig"] command = "${flow}/bin/flow" args = ["lsp"] '' ) ++ ( lib.optional (pkgs.devEnvironment.enableLatex) '' [language.latex] filetypes = ["latex"] roots = [".git"] command = "${texlab}/bin/texlab" settings_section = "texlab" [language.latex.settings.texlab] # See https://github.com/latex-lsp/texlab/blob/master/src/options.rs # bibtexFormatter = "${texlab}/bin/texlab" '' ) ++ ( lib.optional (pkgs.devEnvironment.enableNix) '' [language.nix] filetypes = ["nix"] roots = ["flake.nix", "shell.nix", ".git"] command = "${rnix-lsp}/bin/rnix-lsp" '' ) ++ ( lib.optional (pkgs.devEnvironment.enablePython) '' [language.python] filetypes = ["python"] roots = ["requirements.txt", "setup.py", ".git", ".hg"] command = "${python3.pkgs.python-lsp-server}/bin/pylsp" 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"] '' ) ++ ( lib.optional (pkgs.devEnvironment.enableRust) '' [language.rust] filetypes = ["rust"] roots = ["Cargo.toml"] command = "${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 '' ) ++ ( lib.optional (pkgs.devEnvironment.enableShell) '' [language.bash] filetypes = ["sh"] roots = [".git", ".hg"] command = "${nodePackages.bash-language-server}/bin/bash-language-server" args = ["start"] '' ) ); }