// Copyright 2017-2018 ccls Authors // SPDX-License-Identifier: Apache-2.0 #pragma once #include "serializer.hh" #include namespace ccls { /* The language client plugin needs to send initialization options in the `initialize` request to the ccls language server. If necessary, the command line option --init can be used to override initialization options specified by the client. For example, in shell syntax: '--init={"index": {"comments": 2, "whitelist": ["."]}}' */ struct Config { // **Not available for configuration** std::string fallbackFolder; std::vector> workspaceFolders; // If specified, this option overrides compile_commands.json and this // external command will be executed with an option |projectRoot|. // The initialization options will be provided as stdin. // The stdout of the command should be the JSON compilation database. std::string compilationDatabaseCommand; // Directory containing compile_commands.json. std::string compilationDatabaseDirectory; struct Cache { // Cache directory for indexed files, either absolute or relative to the // project root. // // If empty, retainInMemory will be set to 1 and cache will be stored in // memory. std::string directory = ".ccls-cache"; // Cache serialization format. // // "json" generates $directory/.../xxx.json files which can be pretty // printed with jq. // // "binary" uses a compact binary serialization format. // It is not schema-aware and you need to re-index whenever an internal // struct member has changed. SerializeFormat format = SerializeFormat::Binary; // If false, store cache files as $directory/@a@b/c.cc.blob // // If true, $directory/a/b/c.cc.blob. If cache.directory is absolute, make // sure different projects use different cache.directory as they would have // conflicting cache files for system headers. bool hierarchicalPath = false; // After this number of loads, keep a copy of file index in memory (which // increases memory usage). During incremental updates, the index subtracted // will come from the in-memory copy, instead of the on-disk file. // // The initial load or a save action is counted as one load. // 0: never retain; 1: retain after initial load; 2: retain after 2 loads // (initial load+first save) int retainInMemory = 2; } cache; struct ServerCap { struct DocumentOnTypeFormattingOptions { std::string firstTriggerCharacter = "}"; std::vector moreTriggerCharacter; } documentOnTypeFormattingProvider; // Set to false if you don't want folding ranges. bool foldingRangeProvider = true; struct Workspace { struct WorkspaceFolders { // Set to false if you don't want workspace folders. bool supported = true; bool changeNotifications = true; } workspaceFolders; } workspace; } capabilities; struct Clang { // Arguments matching any of these glob patterns will be excluded, e.g. // ["-fopenmp", "-m*", "-Wall"]. std::vector excludeArgs; // Additional arguments to pass to clang. std::vector extraArgs; // Translate absolute paths in compile_commands.json entries, .ccls options // and cache files. This allows to reuse cache files built otherwhere if the // source paths are different. // // This is a list of colon-separated strings, e.g. ["/container:/host"] // // An entry of "clang -I /container/include /container/a.cc" will be // translated to "clang -I /host/include /host/a.cc". This is simple string // replacement, so "clang /prefix/container/a.cc" will become "clang // /prefix/host/a.cc". std::vector pathMappings; // Value to use for clang -resource-dir if not specified. // // This option defaults to clang -print-resource-dir and should not be // specified unless you are using an esoteric configuration. std::string resourceDir; } clang; struct ClientCapability { // TextDocumentClientCapabilities.publishDiagnostics.relatedInformation bool diagnosticsRelatedInformation = true; // TextDocumentClientCapabilities.documentSymbol.hierarchicalDocumentSymbolSupport bool hierarchicalDocumentSymbolSupport = true; // TextDocumentClientCapabilities.definition.linkSupport bool linkSupport = true; // If false, disable snippets and complete just the identifier part. // TextDocumentClientCapabilities.completion.completionItem.snippetSupport bool snippetSupport = true; } client; struct CodeLens { // Enables code lens on parameter and function variables. bool localVariables = true; } codeLens; struct Completion { // 0: case-insensitive // 1: case-folded, i.e. insensitive if no input character is uppercase. // 2: case-sensitive int caseSensitivity = 2; // Some completion UI, such as Emacs' completion-at-point and company-lsp, // display completion item label and detail side by side. // This does not look right, when you see things like: // "foo" "int foo()" // "bar" "void bar(int i = 0)" // When this option is enabled, the completion item label is very detailed, // it shows the full signature of the candidate. // The detail just contains the completion item parent context. bool detailedLabel = true; // On large projects, completion can take a long time. By default if ccls // receives multiple completion requests while completion is still running // it will only service the newest request. If this is set to false then all // completion requests will be serviced. bool dropOldRequests = true; // Functions with default arguments, generate one more item per default // argument. That is, you get something like: // "int foo()" "Foo" // "void bar()" "Foo" // "void bar(int i = 0)" "Foo" // Be wary, this is quickly quite verbose, // items can end up truncated by the UIs. bool duplicateOptional = true; // If true, filter and sort completion response. ccls filters and sorts // completions to try to be nicer to clients that can't handle big numbers // of completion candidates. This behaviour can be disabled by specifying // false for the option. This option is the most useful for LSP clients // that implement their own filtering and sorting logic. bool filterAndSort = true; struct Include { // Regex patterns to match include completion candidates against. They // receive the absolute file path. // // For example, to hide all files in a /CACHE/ folder, use ".*/CACHE/.*" std::vector blacklist; // Maximum path length to show in completion results. Paths longer than // this will be elided with ".." put at the front. Set to 0 or a negative // number to disable eliding. int maxPathSize = 30; // Whitelist that file paths will be tested against. If a file path does // not end in one of these values, it will not be considered for // auto-completion. An example value is { ".h", ".hpp" } // // This is significantly faster than using a regex. std::vector suffixWhitelist = {".h", ".hpp", ".hh", ".inc"}; std::vector whitelist; } include; // Maxmum number of results. int maxNum = 100; // Add placeholder text. Effective only if client.snippetSupport is true. // // false: foo($1)$0 // true: foo(${1:int a}, ${2:int b})$0 bool placeholder = true; } completion; struct Diagnostics { // Like index.{whitelist,blacklist}, don't publish diagnostics to // blacklisted files. std::vector blacklist; // Time to wait before computing diagnostics for textDocument/didChange. // -1: disable diagnostics on change // 0: immediately // positive (e.g. 500): wait for 500 milliseconds. didChange requests in // this period of time will only cause one computation. int onChange = 1000; // Time to wait before computing diagnostics for textDocument/didOpen. int onOpen = 0; // Time to wait before computing diagnostics for textDocument/didSave. int onSave = 0; bool spellChecking = true; std::vector whitelist; } diagnostics; // Semantic highlighting struct Highlight { // Disable semantic highlighting for files larger than the size. int64_t largeFileSize = 2 * 1024 * 1024; // true: LSP line/character; false: position bool lsRanges = false; // Like index.{whitelist,blacklist}, don't publish semantic highlighting to // blacklisted files. std::vector blacklist; std::vector whitelist; } highlight; struct Index { // If a translation unit's absolute path matches any EMCAScript regex in the // whitelist, or does not match any regex in the blacklist, it will be // indexed. To only index files in the whitelist, add ".*" to the blacklist. // `std::regex_search(path, regex, std::regex_constants::match_any)` // // Example: `ash/.*\.cc` std::vector blacklist; // 0: none, 1: Doxygen, 2: all comments // Plugin support for clients: // - https://github.com/emacs-lsp/lsp-ui // - https://github.com/autozimu/LanguageClient-neovim/issues/224 int comments = 2; // If false, names of no linkage are not indexed in the background. They are // indexed after the files are opened. bool initialNoLinkage = false; // Use the two options to exclude files that should not be indexed in the // background. std::vector initialBlacklist; std::vector initialWhitelist; // If a variable initializer/macro replacement-list has fewer than this many // lines, include the initializer in detailed_name. int maxInitializerLines = 5; // If not 0, a file will be indexed in each tranlation unit that includes // it. int multiVersion = 0; // If multiVersion != 0, files that match blacklist but not whitelist will // still only be indexed for one version. std::vector multiVersionBlacklist; std::vector multiVersionWhitelist; struct Name { // Suppress inline and unnamed namespaces in identifier names. bool suppressUnwrittenScope = false; } name; // Allow indexing on textDocument/didChange. // May be too slow for big projects, so it is off by default. bool onChange = false; // If true, index parameters in declarations. bool parametersInDeclarations = true; // Number of indexer threads. If 0, 80% of cores are used. int threads = 0; // Whether to reparse a file if write times of its dependencies have // changed. The file will always be reparsed if its own write time changes. // 0: no, 1: only during initial load of project, 2: yes int trackDependency = 2; std::vector whitelist; } index; struct Request { // If the document of a request has not been indexed, wait up to this many // milleseconds before reporting error. int64_t timeout = 5000; } request; struct Session { int maxNum = 10; } session; struct WorkspaceSymbol { int caseSensitivity = 1; // Maximum workspace search results. int maxNum = 1000; // If true, workspace search results will be dynamically rescored/reordered // as the search progresses. Some clients do their own ordering and assume // that the results stay sorted in the same order as the search progresses. bool sort = true; } workspaceSymbol; struct Xref { // Maximum number of definition/reference/... results. int maxNum = 2000; } xref; }; REFLECT_STRUCT(Config::Cache, directory, format, hierarchicalPath, retainInMemory); REFLECT_STRUCT(Config::ServerCap::DocumentOnTypeFormattingOptions, firstTriggerCharacter, moreTriggerCharacter); REFLECT_STRUCT(Config::ServerCap::Workspace::WorkspaceFolders, supported, changeNotifications); REFLECT_STRUCT(Config::ServerCap::Workspace, workspaceFolders); REFLECT_STRUCT(Config::ServerCap, documentOnTypeFormattingProvider, foldingRangeProvider, workspace); REFLECT_STRUCT(Config::Clang, excludeArgs, extraArgs, pathMappings, resourceDir); REFLECT_STRUCT(Config::ClientCapability, diagnosticsRelatedInformation, hierarchicalDocumentSymbolSupport, linkSupport, snippetSupport); REFLECT_STRUCT(Config::CodeLens, localVariables); REFLECT_STRUCT(Config::Completion::Include, blacklist, maxPathSize, suffixWhitelist, whitelist); REFLECT_STRUCT(Config::Completion, caseSensitivity, detailedLabel, dropOldRequests, duplicateOptional, filterAndSort, include, maxNum, placeholder); REFLECT_STRUCT(Config::Diagnostics, blacklist, onChange, onOpen, onSave, spellChecking, whitelist) REFLECT_STRUCT(Config::Highlight, largeFileSize, lsRanges, blacklist, whitelist) REFLECT_STRUCT(Config::Index::Name, suppressUnwrittenScope); REFLECT_STRUCT(Config::Index, blacklist, comments, initialNoLinkage, initialBlacklist, initialWhitelist, maxInitializerLines, multiVersion, multiVersionBlacklist, multiVersionWhitelist, name, onChange, parametersInDeclarations, threads, trackDependency, whitelist); REFLECT_STRUCT(Config::Request, timeout); REFLECT_STRUCT(Config::Session, maxNum); REFLECT_STRUCT(Config::WorkspaceSymbol, caseSensitivity, maxNum, sort); REFLECT_STRUCT(Config::Xref, maxNum); REFLECT_STRUCT(Config, compilationDatabaseCommand, compilationDatabaseDirectory, cache, capabilities, clang, client, codeLens, completion, diagnostics, highlight, index, request, session, workspaceSymbol, xref); extern Config *g_config; void doPathMapping(std::string &arg); } // namespace ccls