on master help sign in
wip
a7869c7Blaž Hrastnik
Cargo.lock+31−37
@@ -2,24 +2,18 @@
2# It is not intended for manual editing.
2# It is not intended for manual editing.
3[[package]]
3[[package]]
4name = "aho-corasick"
4name = "aho-corasick"
5−version = "0.7.14"
5+version = "0.7.15"
6source = "registry+https://github.com/rust-lang/crates.io-index"
6source = "registry+https://github.com/rust-lang/crates.io-index"
7−checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d"
7+checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
8dependencies = [
8dependencies = [
9 "memchr",
9 "memchr",
10]
10]
11
11
12[[package]]
12[[package]]
13name = "anyhow"
13name = "anyhow"
14−version = "1.0.33"
14+version = "1.0.34"
15source = "registry+https://github.com/rust-lang/crates.io-index"
15source = "registry+https://github.com/rust-lang/crates.io-index"
16−checksum = "a1fd36ffbb1fb7c834eac128ea8d0e310c5aeb635548f9d58861e1308d46e71c"
16+checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7"
17−
18−[[package]]
19−name = "arc-swap"
20−version = "0.4.7"
21−source = "registry+https://github.com/rust-lang/crates.io-index"
22−checksum = "4d25d88fd6b8041580a654f9d0c581a047baee2b3efee13275f2fc392fc75034"
23
17
24[[package]]
18[[package]]
25name = "arrayref"
19name = "arrayref"
@@ -158,9 +152,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
158
152
159[[package]]
153[[package]]
160name = "blake2b_simd"
154name = "blake2b_simd"
161−version = "0.5.10"
155+version = "0.5.11"
162source = "registry+https://github.com/rust-lang/crates.io-index"
156source = "registry+https://github.com/rust-lang/crates.io-index"
163−checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
157+checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
164dependencies = [
158dependencies = [
165 "arrayref",
159 "arrayref",
166 "arrayvec",
160 "arrayvec",
@@ -279,9 +273,9 @@ dependencies = [
279
273
280[[package]]
274[[package]]
281name = "crossterm"
275name = "crossterm"
282−version = "0.18.1"
276+version = "0.18.2"
283source = "registry+https://github.com/rust-lang/crates.io-index"
277source = "registry+https://github.com/rust-lang/crates.io-index"
284−checksum = "cef9149b29071d44c9fb98fd9c27fcf74405bbdb761889ad6a03f36be93b0b15"
278+checksum = "4e86d73f2a0b407b5768d10a8c720cf5d2df49a9efc10ca09176d201ead4b7fb"
285dependencies = [
279dependencies = [
286 "bitflags",
280 "bitflags",
287 "crossterm_winapi",
281 "crossterm_winapi",
@@ -479,6 +473,7 @@ dependencies = [
479 "jsonrpc-core",
473 "jsonrpc-core",
480 "log",
474 "log",
481 "lsp-types",
475 "lsp-types",
476+ "once_cell",
482 "pathdiff",
477 "pathdiff",
483 "serde",
478 "serde",
484 "serde_json",
479 "serde_json",
@@ -653,15 +648,15 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
653
648
654[[package]]
649[[package]]
655name = "memchr"
650name = "memchr"
656−version = "2.3.3"
651+version = "2.3.4"
657source = "registry+https://github.com/rust-lang/crates.io-index"
652source = "registry+https://github.com/rust-lang/crates.io-index"
658−checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
653+checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
659
654
660[[package]]
655[[package]]
661name = "mio"
656name = "mio"
662−version = "0.7.4"
657+version = "0.7.5"
663source = "registry+https://github.com/rust-lang/crates.io-index"
658source = "registry+https://github.com/rust-lang/crates.io-index"
664−checksum = "f8f1c83949125de4a582aa2da15ae6324d91cf6a58a70ea407643941ff98f558"
659+checksum = "8962c171f57fcfffa53f4df1bb15ec4c8cf26a7569459c9ceb62d94aab0d9584"
665dependencies = [
660dependencies = [
666 "libc",
661 "libc",
667 "log",
662 "log",
@@ -707,9 +702,9 @@ dependencies = [
707
702
708[[package]]
703[[package]]
709name = "num-integer"
704name = "num-integer"
710−version = "0.1.43"
705+version = "0.1.44"
711source = "registry+https://github.com/rust-lang/crates.io-index"
706source = "registry+https://github.com/rust-lang/crates.io-index"
712−checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
707+checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
713dependencies = [
708dependencies = [
714 "autocfg",
709 "autocfg",
715 "num-traits",
710 "num-traits",
@@ -717,9 +712,9 @@ dependencies = [
717
712
718[[package]]
713[[package]]
719name = "num-traits"
714name = "num-traits"
720−version = "0.2.12"
715+version = "0.2.14"
721source = "registry+https://github.com/rust-lang/crates.io-index"
716source = "registry+https://github.com/rust-lang/crates.io-index"
722−checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
717+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
723dependencies = [
718dependencies = [
724 "autocfg",
719 "autocfg",
725]
720]
@@ -837,9 +832,9 @@ dependencies = [
837
832
838[[package]]
833[[package]]
839name = "proc-macro-hack"
834name = "proc-macro-hack"
840−version = "0.5.18"
835+version = "0.5.19"
841source = "registry+https://github.com/rust-lang/crates.io-index"
836source = "registry+https://github.com/rust-lang/crates.io-index"
842−checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
837+checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
843
838
844[[package]]
839[[package]]
845name = "proc-macro-nested"
840name = "proc-macro-nested"
@@ -884,9 +879,9 @@ dependencies = [
884
879
885[[package]]
880[[package]]
886name = "regex"
881name = "regex"
887−version = "1.4.1"
882+version = "1.4.2"
888source = "registry+https://github.com/rust-lang/crates.io-index"
883source = "registry+https://github.com/rust-lang/crates.io-index"
889−checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b"
884+checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
890dependencies = [
885dependencies = [
891 "aho-corasick",
886 "aho-corasick",
892 "memchr",
887 "memchr",
@@ -896,9 +891,9 @@ dependencies = [
896
891
897[[package]]
892[[package]]
898name = "regex-syntax"
893name = "regex-syntax"
899−version = "0.6.20"
894+version = "0.6.21"
900source = "registry+https://github.com/rust-lang/crates.io-index"
895source = "registry+https://github.com/rust-lang/crates.io-index"
901−checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c"
896+checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
902
897
903[[package]]
898[[package]]
904name = "ropey"
899name = "ropey"
@@ -997,11 +992,10 @@ dependencies = [
997
992
998[[package]]
993[[package]]
999name = "signal-hook-registry"
994name = "signal-hook-registry"
1000−version = "1.2.1"
995+version = "1.2.2"
1001source = "registry+https://github.com/rust-lang/crates.io-index"
996source = "registry+https://github.com/rust-lang/crates.io-index"
1002−checksum = "a3e12110bc539e657a646068aaf5eb5b63af9d0c1f7b29c97113fad80e15f035"
997+checksum = "ce32ea0c6c56d5eacaeb814fbed9960547021d3edd010ded1425f180536b20ab"
1003dependencies = [
998dependencies = [
1004− "arc-swap",
1005 "libc",
999 "libc",
1006]
1000]
1007
1001
@@ -1079,18 +1073,18 @@ dependencies = [
1079
1073
1080[[package]]
1074[[package]]
1081name = "thiserror"
1075name = "thiserror"
1082−version = "1.0.21"
1076+version = "1.0.22"
1083source = "registry+https://github.com/rust-lang/crates.io-index"
1077source = "registry+https://github.com/rust-lang/crates.io-index"
1084−checksum = "318234ffa22e0920fe9a40d7b8369b5f649d490980cf7aadcf1eb91594869b42"
1078+checksum = "0e9ae34b84616eedaaf1e9dd6026dbe00dcafa92aa0c8077cb69df1fcfe5e53e"
1085dependencies = [
1079dependencies = [
1086 "thiserror-impl",
1080 "thiserror-impl",
1087]
1081]
1088
1082
1089[[package]]
1083[[package]]
1090name = "thiserror-impl"
1084name = "thiserror-impl"
1091−version = "1.0.21"
1085+version = "1.0.22"
1092source = "registry+https://github.com/rust-lang/crates.io-index"
1086source = "registry+https://github.com/rust-lang/crates.io-index"
1093−checksum = "cae2447b6282786c3493999f40a9be2a6ad20cb8bd268b0a0dbf5a065535c0ab"
1087+checksum = "9ba20f23e85b10754cd195504aebf6a27e2e6cbe28c17778a0c930724628dd56"
1094dependencies = [
1088dependencies = [
1095 "proc-macro2",
1089 "proc-macro2",
1096 "quote",
1090 "quote",
@@ -1125,9 +1119,9 @@ checksum = "238ce071d267c5710f9d31451efec16c5ee22de34df17cc05e56cbc92e967117"
1125
1119
1126[[package]]
1120[[package]]
1127name = "tree-sitter"
1121name = "tree-sitter"
1128−version = "0.17.0"
1122+version = "0.17.1"
1129source = "registry+https://github.com/rust-lang/crates.io-index"
1123source = "registry+https://github.com/rust-lang/crates.io-index"
1130−checksum = "70ee7370fec3aecde3862a7d64c571048f70a7298daef1815e8fc68b9de54b5c"
1124+checksum = "d18dcb776d3affaba6db04d11d645946d34a69b3172e588af96ce9fecd20faac"
1131dependencies = [
1125dependencies = [
1132 "cc",
1126 "cc",
1133 "regex",
1127 "regex",
helix-core/src/syntax.rs+4
@@ -62,6 +62,10 @@ impl LanguageConfiguration {
62 })
62 })
63 .map(Option::as_ref)
63 .map(Option::as_ref)
64 }
64 }
65+
66+ pub fn scope(&self) -> &str {
67+ &self.scope
68+ }
65}
69}
66
70
67use once_cell::sync::Lazy;
71use once_cell::sync::Lazy;
helix-lsp/Cargo.toml+1
@@ -9,6 +9,7 @@ edition = "2018"
9[dependencies]
9[dependencies]
10helix-core = { path = "../helix-core" }
10helix-core = { path = "../helix-core" }
11helix-view = { path = "../helix-view" }
11helix-view = { path = "../helix-view" }
12+once_cell = "1.4"
12
13
13lsp-types = { version = "0.83", features = ["proposed"] }
14lsp-types = { version = "0.83", features = ["proposed"] }
14smol = "1.2"
15smol = "1.2"
helix-lsp/src/lib.rs+53
@@ -4,11 +4,15 @@ mod transport;
4pub use jsonrpc_core as jsonrpc;
4pub use jsonrpc_core as jsonrpc;
5pub use lsp_types as lsp;
5pub use lsp_types as lsp;
6
6
7+pub use once_cell::sync::{Lazy, OnceCell};
8+
7pub use client::Client;
9pub use client::Client;
8pub use lsp::{Position, Url};
10pub use lsp::{Position, Url};
9
11
10use thiserror::Error;
12use thiserror::Error;
11
13
14+use std::{collections::HashMap, sync::Arc};
15+
12#[derive(Error, Debug)]
16#[derive(Error, Debug)]
13pub enum Error {
17pub enum Error {
14 #[error("protocol error: {0}")]
18 #[error("protocol error: {0}")]
@@ -62,3 +66,52 @@ impl Notification {
62}
66}
63
67
64pub use jsonrpc::Call;
68pub use jsonrpc::Call;
69+
70+type LanguageId = String;
71+
72+pub static REGISTRY: Lazy<Registry> = Lazy::new(Registry::init);
73+
74+pub struct Registry {
75+ inner: HashMap<LanguageId, OnceCell<Arc<Client>>>,
76+}
77+
78+impl Registry {
79+ pub fn init() -> Self {
80+ Self {
81+ inner: HashMap::new(),
82+ }
83+ }
84+
85+ pub fn get(&self, id: &str, ex: &smol::Executor) -> Option<Arc<Client>> {
86+ // TODO: use get_or_try_init and propagate the error
87+ self.inner
88+ .get(id)
89+ .map(|cell| {
90+ cell.get_or_init(|| {
91+ // TODO: lookup defaults for id (name, args)
92+
93+ // initialize a new client
94+ let client = Client::start(&ex, "rust-analyzer", &[]);
95+ // TODO: also call initialize().await()
96+ Arc::new(client)
97+ })
98+ })
99+ .cloned()
100+ }
101+}
102+
103+// REGISTRY = HashMap<LanguageId, Lazy/OnceCell<Arc<RwLock<Client>>>
104+// spawn one server per language type, need to spawn one per workspace if server doesn't support
105+// workspaces
106+//
107+// could also be a client per root dir
108+//
109+// storing a copy of Option<Arc<RwLock<Client>>> on Document would make the LSP client easily
110+// accessible during edit/save callbacks
111+//
112+// the event loop needs to process all incoming streams, maybe we can just have that be a separate
113+// task that's continually running and store the state on the client, then use read lock to
114+// retrieve data during render
115+// -> PROBLEM: how do you trigger an update on the editor side when data updates?
116+//
117+// -> The data updates should pull all events until we run out so we don't frequently re-render
helix-term/src/application.rs+11−3
@@ -636,9 +636,17 @@ impl<'a> Application<'a> {
636 }
636 }
637 }
637 }
638 Some(Call::MethodCall(call)) => {
638 Some(Call::MethodCall(call)) => {
639− // TODO: need to make Result<Value, Error>
639+ debug!("Method not found {}", call.method);
640−
640+
641− unimplemented!("{:?}", call)
641+ self.language_server.reply(
642+ call.id,
643+ // TODO: make a Into trait that can cast to Err(jsonrpc::Error)
644+ Err(helix_lsp::jsonrpc::Error {
645+ code: helix_lsp::jsonrpc::ErrorCode::MethodNotFound,
646+ message: "Method not found".to_string(),
647+ data: None,
648+ }),
649+ );
642 }
650 }
643 _ => unreachable!(),
651 _ => unreachable!(),
644 }
652 }
helix-view/src/document.rs+15
@@ -25,6 +25,8 @@ pub struct Document {
25
25
26 /// Tree-sitter AST tree
26 /// Tree-sitter AST tree
27 pub syntax: Option<Syntax>,
27 pub syntax: Option<Syntax>,
28+ /// Corresponding language scope name. Usually `source.<lang>`.
29+ pub language: Option<String>,
28
30
29 /// Pending changes since last history commit.
31 /// Pending changes since last history commit.
30 pub changes: ChangeSet,
32 pub changes: ChangeSet,
@@ -64,6 +66,7 @@ impl Document {
64 mode: Mode::Normal,
66 mode: Mode::Normal,
65 restore_cursor: false,
67 restore_cursor: false,
66 syntax: None,
68 syntax: None,
69+ language: None,
67 changes,
70 changes,
68 old_state,
71 old_state,
69 diagnostics: Vec::new(),
72 diagnostics: Vec::new(),
@@ -73,6 +76,7 @@ impl Document {
73 }
76 }
74
77
75 // TODO: passing scopes here is awkward
78 // TODO: passing scopes here is awkward
79+ // TODO: async fn?
76 pub fn load(path: PathBuf, scopes: &[String]) -> Result<Self, Error> {
80 pub fn load(path: PathBuf, scopes: &[String]) -> Result<Self, Error> {
77 use std::{env, fs::File, io::BufReader};
81 use std::{env, fs::File, io::BufReader};
78 let _current_dir = env::current_dir()?;
82 let _current_dir = env::current_dir()?;
@@ -90,6 +94,15 @@ impl Document {
90 let syntax = Syntax::new(&doc.state.doc, highlight_config.clone());
94 let syntax = Syntax::new(&doc.state.doc, highlight_config.clone());
91
95
92 doc.syntax = Some(syntax);
96 doc.syntax = Some(syntax);
97+ // TODO: maybe just keep an Arc<> pointer to the language_config?
98+ doc.language = Some(language_config.scope().to_string());
99+
100+ // TODO: this ties lsp support to tree-sitter enabled languages for now. Language
101+ // config should use Option<HighlightConfig> to let us have non-tree-sitter configs.
102+
103+ // TODO: circular dep: view <-> lsp
104+ // helix_lsp::REGISTRY;
105+ // view should probably depend on lsp
93 };
106 };
94
107
95 // canonicalize path to absolute value
108 // canonicalize path to absolute value
@@ -98,6 +111,8 @@ impl Document {
98 Ok(doc)
111 Ok(doc)
99 }
112 }
100
113
114+ // TODO: do we need some way of ensuring two save operations on the same doc can't run at once?
115+ // or is that handled by the OS/async layer
101 pub fn save(&self) -> impl Future<Output = Result<(), anyhow::Error>> {
116 pub fn save(&self) -> impl Future<Output = Result<(), anyhow::Error>> {
102 // we clone and move text + path into the future so that we asynchronously save the current
117 // we clone and move text + path into the future so that we asynchronously save the current
103 // state without blocking any further edits.
118 // state without blocking any further edits.