Skip to content

Commit 44c0292

Browse files
committed
Fix case when vim and language server reports different path for the same file.
Close #199.
1 parent 4087bef commit 44c0292

File tree

3 files changed

+57
-25
lines changed

3 files changed

+57
-25
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/languageclient.rs

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,34 @@ impl ILanguageClient for Arc<Mutex<State>> {
598598
}
599599

600600
fn display_diagnostics(&self, filename: &str, diagnostics: &[Diagnostic]) -> Result<()> {
601+
// Line diagnostics.
602+
self.update(|state| {
603+
state
604+
.line_diagnostics
605+
.retain(|&(ref f, _), _| f != filename);
606+
Ok(())
607+
})?;
608+
let mut line_diagnostics = HashMap::new();
609+
for entry in diagnostics {
610+
let line = entry.range.start.line;
611+
let mut msg = String::new();
612+
if let Some(severity) = entry.severity {
613+
msg += &format!("[{:?}]", severity);
614+
}
615+
if let Some(ref code) = entry.code {
616+
let s = code.to_string();
617+
if !s.is_empty() {
618+
msg += &format!("[{}]", s);
619+
}
620+
}
621+
msg += &entry.message;
622+
line_diagnostics.insert((filename.to_owned(), line), msg);
623+
}
624+
self.update(|state| {
625+
state.line_diagnostics.merge(line_diagnostics);
626+
Ok(())
627+
})?;
628+
601629
// Signs.
602630
let mut signs: Vec<_> = diagnostics
603631
.iter()
@@ -660,7 +688,8 @@ impl ILanguageClient for Arc<Mutex<State>> {
660688
let source = source.ok_or_else(|| format_err!("Failed to get highlight source id"))?;
661689
let diagnosticsDisplay = self.get(|state| Ok(state.diagnosticsDisplay.clone()))?;
662690

663-
// Optimize.
691+
// Highlight.
692+
// TODO: Optimize.
664693
self.call(None, "nvim_buf_clear_highlight", json!([0, source, 1, -1]))?;
665694
for dn in diagnostics.iter() {
666695
let severity = dn.severity.unwrap_or(DiagnosticSeverity::Information);
@@ -929,7 +958,7 @@ impl ILanguageClient for Arc<Mutex<State>> {
929958
let diagnostics = self.get(|state| {
930959
state
931960
.diagnostics
932-
.get(&filename)
961+
.get(&filename.canonicalize())
933962
.cloned()
934963
.ok_or_else(|| format_err!("No diagnostics"))
935964
}).unwrap_or_default();
@@ -1512,41 +1541,22 @@ impl ILanguageClient for Arc<Mutex<State>> {
15121541
.to_str()
15131542
.ok_or_else(|| format_err!("Failed to convert PathBuf to str"))?
15141543
.to_owned();
1515-
// Remove first '/' in case of '/C:/blabla'.
1544+
// Workaround bug: remove first '/' in case of '/C:/blabla'.
15161545
if filename.chars().nth(0) == Some('/') && filename.chars().nth(2) == Some(':') {
15171546
filename.remove(0);
15181547
}
1548+
let filename = filename.canonicalize();
15191549
self.update(|state| {
15201550
state
15211551
.diagnostics
15221552
.insert(filename.clone(), params.diagnostics.clone());
1523-
state.line_diagnostics.retain(|fl, _| fl.0 != filename);
15241553
Ok(())
15251554
})?;
15261555

1527-
for entry in &params.diagnostics {
1528-
let line = entry.range.start.line;
1529-
let mut msg = String::new();
1530-
if let Some(severity) = entry.severity {
1531-
msg += &format!("[{:?}]", severity);
1532-
}
1533-
if let Some(ref code) = entry.code {
1534-
let s = code.to_string();
1535-
if !s.is_empty() {
1536-
msg += &format!("[{}]", s);
1537-
}
1538-
}
1539-
msg += &entry.message;
1540-
self.update(|state| {
1541-
state.line_diagnostics.insert((filename.clone(), line), msg);
1542-
Ok(())
1543-
})?;
1544-
}
1545-
15461556
info!("End {}", lsp::notification::PublishDiagnostics::METHOD);
15471557

15481558
let current_filename: String = self.eval(VimVar::Filename)?;
1549-
if filename != current_filename {
1559+
if filename != current_filename.canonicalize() {
15501560
return Ok(());
15511561
}
15521562

src/utils.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,3 +410,25 @@ fn test_diff_value() {
410410
}
411411
);
412412
}
413+
414+
pub trait Canonicalize {
415+
fn canonicalize(&self) -> String;
416+
}
417+
418+
impl<P> Canonicalize for P
419+
where
420+
P: AsRef<Path>,
421+
{
422+
fn canonicalize(&self) -> String {
423+
if let Ok(fc) = std::fs::canonicalize(self) {
424+
if let Some(fs) = fc.to_str() {
425+
return fs.to_owned();
426+
}
427+
}
428+
429+
self.as_ref()
430+
.to_str()
431+
.map(|s| s.to_owned())
432+
.unwrap_or_default()
433+
}
434+
}

0 commit comments

Comments
 (0)