Skip to content

Commit 5187dbe

Browse files
committed
Add pikelet-ide crate
1 parent f3d17d8 commit 5187dbe

File tree

7 files changed

+86
-2
lines changed

7 files changed

+86
-2
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ members = [
33
"./pikelet",
44
"./pikelet-cli",
55
"./pikelet-gui",
6+
"./pikelet-ide",
67
]

pikelet-cli/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@ license = "Apache-2.0"
1515
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1616

1717
[features]
18-
default = ["gui"]
18+
default = ["gui", "ide"]
1919
gui = ["pikelet-gui"]
20+
ide = ["pikelet-ide"]
2021

2122
[dependencies]
2223
codespan-reporting = "0.9.5"
2324
pikelet = { path = "../pikelet" }
2425
pikelet-gui = { path = "../pikelet-gui", optional = true }
26+
pikelet-ide = { path = "../pikelet-ide", optional = true }
2527
pretty = "0.10"
2628
rustyline = "6.2"
2729
structopt = "0.3"

pikelet-cli/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
# pikelet-cli
2+
3+
Command line interface for interacting with the Pikelet programming language

pikelet-cli/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ pub enum Options {
1010
#[structopt(name = "check")]
1111
Check,
1212
/// Runs the language server/IDE support (not yet implemented).
13+
#[cfg(feature = "ide")]
1314
#[structopt(name = "ide")]
1415
Ide,
1516
/// Runs the REPL/interactive mode.
@@ -25,7 +26,8 @@ pub enum Options {
2526
pub fn run(options: Options) -> Result<(), Box<dyn Error>> {
2627
match options {
2728
Options::Check => Err("not yet implemented".into()),
28-
Options::Ide => Err("not yet implemented".into()),
29+
#[cfg(feature = "ide")]
30+
Options::Ide => pikelet_ide::run(),
2931
Options::Repl(options) => repl::run(options),
3032
#[cfg(feature = "gui")]
3133
Options::Gui => {

pikelet-ide/Cargo.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[package]
2+
name = "pikelet-ide"
3+
version = "0.1.0"
4+
authors = ["Brendan Zabarauskas <bjzaba@yahoo.com.au>"]
5+
edition = "2018"
6+
publish = false
7+
description = "Language server protocol implementation for the Pikelet programming language"
8+
homepage = "https://github.com/pikelet-lang/pikelet"
9+
repository = "https://github.com/pikelet-lang/pikelet"
10+
readme = "README.md"
11+
keywords = ["pikelet"]
12+
categories = []
13+
license = "Apache-2.0"
14+
15+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
16+
17+
[dependencies]
18+
flexi_logger = "0.15"
19+
log = "0.4"
20+
lsp-server = "0.3"
21+
lsp-types = "0.79"
22+
serde_json = "1.0.57"
23+
serde = { version = "1.0.114", features = ["derive"] }

pikelet-ide/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# pikelet-ide
2+
3+
Language server protocol implementation for the Pikelet programming language

pikelet-ide/src/lib.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
use log::info;
2+
use lsp_server::{Connection, Message};
3+
use lsp_types::{InitializeParams, ServerCapabilities};
4+
use std::error::Error;
5+
6+
pub fn run() -> Result<(), Box<dyn Error>> {
7+
// Set up logging. Because `stdio_transport` gets a lock on stdout and stdin, we must have
8+
// our logging only write out to stderr.
9+
flexi_logger::Logger::with_str("info").start().unwrap();
10+
info!("Starting Pikelet LSP server");
11+
12+
// Create the transport. Includes the stdio (stdin and stdout) versions but this could
13+
// also be implemented to use sockets or HTTP.
14+
let (connection, io_threads) = Connection::stdio();
15+
16+
// Run the server and wait for the two threads to end (typically by trigger LSP Exit event).
17+
let server_capabilities = serde_json::to_value(&ServerCapabilities::default()).unwrap();
18+
let initialization_params = connection.initialize(server_capabilities)?;
19+
main_loop(&connection, initialization_params)?;
20+
io_threads.join()?;
21+
22+
// Shut down gracefully.
23+
info!("Shutting down server");
24+
25+
Ok(())
26+
}
27+
28+
fn main_loop(connection: &Connection, params: serde_json::Value) -> Result<(), Box<dyn Error>> {
29+
let _params: InitializeParams = serde_json::from_value(params).unwrap();
30+
31+
info!("Starting Pikelet main loop");
32+
for msg in &connection.receiver {
33+
info!("Received msg: {:?}", msg);
34+
match msg {
35+
Message::Request(request) => {
36+
if connection.handle_shutdown(&request)? {
37+
return Ok(());
38+
}
39+
info!("Got request: {:?}", request);
40+
}
41+
Message::Response(response) => {
42+
info!("Received response: {:?}", response);
43+
}
44+
Message::Notification(notification) => {
45+
info!("Received notification: {:?}", notification);
46+
}
47+
}
48+
}
49+
50+
Ok(())
51+
}

0 commit comments

Comments
 (0)