Skip to content

Commit

Permalink
Allow changing the command used to start clangd (#11)
Browse files Browse the repository at this point in the history
* Allow changing the command used to start clangd

* Update `custom_command` description
  • Loading branch information
LDAP authored Mar 19, 2023
1 parent 72b6590 commit 04c8dae
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 16 deletions.
15 changes: 12 additions & 3 deletions LSP-clangd.sublime-settings
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,26 @@
/////////////////////////

// The clangd binary to use.
// "system": Prefers the system binary found in path
// "system": Prefers the system binary below
// "auto": Prefers the system binary but falls back to GitHub without user intervention
// "github": Prefers the latest tested release from GitHub
// "custom": Use the custom command in the initializationOptions below
"binary": "system",
// The command to start `clangd`, generated internally.
// The binary to use when `binary` is set to `system`.
"system_binary": "clangd",
// Generated internally because clangd is configured via command line arguments.
// DO NOT CHANGE THIS, use `system_binary` or `custom_command` instead.
"command": [],
// Enable clangd for C/C++ and Objective-C/C++
"selector": "source.c | source.c++ | source.objc | source.objc++ | source.cuda-c++",
// Makes the auto-complete not trigger twice when writing a -> or when writing ::
"auto_complete_selector": "punctuation.accessor | (meta.preprocessor.include string - punctuation.definition.string.end)",
"initializationOptions": {
// A custom command to start clangd. Set `binary` to `custom` to use this command.
// The command-line arguments which are generated from the `clang.*` settings are appended to this command.
// This can be used for MSYS2's clangd for example.
"custom_command": [],

// @see https://clangd.llvm.org/extensions#file-status
// Enables receiving textDocument/clangd.fileStatus notifications.
// -- unsupported --
Expand Down Expand Up @@ -93,4 +102,4 @@
// Pretty-print JSON output
"clangd.pretty": false,
},
}
}
37 changes: 28 additions & 9 deletions plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,45 @@ def storage_subpath(cls) -> str:
return os.path.join(cls.storage_path(), STORAGE_DIR)

@classmethod
def managed_server_binary_path(cls) -> Optional[str]:
def managed_clangd_path(cls) -> Optional[str]:
binary_name = "clangd.exe" if sublime.platform() == "windows" else "clangd"
path = os.path.join(cls.storage_subpath(), "clangd_{version}/bin/{binary_name}".format(version=VERSION_STRING, binary_name=binary_name))
if os.path.exists(path):
return path
return None

@classmethod
def system_clangd_path(cls) -> Optional[str]:
system_binary = get_settings().get("system_binary")
# Detect if clangd is installed or the command points to a valid binary.
# Fallback, shutil.which has issues on Windows.
system_binary_path = shutil.which(system_binary) or system_binary
if not os.path.isfile(system_binary_path):
return None
return system_binary_path

@classmethod
def clangd_path(cls) -> Optional[str]:
"""The command to start clangd without any configuration arguments"""
binary_setting = get_settings().get("binary")
if binary_setting == "system":
return shutil.which("clangd")
return cls.system_clangd_path()
elif binary_setting == "github":
return cls.managed_server_binary_path()
return cls.managed_clangd_path()
else:
# binary_setting == "auto":
return shutil.which("clangd") or cls.managed_server_binary_path()
return cls.system_clangd_path() or cls.managed_clangd_path()

@classmethod
def needs_update_or_installation(cls) -> bool:
if get_settings().get("binary") == "custom":
return False
return cls.clangd_path() is None

@classmethod
def install_or_update(cls) -> None:
# Binary cannot be set to custom because needs_update_or_installation
# returns False in this case
if get_settings().get("binary") == "system":
ans = sublime.yes_no_cancel_dialog("clangd was not found in your path. Would you like to auto-install clangd from GitHub?")
if ans == sublime.DIALOG_YES:
Expand All @@ -136,7 +151,7 @@ def install_or_update(cls) -> None:
download_server(cls.storage_subpath())

# zip does not preserve file mode
path = cls.managed_server_binary_path()
path = cls.managed_clangd_path()
if not path:
# this should never happen
raise ValueError("installation failed silently")
Expand All @@ -152,13 +167,17 @@ def on_pre_start(
configuration: ClientConfig,
) -> Optional[str]:

clangd_path = cls.clangd_path()
if not clangd_path:
raise ValueError("clangd is currently not installed.")
if get_settings().get("binary") == "custom":
clangd_base_command = configuration.init_options.get("custom_command") # type: List[str]
else:
clangd_path = cls.clangd_path()
if not clangd_path:
raise ValueError("clangd is currently not installed.")
clangd_base_command = [clangd_path]

# The configuration is persisted
# reset the command to prevent adding an argument multiple times
configuration.command = [clangd_path]
configuration.command = clangd_base_command.copy()

for key, value in configuration.init_options.get("clangd").items():
if not value:
Expand Down
27 changes: 23 additions & 4 deletions sublime-package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,29 @@
"enum": [
"system",
"auto",
"github"
"github",
"custom"
],
"enumDescriptions": [
"Prefers the system binary found in path",
"Prefers the system binary but falls back to GitHub without user intervention",
"Prefers the latest tested release from GitHub",
"Use the custom command in the initializationOptions below",
],
},
"system_binary": {
"type": "string",
"default": "clangd",
"markdownDescription": "The binary to use when `binary` is set to `system`."
},
"initializationOptions": {
"additionalProperties": false,
"properties": {
"custom_command": {
"type": "array",
"default": [],
"markdownDescription": "A custom command to start clangd. Set `binary` to `custom` to use this command. The command-line arguments which are generated from the `clang.*` settings are appended to this command."
},
"clangdFileStatus": {
"type": "boolean",
"description": "Enables receiving textDocument/clangd.fileStatus notifications.",
Expand Down Expand Up @@ -195,7 +207,9 @@
"default": null,
"description": "Sets the PCH storage. Storing PCHs in memory increases memory usages, but may improve performance",
"enum": [
null, "disk", "memory"
null,
"disk",
"memory"
]
},
"clangd.enable-config": {
Expand All @@ -209,7 +223,12 @@
],
"default": null,
"description": "Sets the clangd log level",
"enum": [null, "error", "info", "verbose"]
"enum": [
null,
"error",
"info",
"verbose"
]
},
"clangd.path-mappings": {
"type": [
Expand Down Expand Up @@ -260,4 +279,4 @@
}
]
}
}
}

0 comments on commit 04c8dae

Please sign in to comment.