85 releases

0.8.12 Oct 21, 2024
0.8.6 Sep 28, 2024
0.7.9 Jul 21, 2024
0.6.20 Mar 7, 2024
0.2.4 Jul 17, 2022

#4 in Text editors

Download history 1528/week @ 2024-07-17 1340/week @ 2024-07-24 1604/week @ 2024-07-31 1160/week @ 2024-08-07 1662/week @ 2024-08-14 1100/week @ 2024-08-21 1757/week @ 2024-08-28 1171/week @ 2024-09-04 2608/week @ 2024-09-11 1424/week @ 2024-09-18 1967/week @ 2024-09-25 1291/week @ 2024-10-02 2962/week @ 2024-10-09 1712/week @ 2024-10-16 1475/week @ 2024-10-23 976/week @ 2024-10-30

7,297 downloads per month

MIT license

4MB
8K SLoC

CMake LSP implementation based on Tower and Tree-sitter

Crates.io codecov

Intelligent Code Completion: Provides precise code completions by analyzing CMake files, enhancing development efficiency.

  • Real-time Error Detection: Integrates linting functionality to check for potential issues in your code, help maintaining code quality.
  • Support for Neovim, Emacs, VSCode, Helix: Compatible with these popular editors, catering to diverse developer needs.
  • Simple Configuration: Easy to set up and use, minimizing configuration time so you can focus on development.
  • CLI Integration: Not only an LSP, but also includes command-line tools for code formatting, making it convenient for different environments.

If you have any questions or want to help in other ways, feel free to join out matrix room.

Table of Contents

  1. Introduction
  2. Features
  3. Installation
  4. Editor Support
  5. Features
  6. User Feedback
  7. Visual Examples

Installation

cargo install neocmakelsp

Editor Support

Neovim

The configuration of neocmakelsp is in nvim-lspconfig, so just follow nvim-lsp-config to setup it

neocmakelsp can talk to clients in two ways: stdio and tcp. tcp is primarily for debugging. If you want to add a feature or find a bug, you should connect via tcp.

stdio

local configs = require("lspconfig.configs")
local nvim_lsp = require("lspconfig")
if not configs.neocmake then
    configs.neocmake = {
        default_config = {
            cmd = { "neocmakelsp", "--stdio" },
            filetypes = { "cmake" },
            root_dir = function(fname)
                return nvim_lsp.util.find_git_ancestor(fname)
            end,
            single_file_support = true,-- suggested
            on_attach = on_attach, -- on_attach is the on_attach function you defined
            init_options = {
                format = {
                    enable = true
                },
                lint = {
                    enable = true
                },
                scan_cmake_in_package = true -- default is true
            }
        }
    }
    nvim_lsp.neocmake.setup({})
end

tcp

if not configs.neocmake then
    configs.neocmake = {
        default_config = {
            cmd = vim.lsp.rpc.connect('127.0.0.1','9257'),
            filetypes = { "cmake" },
            root_dir = function(fname)
                return nvim_lsp.util.find_git_ancestor(fname)
            end,
            single_file_support = true,-- suggested
            on_attach = on_attach, -- on_attach is the on_attach function you defined
            init_options = {
                format = {
                    enable = true
                }
            }
        }
    }
    nvim_lsp.neocmake.setup({})
end

Helix

stdio

[[language]]
name = "cmake"
auto-format = true
language-servers = [{ name = "neocmakelsp" }]

[language-server.neocmakelsp]
command = "neocmakelsp"
args = ["--stdio"]

tcp

[[language]]
name = "neocmake"
auto-format = true
language-servers = [{ name = "neocmakelsp" }]

[language-server.neocmakelsp]
command = "nc"
args = ["localhost", "9257"]

Emacs

To use neocmakelsp with eglot:

(use-package cmake-ts-mode
  :config
  (add-hook 'cmake-ts-mode-hook
    (defun setup-neocmakelsp ()
      (require 'eglot)
      (add-to-list 'eglot-server-programs `((cmake-ts-mode) . ("neocmakelsp" "--stdio")))
      (eglot-ensure))))

Features

  • watchfile
  • complete
  • symbol_provider
  • On hover
  • Format
  • document_link
  • GO TO Definitation
    • find_package
    • include
  • Search cli
  • Get the project struct
  • It is also a cli tool to format
  • Lint

Lint form 6.0.27

Put a file named .neocmakelint.toml under the root of the project.

command_upcase = "ignore" # "lowercase", "upcase"

This will check the case of all commands.

cmake-lint integration

When cmake-lint is installed, neocmakelsp will utilize it to offer linting and code analysis each time the file is saved. This functionality can be enabled or disabled in the .neocmakelint.toml file:

enable_external_cmake_lint = true # true to use external cmake-lint, or false to disable it

If enable_external_cmake_lint is turned on but cmake-lint is not installed, external linting will not report any error message.

If you want to use watchfile in Neovim, set

capabilities = {
    workspace = {
        didChangeWatchedFiles = {
            dynamicRegistration = true,
            relative_pattern_support = true,
        },

    },

}

It will check CMakeCache.txt, and get whether the package is exist

Snippet Support

capabilities = {
   textDocument = {
       completion = {
           completionItem = {
               snippetSupport = true
           }
       }
   }
}

LSP init_options

init_options = {
    format = {
        enable = true, -- to use lsp format
    },
    lint = {
        enable = true
    },
    scan_cmake_in_package = false, -- it will deeply check the cmake file which found when search cmake packages.
    semantic_token = false,
    -- semantic_token heighlight. if you use treesitter highlight, it is suggested to set with false. it can be used to make better highlight for vscode which only has textmate highlight
}

TODO

  • Undefined function check

Visual Examples

Search

symbol

Symbol

Complete and symbol support

Complete CompleteFindpackage

OnHover

onHover

GoToDefinition

Show JumpToFile

Tree

TreeShow

Format cli

Note: When formatting files, make sure that your .editorconfig file is in your working directory

format the file

Usage: neocmakelsp {format|--format|-F} [OPTIONS] <FormatPath>...

Arguments:
  <FormatPath>...  file or folder to format

Options:
  -o, --override  override
  -h, --help      Print help

It will read .editorconfig file to format files, just set like

[CMakeLists.txt]
indent_style = space
indent_size = 4

Note

The format do the min things, just do trim and place the first line to the right place by the indent you set, this means

function(A)

        set(A
        B
            C
        )

    endfunction()

it will just become


function(A)

    set(A
        B
            C
        )

endfunction()

It just remove the space in the end, replace \t at the begin of each line to , if set indent_size to space, and format the first line to right place. It does little, but I think it is enough.

User Feedback

  • I do not know if all features will work on macOS and Windows, so if someone use macOS or Windows, please open an issue if you find any bugs.
  • I want a co-maintainer, who ideally is familiar with macOS, Windows and LSP.

Dependencies

~17–29MB
~423K SLoC