What is clice?
clice is a completely new C++ language server designed to address the shortcomings of existing C++ language servers. It provides code navigation and intelligent suggestions for your editor.
Why a New Language Server?
So the first question is, why develop a new language server? Is it necessary to reinvent the wheel?
This question deserves a serious answer. Before this project, I had written many projects, both large and small. But the vast majority of them were toy projects, written only to verify some idea or for personal learning, without solving any real problems. clice is not like that - it genuinely intends to solve existing problems (specific problems will be discussed later), rather than rewriting for the sake of rewriting.
At the beginning of this year, I wanted to participate in the development of the LLVM project. I wanted to start from what I'm more familiar with - C++, specifically clang. But without requirements, I couldn't just stare at the source code. The normal process in such cases is to start with some "first issues" and gradually get familiar with the project. But I found this boring - I wanted to do something big right from the start, like implementing some new C++ standard feature. However, I found there was almost no place for me to get involved here, as new feature implementations are almost always completed by a few core clang developers. Well, since there's no opportunity here, let's look elsewhere. My attention naturally shifted to clangd, since I mainly use VSCode for development, and the best C++ language server on VSCode is clangd.
At the time, I knew nothing about clangd, except that I found it seemed to render keyword highlighting incorrectly. So I started reading clangd's source code while browsing through clangd's numerous issues to see if there was anything I could solve. After going through hundreds of issues, I found there were quite a few problems here. At the time, I was particularly interested in an issue about code completion within templates. Why was I interested in this? Readers familiar with me might know that I'm quite an experienced metaprogramming player, having written many related articles before. Naturally, I'm not only curious about how template metaprogramming itself works, but also curious about how clang, as a compiler, implements related features. This issue was a good entry point for me. After spending several weeks exploring prototype implementations, I initially solved that issue, but then I found that there was no one to review the related code!
After some investigation, I found that clangd's current situation is quite bad. Let's go through the timeline: clangd was originally just a simple small project within LLVM, not outstanding in terms of functionality and usability. As MaskRay mentioned in this blog post about ccls, clangd at the time could only handle single compilation units, and cross-compilation unit requests couldn't be processed. This blog post was published in 2017, which is also one reason why MaskRay chose to write ccls. ccls is also a C/C++ language server that was stronger than clangd at that point. However, later, Google started sending people to improve clangd to meet their internal large codebase needs. At the same time, the LSP standard content was constantly expanding, and clangd was continuously following up on new standard content, but ccls's author seemed to gradually become busy with other things and didn't have much time to maintain ccls. So in the end, clangd had surpassed ccls overall. The turning point occurred around 2023, when clangd seemed to have reached a highly usable state for Google internally, and the original employees responsible for clangd were transferred to do other things. Currently, clangd's issues are mainly handled by only one person, HighCommander4, purely out of passion, not employed by anyone. Since he's not specifically employed to maintain clangd, he can only handle issues in his limited free time, and only limited to answering questions and very limited reviews. As he mentioned in this comment:
The other part of the reason is lack of resources to pursue the ideas we do have, such as the idea mentioned above of trying to shift more of the burden to disk usage through more aggressive preamble caching. I'm a casual contributor, and the limited time I have to spend on clangd is mostly taken up by answering questions, some code reviews, and the occasional small fix / improvement; I haven't had the bandwidth to drive this type of performance-related experimentation.
Given this situation, it's not surprising that large PRs like preliminary support for C++20 modules for clangd have been delayed for nearly a year. After realizing this current state, I had the idea of writing a language server myself. I estimated the project size - removing test code, it would take about 20,000 lines to complete, which is a workload that one person can accomplish over a period of time, and there are precedents like ccls and rust-analyzer. Another point is that clangd's code is already dated - despite having many comments, the related logic is still very convoluted, and the time spent on large-scale modifications might not be faster than rewriting.
So I got to work. I categorized clangd's hundreds of issues to see if there were some problems that were difficult to solve due to clangd's initial architectural design errors and were therefore shelved. If so, could these be considered and solved during redesign? I found that there were indeed some! So in the following time, I spent about two months learning and researching the related mechanisms in clang, exploring solutions to related problems, and exploring prototype implementations. After confirming that the related problems could basically be solved, I officially started the development of clice.