# load plugin eval %sh{kak-lsp} # eval %sh{kak-lsp-diags} define-command -override -hidden lsp-do-send-async %{ # echo -debug ===BEGIN-LSP # echo -quoting shell -debug %reg{a} # echo -debug ===END-LSP echo -quoting shell -to-file %opt{lsp_fifo} %reg{a} echo -to-file %opt{lsp_fifo} ' ' # nop %sh{ notify-send "this runs!" } } define-command -override -hidden lsp-do-send-sync %{ nop %sh{ notify-send 'this runs' } unset-option buffer lsp_do_send_maybe_sync evaluate-commands %sh{ tmp=$(mktemp -q -d -t 'kak-lsp-sync.XXXXXX' 2>/dev/null || mktemp -q -d) pipe=${tmp}/fifo if ! mkfifo ${pipe}; then echo 'fail failed to create fifo' exit fi trap "rm -f ${pipe}; rmdir ${tmp} 2>/dev/null" EXIT INT QUIT printf >${kak_opt_lsp_fifo} "%s '%s' " \ "${kak_quoted_reg_a}" "${pipe}" cat ${pipe} } } # mappings map global user l ': enter-user-mode lsp' -docstring 'LSP mode' map global insert ':try lsp-snippets-select-next-placeholders catch %{ execute-keys -with-hooks tab> }' -docstring 'Select next snippet placeholder' map global object a 'lsp-object' -docstring 'LSP any symbol' map global object 'lsp-object' -docstring 'LSP any symbol' map global object f 'lsp-object Function Method' -docstring 'LSP function or method' map global object t 'lsp-object Class Interface Struct' -docstring 'LSP class interface or struct' map global object d 'lsp-diagnostic-object --include-warnings' -docstring 'LSP errors and warnings' map global object D 'lsp-diagnostic-object' -docstring 'LSP errors' # override the code actions icon in the modeline define-command -hidden -override lsp-show-code-actions -params 1.. %{ set-option buffer lsp_modeline_code_actions "" } define-command -hidden -override lsp-hide-code-actions %{ set-option buffer lsp_modeline_code_actions "" } # Server Config set-option global lsp_debug false # list of filetypes for which LSP will be activated in the window scope declare-option str-list lsp_filetypes python go rust bash fish c cpp typst markdown yaml json jsonc bash sh typescript javascript latex declare-option -hidden bool inlay_enabled false define-command -hidden inlay-on %{ lsp-inlay-hints-enable window set-option window inlay_enabled true } define-command -hidden inlay-off %{ lsp-inlay-hints-disable window set-option window inlay_enabled false } define-command -hidden inlay-toggle %{ evaluate-commands %sh{ if [ "$kak_opt_inlay_enabled" = "true" ]; then echo "inlay-off" else echo "inlay-on" fi } } declare-option -hidden bool inlay_diagnostics_enabled false define-command -hidden inlay-diagnostics-on %{ lsp-inlay-diagnostics-enable window set-option window inlay_diagnostics_enabled true } define-command -hidden inlay-diagnostics-off %{ lsp-inlay-diagnostics-disable window set-option window inlay_diagnostics_enabled false } define-command -hidden inlay-diagnostics-toggle %{ evaluate-commands %sh{ if [ "$kak_opt_inlay_diagnostics_enabled" = "true" ]; then echo "inlay-diagnostics-off" else echo "inlay-diagnostics-on" fi } } declare-option -hidden bool inline_diagnostics_enabled true define-command -hidden inline-diagnostics-on %{ lsp-inline-diagnostics-enable window set-option window inline_diagnostics_enabled true } define-command -hidden inline-diagnostics-off %{ lsp-inline-diagnostics-disable window set-option window inline_diagnostics_enabled false } define-command inline-diagnostics-toggle %{ evaluate-commands %sh{ if [ "$kak_opt_inline_diagnostics_enabled" = "true" ]; then echo "inline-diagnostics-off" else echo "inline-diagnostics-on" fi } } define-command -hidden lsp-filetype-hooks-update %{ try %{ remove-hooks global lsp-filetypes } # convert the str-list into regex of form (a|b|c|...) hook -group lsp-filetypes global WinSetOption %exp~filetype=%sh{ printf '%s\n' "($kak_opt_lsp_filetypes)" | sed 's/ /|/g' }~ %{ # commands to execute for lsp window settings lsp-enable-window inlay-on # only map to UI mode if that module is available map -docstring 'toggle inlay hints' window ui h ': inlay-toggle' map -docstring 'toggle inlay diagnostics' window ui d ': inlay-diagnostics-toggle' map -docstring 'toggle inline diagnostics' window ui e ': inline-diagnostics-toggle' trigger-user-hook lsp-enabled } } lsp-filetype-hooks-update hook global WinSetOption lsp_filetypes=.* lsp-filetype-hooks-update hook global BufSetOption lsp_filetypes=.* lsp-filetype-hooks-update hook global GlobalSetOption lsp_filetypes=.* lsp-filetype-hooks-update remove-hooks global lsp-filetype-python hook -group lsp-filetype-python global BufSetOption filetype=python %{ set-option buffer lsp_servers %{ [basedpyright-langserver] root_globs = ["requirements.txt", "setup.py", "pyproject.toml", "pyrightconfig.json", ".git", ".hg"] args = ["--stdio"] settings_section = "basedpyright" [basedpyright-langserver.settings.basedpyright.analysis] typeCheckingMode = "standard" inlayHints.genericTypes = true } } remove-hooks global lsp-filetype-latex hook -group lsp-filetype-latex global BufSetOption filetype=latex %{ set-option buffer lsp_servers %{ [ltex-ls-plus] root_globs = [".git", ".hg", "main.tex"] [ltex-ls-plus.settings.ltex] # TODO: write a script where the dictionary is a list of words # that's read from a file and then output in TOML format. # This way we can implement adding our own words to this list dynamically # dictionary = { "en-US" = ["builtin", "Fichtinger", "SonarAuth", "sexpenis" ], "en-CA" = ["more", "words"] } dictionary = { "en-US" = [] } [texlab] root_globs = [".git", ".hg"] [texlab.settings.texlab] # See https://github.com/latex-lsp/texlab/wiki/Configuration # # Preview configuration for zathura with SyncTeX search. # For other PDF viewers see https://github.com/latex-lsp/texlab/wiki/Previewing build.onSave = true forwardSearch.executable = "zathura" forwardSearch.args = [ "%p", "--synctex-forward", # Support texlab-forward-search "%l:1:%f", "--synctex-editor-command", # Inverse search: use Control+Left-Mouse-Button to jump to source. """ sh -c ' echo " evaluate-commands -client %%opt{texlab_client} %%{ evaluate-commands -try-client %%opt{jumpclient} %%{ edit -- %%{input} %%{line} } } " | kak -p $kak_session ' """, ] } require-module ltex-dictionary # ltex-dictionary-load # define-command -docstring 'Add selection to ltex-ls dictionary' ltex-add %{ # set-option buffer lsp_servers %sh{ # printf %s "$kak_opt_lsp_servers" | kak -f "$(printf 'dictionary =s\\[.*\\]]_a, "%s"' "$kak_selection")" # } # } declare-user-mode ltex map -docstring 'ltex mode' buffer user L ': enter-user-mode ltex' map -docstring 'PDF preview search' buffer ltex / ': texlab-forward-search' map -docstring 'add selection to ltex dictionary' buffer ltex s ': ltex-add' } remove-hooks global lsp-filetype-javascript hook -group lsp-filetype-javascript global BufSetOption filetype=(?:javascript|typescript) %{ set-option buffer lsp_servers %{ [typescript-language-server] root_globs = ["package.json", "tsconfig.json", "jsconfig.json", ".git", ".hg"] args = ["--stdio"] settings_section = "_" [typescript-language-server.settings._] # quotePreference = "double" # typescript.format.semicolons = "insert" } } # use our custom fish-lsp wrapper because it sets env vars hook -group lsp-filetype-fish global BufSetOption filetype=fish %{ set-option buffer lsp_servers %{ [fish-lsp] root_globs = [".git"] args = ["start"] command = "/home/fic/.config/kak/scripts/fish-lsp.fish" } } remove-hooks global lsp-filetype-markdown hook -group lsp-filetype-markdown global BufSetOption filetype=markdown %{ set-option buffer lsp_servers %{ [marksman] root_globs = [".marksman.toml", ".git"] args = ["server"] [harper-ls] root_globs = ["*"] args = ["--stdio"] command = "harper-ls" [harper-ls.settings.harper-ls.linters] LongSentences = false } } remove-hooks global lsp-filetype-typst hook -group lsp-filetype-typst global BufSetOption filetype=typst %{ set-option buffer lsp_servers %{ [tinymist] root_globs = [".git", ".hg"] args = ["lsp"] settings_section = "_" [tinymist.settings._] # See https://myriad-dreamin.github.io/tinymist/configurations.html exportPdf = "never" # exportPdf = "onDocumentHasTitle" formatterMode = "typstyle" previewFeature = "disable" [harper-ls] root_globs = ["*"] args = ["--stdio"] command = "harper-ls" [harper-ls.settings.harper-ls.linters] LongSentences = false } set-option -add buffer lsp_servers "formatterPrintWidth = %opt{autowrap_column}" } # # can be empty, global, or file # declare-option -hidden str harper_add "" # define-command -hidden harper-add -params 1 %{ # set-option window harper_add %arg{1} # lsp-code-actions -auto-single # } # # can override this to customize what's rendered in the menu # # Each code action is two args: its name, and the corresponding command # define-command -override -hidden lsp-perform-code-action -params 1.. -docstring "Called on :lsp-code-actions" %{ # evaluate-commands %sh{ # # harper specific filtering # if printf '%s' "$kak_opt_lsp_servers" | grep -q 'harper-ls'; then # if [ "$kak_opt_harper_add" = "global" ]; then # # filter and keep only # echo "echo -debug 'harper adding global'" # fi # fi # echo "echo -debug dumping $# code actions args:" # echo "echo -debug %arg{@}" # } # lsp-menu %arg{@} # } define-command lsp-inlay-hint-raw %{ evaluate-commands %sh{ tmp=$(mktemp -d) pipe="${tmp}/fifo" mkfifo "$pipe" || { echo "fail failed to create fifo"; exit 1; } trap "rm -f \"$pipe\"; rmdir \"$tmp\"" EXIT INT QUIT reg_a="$kak_session $kak_client true false $kak_buffile $kak_timestamp $kak_opt_filetype $kak_opt_lsp_language_id $kak_opt_lsp_servers $kak_opt_lsp_semantic_tokens $kak_opt_lsp_config $kak_opt_lsp_server_initialization_options map-end textDocument/inlayHint $kak_buf_line_count" printf "%s '%s' " "$reg_a" "$pipe" > "$kak_opt_lsp_fifo" raw=$(cat "$pipe") raw_escaped=$(printf %s "$raw" | sed "s/'/''/g") printf "set-register z '%s'\n" "$raw_escaped" } }