# Defines the kakrc. { # Feature flags clipboard ? false, typescript ? false, haskell ? false, clojure ? 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 '' + (lib.optionalString clipboard '' map global user y c map global user p !p ''); # Initialization code for IDE mode needed for every supported # language, and inlay diagnostics. ide-init = '' lsp-enable-window hook window ModeChange .*:.*:insert %{ lsp-inlay-diagnostics-disable window 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-previous-symbol' map global normal ': lsp-next-symbol' map global normal ': lsp-hover-next-symbol' map global normal ': lsp-hover-previous-symbol' 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} face global keyword rgb:${theme.cyan.normal} } ''); # 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:${theme.green.bright} face window meta keyword } ''); # Clojure-lsp has all the IDE features I use. clojure-config = (lib.optionalString clojure '' hook global WinSetOption filetype=clojure %{ ${ide-full} } ''); # 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:${theme.purple.normal} face global attribute keyword face global operator keyword face global keyword rgb:${theme.blue.bright} face global value string face global meta rgb:${theme.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 } hook global NormalIdle .* %{ lsp-highlight-references } hook global InsertMove .* %{ lsp-highlight-references } face global type rgb:${theme.blue.normal} face global trait rgb:${theme.purple.normal} face global macro rgb:${theme.green.bright} face global format rgb:${theme.orange.bright} face global attribute rgb:${theme.orange.bright} face global operator rgb:${theme.yellow.normal} face global function rgb:${theme.green.bright} face global keyword rgb:${theme.misc.blueGrey} face global variable white face global value white face global meta white face global alias rgb:${theme.orange.normal} face global enum type face global struct type face global union type face global lifetime rgb:${theme.pink.pastel} face global module rgb:ffffff } ''); in pkgs.writeTextFile (rec { name = "kakrc.kak"; destination = "/share/kak/autoload/${name}"; text = '' set global tabstop 4 set global indentwidth 4 eval %sh{ kak-lsp --kakoune -s $kak_session } add-highlighter global/ number-lines -separator ' │ ' -hlcursor 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 hook global WinSetOption filetype=markdown %{ hook window -group spellck BufReload .* spell hook window -group spellck NormalIdle .* spell hook window -group spellck InsertIdle .* spell hook -once -always window WinSetOption filetype=.* %{ remove-hooks window spellck } } ${keybinds} ${typescript-config} ${haskell-config} ${clojure-config} ${python-config} ${rust-config} ${nix-config} hook global KakBegin .* %{ cursorline colorscheme colors } ''; })