# Kak-lsp + ccls

**URL:** <https://discuss.kakoune.com/t/kak-lsp-ccls/750>\
**Category:** Plugins\
**Tags:** lsp, plugins\
**Created:** [October 13, 2019, 6:13am UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750 "2019-10-13T06:13:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![MaskRay](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/maskray/32/336_2.png) [@MaskRay](https://discuss.kakoune.com/u/MaskRay)\
**Post date:** [October 13, 2019, 6:13am UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/1 "2019-10-13T06:13:53Z")

</div>

Install [kak-lsp](https://github.com/ul/kak-lsp) (`git clone https://github.com/ul/kak-lsp; cd kak-lsp; cargo install --locked --force --path .; cp target/release/kak-lsp ~/.local/bin/`) (`~/.local/bin` is in my `PATH`)

`~/.config/kak-lsp/kak-lsp.toml`

```toml
snippet_support = false
verbosity = 2

[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"]
roots = [".ccls-root", ".ccls", "compile_commands.json"]
# ensure `ccls` is in a PATH directory, see https://github.com/MaskRay/ccls/wiki/Install#shell-script-wrapper
command = "ccls"
# kak-lsp does not support newText yet
args = ["--init={\"completion\":{\"detailedLabel\":false}}"]

```

Add the following to my `~/.config/kak/kakrc`:

```auto
eval %sh{kak-lsp --kakoune -s $kak_session}
hook global WinSetOption filetype=(c|cpp) %{
    lsp-enable-window
}

```

`.ccls` can be hierarchical ([Project Setup · MaskRay/ccls Wiki · GitHub](https://github.com/MaskRay/ccls/wiki/Project-Setup#ccls-file)). I hope `.ccls-root` has the highest priority but I am not sure whether that is the case.

```zsh
cd /tmp; mkdir d; cd d
touch .ccls # an empty .ccls ensures all .c/.cc/.cpp files are indexed with the default clang command line options
touch a.cc
kak a.cc

```

### Note about `completion.detailedLabel: false`

If I delete this initialization option, the completion items will look weird.

 ![screen](https://discuss.kakoune.com/uploads/default/original/1X/a4cf7777036b8078312c66f179d051ab5701d054.jpeg)

What ccls responds (to the `textDocument/completion` request) is something like this:

```json
{"label":"foo(int a, int b) -> void","kind":3,"detail":"","sortText":" ","filterText":"foo","insertTextFormat
":1,"textEdit":{"range":{"start":{"line":4,"character":4},"end":{"line":4,"character":7}},"newText":"foo"}

```

The client is expected to insert `newText` instead of `label` in the buffer.

---

<div class="post-metadata">

**Author:** ![andreyorst](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/andreyorst/32/29_2.png) [@andreyorst](https://discuss.kakoune.com/u/andreyorst)\
**Post date:** [October 13, 2019, 10:20am UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/2 "2019-10-13T10:20:30Z")

</div>

I can’t understand if this is an instruction or a complaint?

---

<div class="post-metadata">

**Author:** ![MaskRay](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/maskray/32/336_2.png) [@MaskRay](https://discuss.kakoune.com/u/MaskRay)\
**Post date:** [October 13, 2019, 2:52pm UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/3 "2019-10-13T14:52:11Z")

</div>

Both an instruction and a complaint (I have to workaround the `textEdit` feature that is not supported). ul pointed me to [https://github.com/mawww/kakoune/issues/2898](https://github.com/mawww/kakoune/issues/2898)

---

<div class="post-metadata">

**Author:** ![occivink](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/occivink/32/27_2.png) [@occivink](https://discuss.kakoune.com/u/occivink)\
**Post date:** [October 13, 2019, 4:08pm UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/4 "2019-10-13T16:08:48Z")

</div>

It’s nice to have you here. Thanks for working on ccls, it’s really good.

---

<div class="post-metadata">

**Author:** ![andreyorst](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/andreyorst/32/29_2.png) [@andreyorst](https://discuss.kakoune.com/u/andreyorst)\
**Post date:** [October 13, 2019, 7:45pm UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/5 "2019-10-13T19:45:00Z")

</div>

what advantages does it have over `clangd`?

---

<div class="post-metadata">

**Author:** ![MaskRay](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/maskray/32/336_2.png) [@MaskRay](https://discuss.kakoune.com/u/MaskRay)\
**Post date:** [October 16, 2019, 2:26am UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/6 "2019-10-16T02:26:34Z")

</div>

IMO ccls has a better global index model.

Better performance, better indexing features, more initialization options for customization. clangd has recently provided some niche features that I’d like to investigate: clang-tidy integration, expanding macros, expanding `auto`, etc.

The core of ccls is significantly simpler than clangd. It is much less clang-oriented. In theory it can be easily adapted to create language servers for other programming languages. Yes, I have to say a lot of language servers do not do cross references correctly.

---

<div class="post-metadata">

**Author:** ![andreyorst](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/andreyorst/32/29_2.png) [@andreyorst](https://discuss.kakoune.com/u/andreyorst)\
**Post date:** [October 16, 2019, 5:49am UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/7 "2019-10-16T05:49:30Z")

</div>

> Better performance, better indexing features

in my experience it is the opposite. I’m using network mounted file system via **sshfs** and **clangd** instantly works insanely fast on our project, which is pretty big, while **ccls** had to build some cache before becoming responsible and later had some issues with snappiness. Though this may be outdated information, because I’ve tried **ccls** maybe half a year ago or more.

The other feature of **clangd** that I like, is that it can either use `compile_commands.json` or `compile_flags.txt`. **ccls** also can use `compile_commands.json`, but `.ccls` is much more complex, compared to `compile_flags.txt` which I can basically use in my Makefiles like so: `CFLAGS = $(shell cat compile_flags.txt | tr '\n' ' ')` and then have identical flags for linting and compilation.

---

<div class="post-metadata">

**Author:** ![MaskRay](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/maskray/32/336_2.png) [@MaskRay](https://discuss.kakoune.com/u/MaskRay)\
**Post date:** [October 16, 2019, 8:05am UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/8 "2019-10-16T08:05:20Z")

</div>

> in my experience it is the opposite. I’m using network mounted file system via **sshfs** and **clangd** instantly works insanely fast on our project, which is pretty big, while **ccls** had to build some cache before becoming responsible and later had some issues with snappiness. Though this may be outdated information, because I’ve tried **ccls** maybe half a year ago or more.

I think that is because you don’t use `clangd -background-index`. You will not get project-wide references.

You can get similar behavior from ccls with the initialization option [`index.initialBlacklist`](https://github.com/MaskRay/ccls/wiki/Customization#indexinitialblacklist)

`args = ["--init={\"index\":{\"initialBlackList\":["."]}}"]`

> The other feature of **clangd** that I like, is that it can either use `compile_commands.json` or `compile_flags.txt` . **ccls** also can use `compile_commands.json` , but `.ccls` is much more complex

Yes, it supports some `%cpp` directives, but you can use it as if you are using `compile_flags.txt`. I have provided some examples ([Project Setup · MaskRay/ccls Wiki · GitHub](https://github.com/MaskRay/ccls/wiki/Project-Setup#ccls-examples)) but I understand that people may be reluctant to read the full description.

For that simple use case, the only difference between `compile_flags.txt` and `.ccls` is that `.ccls` requires explicit mention of the compiler driver, which is usually `clang`. There are good reasons to behave this way, you may try `aarch64-linux-gnu-clang` and `clang-cl`.

---

<div class="post-metadata">

**Author:** ![andreyorst](https://discuss.kakoune.com/user_avatar/discuss.kakoune.com/andreyorst/32/29_2.png) [@andreyorst](https://discuss.kakoune.com/u/andreyorst)\
**Post date:** [October 16, 2019, 10:07am UTC](https://discuss.kakoune.com/t/kak-lsp-ccls/750/9 "2019-10-16T10:07:41Z")

</div>

> [@MaskRay](#):
>
> I think that is because you don’t use `clangd -background-index` . You will not get project-wide references.

I don’t use references at all, so I think I can live with that.
