# Defines the kakrc. { # Feature flags typescript ? false, haskell ? false, python ? false, rust ? false, nix ? true, # Color theme theme, # Build tools pkgs, lib, }: let keybinds = '' map global insert :buffer-next map global normal :buffer-next ''; # Initialization code for IDE mode needed for every supported # language, and inlay diagnostics. ide-init = '' eval %sh{ kak-lsp --kakoune -s $kak_session } lsp-enable-window lsp-inlay-diagnostics-enable window hook window ModeChange .*:.*:insert %{ remove-highlighter window/lsp_diagnostics } hook window ModeChange .*:insert:normal %{ lsp-inlay-diagnostics-enable window } ''; # Implies `ide-init`. Adds code actions and hover. ide-core = '' ${ide-init} map buffer normal ': lsp-code-actions' map buffer normal ': lsp-hover' ''; # Implies `ide-core`, which implies `ide-init`. ide-full = '' ${ide-core} hook window -group semtok BufReload .* lsp-semantic-tokens hook window -group semtok NormalIdle .* lsp-semantic-tokens hook window -group semtok InsertIdle .* lsp-semantic-tokens hook -once -always window WinSetOption filetype=.* %{ remove-hooks window semtok } map global normal ': lsp-next-function' map global normal ': lsp-previous-function' map global normal ': lsp-previous-location *goto*' map global normal ': lsp-next-location *goto*' ''; in # Nix hacking-related configuration. Nix has a very weak language # server, and it basically only supports `ide-init` (for completions). let nix-config = (lib.optionalString nix '' hook global WinSetOption filetype=nix %{ ${ide-init} } ''); # Sometimes work requires me to touch the frontend. Ew. `ide-core` # suffices here. typescript-config = (lib.optionalString typescript '' hook global WinSetOption filetype=(javascript|typescript) %{ ${ide-core} } ''); # Python-related config. Python does not support more features than # those in `ide-core`. python-config = (lib.optionalString python '' hook global WinSetOption filetype=python %{ ${ide-core} face window keyword rgb:${green.bright} face window meta keyword } ''); # Haskell development. Haskell has a language server with # the features in `ide-full`. haskell-config = (lib.optionalString haskell '' hook global WinSetOption filetype=haskell %{ ${ide-full} set-option buffer tabstop 2 face global variable rgb:${purple.normal} face global attribute keyword face global operator keyword face global keyword rgb:${blue.bright} face global value string face global meta rgb:${pink.normal} } ''); # Rust development. Rust's language servers all support the # `ide-full` features. rust-config = (lib.optionalString rust '' hook global WinSetOption filetype=rust %{ ${ide-full} hook global -group yeet ModuleLoaded rust %{ # Override the Rust highlighting with semantic # tokens supplied by the LSP client remove-hooks global rust-highlight remove-highlighter shared/rust # Request tokens lsp-semantic-tokens # Self-destruct this hook (it should only run once) remove-hooks global yeet } } ''); in pkgs.writeTextFile (rec { name = "kakrc.kak"; destination = "/share/kak/autoload/${name}"; text = with theme; '' add-highlighter global/ number-lines -separator ' │ ' -hlcursor set global tabstop 4 face global InlayHint rgb:828282 face global InlayDiagnosticWarning rgb:a39e31+f face global InlayDiagnosticError rgb:ad494f+f face global InlayDiagnosticHint rgb:4d965a+f face global InlayDiagnosticInfo rgb:4d965a+f '' ++ keybinds ++ typescript-config ++ haskell-config ++ python-config ++ rust-config ++ nix-config; })