Skip to content

Commit

Permalink
Add docs for multiconfig, validation of
Browse files Browse the repository at this point in the history
project config paths
  • Loading branch information
WillLillis committed Oct 18, 2024
1 parent 25dd4c9 commit 11ffd36
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 14 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,13 @@ selectively target specific assemblers and/or instruction sets. Omitting an item
from the `assemblers` or `instruction_sets` sections is equivalent to setting it
to `false`. Be default, diagnostics are enabled and the server attempts to invoke
`gcc` (and then `clang`) to generate them. If the `compiler` config field is specified,
the server will attempt to use the specified path to generate diagnostics.
the server will attempt to use the specified path to generate diagnostics. Different
configurations can be created for different sub-directories within your project as
`projects`. Source files not contained within any `project` configs will use the default
configuration if provided.

```toml
# Root-level, default configuration
version = "0.1"

[assemblers]
Expand All @@ -67,14 +71,24 @@ nasm = false
[instruction_sets]
x86 = false
x86_64 = true
z80 = false
arm = false
riscv = false
# z80 = false # Omitting a field is the same as setting it to false
# arm = false
# riscv = false

[opts]
compiler = "zig" # need "cc" as the first argument in `compile_flags.txt`
diagnostics = true
default_diagnostics = true

# Configure the server's treatment of source files in the `arm-project` sub-directory
[[projects]]
path = "arm-project"

[projects.assemblers]
gas = false

[projects.instruction_sets]
arm = true
```

### [OPTIONAL] Extend functionality via `compile_commands.json`/`compile_flags.txt`
Expand Down
4 changes: 4 additions & 0 deletions src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,10 @@ fn main_loop(
info!("Recieved shutdown request");
return Ok(());
} else if let Ok((id, params)) = cast_req::<HoverRequest>(req.clone()) {
info!(
"Selected config: {:#?}",
config.get_config(&params.text_document_position_params.text_document.uri),
);
handle_hover_request(
connection,
id,
Expand Down
45 changes: 42 additions & 3 deletions src/lsp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,7 +618,6 @@ pub fn get_hover_resp(
return instr_lookup;
}

// TODO: Do the directive lookups next
// directive lookup
{
if config.assemblers.gas.unwrap_or(false) || config.assemblers.masm.unwrap_or(false) {
Expand Down Expand Up @@ -1134,7 +1133,8 @@ fn get_include_resp(
}
}

/// Filter out duplicate completion suggestions
/// Filter out duplicate completion suggestions, and those that aren't allowed
/// by `config`
fn filtered_comp_list(comps: &[CompletionItem]) -> Vec<CompletionItem> {
let mut seen = HashSet::new();

Expand Down Expand Up @@ -1771,8 +1771,47 @@ pub fn get_config(params: &InitializeParams) -> RootConfig {
(None, None) => RootConfig::default(),
};

// TODO: Canonicalize `path`s in `projects`
// Validate project paths and enforce default diagnostics settings
if let Some(ref mut projects) = config.projects {
if let Some(ref path) = get_project_root(params) {
let mut project_idx = 0;
while project_idx < projects.len() {
let mut path = path.clone();
path.push(&projects[project_idx].path);
let Ok(project_path) = path.canonicalize() else {
error!("Failed to canonicalize project path \"{}\", disabling this project configuration.", path.display());
projects.remove(project_idx);
continue;
};
if !project_path.is_dir() {
error!("Project path \"{}\" is not a directory, disabling this project configuration.", path.display());
projects.remove(project_idx);
continue;
}
projects[project_idx].path = project_path;
// Want diagnostics enabled by default
if projects[project_idx].config.opts.diagnostics.is_none() {
projects[project_idx].config.opts.diagnostics = Some(true);
}

// Want default diagnostics enabled by default
if projects[project_idx]
.config
.opts
.default_diagnostics
.is_none()
{
projects[project_idx].config.opts.default_diagnostics = Some(true);
}
project_idx += 1;
}
} else {
error!("Unable to detect project root directory. The projects configuration feature has been disabled.");
*projects = Vec::new();
}
}

// Enforce default diagnostics settings for default config
if let Some(ref mut default_cfg) = config.default_config {
// Want diagnostics enabled by default
if default_cfg.opts.diagnostics.is_none() {
Expand Down
12 changes: 5 additions & 7 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ impl Default for Assemblers {
}

impl Assemblers {
fn empty() -> Self {
const fn empty() -> Self {
Self {
gas: Some(false),
go: Some(false),
Expand Down Expand Up @@ -861,7 +861,7 @@ impl Default for InstructionSets {
}

impl InstructionSets {
fn empty() -> Self {
const fn empty() -> Self {
Self {
x86: Some(false),
x86_64: Some(false),
Expand All @@ -872,8 +872,6 @@ impl InstructionSets {
}
}

// TODO: Add logic handling empty configs (both `default_config` and `projects` = `None`)

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RootConfig {
#[serde(flatten)]
Expand Down Expand Up @@ -907,7 +905,7 @@ impl RootConfig {
};
if let Some(projects) = &self.projects {
for project in projects {
if project.path.starts_with(&request_path) {
if request_path.starts_with(&project.path) {
return &project.config;
}
}
Expand Down Expand Up @@ -1102,7 +1100,7 @@ impl Default for Config {

impl Config {
#[must_use]
pub fn empty() -> Self {
pub const fn empty() -> Self {
Self {
version: None,
assemblers: Assemblers::empty(),
Expand Down Expand Up @@ -1134,7 +1132,7 @@ impl Default for ConfigOptions {
}

impl ConfigOptions {
fn empty() -> Self {
const fn empty() -> Self {
Self {
compiler: None,
diagnostics: Some(false),
Expand Down

0 comments on commit 11ffd36

Please sign in to comment.