Rust-Kak lsp: LSP client. Implemented in Rust and supports rls out of the box.

Kakoune Language Server Protocol Client

kak-lsp is a Language Server Protocol client for Kakoune implemented in Rust.

Installation

Note
kak-lsp.toml destination in all described installation methods is just an example. Also, kak-lsp doesn’t read the configuration file from the current working directory or binary’s dir by default. Please consult Configuring kak-lsp to figure out where does kak-lsp expect kak-lsp.toml to be in your environment and how to specify a custom path to it. However, if you don’t need to change configuration then feel free to skip copying it anywhere as the default configuration is embedded into kak-lsp binary.

Pre-built binaries

MacOS

Homebrew
brew install ul/kak-lsp/kak-lsp
Manual
curl -O -L https://github.com/ul/kak-lsp/releases/download/v8.0.0/kak-lsp-v8.0.0-x86_64-apple-darwin.tar.gz
tar xzvf kak-lsp-v8.0.0-x86_64-apple-darwin.tar.gz

# replace `~/.local/bin/` with something on your `$PATH`
mv kak-lsp ~/.local/bin/

mkdir -p ~/.config/kak-lsp
mv kak-lsp.toml ~/.config/kak-lsp/

Linux

Package managers
  • Arch Linux: pacman -S kak-lsp or AUR/kak-lsp-git

  • Void Linux: xbps-install -S kak-lsp

  • Fedora Copr: sudo dnf copr enable atim/kakoune -y && sudo dnf install kak-lsp

Others
wget https://github.com/ul/kak-lsp/releases/download/v8.0.0/kak-lsp-v8.0.0-x86_64-unknown-linux-musl.tar.gz
tar xzvf kak-lsp-v8.0.0-x86_64-unknown-linux-musl.tar.gz

# replace `~/.local/bin/` with something on your `$PATH`
mv kak-lsp ~/.local/bin/

mkdir -p ~/.config/kak-lsp
mv kak-lsp.toml ~/.config/kak-lsp/

From the source

git clone https://github.com/ul/kak-lsp
cd kak-lsp

cargo install --locked --force --path .

# replace `~/.config` with OS-specific dir as described at https://docs.rs/dirs/2.0.1/dirs/fn.config_dir.html
mkdir -p ~/.config/kak-lsp

# or just link if you are okay with default config
cp kak-lsp.toml ~/.config/kak-lsp/

With plug.kak

If you don’t mind using plugin manager, you can install kak-lsp with plug.kak. Add this code to your kakrc:

plug "ul/kak-lsp" do %{
    cargo install --locked --force --path .
}

You can replace cargo install with ln -sf target/release/kak-lsp ~/.local/bin/ where ~/.local/bin/ can be replaced to something in your $PATH.

Examples of configuration with plug.kak can be found at Wiki.

Language servers

kak-lsp doesn’t manage installation of language servers, please install them by yourself for the languages you plan to use kak-lsp with. Please consult the How to install servers wiki page for quick installation of language servers supported by kak-lsp out of the box.

Usage

Note
Contents below corresponds to the master branch HEAD and could be slightly out-of-sync with the version installed from pre-built binaries. The most common case is new commands being in a pre-release testing stage. Please refer README.asciidoc revision tagged with version you use or README.asciidoc from the release archive (included starting from version 5.10.0).

To enable LSP support for configured languages (see the next section) just add the following commands to your kakrc:

eval %sh{kak-lsp --kakoune -s $kak_session}
lsp-enable

A bit more involved but recommended way is to enable kak-lsp only for specific filetypes you need via lsp-enable-window, e.g.:

eval %sh{kak-lsp --kakoune -s $kak_session}
hook global WinSetOption filetype=(rust|python|go|javascript|typescript|c|cpp) %{
    lsp-enable-window
}

Either way you get:

  • completions

  • lsp-definition command to go to definition, mapped to gd by default

  • lsp-hover command to show hover info (including relevant diagnostics when available)

    • to automatically show hover when you move around use lsp-auto-hover-enable

    • to show hover anchored to hovered position do set global lsp_hover_anchor true

    • to exclude diagnostics do set-option global lsp_show_hover_format 'printf %s "${lsp_info}"'

  • lsp-declaration command to jump to the declaration of the symbol under the main cursor

  • lsp-definition command to jump to the definition of the symbol under the main cursor

  • lsp-type-definition command to jump to the definition of the type of the symbol under the main cursor

  • lsp-implementation command to find implementations for a symbol under the main cursor

  • lsp-references command to find references for a symbol under the main cursor, mapped to gr by default

    • for the previous five commands, *goto* buffer has grep filetype so you can press <ret> on a line or use the grep-jump command

  • lsp-find-error command to jump to the next or previous error in the file

    • lsp-references-previous-match and lsp-references-next-match to navigate between references

  • lsp-highlight-references command to highlight references in current buffer for a symbol under the main cursor with Reference face (which is equal to MatchingChar face by default)

  • lsp-document-symbol command to list current buffer’s symbols

  • lsp-workspace-symbol command to list project-wide symbols matching the query

  • lsp-workspace-symbol-incr command to incrementally list project-wide symbols matching the query

    • *symbols* buffer has grep filetype so you can press <ret> on a line or use the grep-jump command

    • lsp-symbols-previous-match and lsp-symbols-next-match to navigate between symbols

  • lsp-diagnostics command to list project-wide diagnostics (current buffer determines project and language to collect diagnostics)

    • *diagnostics* buffer has make filetype so you can press <ret> on a line or use the make-jump command

  • inline diagnostics highlighting using DiagnosticError and DiagnosticWarning faces; could be disabled with lsp-inline-diagnostics-disable command

  • flags in the left margin on lines with errors or warnings; could be disabled with lsp-diagnostic-lines-disable command

  • lsp-formatting command to format current buffer, according to the tabstop and lsp_insert_spaces options

  • lsp-formatting-sync command to format current buffer synchronously, suitable for use with BufWritePre hook:

hook global WinSetOption filetype=rust %{
    hook window BufWritePre .* lsp-formatting-sync
}
  • lsp-rename <new_name> and lsp-rename-prompt commands to rename the symbol under the main cursor.

  • lsp-code-actions command to open a menu with code actions available for the current main cursor position

  • lsp_diagnostic_error_count and lsp_diagnostic_warning_count options which contains number of diagnostics errors and warnings published for the current buffer. For example, you can put it into your modeline to see at a glance if there are errors in the current file

  • starting new kak-lsp session when Kakoune session begins and stopping it when Kakoune session ends

Note
By default, kak-lsp exits when it doesn’t receive any request from Kakoune during 30 minutes, even if Kakoune session is still up and running. Change server.timeout in kak-lsp.toml to tweak duration, or set it to 0 to disable this behaviour. In any scenario making new request would lead to attempt to spin up server if it is down.
  • lsp user mode (see Kakoune docs for more details about user modes):

Binding Command

a

lsp-code-actions

c

lsp-capabilities

d

lsp-definition

e

lsp-diagnostics

f

lsp-formatting

h

lsp-hover

i

lsp-implementation

r

lsp-references

s

lsp-signature-help

S

lsp-document-symbol

o

lsp-workspace-symbol-incr

n

lsp-find-error

p

lsp-find-error --previous

y

lsp-type-definition

&

lsp-highlight-references

To know which subset of kak-lsp commands is backed by current buffer filetype’s language server use lsp-capabilities command.

All commands are also represented as subcommands of umbrella lsp command if you prefer this style. For example, you can use lsp references instead of lsp-references.

Configuration

kak-lsp itself has configuration, but it also adds configuration options to Kakoune that affect the Kakoune integration.

Configuring kak-lsp

kak-lsp is configured via configuration file in TOML format. By default kak-lsp tries to read kak-lsp/kak-lsp.toml under OS-specific config dir as described here, but you can override it with command-line option --config.

Look into the default kak-lsp.toml in the root of repository, it should be quite self-descriptive. The only example which is not covered by default kak-lsp.toml is setting initialization options for a language server. It’s done like this:

[language.go.initialization_options]
formatTool = "gofmt"

Important: The configuration file does not extend the default configuration, but rather overwrites it. This means that if you want to customize any of the configuration, you must copy the entire default configuration and then edit it.

If you are setting any options to server via cli do not forget to append them to %sh{kak-lsp --kakoune …​} in your kakrc. It’s not needed if you change options in ~/.config/kak-lsp/kak-lsp.toml file.

Please let us know if you have any ideas about how to make default config more sensible.

Configuring Kakoune

kak-lsp’s Kakoune integration declares the following options:

  • lsp_completion_trigger (str): This option is set to a Kakoune command, which is executed every time the user pauses in insert mode. If the command succeeds, kak-lsp will send a completion request to the language server.

  • lsp_diagnostic_line_error_sign (str): When using lsp-diagnostic-lines-enable and the language server detects an error, kak-lsp will add a flag to the left-most column of the window, using this string and the LineFlagErrors face.

  • lsp_diagnostic_line_warning_sign (str): When using lsp-diagnostic-lines-enable and the language server detects an warning, kak-lsp will add a flag to the left-most column of the window, using this string and the LineFlagErrors face.

  • lsp_hover_anchor (bool): When using lsp-hover or lsp-auto-hover-enable, if this option is true then the hover information will be displayed next to the active selection. Otherwise, the information will be displayed in a box in the lower-right corner.

  • lsp_hover_max_lines (int): If greater than 0 then limit rendered hover information to the given number of lines.

  • lsp_hover_insert_mode_trigger (str): This option is set to a Kakoune command. When using lsp-auto-hover-insert-mode-enable, this command is executed every time the user pauses in insert mode. If the command succeeds, kak-lsp will send a hover-information request for the text selected by the command.

  • lsp_insert_spaces (bool): When using lsp-formatting, if this option is true, kak-lsp will ask the language server to indent with spaces rather than tabs.

  • lsp_auto_highlight_references (bool): If this option is true then lsp-highlight-references is executed every time user pauses in normal mode.

  • lsp_server_configuration (str-to-str-map): At startup, and when this option is modified, kak-lsp will send its contents to the language server in a workspace/DidChangeConfiguration notification. Some languages servers allow dynamic configuration in this way. See below for more information about this option.

  • lsp_server_initialization_options (str-to-str-map): When initialize request is sent to the language server kak-lsp will ask Kakoune for this option value in the buffer which provoked start of the language server. If value is non-empty then it will override initialization_options set for the buffer’s filetype in kak-lsp.toml. See below for more information about this option.

The lsp_server_configuration and lsp_server_initialization_options options are unusual, since the language server wants deeply-nested JSON objects, which are hard to represent in Kakoune. If a language server’s documentation says it wants a structure like this:

{
    "settings": {
        "rust": {
            "clippy_preference": "on"
        }
    }
}

…​you can achieve the same thing in Kakoune with:

set-option global lsp_server_configuration rust.clippy_preference="on"

That is, the keys of the lsp_server_configuration option are a .-delimited path of JSON objects. For implementation reasons, the values use TOML serialisation rules rather than JSON rules, but they’re pretty much the same thing for strings, numbers and booleans, which are the most common configuration types.

Inlay hints for rust-analyzer

Inlay hints are a feature supported by rust-analyzer, which show inferred types, parameter names in function calls, and the types of chained calls inline in the code. To enable support for it in kak-lsp, add the following to your kakrc:

hook global WinSetOption filetype=rust %{
  hook window -group rust-inlay-hints BufReload .* rust-analyzer-inlay-hints
  hook window -group rust-inlay-hints NormalIdle .* rust-analyzer-inlay-hints
  hook window -group rust-inlay-hints InsertIdle .* rust-analyzer-inlay-hints
  hook -once -always window WinSetOption filetype=.* %{
    remove-hooks window rust-inlay-hints
  }
}

You can change the face of the hints with set-face global InlayHint <face>.

Note that this requires you to build Kakoune from source as the feature that allows this is not yet in a release.

Semantic Tokens

kak-lsp supports the semanticTokens feature for semantic highlighting. If the language server supports it, you can enable it with:

hook global WinSetOption filetype=<language> %{
  hook window -group semantic-tokens BufReload .* lsp-semantic-tokens
  hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens
  hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens
  hook -once -always window WinSetOption filetype=.* %{
    remove-hooks window semantic-tokens
  }
}

The faces used for semantic tokens and modifiers can be modified in kak-lsp.toml, under the semantic_tokens and semantic_modifiers sections. The modifiers are used first if available, and then the main token type is used if no modifier face is specified.

Inlay Diagnostics

kak-lsp supports showing diagnostics inline after their respective line, but this behaviour can be somewhat buggy and must be enabled explicitly:

lsp-inlay-diagnostics-enable global

Note that this requires you to build Kakoune from source as the feature that allows this is not yet in a release.

Limitations

Encoding

kak-lsp works only with UTF-8 documents.

Position.character interpretation

Currently, kak-lsp doesn’t conform to the spec regarding the interpretation of Position.character. LSP spec says that

A position inside a document (see Position definition below) is expressed as a zero-based line and character offset. The offsets are based on a UTF-16 string representation. So a string of the form a?b the character offset of the character a is 0, the character offset of ? is 1 and the character offset of b is 3 since ? is represented using two code units in UTF-16.

However, kak-lsp treats Position.character as an offset in UTF-8 code points by default. Fortunately, it appears to produce the same result within the Basic Multilingual Plane (BMP) which includes a lot of characters.

Unfortunately, many language servers violate the spec as well, and in an inconsistent manner. Please refer https://github.com/Microsoft/language-server-protocol/issues/376 for more information. There are two main types of violations we met in the wild:

1) Using UTF-8 code points, just like kak-lsp does. Those should work well with kak-lsp for characters outside BMP out of the box.

2) Using UTF-8 code units (bytes), just like Kakoune does. Those are supported by kak-lsp but require adding offset_encoding = "utf-8" to language server configuration in kak-lsp.toml.

Troubleshooting

If kak-lsp fails try to put this line in your kakrc after kak-lsp --kakoune invocation:

set global lsp_cmd "kak-lsp -s %val{session} -vvv --log /tmp/kak-lsp.log"

to enable debug logging.

If it will not give enough insights to fix the problem or if the problem is a bug in kak-lsp itself please don’t hesitate to raise an issue.

Note
Some Kakoune plugins could interfere with kak-lsp, particularly completions providers. E.g. racer.kak competes for autocompletion in Rust files.

Crashes

For troubleshooting crashes, you might like to run kak-lsp outside of Kakoune.

To do this:

  1. Before launching Kakoune, run kak-lsp with an arbitrary session ID (here foobar):

    kak-lsp -s foobar
  2. In a second terminal, run Kakoune with the same session ID:

    kak -s foobar

Versioning

kak-lsp follows SemVer with one notable difference from common practice: we don’t use 0 major version to indicate that product is not yet reached stability. Even for non-stable and not feature-complete product user should be clearly informed about breaking change. Therefore we start with major version 1 and increment it each time when upgrade requires user’s attention.

Comments

  • WIP: textDocument/selectionRange support
    WIP: textDocument/selectionRange support

    May 23, 2020

    WIP because while the current implementation does something, it's not very useful. It should probably send the entire hierarchy of selections to the client, so it can go back and forth between them until the cursor moves outside?

    Reply
  • Inlay diagnostics with ' don't display correctly
    Inlay diagnostics with ' don't display correctly

    May 25, 2020

    kak-lsp sends eval "set buffer lsp_diagnostics 50 ''9.16+0|{DiagnosticError}{\} "encoding/json" imported but not used''" to the client, but the quotes don't end up matching right and it errors out.

    Reply
  • Issues with formatting Go code
    Issues with formatting Go code

    May 27, 2020

    Formatting code does not work, the problem appears to be the command send from kak-lsp to the editor. Here is a kak-lsp log with opening the file and running :lsp-formatting

    kak-lsp log (click to show)

    May 27 13:08:00.399 INFO Starting main event loop, module: kak_lsp::session:29
    May 27 13:08:02.335 DEBG From editor: 
    session  = "foobar"
    client   = ""
    buffile  = "/home/george/tmp/kak-tests/lsp-go-problem/hello.go"
    filetype = "go"
    version  = 1
    method   = "workspace/didChangeConfiguration"
    [params.settings]
    , module: kak_lsp::editor_transport:125
    May 27 13:08:02.335 DEBG Searching for vars starting with KAK_LSP_PROJECT_ROOT_GO, module: kak_lsp::project_root:41
    May 27 13:08:02.335 DEBG Routing editor request to Route { session: "foobar", language: "go", root: "/home/george/tmp/kak-tests/lsp-go-problem" }, module: kak_lsp::session:95
    May 27 13:08:02.335 DEBG Spawning a new controller for Route { session: "foobar", language: "go", root: "/home/george/tmp/kak-tests/lsp-go-problem" }, module: kak_lsp::session:117
    May 27 13:08:02.335 INFO Starting Language server `gopls `, module: kak_lsp::language_server_transport:21
    May 27 13:08:02.336 DEBG From editor: 
    session  = "foobar"
    client   = ""
    buffile  = "/home/george/tmp/kak-tests/lsp-go-problem/hello.go"
    filetype = "go"
    version  = 1
    method   = "textDocument/didOpen"
    [params]
    draft    = """
    package main
    
    func main() {
    fmt.Println(\"hello\")
    }
    """
    , module: kak_lsp::editor_transport:125
    May 27 13:08:02.336 DEBG Searching for vars starting with KAK_LSP_PROJECT_ROOT_GO, module: kak_lsp::project_root:41
    May 27 13:08:02.336 DEBG Routing editor request to Route { session: "foobar", language: "go", root: "/home/george/tmp/kak-tests/lsp-go-problem" }, module: kak_lsp::session:95
    May 27 13:08:02.336 DEBG To editor `foobar`: lsp-get-server-initialization-options '/tmp/kak-lsp/george/a2b23d1eeb021d31', module: kak_lsp::editor_transport:85
    May 27 13:08:02.342 DEBG lsp_server_initialization_options:
    , module: kak_lsp::general:192
    May 27 13:08:02.342 DEBG Language server is not initialized, parking request, module: kak_lsp::controller:73
    May 27 13:08:02.342 DEBG To server: {"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}}},"colorProvider":null,"completion":{"completionItem":{"documentationFormat":["plaintext"],"snippetSupport":true}},"semanticHighlightingCapabilities":{"semanticHighlighting":true}},"workspace":{"workspaceEdit":{"documentChanges":true,"resourceOperations":["create","delete","rename"]}}},"processId":12542,"rootUri":"file:///home/george/tmp/kak-tests/lsp-go-problem","trace":"off"},"id":0}, module: kak_lsp::language_server_transport:175
    May 27 13:08:02.348 DEBG From server: {"jsonrpc":"2.0","result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"save":{}},"completionProvider":{"triggerCharacters":["."]},"hoverProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"codeActionProvider":{"codeActionKinds":["quickfix","source.organizeImports"]},"documentLinkProvider":{},"documentFormattingProvider":true,"renameProvider":true,"foldingRangeProvider":true,"executeCommandProvider":{"commands":["tidy"]},"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":"workspace/didChangeWorkspaceFolders"}}},"custom":null},"id":0}, module: kak_lsp::language_server_transport:149
    May 27 13:08:02.348 DEBG To server: {"jsonrpc":"2.0","method":"initialized","params":{}}, module: kak_lsp::language_server_transport:175
    May 27 13:08:02.348 DEBG To server: {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"go","text":"package main\n\nfunc main() {\nfmt.Println(\"hello\")\n}\n","uri":"file:///home/george/tmp/kak-tests/lsp-go-problem/hello.go","version":1}}}, module: kak_lsp::language_server_transport:175
    May 27 13:08:02.348 DEBG To server: {"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}, module: kak_lsp::language_server_transport:175
    May 27 13:08:02.348 DEBG To server: {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"go","text":"package main\n\nfunc main() {\nfmt.Println(\"hello\")\n}\n","uri":"file:///home/george/tmp/kak-tests/lsp-go-problem/hello.go","version":1}}}, module: kak_lsp::language_server_transport:175
    May 27 13:08:02.391 DEBG From editor: 
    session   = "foobar"
    client    = "client0"
    buffile   = "/home/george/tmp/kak-tests/lsp-go-problem/hello.go"
    filetype  = "go"
    version   = 1
    method    = "textDocument/hover"
    [params.position]
    line      = 1
    column    = 1
    , module: kak_lsp::editor_transport:125
    May 27 13:08:02.391 DEBG Searching for vars starting with KAK_LSP_PROJECT_ROOT_GO, module: kak_lsp::project_root:41
    May 27 13:08:02.392 DEBG Routing editor request to Route { session: "foobar", language: "go", root: "/home/george/tmp/kak-tests/lsp-go-problem" }, module: kak_lsp::session:95
    May 27 13:08:02.392 DEBG To server: {"jsonrpc":"2.0","method":"textDocument/hover","params":{"position":{"character":0,"line":0},"textDocument":{"uri":"file:///home/george/tmp/kak-tests/lsp-go-problem/hello.go"}},"id":1}, module: kak_lsp::language_server_transport:175
    May 27 13:08:02.420 DEBG From server: {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"2020/05/27 13:08:02 Build info\n----------\ngolang.org/x/tools/cmd/gopls master-cmd.gopls\n    golang.org/x/[email protected](devel)\n    golang.org/x/[email protected] h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=\n    golang.org/x/[email protected] h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=\n\nGo info\n-------\ngo version go1.14.1 linux/amd64\n\nGO111MODULE=\"\"\nGOARCH=\"amd64\"\nGOBIN=\"\"\nGOCACHE=\"/home/george/.cache/go-build\"\nGOENV=\"/home/george/.config/go/env\"\nGOEXE=\"\"\nGOFLAGS=\"\"\nGOHOSTARCH=\"amd64\"\nGOHOSTOS=\"linux\"\nGOINSECURE=\"\"\nGONOPROXY=\"*\"\nGONOSUMDB=\"*\"\nGOOS=\"linux\"\nGOPATH=\"/home/george/.go\"\nGOPRIVATE=\"*\"\nGOPROXY=\"https://proxy.golang.org,direct\"\nGOROOT=\"/nix/store/gvw1mfpdrk7i82884yhxf9lf5j3c12zm-go-1.14.1/share/go\"\nGOSUMDB=\"sum.golang.org\"\nGOTMPDIR=\"\"\nGOTOOLDIR=\"/nix/store/gvw1mfpdrk7i82884yhxf9lf5j3c12zm-go-1.14.1/share/go/pkg/tool/linux_amd64\"\nGCCGO=\"gccgo\"\nAR=\"ar\"\nCC=\"/nix/store/k930l9lckxjf4zmafv4aapvdbd2sibmj-gcc-wrapper-9.3.0/bin/cc\"\nCXX=\"g++\"\nCGO_ENABLED=\"1\"\nGOMOD=\"/home/george/tmp/kak-tests/lsp-go-problem/go.mod\"\nCGO_CFLAGS=\"-g -O2\"\nCGO_CPPFLAGS=\"\"\nCGO_CXXFLAGS=\"-g -O2\"\nCGO_FFLAGS=\"-g -O2\"\nCGO_LDFLAGS=\"-g -O2\"\nPKG_CONFIG=\"pkg-config\"\nGOGCCFLAGS=\"-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build784385011=/tmp/go-build -gno-record-gcc-switches\"\n"}}, module: kak_lsp::language_server_transport:149
    May 27 13:08:02.420 DEBG To editor `foobar`: echo -debug LSP: '2020/05/27 13:08:02 Build info
    ----------
    golang.org/x/tools/cmd/gopls master-cmd.gopls
        golang.org/x/[email protected](devel)
        golang.org/x/[email protected] h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
        golang.org/x/[email protected] h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
    
    Go info
    -------
    go version go1.14.1 linux/amd64
    
    GO111MODULE=""
    GOARCH="amd64"
    GOBIN=""
    GOCACHE="/home/george/.cache/go-build"
    GOENV="/home/george/.config/go/env"
    GOEXE=""
    GOFLAGS=""
    GOHOSTARCH="amd64"
    GOHOSTOS="linux"
    GOINSECURE=""
    GONOPROXY="*"
    GONOSUMDB="*"
    GOOS="linux"
    GOPATH="/home/george/.go"
    GOPRIVATE="*"
    GOPROXY="https://proxy.golang.org,direct"
    GOROOT="/nix/store/gvw1mfpdrk7i82884yhxf9lf5j3c12zm-go-1.14.1/share/go"
    GOSUMDB="sum.golang.org"
    GOTMPDIR=""
    GOTOOLDIR="/nix/store/gvw1mfpdrk7i82884yhxf9lf5j3c12zm-go-1.14.1/share/go/pkg/tool/linux_amd64"
    GCCGO="gccgo"
    AR="ar"
    CC="/nix/store/k930l9lckxjf4zmafv4aapvdbd2sibmj-gcc-wrapper-9.3.0/bin/cc"
    CXX="g++"
    CGO_ENABLED="1"
    GOMOD="/home/george/tmp/kak-tests/lsp-go-problem/go.mod"
    CGO_CFLAGS="-g -O2"
    CGO_CPPFLAGS=""
    CGO_CXXFLAGS="-g -O2"
    CGO_FFLAGS="-g -O2"
    CGO_LDFLAGS="-g -O2"
    PKG_CONFIG="pkg-config"
    GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build784385011=/tmp/go-build -gno-record-gcc-switches"
    ', module: kak_lsp::editor_transport:85
    May 27 13:08:02.469 DEBG From server: {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"2020/05/27 13:08:02 go/packages.Load\n\tpackages = 1"}}, module: kak_lsp::language_server_transport:149
    May 27 13:08:02.469 DEBG From server: {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":3,"message":"2020/05/27 13:08:02 go/packages.Load\n\tpackage = hello\n\tfiles = [/home/george/tmp/kak-tests/lsp-go-problem/hello.go]"}}, module: kak_lsp::language_server_transport:149
    May 27 13:08:02.469 DEBG To editor `foobar`: echo -debug LSP: '2020/05/27 13:08:02 go/packages.Load
    	packages = 1', module: kak_lsp::editor_transport:85
    May 27 13:08:02.471 DEBG From server: {"jsonrpc":"2.0","result":null,"id":1}, module: kak_lsp::language_server_transport:149
    May 27 13:08:02.471 DEBG From server: {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///home/george/tmp/kak-tests/lsp-go-problem/hello.go","diagnostics":[{"range":{"start":{"line":3,"character":0},"end":{"line":3,"character":11}},"severity":1,"source":"compiler","message":"undeclared name: fmt"}]}}, module: kak_lsp::language_server_transport:149
    May 27 13:08:02.471 DEBG From server: {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///home/george/tmp/kak-tests/lsp-go-problem/hello.go","diagnostics":[{"range":{"start":{"line":3,"character":0},"end":{"line":3,"character":11}},"severity":1,"source":"compiler","message":"undeclared name: fmt"}]}}, module: kak_lsp::language_server_transport:149
    May 27 13:08:02.472 DEBG To editor `foobar`: echo -debug LSP: '2020/05/27 13:08:02 go/packages.Load
    	package = hello
    	files = [/home/george/tmp/kak-tests/lsp-go-problem/hello.go]', module: kak_lsp::editor_transport:85
    May 27 13:08:02.474 DEBG To editor `foobar`: 
            eval -buffer '/home/george/tmp/kak-tests/lsp-go-problem/hello.go' 'set buffer lsp_diagnostic_error_count 1
             set buffer lsp_diagnostic_warning_count 0
             set buffer lsp_errors 1 4.1,4.11|DiagnosticError
             eval "set buffer lsp_error_lines 1 4|%opt[lsp_diagnostic_line_error_sign] ''0| ''"', module: kak_lsp::editor_transport:85
    May 27 13:08:02.477 DEBG To editor `foobar`: 
            eval -buffer '/home/george/tmp/kak-tests/lsp-go-problem/hello.go' 'set buffer lsp_diagnostic_error_count 1
             set buffer lsp_diagnostic_warning_count 0
             set buffer lsp_errors 1 4.1,4.11|DiagnosticError
             eval "set buffer lsp_error_lines 1 4|%opt[lsp_diagnostic_line_error_sign] ''0| ''"', module: kak_lsp::editor_transport:85
    May 27 13:08:04.152 DEBG From editor: 
    session      = "foobar"
    client       = "client0"
    buffile      = "/home/george/tmp/kak-tests/lsp-go-problem/hello.go"
    filetype     = "go"
    version      = 1
    method       = "textDocument/formatting"
    [params]
    tabSize      = 8
    insertSpaces = true
    , module: kak_lsp::editor_transport:125
    May 27 13:08:04.152 DEBG Searching for vars starting with KAK_LSP_PROJECT_ROOT_GO, module: kak_lsp::project_root:41
    May 27 13:08:04.153 DEBG Routing editor request to Route { session: "foobar", language: "go", root: "/home/george/tmp/kak-tests/lsp-go-problem" }, module: kak_lsp::session:95
    May 27 13:08:04.153 DEBG To server: {"jsonrpc":"2.0","method":"textDocument/formatting","params":{"options":{"insertSpaces":true,"tabSize":8},"textDocument":{"uri":"file:///home/george/tmp/kak-tests/lsp-go-problem/hello.go"}},"id":2}, module: kak_lsp::language_server_transport:175
    May 27 13:08:04.154 DEBG From server: {"jsonrpc":"2.0","result":[{"range":{"start":{"line":3,"character":0},"end":{"line":4,"character":0}},"newText":""},{"range":{"start":{"line":4,"character":0},"end":{"line":4,"character":0}},"newText":"\tfmt.Println(\"hello\")\n"}],"id":2}, module: kak_lsp::language_server_transport:149
    May 27 13:08:04.155 DEBG To editor `foobar`: eval -client client0 'eval -draft -save-regs ''^'' ''select 4.1,4.1000000 5.1+0
                exec -save-regs '''''''' Z
                exec ''''z<space>''''
                        lsp-replace-selection ''''''''
    exec ''''z<space>''''
                        lsp-insert-before-selection ''''	fmt.Println("hello")
    ''''''', module: kak_lsp::editor_transport:85
    May 27 13:08:04.200 DEBG From editor: 
    session   = "foobar"
    client    = "client0"
    buffile   = "/home/george/tmp/kak-tests/lsp-go-problem/hello.go"
    filetype  = "go"
    version   = 1
    method    = "textDocument/hover"
    [params.position]
    line      = 1
    column    = 1
    , module: kak_lsp::editor_transport:125
    May 27 13:08:04.200 DEBG Searching for vars starting with KAK_LSP_PROJECT_ROOT_GO, module: kak_lsp::project_root:41
    May 27 13:08:04.200 DEBG Routing editor request to Route { session: "foobar", language: "go", root: "/home/george/tmp/kak-tests/lsp-go-problem" }, module: kak_lsp::session:95
    May 27 13:08:04.200 DEBG To server: {"jsonrpc":"2.0","method":"textDocument/hover","params":{"position":{"character":0,"line":0},"textDocument":{"uri":"file:///home/george/tmp/kak-tests/lsp-go-problem/hello.go"}},"id":3}, module: kak_lsp::language_server_transport:175
    May 27 13:08:04.201 DEBG From server: {"jsonrpc":"2.0","result":null,"id":3}, module: kak_lsp::language_server_transport:149
    May 27 13:08:07.311 DEBG From editor: 
    session  = "foobar"
    client   = ""
    buffile  = ""
    filetype = ""
    version  = 0
    method   = "stop"
    [params]
    , module: kak_lsp::editor_transport:125
    May 27 13:08:07.311 INFO Shutting down language servers and exiting, module: kak_lsp::session:180
    May 27 13:08:07.311 INFO Exit go in project /home/george/tmp/kak-tests/lsp-go-problem, module: kak_lsp::session:185
    May 27 13:08:07.311 INFO Waiting for Controller to finish..., module: kak_lsp::thread_worker:18
    May 27 13:08:07.311 DEBG To server: {"jsonrpc":"2.0","method":"exit","params":null}, module: kak_lsp::language_server_transport:175
    May 27 13:08:07.311 INFO Waiting for Messages to language server to finish..., module: kak_lsp::thread_worker:18
    May 27 13:08:07.311 DEBG Received signal to stop language server, closing pipe, module: kak_lsp::language_server_transport:186
    May 27 13:08:07.311 DEBG Waiting for language server process end, module: kak_lsp::language_server_transport:81
    May 27 13:08:07.312 DEBG Language server closed pipe, stopping reading, module: kak_lsp::language_server_transport:127
    May 27 13:08:07.312 ERRO Language server error: gopls-legacy: failed reading header line "EOF"
    , module: kak_lsp::language_server_transport:52
    May 27 13:08:07.315 DEBG From editor: 
    session  = "foobar"
    client   = ""
    buffile  = "/home/george/tmp/kak-tests/lsp-go-problem/hello.go"
    filetype = "go"
    version  = 1
    method   = "textDocument/didClose"
    [params]
    , module: kak_lsp::editor_transport:125
    May 27 13:08:08.311 INFO ... Messages to language server terminated with ok, module: kak_lsp::thread_worker:20
    May 27 13:08:08.311 INFO Waiting for Messages from language server to finish..., module: kak_lsp::thread_worker:18
    May 27 13:08:08.311 INFO ... Messages from language server terminated with ok, module: kak_lsp::thread_worker:20
    May 27 13:08:08.311 INFO Waiting for Language server errors to finish..., module: kak_lsp::thread_worker:18
    May 27 13:08:08.311 INFO ... Language server errors terminated with ok, module: kak_lsp::thread_worker:20
    May 27 13:08:08.311 INFO ... Controller terminated with ok, module: kak_lsp::thread_worker:20
    May 27 13:08:08.311 INFO Waiting for Messages to editor to finish..., module: kak_lsp::thread_worker:18
    May 27 13:08:08.311 INFO ... Messages to editor terminated with ok, module: kak_lsp::thread_worker:20
    

    And here is the erorr in *debug*:

    error running command 'eval -client client0 'eval -draft -save-regs ''^'' ''select 4.1,4.1000000 5.1+0
                exec -save-regs '''''''' Z
                exec ''''z<space>''''
                        lsp-replace-selection ''''''''
    exec ''''z<space>''''
                        lsp-insert-before-selection ''''	fmt.Println("hello")
    '''''''': 1:1: 'eval' 1:1: 'eval' 1:1: 'select' '5.1+0' does not follow <line>.<column>,<line>.<column> format
    
    Reply
  • Waiting for shell command to finish infinite
    Waiting for shell command to finish infinite

    May 31, 2020

    This is based on an issue that was posted on Reddit recently on the Kakoune subreddit.

    What happens is that kak-lsp starts a language server on either standalone files or a project, and upon trying to write a file Kakoune hangs on waiting for shell command to finish.

    For me, this is happening on Nim files. Specifically on a Nim file that isn't part of a project and not in a directory that has a .nimble file or .git directory.

    Here's is my configuration for kak-lsp

    plug "ul/kak-lsp" do %{
       cargo install --force --path ~/.local/bin --locked
       cargo clean
    } config %{
    	
    	set-option global lsp_cmd "kak-lsp -vvv -c ~/.config/kak-lsp/kak-lsp.toml -s %val{session} --log ~/.config/kak-lsp/kak-lsp.log"
    	
    	define-command lsp-restart %{ lsp-stop; lsp-start }
    	
    	set-option global lsp_completion_trigger "execute-keys 'h<a-h><a-k>\S[^\s,=;*(){}\[\]]\z<ret>'"
    	set-option global lsp_diagnostic_line_error_sign "!"
    	set-option global lsp_diagnostic_line_warning_sign "?"
    	
    	hook global WinSetOption filetype=(c|cpp|objc|d|rust|haskell|nim|elixir|latex|javascript) %{
    		
    		lsp-enable-window
    		echo -debug "Enabling LSP for filtetype %opt{filetype}"
    		
    		lsp-auto-hover-enable
    		lsp-auto-hover-insert-mode-disable
    		set-option global lsp_auto_highlight_references true
    		set-option global lsp_hover_anchor true
    		
    		# Semantic highlighting
    		hook window -group semantic-tokens BufReload .* lsp-semantic-tokens
    		hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens
    		hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens
    		hook -once -always window WinSetOption filetype=.* %{
    			 remove-hooks window semantic-tokens
    		}
    		
    		# Other things
    		hook window BufWritePre .* lsp-formatting-sync 
    		hook window BufWritePost .* lsp-diagnostics
    		hook -always global KakEnd .* lsp-exit
    	}
    
    }
    

    Here's my configuration for Nim:

    hook global WinSetOption filetype=nim %{
    	set-option window aligntab false
    	set-option window tabstop 2
    	set-option window indentwidth 2
    	set-option window lintcmd 'sleep 0.3; nim check'
    	hook -once window WinSetOption filetype=.* %{
    		unset-option window lintcmd
    	}
    }
    

    And here's why I have to use nimlsp with kak-lsp:

    [language.nim]
    filetypes = ["nim"]
    roots = ["*.nimble", ".git"]
    command = "nimlsp"
    

    According to the linked Reddit post, this happens for other languages like Rust, Python, and Dart.

    Reply
  • Gutter error and purescript setup
    Gutter error and purescript setup

    Jun 13, 2020

    Hello there!

    I've been trying to config this to work with purescript-language-server and I've had some success, but I can't seem to make the error gutter work.

    image

    This is my kakrc file:

    source "%val{config}/plugins/plug.kak/rc/plug.kak"
    
    plug "andreyorst/plug.kak" noload
    plug "andreyorst/smarttab.kak" config %{
      hook global WinCreate .* %{
        expandtab
        set-option global softtabstop 2
        set-option global tabstop 2
        set-option global indentwidth 2
      }
    }
    plug "alexherbo2/manual-indent.kak"
    plug "alexherbo2/surround.kak" config %{
      map global user s :surround<ret> -docstring "surround selection"
      set-option global surround_begin auto-pairs-disable
      set-option global surround_end auto-pairs-enable
      set-option -add global surround_pairs "*" "*" "_" "_"
    }
    plug "alexherbo2/auto-pairs.kak"
    plug "lePerdu/kakboard" config %{
      hook global WinCreate .* %{ kakboard-enable }
    }
    plug "delapouite/kakoune-livedown"
    plug "ftonneau/digraphs.kak" %{
      set-option global digraphs_path "plugins/digraphs.kak"
      digraphs-enable-on <F5> <F6>
    }
    plug "ul/kak-lsp" do %{
      cargo build --release --locked
      cargo install --force --path .
      ln -sf $(pwd)/target/release/kak-lsp ~/.local/apps/kakoune/bin/
    } config %{
      set-option global lsp_cmd "kak-lsp -s %val{session} -vvv --log /tmp/kak-lsp.log"
      evaluate-commands %sh{ echo ${kak_opt_lsp_cmd} >> /tmp/kak-lsp.log }
    
      define-command lsp-restart -docstring "restart lsp server" %{ lsp-stop; lsp-start }
    
      map global normal <a-,> ": enter-user-mode lsp<ret>"
    
      hook global WinSetOption filetype=(purescript) %{
        set-option window lsp_hover_anchor false
        lsp-auto-hover-enable
        lsp-enable-window
      }
    
      hook global KakEnd .* lsp-exit
    }
    
    set-face global comment bright-black
    set-face global LineNumbers bright-black
    set-face global Whitespace bright-black
    set-face global MatchingChar red+b
    
    add-highlighter global/ number-lines -relative -hlcursor
    add-highlighter global/ show-matching
    add-highlighter global/ show-whitespaces
    
    map global normal / /(?i)
    map global normal <a-/> <a-/>(?i)
    map global normal "#" ": comment-line<ret>"
    
    # purescript.kak development
    source ~/Projects/personal/kakoune/purescript.kak/filetype/purescript.kak
    

    The relevant purescript part of kak-lsp.toml:

    [language.purescript]
    filetypes = ["purescript"]
    roots = ["spago.dhall", ".git"]
    command = "purescript-language-server"
    args = ["--stdio", "--config {}"]
    

    And finally the relevant part from /tmp/kak-lsp.log:

    Jun 13 10:00:40.098 DEBG Searching for vars starting with KAK_LSP_PROJECT_ROOT_PURESCRIPT, module: kak_lsp::project_root:42
    Jun 13 10:00:40.098 DEBG Routing editor request to Route { session: "23395", language: "purescript", root: "/home/razcore/Documents/learn/scheme48" }, module: kak_lsp::session:95
    Jun 13 10:00:40.098 DEBG To server: {"jsonrpc":"2.0","method":"textDocument/didSave","params":{"textDocument":{"uri":"file:///home/razcore/Documents/learn/scheme48/src/Main.purs"}}}, module: kak_lsp::language_server_transport:175
    Jun 13 10:00:40.099 DEBG From server: {"jsonrpc":"2.0","method":"textDocument/diagnosticsBegin"}, module: kak_lsp::language_server_transport:149
    Jun 13 10:00:40.099 WARN Unsupported method: textDocument/diagnosticsBegin, module: kak_lsp::controller:366
    Jun 13 10:00:40.121 DEBG From server: {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"Built with 1 issues for file: \"/home/razcore/Documents/learn/scheme48/src/Main.purs\", all diagnostic files: [\"/home/razcore/Documents/learn/scheme48/src/Main.purs\"]"}}, module: kak_lsp::language_server_transport:149
    Jun 13 10:00:40.122 DEBG From server: {"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///home/razcore/Documents/learn/scheme48/src/Main.purs","diagnostics":[{"range":{"start":{"line":356,"character":0},"end":{"line":356,"character":0}},"severity":1,"code":"ErrorParsingModule","source":"PureScript","message":"  Unable to parse module:\n  Unexpected or mismatched indentation\n"}]}}, module: kak_lsp::language_server_transport:149
    Jun 13 10:00:40.122 DEBG From server: {"jsonrpc":"2.0","method":"textDocument/diagnosticsEnd"}, module: kak_lsp::language_server_transport:149
    Jun 13 10:00:40.122 WARN Unsupported method: textDocument/diagnosticsEnd, module: kak_lsp::controller:366
    Jun 13 10:00:40.122 DEBG To editor `23395`: echo -debug LSP: 'Built with 1 issues for file: "/home/razcore/Documents/learn/scheme48/src/Main.purs", all diagnostic files: ["/home/razcore/Documents/learn/scheme48/src/Main.purs"]', module: kak_lsp::editor_transport:85
    Jun 13 10:00:40.124 DEBG To editor `23395`: 
            eval -buffer '/home/razcore/Documents/learn/scheme48/src/Main.purs' 'set buffer lsp_diagnostic_error_count 1
             set buffer lsp_diagnostic_warning_count 0
             set buffer lsp_errors 7 357.1,357.1|DiagnosticError
             eval "set buffer lsp_error_lines 7 357|%opt[lsp_diagnostic_line_error_sign] ''0| ''"
             eval "set buffer lsp_diagnostics 7 ''357.0+0|{DiagnosticError}{\}   Unable to parse module:
      Unexpected or mismatched indentation
    ''"', module: kak_lsp::editor_transport:85
    

    I can use the lsp-find-error and it jumps to the right place so it seems that kak-lsp is aware of the error. I'm not sure exactly what's the problem. My rust knowledge is also pretty much 0 so I can't really try to debug this myself.

    Any help appreciated. Thanks for the extension plugin!

    Reply
  • No diagnostics, completion, or hover for any language server
    No diagnostics, completion, or hover for any language server

    Jun 15, 2020

    So I have this on the Kakoune Community site, but to have it here for others to look.

    Here's the output of uname -a (for the sake of it):

    Linux my-void 5.4.46_1 #1 SMP PREEMPT Wed Jun 10 19:33:58 UTC 2020 x86_64 GNU/Linux
    

    kak -version: Kakoune v2020.01.16-273-g74e3e5ef

    kak-lsp -V: kak-lsp 8.0.0-snapshot (I'm on the most recent master)

    Here's the bit from my kakoune config for kak-lsp:

    plug "ul/kak-lsp" do %{
        cargo build --release --locked
        cargo install --force --path . --locked
        cargo clean
    } config %{
    	
        set-option global lsp_cmd "kak-lsp --kakoune -vvv -c $HOME/.config/kak-lsp/kak-lsp.toml -s %val{session} --log $HOME/.config/kak-lsp/kak-lsp.log"
    
        define-command lsp-restart %{ lsp-stop; lsp-start }
    
        set-option global lsp_completion_trigger "execute-keys 'h<a-h><a-k>\S[^\s,=;*(){}\[\]]\z<ret>'"
        set-option global lsp_diagnostic_line_error_sign "!"
        set-option global lsp_diagnostic_line_warning_sign "?"
        hook global WinSetOption filetype=(c|cpp|objc|d|rust|haskell|nim|elixir|latex|javascript) %{
    
            lsp-start
        	lsp-enable-window
        	echo -debug "Enabling LSP for filtetype %opt{filetype}"
        	
        	lsp-auto-hover-enable
        	lsp-auto-hover-insert-mode-disable
        	set-option global lsp_auto_highlight_references true
        	set-option global lsp_hover_anchor true
        	
        	# Semantic highlighting
        	hook window -group semantic-tokens BufReload .* lsp-semantic-tokens
        	hook window -group semantic-tokens NormalIdle .* lsp-semantic-tokens
        	hook window -group semantic-tokens InsertIdle .* lsp-semantic-tokens
        	hook -once -always window WinSetOption filetype=.* %{
        		 remove-hooks window semantic-tokens
        	}
        	
        	# Other things
        	# hook window BufWritePre .* lsp-formatting-sync
        	hook window BufWritePost .* lsp-diagnostics
        	hook -always global KakEnd .* lsp-exit
            hook global WinSetOption filetype=rust %{
                set-option window lsp_server_configuration rust.clippy_preference="on"
            }
        }
    }
    

    And my kak-lsp.toml:

    lsp_hover_anchor=true
    lsp_hover_max_lines=6
    snippet_support = true
    verbosity = 3
    
    [semantic_scopes]
    # Map textmate scopes to kakoune faces for semantic highlighting
    # the underscores are translated to dots, and indicate nesting.
    # That is, if variable_other_field is omitted, it will try the face for
    # variable_other and then variable
    #
    # To see a list of available scopes in the debug buffer, run lsp-semantic-available-scopes
    variable = "variable"
    entity_name_function = "function"
    entity_name_type = "type"
    variable_other_enummember = "variable"
    entity_name_namespace = "module"
    
    # Semantic tokens support
    # See https://github.com/microsoft/vscode-languageserver-node/blob/8c8981eb4fb6adec27bf1bb5390a0f8f7df2899e/client/src/semanticTokens.proposed.ts#L288
    # for token/modifier types.
    
    [semantic_tokens]
    type = "type"
    variable = "variable"
    namespace = "module"
    function = "function"
    string = "string"
    keyword = "keyword"
    operator = "operator"
    comment = "comment"
    
    [semantic_modifiers]
    documentation = "documentation"
    readonly = "default+d"
    
    [server]
    # exit session if no requests were received during given period in seconds
    # works only in unix sockets mode (-s/--session)
    # set to 0 to disable
    timeout = 1800 # seconds = 30 minutes
    
    [language.c_cpp]
    filetypes = ["c", "cpp", "objc", "objcpp", "cuda"]
    roots = [".ccls", "compile_commands.json"]
    command = "ccls"
    args= ["--init={\"completion\":{\"detailedLabel\":false},\"highlight\":{\"lsRanges\":true}"]
    
    [language.d]
    filetypes = ["d", "di"]
    roots = [".git", "dub.sdl", "dub.json"]
    command = "dls"
    
    [language.rust]
    filetypes = ["rust"]
    roots = ["Cargo.toml"]
    command = "rls"
    
    [language.haskell]
    filetypes = ["haskell"]
    roots = ["Setup.hs", "stack.yaml", "*.cabal"]
    command = "haskell-language-server-wrapper"
    args = ["--lsp"]
    
    [language.nim]
    filetypes = ["nim"]
    roots = ["*.nimble", ".git"]
    command = "nimlsp"
    
    [language.elixir]
    filetypes = ["elixir", "exs", "eex"]
    roots = ["mix.exs"]
    command = "~/Tools/Elixir/elixir-ls/release/language_server.sh"
    
    [language.latex]
    filetypes = ["latex"]
    roots = [".git"]
    command = "texlab"
    
    [language.javascript]
    filetypes = ["javascript"]
    roots = ["package.json", "jsconfig.json"]
    command = "tsserver"
    
    [language.typescript]
    filetypes = ["typescript"]
    roots = ["package.json", "tsconfig.json"]
    command = "tsserver"
    

    All the executables for the language servers are in my $PATH (I can run :eval %sh{ echo $PATH } and get all the correct directories in $PATH), and I can run them outside of Kakoune.

    I get the feeling there's one silly thing that I've done that's giving me troubles, but I'm not sure as to what it is.

    Reply
  • non-latin symbols cause junk and improper highlighting
    non-latin symbols cause junk and improper highlighting

    Apr 5, 2019

    Here's an example with improper highlighting (with underline): image

    Here's an example of junk (M-oM-?M-=): image

    Possibly related to https://github.com/ul/kak-lsp/issues/170#issuecomment-476136199

    bug high priority 
    Reply
  • 'evaluate-commands' 131:15206: 'def' unknown option '-shell-candidates'
    'evaluate-commands' 131:15206: 'def' unknown option '-shell-candidates'

    Oct 8, 2018

    Just updated kakoune and kak-lsp and now this command:

    evaluate-commands %sh{kak-lsp --kakoune -s $kak_session}
    

    Throws this error:

    'evaluate-commands' 131:15206: 'def' unknown option '-shell-candidates' 
    

    Probably related to https://github.com/mawww/kakoune/pull/2419/, but I didn't have time to look into it to verify.

    Reply
  • What is the lsp-snippet story?
    What is the lsp-snippet story?

    Dec 18, 2018

    Is there a setup that enables lsp-snippet completions? https://discuss.kakoune.com/t/need-snippets-we-got-snippets/42 mentions several snippet plugins, but no confirmation of a working setup.

    Does kak-lsp emit snippets? If not what is blocking this use case?

    Reply
  • Simplify dispatching
    Simplify dispatching

    Oct 13, 2018

    Ref https://github.com/ul/kak-lsp/commit/3f121aff1259428874fb17a1014cc54e40b39c72#r30889210

    refactor 
    Reply
  • Proper structure of main script, for loading by plugin managers
    Proper structure of main script, for loading by plugin managers

    Oct 19, 2018

    Hello. I'm writing a plugin manager, and currently I'm not able to use your plugin, if it is loaded by the plugin manager.

    I've added noload option to workaround this issue, but I think that this isn't proper way of how plugin should work. I still want to be able to start lsp manually, I just don't want to avoid loading of main script, and load it via shell command.

    My current setup is:

    plug "ul/kak-lsp" "noload" %{
        hook global WinSetOption filetype=(c,cpp,rust) %{
            evaluate-commands %sh{ kak-lsp --kakoune -s $kak_session }
        }
    }
    

    Let me breakdown this for you: plug - it's a command that does the following:

    • checks if first parameter (which is a repo) exists at plugin installation path, and if it exists:
      • parses parameters, like "noload", "branch: ...", "tag: ...";
      • loads all .kak files in the repo. If "noload" is specified this step is skipped;
      • loads %{settings} from the last parameter even if previous step was skipped.

    So this configuration skips the plugin files itself, but sets the hooks that will call external program, that will load lsp.kak script. I think that this should be handled by lsp.kak and not by external program. So user configuration can be like this:

    plug "ul/kak-lsp" %{
        set-option global lsp_path_to_executable "no/more/symlinking"
        hook global WinSetOption filetype=(c,cpp,rust) %{
            lsp-start [optional parameters]
        }
    }
    

    So script could handle everything by itself, as a plugin should do. Final proposal workflow is:

    • source lsp.kak either by plugin manager, or from user configuration, or from autoload folder;
    • configure some options like path to kak-lsp inside kakoune's config;
    • start lsp via generic command by entering it manually or by hook.

    I understand that simply calling kak-lsp from shell and passing session id to it feels easier, but I think that this should be handled in the main script, and not in the binary.

    enhancement 
    Reply
  • Kakoune waiting for kak-lsp to finish
    Kakoune waiting for kak-lsp to finish

    Jul 1, 2019

    I have had this problem for quite some time, I haven't reported it yet because I think it is hard to debug, and I can live with it well enough.

    I shall describe it as well as possible.

    In files that do not have a language server (git commit or text/markdown file) sometimes (once a day) kakoune waits indefinitely for a shell command to finish. If I do killall kak-lsp, kakoune continues again. However if instead of doing killall kak-lsp I do ctrl-c in kakoune, my whole x server crashes.

    This problem only happens when I'm working in my default session which is started when I log in and which I often connect to.

    If I do ps -aux | grep kak I see the following processes.

    jjk        974  4.7  0.0  14120  7208 ?        R    13:48   6:58 kak -s default -d
    jjk       1427  0.0  0.0 143156  4840 ?        Sl   15:47   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --daemonize --initial-request
    jjk       5771  0.0  0.0  13048  6376 pts/0    S+   16:08   0:00 kak -c default -e  edit %{/home/jjk/git/dance/tsconfig.json}; 
    jjk       5782  0.0  0.0   7100  1980 ?        S    16:08   0:00 sh -c  ( lsp_draft=$(printf '%s.' "${kak_opt_lsp_draft}" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed "s/$(printf '\t')/\\\\t/g") lsp_draft=${lsp_draft%.} printf ' session  = "%s" client   = "%s" buffile  = "%s" filetype = "%s" version  = %d method   = "textDocument/didOpen" [params] draft    = """ %s""" ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" "${lsp_draft}" | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       5790  0.0  0.0   7100  1672 ?        S    16:08   0:00 sh -c  ((printf ' session  = "%s" client   = "%s" buffile  = "%s" filetype = "%s" version  = %d method   = "workspace/didChangeConfiguration" [params.settings] ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}"; eval set -- $kak_opt_lsp_server_configuration while [ $# -gt 0 ]; do     key=${1%%=*}     value=${1#*=}     quotedkey='"'$(printf %s "$key"|sed -e 's/\\/\\\\/' -e 's/"/\\"/')'"'      printf '%s = %s\n' "$quotedkey" "$value"      shift done ) | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       5793  0.0  0.0  75200  5040 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       5795  0.0  0.0  75200  5124 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       5799  0.0  0.0   7100  1636 ?        S    16:08   0:00 sh -c  ((printf ' session  = "%s" client   = "%s" buffile  = "%s" filetype = "%s" version  = %d method   = "workspace/didChangeConfiguration" [params.settings] ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}"; eval set -- $kak_opt_lsp_server_configuration while [ $# -gt 0 ]; do     key=${1%%=*}     value=${1#*=}     quotedkey='"'$(printf %s "$key"|sed -e 's/\\/\\\\/' -e 's/"/\\"/')'"'      printf '%s = %s\n' "$quotedkey" "$value"      shift done ) | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       5801  0.0  0.0  75200  4984 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       5818  0.0  0.0   7100   424 ?        S    16:08   0:00 sh -c  (printf ' session   = "%s" client    = "%s" buffile   = "%s" filetype  = "%s" version   = %d method    = "textDocument/hover" [params.position] line      = %d column    = %d ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" ${kak_cursor_line} ${kak_cursor_column} | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       5821  0.0  0.0  75200  4876 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       6091  0.0  0.0   7100   424 ?        S    16:08   0:00 sh -c  (printf ' session   = "%s" client    = "%s" buffile   = "%s" filetype  = "%s" version   = %d method    = "textDocument/hover" [params.position] line      = %d column    = %d ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" ${kak_cursor_line} ${kak_cursor_column} | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       6094  0.0  0.0  75200  4980 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       6142  0.0  0.0   7100  1728 ?        S    16:08   0:00 sh -c  (printf ' session   = "%s" client    = "%s" buffile   = "%s" filetype  = "%s" version   = %d method    = "textDocument/hover" [params.position] line      = %d column    = %d ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" ${kak_cursor_line} ${kak_cursor_column} | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       6145  0.0  0.0  75200  5000 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       6171  0.0  0.0   7100   424 ?        S    16:08   0:00 sh -c  (printf ' session   = "%s" client    = "%s" buffile   = "%s" filetype  = "%s" version   = %d method    = "textDocument/hover" [params.position] line      = %d column    = %d ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" ${kak_cursor_line} ${kak_cursor_column} | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       6174  0.0  0.0  75200  5180 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       6219  0.0  0.0   7100  1632 ?        S    16:08   0:00 sh -c  (printf ' session   = "%s" client    = "%s" buffile   = "%s" filetype  = "%s" version   = %d method    = "textDocument/hover" [params.position] line      = %d column    = %d ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" ${kak_cursor_line} ${kak_cursor_column} | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk       6222  0.0  0.0  75200  4980 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk       6283  0.0  0.0   7100  2752 ?        S    16:08   0:00 sh -c  ( lsp_draft=$(printf '%s.' "${kak_opt_lsp_draft}" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed "s/$(printf '\t')/\\\\t/g") lsp_draft=${lsp_draft%.} printf ' session  = "%s" client   = "%s" buffile  = "%s" filetype = "%s" version  = %d method   = "textDocument/didChange" [params] draft    = """ %s""" ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" "${lsp_draft}" | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null 
    jjk       6284  0.0  0.0   7100  1896 ?        S    16:08   0:00 sh -c  ( lsp_draft=$(printf '%s.' "${kak_opt_lsp_draft}" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed "s/$(printf '\t')/\\\\t/g") lsp_draft=${lsp_draft%.} printf ' session  = "%s" client   = "%s" buffile  = "%s" filetype = "%s" version  = %d method   = "textDocument/didChange" [params] draft    = """ %s""" ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" "${lsp_draft}" | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null 
    jjk       6292  0.0  0.0  75200  5124 ?        Sl   16:08   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk      11718  0.0  0.0   7100  2836 pts/2    S+   16:15   0:00 sh -c      autoload_directory() {         find -L "$1" -type f -name '*\.kak' \             | sed 's/.*/try %{ source "&" } catch %{ echo -debug Autoload: could not load "&" }/'     }      echo "colorscheme default"      if [ -d "${kak_config}/autoload" ]; then         autoload_directory ${kak_config}/autoload     elif [ -d "${kak_runtime}/autoload" ]; then         autoload_directory ${kak_runtime}/autoload     fi      if [ -f "${kak_runtime}/kakrc.local" ]; then         echo "source '${kak_runtime}/kakrc.local'"     fi      if [ -f "${kak_config}/kakrc" ]; then         echo "source '${kak_config}/kakrc'"     fi 
    jjk      32030  0.0  0.0   7100   420 ?        S    16:07   0:00 sh -c  (printf ' session   = "%s" client    = "%s" buffile   = "%s" filetype  = "%s" version   = %d method    = "textDocument/hover" [params.position] line      = %d column    = %d ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" ${kak_cursor_line} ${kak_cursor_column} | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk      32032  0.0  0.0  75200  5044 ?        Sl   16:07   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk      32039  0.0  0.0   7100   424 ?        S    16:07   0:00 sh -c  (printf ' session  = "%s" client   = "%s" buffile  = "%s" filetype = "%s" version  = %d method   = "textDocument/didSave" [params] ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk      32041  0.0  0.0  75200  4880 ?        Sl   16:07   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk      32058  0.0  0.0   7100  1640 ?        S    16:07   0:00 sh -c  (printf ' session   = "%s" client    = "%s" buffile   = "%s" filetype  = "%s" version   = %d method    = "textDocument/hover" [params.position] line      = %d column    = %d ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" ${kak_cursor_line} ${kak_cursor_column} | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk      32060  0.0  0.0  75200  4996 ?        Sl   16:07   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    jjk      32113  0.0  0.0   7100   424 ?        S    16:07   0:00 sh -c  (printf ' session  = "%s" client   = "%s" buffile  = "%s" filetype = "%s" version  = %d method   = "textDocument/didClose" [params] ' "${kak_session}" "${kak_client}" "${kak_buffile}" "${kak_opt_filetype}" "${kak_timestamp}" | ${kak_opt_lsp_cmd} --request) > /dev/null 2>&1 < /dev/null & 
    jjk      32115  0.0  0.0  75200  5100 ?        Sl   16:07   0:00 /home/jjk/git/kak-lsp-git/src/kak-lsp/target/release/kak-lsp -s default --request
    

    I have attached gdb to 5793, which is in this instruction:

    0x00007f708b0a2c3b in connect () from /usr/lib/libpthread.so.0
    

    I have also attached to 1427, which is in instruction:

    0x00007f76fecaf77c in [email protected]@GLIBC_2.3.2 () from /usr/lib/libpthread.so.0
    

    If you need more debugging info I can provide it, the problem happens daily.

    bug 
    Reply