Skip to content

Commit

Permalink
Fix case when vim and language server reports different path for the …
Browse files Browse the repository at this point in the history
…same file.

Close #199.
  • Loading branch information
autozimu committed Jan 3, 2018
1 parent 4087bef commit 44c0292
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 34 additions & 24 deletions src/languageclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,34 @@ impl ILanguageClient for Arc<Mutex<State>> {
}

fn display_diagnostics(&self, filename: &str, diagnostics: &[Diagnostic]) -> Result<()> {
// Line diagnostics.
self.update(|state| {
state
.line_diagnostics
.retain(|&(ref f, _), _| f != filename);
Ok(())
})?;
let mut line_diagnostics = HashMap::new();
for entry in diagnostics {
let line = entry.range.start.line;
let mut msg = String::new();
if let Some(severity) = entry.severity {
msg += &format!("[{:?}]", severity);
}
if let Some(ref code) = entry.code {
let s = code.to_string();
if !s.is_empty() {
msg += &format!("[{}]", s);
}
}
msg += &entry.message;
line_diagnostics.insert((filename.to_owned(), line), msg);
}
self.update(|state| {
state.line_diagnostics.merge(line_diagnostics);
Ok(())
})?;

// Signs.
let mut signs: Vec<_> = diagnostics
.iter()
Expand Down Expand Up @@ -660,7 +688,8 @@ impl ILanguageClient for Arc<Mutex<State>> {
let source = source.ok_or_else(|| format_err!("Failed to get highlight source id"))?;
let diagnosticsDisplay = self.get(|state| Ok(state.diagnosticsDisplay.clone()))?;

// Optimize.
// Highlight.
// TODO: Optimize.
self.call(None, "nvim_buf_clear_highlight", json!([0, source, 1, -1]))?;
for dn in diagnostics.iter() {
let severity = dn.severity.unwrap_or(DiagnosticSeverity::Information);
Expand Down Expand Up @@ -929,7 +958,7 @@ impl ILanguageClient for Arc<Mutex<State>> {
let diagnostics = self.get(|state| {
state
.diagnostics
.get(&filename)
.get(&filename.canonicalize())
.cloned()
.ok_or_else(|| format_err!("No diagnostics"))
}).unwrap_or_default();
Expand Down Expand Up @@ -1512,41 +1541,22 @@ impl ILanguageClient for Arc<Mutex<State>> {
.to_str()
.ok_or_else(|| format_err!("Failed to convert PathBuf to str"))?
.to_owned();
// Remove first '/' in case of '/C:/blabla'.
// Workaround bug: remove first '/' in case of '/C:/blabla'.
if filename.chars().nth(0) == Some('/') && filename.chars().nth(2) == Some(':') {
filename.remove(0);
}
let filename = filename.canonicalize();
self.update(|state| {
state
.diagnostics
.insert(filename.clone(), params.diagnostics.clone());
state.line_diagnostics.retain(|fl, _| fl.0 != filename);
Ok(())
})?;

for entry in &params.diagnostics {
let line = entry.range.start.line;
let mut msg = String::new();
if let Some(severity) = entry.severity {
msg += &format!("[{:?}]", severity);
}
if let Some(ref code) = entry.code {
let s = code.to_string();
if !s.is_empty() {
msg += &format!("[{}]", s);
}
}
msg += &entry.message;
self.update(|state| {
state.line_diagnostics.insert((filename.clone(), line), msg);
Ok(())
})?;
}

info!("End {}", lsp::notification::PublishDiagnostics::METHOD);

let current_filename: String = self.eval(VimVar::Filename)?;
if filename != current_filename {
if filename != current_filename.canonicalize() {
return Ok(());
}

Expand Down
22 changes: 22 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,25 @@ fn test_diff_value() {
}
);
}

pub trait Canonicalize {
fn canonicalize(&self) -> String;
}

impl<P> Canonicalize for P
where
P: AsRef<Path>,
{
fn canonicalize(&self) -> String {
if let Ok(fc) = std::fs::canonicalize(self) {
if let Some(fs) = fc.to_str() {
return fs.to_owned();
}
}

self.as_ref()
.to_str()
.map(|s| s.to_owned())
.unwrap_or_default()
}
}

0 comments on commit 44c0292

Please sign in to comment.