Skip to content

Commit

Permalink
chore(els): improve document link
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Oct 14, 2024
1 parent 1206e50 commit 715cdbe
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 27 deletions.
5 changes: 3 additions & 2 deletions crates/els/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ fn load_modules<'a>(
cache: Cache,
root: &Path,
mods: impl Iterator<Item = &'a str>,
shared: SharedCompilerResource,
) {
let src = mods.fold("".to_string(), |acc, module| {
acc + &format!("_ = pyimport \"{module}\"\n")
Expand All @@ -358,7 +359,6 @@ fn load_modules<'a>(
input: Input::str(src.clone()),
..cfg
};
let shared = SharedCompilerResource::new(cfg.clone());
let mut checker = PackageBuilder::inherit(cfg, shared.clone());
let _res = checker.build(src, "exec");
let mut cache = cache.borrow_mut();
Expand All @@ -384,7 +384,7 @@ fn load_modules<'a>(
}

impl CompletionCache {
pub fn new(cfg: ErgConfig, flags: Flags) -> Self {
pub fn new(cfg: ErgConfig, flags: Flags, shared: SharedCompilerResource) -> Self {
let cache = Shared::new(Dict::default());
let clone = cache.clone();
spawn_new_thread(
Expand Down Expand Up @@ -436,6 +436,7 @@ impl CompletionCache {
clone.clone(),
erg_pystd_path(),
major_mods.into_iter().chain(py_specific_mods),
shared,
);
// TODO: load modules from site-packages
flags
Expand Down
51 changes: 28 additions & 23 deletions crates/els/doc_link.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::path::Path;

use erg_common::spawn::safe_yield;
use erg_common::Str;
use erg_compiler::artifact::BuildRunnable;
use erg_compiler::erg_parser::ast::{ClassAttr, Expr, Literal};
Expand All @@ -14,10 +15,14 @@ use crate::_log;
use crate::server::{ELSResult, RedirectableStdout, Server};
use crate::util::NormalizedUrl;

/// programming related words are not considered usual words (e.g. `if`, `while`)
fn is_not_symbol(word: &str) -> bool {
word.chars()
.all(|c| c.is_ascii_digit() || c.is_ascii_punctuation())
}

fn is_usual_word(word: &str) -> bool {
matches!(
word,
word.to_ascii_lowercase().as_str(),
"a" | "the"
| "an"
| "is"
Expand Down Expand Up @@ -89,6 +94,12 @@ fn is_usual_word(word: &str) -> bool {
| "whether"
| "so"
| "although"
| "if"
| "unless"
| "because"
| "for"
| "since"
| "while"
)
}

Expand All @@ -98,6 +109,9 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
params: DocumentLinkParams,
) -> ELSResult<Option<Vec<DocumentLink>>> {
_log!(self, "document link requested: {params:?}");
while !self.flags.builtin_modules_loaded() {
safe_yield();
}
let uri = NormalizedUrl::new(params.text_document.uri);
let mut res = vec![];
res.extend(self.get_document_link(&uri));
Expand Down Expand Up @@ -138,9 +152,9 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
let mut col = comment.token.col_begin;
for li in comment.token.content.split('\n') {
let li = Str::rc(li);
let words = li.split_with(&[" ", "'", "\"", "`"]);
let words = li.split_with(&[" ", "'", "\"", "`", "(", ")", "[", "]", "{", "}"]);
for word in words {
if word.trim().is_empty() || is_usual_word(word) {
if word.trim().is_empty() || is_usual_word(word) || is_not_symbol(word) {
col += word.len() as u32 + 1;
continue;
}
Expand All @@ -164,7 +178,9 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
data: None,
});
} else if let Some((_, vi)) = mod_ctx.context.get_type_info(&typ) {
res.push(self.gen_doc_link_from_vi(word, range, vi));
if let Some(doc) = self.gen_doc_link_from_vi(word, range, vi) {
res.push(doc);
}
}
col += word.len() as u32 + 1;
}
Expand All @@ -174,31 +190,20 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
res
}

fn gen_doc_link_from_vi(&self, name: &str, range: Range, vi: &VarInfo) -> DocumentLink {
fn gen_doc_link_from_vi(&self, name: &str, range: Range, vi: &VarInfo) -> Option<DocumentLink> {
let mut target = if let Some(path) = vi.t.module_path() {
Url::from_file_path(path).ok()
Url::from_file_path(path).ok()?
} else {
vi.def_loc
.module
.as_ref()
.and_then(|path| Url::from_file_path(path).ok())
Url::from_file_path(vi.def_loc.module.as_ref()?).ok()?
};
if let Some(target) = target.as_mut() {
target.set_fragment(
vi.def_loc
.loc
.ln_begin()
.map(|l| format!("L{l}"))
.as_deref(),
);
}
target.set_fragment(Some(&format!("L{}", vi.def_loc.loc.ln_begin()?)));
let tooltip = format!("{name}: {}", vi.t);
DocumentLink {
Some(DocumentLink {
range,
target,
target: Some(target),
tooltip: Some(tooltip),
data: None,
}
})
}

#[allow(clippy::only_used_in_recursion)]
Expand Down
5 changes: 3 additions & 2 deletions crates/els/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,10 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
pub fn new(cfg: ErgConfig, stdout_redirect: Option<mpsc::Sender<Value>>) -> Self {
let flags = Flags::default();
let cfg = Self::register_packages(cfg);
let shared = SharedCompilerResource::new(cfg.copy());
Self {
comp_cache: CompletionCache::new(cfg.copy(), flags.clone()),
shared: SharedCompilerResource::new(cfg.copy()),
comp_cache: CompletionCache::new(cfg.copy(), flags.clone(), shared.clone()),
shared,
cfg,
home: normalize_path(std::env::current_dir().unwrap_or_default()),
erg_path: erg_path().clone(), // already normalized
Expand Down

0 comments on commit 715cdbe

Please sign in to comment.