From ef5e5f9296d27d11ddfddf6d1c7daf93f9464ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Wed, 21 Oct 2020 13:47:20 +0900 Subject: [PATCH] state.version tracking --- helix-core/src/state.rs | 2 ++ helix-lsp/src/lib.rs | 32 +++++++++++++++++++++----------- helix-term/src/application.rs | 33 +++++++-------------------------- helix-view/src/commands.rs | 7 ++++++- 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/helix-core/src/state.rs b/helix-core/src/state.rs index 0f94f696f..75e5cd40e 100644 --- a/helix-core/src/state.rs +++ b/helix-core/src/state.rs @@ -29,6 +29,7 @@ pub struct State { pub changes: ChangeSet, pub old_state: Option<(Rope, Selection)>, + pub version: i64, pub diagnostics: Vec, } @@ -61,6 +62,7 @@ impl State { changes, old_state, diagnostics: Vec::new(), + version: 0, } } diff --git a/helix-lsp/src/lib.rs b/helix-lsp/src/lib.rs index 939f99271..f8c73902b 100644 --- a/helix-lsp/src/lib.rs +++ b/helix-lsp/src/lib.rs @@ -2,6 +2,8 @@ mod transport; use transport::{Payload, Transport}; +use helix_core::{State, Transaction}; + // use std::collections::HashMap; use jsonrpc_core as jsonrpc; @@ -13,14 +15,24 @@ use serde::{Deserialize, Serialize}; pub use lsp::Position; pub use lsp::Url; -use smol::prelude::*; use smol::{ channel::{Receiver, Sender}, io::{BufReader, BufWriter}, + // prelude::*, process::{Child, ChildStderr, Command, Stdio}, Executor, }; +pub mod util { + use super::*; + + pub fn lsp_pos_to_pos(doc: &helix_core::RopeSlice, pos: lsp::Position) -> usize { + let line = doc.line_to_char(pos.line as usize); + let line_start = doc.char_to_utf16_cu(line); + doc.utf16_cu_to_char(pos.character as usize + line_start) + } +} + /// A type representing all possible values sent from the server to the client. #[derive(Debug, PartialEq, Clone, Deserialize, Serialize)] #[serde(deny_unknown_fields)] @@ -58,7 +70,7 @@ impl Notification { } pub struct Client { - process: Child, + _process: Child, stderr: BufReader, outgoing: Sender, @@ -90,7 +102,7 @@ impl Client { let (incoming, outgoing) = Transport::start(ex, reader, writer); Client { - process, + _process: process, stderr, outgoing, @@ -224,15 +236,12 @@ impl Client { // Text document // ------------------------------------------------------------------------------------------- - pub async fn text_document_did_open( - &mut self, - state: &helix_core::State, - ) -> anyhow::Result<()> { + pub async fn text_document_did_open(&mut self, state: &State) -> anyhow::Result<()> { self.notify::(lsp::DidOpenTextDocumentParams { text_document: lsp::TextDocumentItem { uri: lsp::Url::from_file_path(state.path().unwrap()).unwrap(), language_id: "rust".to_string(), // TODO: hardcoded for now - version: 0, + version: state.version, text: String::from(&state.doc), }, }) @@ -242,14 +251,15 @@ impl Client { // TODO: trigger any time history.commit_revision happens pub async fn text_document_did_change( &mut self, - state: &helix_core::State, + state: &State, + transaction: &Transaction, ) -> anyhow::Result<()> { self.notify::(lsp::DidChangeTextDocumentParams { text_document: lsp::VersionedTextDocumentIdentifier::new( lsp::Url::from_file_path(state.path().unwrap()).unwrap(), - 0, // TODO: version + state.version, ), - content_changes: vec![], // TODO: + content_changes: vec![], // TODO: probably need old_state here too? }) .await } diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index 5551e26f4..a1a6b9ea7 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -568,23 +568,12 @@ impl<'a> Application<'a> { use helix_lsp::Notification; match notification { Some(Notification::PublishDiagnostics(params)) => { - let view = self.editor.views.iter_mut().find(|view| { - let path = view - .state - .path - .as_ref() - .map(|path| helix_lsp::Url::from_file_path(path).unwrap()); - - eprintln!("{:?} {} {}", path, params.uri, params.diagnostics.len()); - // HAXX - path == Some(params.uri.clone()) - }); - - fn lsp_pos_to_pos(doc: &helix_core::RopeSlice, pos: helix_lsp::Position) -> usize { - let line = doc.line_to_char(pos.line as usize); - let line_start = doc.char_to_utf16_cu(line); - doc.utf16_cu_to_char(pos.character as usize + line_start) - } + let path = Some(params.uri.to_file_path().unwrap()); + let view = self + .editor + .views + .iter_mut() + .find(|view| view.state.path == path); if let Some(view) = view { let doc = view.state.doc().slice(..); @@ -592,18 +581,10 @@ impl<'a> Application<'a> { .diagnostics .into_iter() .map(|diagnostic| { + use helix_lsp::util::lsp_pos_to_pos; let start = lsp_pos_to_pos(&doc, diagnostic.range.start); let end = lsp_pos_to_pos(&doc, diagnostic.range.end); - // eprintln!( - // "{:?}-{:?} {}-{} {}", - // diagnostic.range.start, - // diagnostic.range.end, - // start, - // end, - // diagnostic.message - // ); - helix_core::Diagnostic { range: (start, end), line: diagnostic.range.start.line as usize, diff --git a/helix-view/src/commands.rs b/helix-view/src/commands.rs index 1d7737f00..e29d070ec 100644 --- a/helix-view/src/commands.rs +++ b/helix-view/src/commands.rs @@ -391,6 +391,12 @@ fn append_changes_to_history(view: &mut View) { // annotations either add a new layer or compose into the previous one. let transaction = Transaction::from(changes).with_selection(view.state.selection().clone()); + // increment document version + // TODO: needs to happen on undo/redo too + view.state.version += 1; + + // TODO: trigger lsp/documentDidChange with changes + // HAXX: we need to reconstruct the state as it was before the changes.. let (doc, selection) = view.state.old_state.take().unwrap(); let mut old_state = State::new(doc); @@ -399,7 +405,6 @@ fn append_changes_to_history(view: &mut View) { // TODO: take transaction by value? view.history.commit_revision(&transaction, &old_state); - // TODO: need to start the state with these vals // HAXX view.state.old_state = Some((view.state.doc().clone(), view.state.selection.clone())); }