diff --git a/profiles/develop/default.nix b/profiles/develop/default.nix index 48694f1b..7cc089c5 100644 --- a/profiles/develop/default.nix +++ b/profiles/develop/default.nix @@ -2,11 +2,18 @@ { imports = [ ./zsh + ./kakoune ]; + environment.shellAliases = { + v = "XDG_CONFIG_HOME=/etc/xdg $EDITOR"; + }; + environment.sessionVariables = { LESS = "-iFJMRWX -z-4 -x4"; LESSOPEN = "|${pkgs.lesspipe}/bin/lesspipe.sh %s"; + EDITOR = "kak"; + VISUAL = "kak"; }; environment.systemPackages = with pkgs; [ diff --git a/profiles/develop/kakoune/default.nix b/profiles/develop/kakoune/default.nix new file mode 100644 index 00000000..52b9b44c --- /dev/null +++ b/profiles/develop/kakoune/default.nix @@ -0,0 +1,46 @@ +{ pkgs, ... }: +{ + environment.systemPackages = with pkgs; [ + cquery + kak-lsp + kakoune + kakoune-unwrapped + nixpkgs-fmt + python3Packages.python-language-server + rustup + ]; + + environment.etc = { + "xdg/kak/kakrc".source = ./kakrc; + "xdg/kak/autoload/plugins".source = ./plugins; + "xdg/kak/autoload/lint".source = ./lint; + "xdg/kak/autoload/lsp".source = ./lsp; + "xdg/kak/autoload/default".source = "${pkgs.kakoune-unwrapped}/share/kak/rc"; + }; + + nixpkgs.overlays = let + kak = self: super: { + kakoune = super.kakoune.override { + configure.plugins = with super.kakounePlugins; [ + (kak-fzf.override { fzf = super.skim; }) + kak-auto-pairs + kak-buffers + kak-powerline + ]; + }; + + kakoune-unwrapped = super.kakoune-unwrapped.overrideAttrs ( + o: rec { + version = "2019.12.10"; + src = super.fetchFromGitHub { + repo = "kakoune"; + owner = "mawww"; + rev = "v${version}"; + hash = "sha256-TnRQ73bIQGavXNp+wrKtYHgGem+R6JDWt333z2izYzE="; + }; + } + ); + }; + in + [ kak ]; +} diff --git a/profiles/develop/kakoune/kakrc b/profiles/develop/kakoune/kakrc new file mode 100644 index 00000000..22626b08 --- /dev/null +++ b/profiles/develop/kakoune/kakrc @@ -0,0 +1,99 @@ +hook global WinCreate ^[^*]+$ %{ add-highlighter window/ number-lines } + +# colorscheme +face global Information yellow,default +face global MenuBackground black,white +face global MenuForeground white,black +face global comment white+d +face global meta blue +addhl global/ column 80 SecondaryCursor + +# convert tabs to spaces and cleanup trailing whitespace on save +hook global BufWritePre ^[^*]+$ %{ + try %{ execute-keys -draft \%@s\h+$d } +} + +# useful mappings +map global normal ': delete-buffer' +map global normal ': write' +map global normal ': quit' +map global normal ': buffer-next' +map global normal ': buffer-previous' +map global -docstring "comment line" user c ': comment-line' +map global -docstring "comment block" user C ': comment-block' +map -docstring "format buffer" global user f ': format' + +# splits just like vim using tmux +define-command -params 0.. -file-completion \ + -docstring "split tmux pane vertically" split \ + %{ tmux-terminal-vertical kak -c %val{session} -e edit! %arg{@} } + +define-command -params 0.. -file-completion \ + -docstring "split tmux pane horizontally" vsplit \ + %{ tmux-terminal-horizontal kak -c %val{session} -e edit! %arg{@} } + +alias global sp split +alias global vs vsplit + +# jj to leave insert mode +hook global InsertChar j %{ try %{ + exec -draft hH jj d + exec +}} + +set global ui_options ncurses_assistant=none +set global tabstop 2 +set global indentwidth 2 + +hook global InsertCompletionShow .* %{ + try %{ + # this command temporarily removes cursors preceded by whitespace; + # if there are no cursors left, it raises an error, does not + # continue to execute the mapping commands, and the error is eaten + # by the `try` command so no warning appears. + execute-keys -draft 'h\h' + map window insert + map window insert + } +} +hook global InsertCompletionHide .* %{ + unmap window insert + unmap window insert +} + +try %{ require-module kak } +add-highlighter shared/kakrc/code/if_else regex \b(if|else)\b 0:keyword + +# create an if for conditional parsing +define-command -docstring "if [else [if ] ]: if statement that accepts shell-valid condition string" \ +if -params 2.. %{ evaluate-commands %sh{ + while [ true ]; do + condition="[ $1 ]" + if [ -n "$3" ] && [ "$3" != "else" ]; then + printf "%s\n" "fail %{if: unknown operator '$3'}" + elif [ $# -eq 3 ]; then + printf "%s\n" "fail %{if: wrong argument count}" + elif eval $condition; then + [ -n "${2##*&*}" ] && arg="$2" || arg="$(printf '%s' "$2" | sed 's/&/&&/g')" + printf "%s\n" "evaluate-commands %& $arg &" + elif [ $# -eq 4 ]; then + [ -n "${4##*&*}" ] && arg="$4" || arg="$(printf '%s' "$4" | sed 's/&/&&/g')" + printf "%s\n" "evaluate-commands %& $arg &" + elif [ $# -gt 4 ]; then + if [ "$4" = "if" ]; then + shift 4 + continue + else + printf "%s\n" "fail %{if: wrong argument count}" + fi + fi + exit + done +}} + +# show git diff on sidebar if it git repository +if %[ "$(command git status 2>/dev/null)" ] %{ + hook global WinCreate .* %{ git show-diff } + hook global BufWritePost .* %{ git show-diff } + hook global ModeChange insert:normal %{ git show-diff } +} diff --git a/profiles/develop/kakoune/lint/nix.kak b/profiles/develop/kakoune/lint/nix.kak new file mode 100644 index 00000000..59407b3b --- /dev/null +++ b/profiles/develop/kakoune/lint/nix.kak @@ -0,0 +1,20 @@ +hook -group lint global WinSetOption filetype=nix %{ + # remove '' for nix, annoying for string literals + set buffer auto_pairs ( ) { } [ ] '"' '"' ` ` + + set buffer lintcmd ' + run () { + nix-instantiate --parse $1 2>&1 >&- > /dev/null | + awk '' + {printf $NF ":" " "} + !($NF="") !($(NF-1)="") {sub(/, $/, "")}1 + '' + } && run \ + ' + lint-enable + set buffer formatcmd "nixpkgs-fmt" + hook buffer BufWritePre .* %{ + format + lint + } +} diff --git a/profiles/develop/kakoune/lsp/c.kak b/profiles/develop/kakoune/lsp/c.kak new file mode 100644 index 00000000..d080b63d --- /dev/null +++ b/profiles/develop/kakoune/lsp/c.kak @@ -0,0 +1,3 @@ +hook -group lsp global WinSetOption filetype=(c|cpp) %{ + lsp-enable-window +} diff --git a/profiles/develop/kakoune/lsp/common.kak b/profiles/develop/kakoune/lsp/common.kak new file mode 100644 index 00000000..79e1e126 --- /dev/null +++ b/profiles/develop/kakoune/lsp/common.kak @@ -0,0 +1,10 @@ +eval %sh{kak-lsp --kakoune -s $kak_session} +hook -group lsp global WinSetOption filetype=(elm|rust|c|cpp|python) %{ + lsp-auto-hover-enable + + # easily enter lsp mode + map -docstring "language-server mode" buffer user l ': enter-user-mode lsp' + + set buffer lsp_hover_anchor true + set buffer lsp_auto_highlight_references true +} diff --git a/profiles/develop/kakoune/lsp/elm.kak b/profiles/develop/kakoune/lsp/elm.kak new file mode 100644 index 00000000..43dad302 --- /dev/null +++ b/profiles/develop/kakoune/lsp/elm.kak @@ -0,0 +1,5 @@ +# elm formating is currently broken in els so use formatcmd as workaround +hook -group lsp global WinSetOption filetype=elm %{ + set buffer formatcmd "elm-format --stdin --yes --elm-version 0.19" + lsp-enable-window +} diff --git a/profiles/develop/kakoune/lsp/python.kak b/profiles/develop/kakoune/lsp/python.kak new file mode 100644 index 00000000..26b4e3b8 --- /dev/null +++ b/profiles/develop/kakoune/lsp/python.kak @@ -0,0 +1,3 @@ +hook -group lsp global WinSetOption filetype=python %{ + lsp-enable-window +} diff --git a/profiles/develop/kakoune/lsp/rust.kak b/profiles/develop/kakoune/lsp/rust.kak new file mode 100644 index 00000000..6c095bd9 --- /dev/null +++ b/profiles/develop/kakoune/lsp/rust.kak @@ -0,0 +1,10 @@ +hook -group lsp global WinSetOption filetype=rust %{ +# racer.kak conflicts with rls completion; keep before lsp-enable + racer-disable-autocomplete +# remove apostrophe from auto closing pairs; annoying for rust lifetimes + set buffer auto_pairs ( ) { } [ ] '"' '"' ` ` + + lsp-enable-window + + set buffer lsp_server_configuration rust.clippy_preference="on" +} diff --git a/profiles/develop/kakoune/plugins/auto-pairs.kak b/profiles/develop/kakoune/plugins/auto-pairs.kak new file mode 100644 index 00000000..e0a5d6ba --- /dev/null +++ b/profiles/develop/kakoune/plugins/auto-pairs.kak @@ -0,0 +1,6 @@ +hook global WinCreate .* %{ + auto-pairs-enable +} + +map global user s -docstring 'Surround' ': auto-pairs-surround ' +map global user S -docstring 'Surround++' ': auto-pairs-surround _ _ * *' diff --git a/profiles/develop/kakoune/plugins/buffer.kak b/profiles/develop/kakoune/plugins/buffer.kak new file mode 100644 index 00000000..fe1b4383 --- /dev/null +++ b/profiles/develop/kakoune/plugins/buffer.kak @@ -0,0 +1,4 @@ +hook global WinDisplay .* info-buffers + +map global user b ':enter-buffers-mode' -docstring 'buffers…' +map global user B ':enter-user-mode -lock buffers' -docstring 'buffers (lock)…' diff --git a/profiles/develop/kakoune/plugins/fzf.kak b/profiles/develop/kakoune/plugins/fzf.kak new file mode 100644 index 00000000..aa2be846 --- /dev/null +++ b/profiles/develop/kakoune/plugins/fzf.kak @@ -0,0 +1 @@ +map -docstring "fzf-mode" global normal ': fzf-mode' diff --git a/profiles/develop/kakoune/plugins/vertical-selection.kak b/profiles/develop/kakoune/plugins/vertical-selection.kak new file mode 100644 index 00000000..eeb68b3e --- /dev/null +++ b/profiles/develop/kakoune/plugins/vertical-selection.kak @@ -0,0 +1,3 @@ +map -docstring "vertical selection down" global user v ': vertical-selection-down' +map -docstring "vertical selection up" global user ': vertical-selection-up' +map -docstring "vertical selection both" global user V ': vertical-selection-up-and-down'