Created
May 11, 2020 00:45
-
-
Save anirudhb/28647e85edf8828a19b07cd84460b23c to your computer and use it in GitHub Desktop.
Patch to improve Dart LSP support for LanguageClient-Neovim
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/language_server_protocol.rs b/src/language_server_protocol.rs | |
index 1b3d7cb..d38aaf3 100644 | |
--- a/src/language_server_protocol.rs | |
+++ b/src/language_server_protocol.rs | |
@@ -1197,6 +1197,14 @@ impl LanguageClient { | |
related_information: Some(true), | |
..PublishDiagnosticsCapability::default() | |
}), | |
+ code_action: Some(CodeActionCapability { | |
+ code_action_literal_support: Some(CodeActionLiteralSupport { | |
+ code_action_kind: CodeActionKindLiteralSupport { | |
+ value_set: vec!["quickfix".to_owned(), "assist".to_owned(), "refactor".to_owned()], | |
+ }, | |
+ }), | |
+ ..CodeActionCapability::default() | |
+ }), | |
code_lens: Some(GenericCapability { | |
dynamic_registration: Some(true), | |
}), | |
@@ -3172,6 +3180,10 @@ impl LanguageClient { | |
virtual_texts.extend(self.virtual_texts_from_code_lenses(filename)?.into_iter()); | |
} | |
+ if UseVirtualText::All == use_virtual_text { | |
+ virtual_texts.extend(self.virtual_texts_from_close_labels(filename)?.into_iter()); | |
+ } | |
+ | |
if self.get(|state| state.is_nvim)? { | |
let namespace_id = self.get_or_create_namespace(&LCNamespace::VirtualText)?; | |
self.vim()?.set_virtual_texts( | |
@@ -3233,7 +3245,7 @@ impl LanguageClient { | |
.push_str(format!(" | {}", text).as_str()), | |
None => virtual_texts.push(VirtualText { | |
line, | |
- text, | |
+ text: format!("// {}", text), | |
hl_group: "Comment".into(), | |
}), | |
} | |
@@ -3243,6 +3255,32 @@ impl LanguageClient { | |
Ok(virtual_texts) | |
} | |
+ fn virtual_texts_from_close_labels(&self, filename: &str) -> Fallible<Vec<VirtualText>> { | |
+ let mut virtual_texts = vec![]; | |
+ let close_labels = self.get(|state| state.close_labels.get(filename).cloned().unwrap_or_default())?; | |
+ | |
+ for cl in close_labels { | |
+ let line = cl.lnum; | |
+ let text = cl.label; | |
+ | |
+ match virtual_texts | |
+ .iter() | |
+ .position(|v: &VirtualText| v.line == line) | |
+ { | |
+ Some(idx) => virtual_texts[idx] | |
+ .text | |
+ .push_str(format!(" | {}", text).as_str()), | |
+ None => virtual_texts.push(VirtualText { | |
+ line, | |
+ text, | |
+ hl_group: "Comment".into(), | |
+ }), | |
+ } | |
+ } | |
+ | |
+ Ok(virtual_texts) | |
+ } | |
+ | |
pub fn languageClient_handleCompleteDone(&self, params: &Value) -> Fallible<()> { | |
let filename = self.vim()?.get_filename(params)?; | |
let position = self.vim()?.get_position(params)?; | |
@@ -3657,6 +3695,37 @@ impl LanguageClient { | |
Ok(()) | |
} | |
+ pub fn dart_handleCloseLabels(&self, params: &Value) -> Fallible<()> { | |
+ info!("Begin {}", NOTIFICATION__DartCloseLabels); | |
+ let params: CloseLabelParams = serde_json::from_value(params.clone())?; | |
+ let mut filename = params.uri.filepath()?.to_string_lossy().into_owned(); | |
+ // Workaround bug: remove first '/' in case of '/C:/blabla'. | |
+ if filename.starts_with('/') && filename.chars().nth(2) == Some(':') { | |
+ filename.remove(0); | |
+ } | |
+ // Unify name to avoid mismatch due to case insensitivity. | |
+ let filename = filename.canonicalize(); | |
+ let close_labels = params | |
+ .labels | |
+ .into_iter() | |
+ .map(|lab| { | |
+ CloseLabel { | |
+ label: lab.label, | |
+ lnum: lab.range.end.line, | |
+ } | |
+ }) | |
+ .collect::<Vec<_>>(); | |
+ | |
+ self.update(|state| { | |
+ state | |
+ .close_labels | |
+ .insert(filename.clone(), close_labels.clone()); | |
+ Ok(()) | |
+ })?; | |
+ info!("End {}", NOTIFICATION__DartCloseLabels); | |
+ Ok(()) | |
+ } | |
+ | |
pub fn window_progress(&self, params: &Value) -> Fallible<()> { | |
info!("Begin {}", NOTIFICATION__WindowProgress); | |
let params: WindowProgressParams = params.clone().to_lsp()?; | |
diff --git a/src/logger.rs b/src/logger.rs | |
index e7c22e4..ad2d25e 100644 | |
--- a/src/logger.rs | |
+++ b/src/logger.rs | |
@@ -74,7 +74,7 @@ fn create_config(path: &Option<PathBuf>, level: LevelFilter) -> Fallible<Config> | |
.write(true) | |
.truncate(true) | |
.open(&path) | |
- .with_context(|err| format!("Failed to open file ({}): {}", path, err))?; | |
+ .with_context(|err| format!("Failed to open file ({:?}): {}", path, err))?; | |
#[allow(clippy::write_literal)] | |
writeln!( | |
f, | |
diff --git a/src/rpchandler.rs b/src/rpchandler.rs | |
index 7811be7..5a337d3 100644 | |
--- a/src/rpchandler.rs | |
+++ b/src/rpchandler.rs | |
@@ -183,6 +183,7 @@ impl LanguageClient { | |
NOTIFICATION__RustBeginBuild => self.rust_handleBeginBuild(¶ms)?, | |
NOTIFICATION__RustDiagnosticsBegin => self.rust_handleDiagnosticsBegin(¶ms)?, | |
NOTIFICATION__RustDiagnosticsEnd => self.rust_handleDiagnosticsEnd(¶ms)?, | |
+ NOTIFICATION__DartCloseLabels => self.dart_handleCloseLabels(¶ms)?, | |
NOTIFICATION__WindowProgress => self.window_progress(¶ms)?, | |
NOTIFICATION__ServerExited => self.languageClient_serverExited(¶ms)?, | |
diff --git a/src/types.rs b/src/types.rs | |
index f0a4b26..813e6d0 100644 | |
--- a/src/types.rs | |
+++ b/src/types.rs | |
@@ -54,6 +54,7 @@ pub const NOTIFICATION__ClearDocumentHighlight: &str = "languageClient/clearDocu | |
pub const NOTIFICATION__RustBeginBuild: &str = "rustDocument/beginBuild"; | |
pub const NOTIFICATION__RustDiagnosticsBegin: &str = "rustDocument/diagnosticsBegin"; | |
pub const NOTIFICATION__RustDiagnosticsEnd: &str = "rustDocument/diagnosticsEnd"; | |
+pub const NOTIFICATION__DartCloseLabels: &str = "dart/textDocument/publishClosingLabels"; | |
// This is an RLS extension but the name is general enough to assume it might be implemented by | |
// other language servers or planned for inclusion in the base protocol. | |
pub const NOTIFICATION__WindowProgress: &str = "window/progress"; | |
@@ -110,6 +111,24 @@ pub enum UseVirtualText { | |
No, | |
} | |
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | |
+pub struct CloseLabel { | |
+ pub label: String, | |
+ pub lnum: u64, | |
+} | |
+ | |
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | |
+pub struct CloseLabelParams { | |
+ pub uri: Url, | |
+ pub labels: Vec<CloseLabelParamsLabel>, | |
+} | |
+ | |
+#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] | |
+pub struct CloseLabelParamsLabel { | |
+ pub label: String, | |
+ pub range: Range, | |
+} | |
+ | |
#[derive(Serialize)] | |
pub struct State { | |
// Program state. | |
@@ -135,6 +154,8 @@ pub struct State { | |
pub diagnostics: HashMap<String, Vec<Diagnostic>>, | |
// filename => codeLens. | |
pub code_lens: HashMap<String, Vec<CodeLens>>, | |
+ // filename => closeLabels. | |
+ pub close_labels: HashMap<String, Vec<CloseLabel>>, | |
#[serde(skip_serializing)] | |
pub line_diagnostics: HashMap<(String, u64), String>, | |
pub sign_next_id: u64, | |
@@ -221,6 +242,7 @@ impl State { | |
semantic_scope_to_hl_group_table: HashMap::new(), | |
semantic_highlights: HashMap::new(), | |
code_lens: HashMap::new(), | |
+ close_labels: HashMap::new(), | |
diagnostics: HashMap::new(), | |
line_diagnostics: HashMap::new(), | |
sign_next_id: 75_000, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment