cxxd

C/C++ language server implemented on top of Clang frontend.

Github星跟踪图

Contents

About

cxxd is a C/C++ language server which offers rich support for features that aid the process of source code navigation, editing,
automatic formatting, static analysis etc. One can utilize it, for example, to bring IDE-like features to an editor of your choice.

Features

Feature, Status, cxxd-vim frontend
------------, :-------------:, :-------------:
Indexer, :heavy_check_mark:, :heavy_check_mark:
Find-all-references, :heavy_check_mark:, :heavy_check_mark:
Go-to-definition, :heavy_check_mark:, :heavy_check_mark:
Go-to-include, :heavy_check_mark:, :heavy_check_mark:
Type-deduction, :heavy_check_mark:, :heavy_check_mark:
Fetch-all-diagnostics, :heavy_check_mark:, :heavy_check_mark:
Fixits-and-diagnostics, :heavy_check_mark:, :heavy_check_mark:
Semantic-syntax-highlighting, :heavy_check_mark:, :heavy_check_mark:
Code-completion, work-in-progress, work-in-progress
Clang-tidy, :heavy_check_mark:, :heavy_check_mark:
Clang-format, :heavy_check_mark:, :heavy_check_mark:
JSON-compilation-database, :heavy_check_mark:, :heavy_check_mark:
Project-builder, :heavy_check_mark:, :heavy_check_mark:
External configuration via JSON, :heavy_check_mark:, :heavy_check_mark:

In essence, the main idea behind it is very much alike to what LSP offers
and its implementations like clangd.

Supported platforms

Platform, Status, Comments
------------, :-------------:, :-------------:
Linux, :heavy_check_mark:, Main development environment of this project.
Windows, :x:, Not officially tested but it might work.
macOS, :x:, Not officially tested but it might work.

Dependencies

Required: Python2, libclang (with Python bindings), g++

Optional: clang-format, clang-tidy

In Fedora-based distributions, one may install the dependencies by running:

  • sudo dnf install python2 clang-devel clang-libs clang-tools-extra && pip install --user clang

In Debian-based distributions, one may install the dependencies by running:

  • sudo apt-get install python2.7 libclang-dev clang-tidy clang-format && pip install --user clang

API

API tries to stay fairly trivial and straightforward without putting too much burden (impl. details) on the frontend side but there are couple of important bits and pieces that should be understood in order to efficiently use this API.

Design

Services

Aforementioned features are organized into services.
Each service:

  • Is assigned its own unique ID
  • Runs in its own context (process)
  • Supports a set of common operations: startup, shutdown, request
  • Provides a user-defined hook, so called plugin, to be invoked on completion of any of the supported operations

Server

Communication with any of the service is established/routed via proxy server which sits in between the client (frontend) and corresponding service. Server implements a very simple API:

  • start-all-services
  • start-service
  • shutdown-all-services
  • shutdown-service
  • send-service-request

Public API, which is exposed to clients, is implemented on top of server API.

Async

API, due to the nature of features being implemented, is designed to work in an asynchronous fashion. That means that retrieving the result from corresponding operation cannot be done via regular (synchronous) return-value mechanism but instead one must register a hook (callback) object which will then be invoked once the result is ready (after operation has completed). These callbacks we call plugins.

Plugin

Plugin is a mechanism to subscribe for a result of an asynchronous operation. This is a customization go-to point for client code to decide what to do with the result (e.g. process it further and communicate it back to the frontend using the appropriate inter-process mechanism).

Diagram

Diagram

Example usage

cxxd integration tests

Integration test suite is actually a representative example of a frontend which has a main purpose in validating the data computed by the services (e.g. if go-to-definition returns a valid/expected source code location). Some other frontends will rather like to do something more with the data, e.g. visualize it or populate the UI elements with it.

So, integration tests have all of the important bits which depict the usage of an API:

  • We have to start the server before anything else.

  • A mechanism which provides customization point for application-specific purposes is factory function. Factory function will be invoked during the server startup phase. Its purpose is to provide a means to instantiate an application-specific server with main (customization) part being the registration of application-specific plugins.

  • Application-specific plugins in integration tests will only make a copy of received data to be able to validate its contents from the test execution context.

  • To communicate the received data to different execution contexts (processes), one shall use some form of inter-process communication mechanisms. This integration test suite implements the inter-process communication by utilizing the shared-memory to store the data and named-semaphores to synchronize between R/W accesses. Some other application will use other means to achieve the same (i.e. to communicate the data back to vim instance one could make use one of the RPC mechanisms that vim provides).

  • Example of triggering the service is running the source code indexer on the given directory, waiting until it is completed and querying if it has run successfuly.

  • Many other examples depicting the usage of an API

Frontend implementation for Vim

Public API

General cxxd server startup/shutdown API, API, Return Value, -------------, :-------------:, server_start(get_server_instance, get_server_instance_args, project_root_directory, log_file), handle, server_stop(handle, *payload), status, payload, server_start_all_services(handle, *payload), status, payload, server_stop_all_services(handle, *payload), status, payload, ----------------------------

Source code model API, API, Return Value, -------------, :-------------:, source_code_model_start(handle, compiler_args), status, payload, source_code_model_stop(handle, subscribe_for_callback), status, payload, source_code_model_semantic_syntax_highlight_request(handle, filename, contents), status, [translation_unit_ast, ast_visitor_function], source_code_model_diagnostics_request(handle, filename, contents), status, [diagnostics_iterator, diagnostics_visitor_function, fixit_visitor_function], source_code_model_type_deduction_request(handle, filename, contents, line, col), status, type_spelling, source_code_model_go_to_definition_request(handle, filename, contents, line, col), status, [definition_filename, definition_line, definition_column], source_code_model_go_to_include_request(handle, filename, contents, line), status, include_header_filename, source_code_model_indexer_run_on_single_file_request(handle, filename, contents), status, None, source_code_model_indexer_run_on_directory_request(handle), status, None, source_code_model_indexer_drop_single_file_request(handle, filename), status, None, source_code_model_indexer_drop_all_request(handle, remove_db_from_disk), status, None, source_code_model_indexer_drop_all_and_run_on_directory_request(handle), status, None, source_code_model_indexer_find_all_references_request(handle, filename, line, col), status, list_of_references(filename, line, column, context), source_code_model_indexer_fetch_all_diagnostics_request(handle, sorting_strategy), status, list_of_diagnostics(filename, line, column, description, severity), ----------------------------

Project Builder API, API, Return Value, -------------, :-------------:, project_builder_start(handle), status, payload, project_builder_stop(handle, subscribe_for_callback), status, payload, project_builder_request(handle, build_command), status, [build_cmd_output_filename, build_exit_code, duration], ----------------------------

Clang-format API, API, Return Value, -------------, :-------------:, clang_format_start(handle), status, payload, clang_format_stop(handle, subscribe_for_callback), status, payload, clang_format_request(handle, filename), status, None, ----------------------------

Clang-tidy API, API, Return Value, -------------, :-------------:, clang_tidy_start(handle, json_compilation_database), status, payload, clang_tidy_stop(handle, subscribe_for_callback), status, payload, clang_tidy_request(handle, filename, apply_fixes), status, clang_tidy_output_filename, # Screenshots

Screenshots from cxxd-vim

FAQ

How do I make use of this in <insert_environment_of_your_choice>?

Look for and install a frontend suitable for your environment. I.e. cxxd-vim if you want to try it out from Vim. This is only a backend server.
Other supported frontends are listed in the table from above and hopefully more will come with the help of community.

How do I develop a new frontend on top of it?

Understand the API. Look how cxxd integration tests have been implemented on top if it. Look into other available frontend implementations, such as the one for Vim.

Why?

One may question the reasoning behind the existence of this project (given that we have other alternatives such as aforementioned clangd),
but the whole idea and implementation
started to grow couple of months before LSP has been officially announced and, this being my own pet project, I decided not to stop with the development but to try to drive it more forward.

Idea may not have been obvious or recognized by many people as it has been actively developed under my other project, Yavide, which is a heavily modded Vim so naturally not really attracted by many. In order to enable usage from different editors (or any other type of frontends), I have decied to finally put some effort into packaging the server functionality into this standalone repository.

主要指标

概览
名称与所有者JBakamovic/cxxd
主编程语言Python
编程语言Python (语言数: 1)
平台
许可证GNU General Public License v3.0
所有者活动
创建于2017-12-15 16:09:24
推送于2023-03-30 12:33:23
最后一次提交2023-01-03 15:40:50
发布数0
用户参与
星数153
关注者数11
派生数9
提交数219
已启用问题?
问题数7
打开的问题数4
拉请求数0
打开的拉请求数0
关闭的拉请求数0
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?