Skip to content

Commit a65a4ae

Browse files
authored
feat: Add include-path CLI parameter with clap (#71)
Closes #70
1 parent 7594ff7 commit a65a4ae

File tree

6 files changed

+259
-27
lines changed

6 files changed

+259
-27
lines changed

Cargo.lock

+122-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "protols"
33
description = "Language server for proto3 files"
4-
version = "0.11.2"
4+
version = "0.11.5"
55
edition = "2024"
66
license = "MIT"
77
homepage = "https://github.com/coder3101/protols"
@@ -28,6 +28,7 @@ tempfile = "3.12.0"
2828
serde = { version = "1.0.209", features = ["derive"] }
2929
basic-toml = "0.1.9"
3030
pkg-config = "0.3.31"
31+
clap = { version = "4.5.5", features = ["derive"] }
3132

3233
[dev-dependencies]
3334
insta = { version = "1.39.0", features = ["yaml"] }

README.md

+21-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
- [Installation](#installation)
2424
- [For Neovim](#for-neovim)
25+
- [Command Line Options](#command-line-options)
2526
- [For Visual Studio Code](#for-visual-studio-code)
2627
- [Configuration](#configuration)
2728
- [Basic Configuration](#basic-configuration)
@@ -57,6 +58,25 @@ Then, configure it in your `init.lua` using [nvim-lspconfig](https://github.com/
5758
require'lspconfig'.protols.setup{}
5859
```
5960

61+
### Command Line Options
62+
63+
Protols supports various command line options to customize its behavior:
64+
65+
```
66+
protols [OPTIONS]
67+
68+
Options:
69+
-i, --include-paths <INCLUDE_PATHS> Include paths for proto files, comma-separated
70+
-V, --version Print version information
71+
-h, --help Print help information
72+
```
73+
74+
For example, to specify include paths when starting the language server:
75+
76+
```bash
77+
protols --include-paths=/path/to/protos,/another/path/to/protos
78+
```
79+
6080
### For Visual Studio Code
6181

6282
If you're using Visual Studio Code, you can install the [Protobuf Language Support](https://marketplace.visualstudio.com/items?itemName=ianandhum.protobuf-support) extension, which uses this LSP under the hood.
@@ -86,7 +106,7 @@ protoc = "protoc"
86106

87107
The `[config]` section contains stable settings that should generally remain unchanged.
88108

89-
- `include_paths`: Directories to search for `.proto` files. Absolute or relative to LSP workspace root. Worspace root is already included in include_paths
109+
- `include_paths`: These are directories where `.proto` files are searched. Paths can be absolute or relative to the LSP workspace root, which is already included in the `include_paths`. You can also specify this using the `--include-paths` flag in the command line. The include paths from the CLI are combined with those from the configuration. While configuration-based include paths are specific to a workspace, the CLI-specified paths apply to all workspaces on the server.
90110

91111
#### Path Configuration
92112

src/config/workspace.rs

+48-4
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ pub struct WorkspaceProtoConfigs {
1818
configs: HashMap<Url, ProtolsConfig>,
1919
formatters: HashMap<Url, ClangFormatter>,
2020
protoc_include_prefix: Vec<PathBuf>,
21+
cli_include_paths: Vec<PathBuf>,
2122
}
2223

2324
impl WorkspaceProtoConfigs {
24-
pub fn new() -> Self {
25+
pub fn new(cli_include_paths: Vec<PathBuf>) -> Self {
2526
// Try to find protobuf library and get its include paths
2627
// Do not emit metadata on stdout as LSP programs can consider
2728
// it part of spec
@@ -38,6 +39,7 @@ impl WorkspaceProtoConfigs {
3839
formatters: HashMap::new(),
3940
configs: HashMap::new(),
4041
protoc_include_prefix,
42+
cli_include_paths,
4143
}
4244
}
4345

@@ -100,6 +102,15 @@ impl WorkspaceProtoConfigs {
100102
.map(|p| if p.is_relative() { w.join(p) } else { p })
101103
.collect();
102104

105+
// Add CLI include paths
106+
for path in &self.cli_include_paths {
107+
if path.is_relative() {
108+
ipath.push(w.join(path));
109+
} else {
110+
ipath.push(path.clone());
111+
}
112+
}
113+
103114
ipath.push(w.to_path_buf());
104115
ipath.extend_from_slice(&self.protoc_include_prefix);
105116
Some(ipath)
@@ -139,6 +150,7 @@ mod test {
139150
use async_lsp::lsp_types::{Url, WorkspaceFolder};
140151
use insta::assert_yaml_snapshot;
141152
use tempfile::tempdir;
153+
use std::path::PathBuf;
142154

143155
use super::{CONFIG_FILE_NAMES, WorkspaceProtoConfigs};
144156

@@ -149,7 +161,7 @@ mod test {
149161
let f = tmpdir.path().join("protols.toml");
150162
std::fs::write(f, include_str!("input/protols-valid.toml")).unwrap();
151163

152-
let mut ws = WorkspaceProtoConfigs::new();
164+
let mut ws = WorkspaceProtoConfigs::new(vec![]);
153165
ws.add_workspace(&WorkspaceFolder {
154166
uri: Url::from_directory_path(tmpdir.path()).unwrap(),
155167
name: "Test".to_string(),
@@ -183,7 +195,7 @@ mod test {
183195
let f = tmpdir.path().join("protols.toml");
184196
std::fs::write(f, include_str!("input/protols-valid.toml")).unwrap();
185197

186-
let mut ws = WorkspaceProtoConfigs::new();
198+
let mut ws = WorkspaceProtoConfigs::new(vec![]);
187199
ws.add_workspace(&WorkspaceFolder {
188200
uri: Url::from_directory_path(tmpdir.path()).unwrap(),
189201
name: "Test".to_string(),
@@ -218,7 +230,7 @@ mod test {
218230
let f = tmpdir.path().join(file);
219231
std::fs::write(f, include_str!("input/protols-valid.toml")).unwrap();
220232

221-
let mut ws = WorkspaceProtoConfigs::new();
233+
let mut ws = WorkspaceProtoConfigs::new(vec![]);
222234
ws.add_workspace(&WorkspaceFolder {
223235
uri: Url::from_directory_path(tmpdir.path()).unwrap(),
224236
name: "Test".to_string(),
@@ -229,4 +241,36 @@ mod test {
229241
assert!(ws.get_workspace_for_uri(&workspace).is_some());
230242
}
231243
}
244+
245+
#[test]
246+
fn test_cli_include_paths() {
247+
let tmpdir = tempdir().expect("failed to create temp directory");
248+
let f = tmpdir.path().join("protols.toml");
249+
std::fs::write(f, include_str!("input/protols-valid.toml")).unwrap();
250+
251+
// Set CLI include paths
252+
let cli_paths = vec![
253+
PathBuf::from("/path/to/protos"),
254+
PathBuf::from("relative/path"),
255+
];
256+
let mut ws = WorkspaceProtoConfigs::new(cli_paths);
257+
ws.add_workspace(&WorkspaceFolder {
258+
uri: Url::from_directory_path(tmpdir.path()).unwrap(),
259+
name: "Test".to_string(),
260+
});
261+
262+
let inworkspace = Url::from_file_path(tmpdir.path().join("foobar.proto")).unwrap();
263+
let include_paths = ws.get_include_paths(&inworkspace).unwrap();
264+
265+
// Check that CLI paths are included in the result
266+
assert!(include_paths.iter().any(|p| p.ends_with("relative/path") ||
267+
p == &PathBuf::from("/path/to/protos")));
268+
269+
// The relative path should be resolved relative to the workspace
270+
let resolved_relative_path = tmpdir.path().join("relative/path");
271+
assert!(include_paths.contains(&resolved_relative_path));
272+
273+
// The absolute path should be included as is
274+
assert!(include_paths.contains(&PathBuf::from("/path/to/protos")));
275+
}
232276
}

0 commit comments

Comments
 (0)