mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-07-07 21:25:32 +00:00
Repair textDocument/foldingRange request
This commit is contained in:
parent
15978f0b9f
commit
f0d39964b7
6 changed files with 81 additions and 50 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@ target/
|
||||||
/.idea
|
/.idea
|
||||||
tarpaulin-report.html
|
tarpaulin-report.html
|
||||||
crates/**/Cargo.lock
|
crates/**/Cargo.lock
|
||||||
|
*.snap.new
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
db::analysis::TexAnalysis,
|
db::analysis::TexAnalysis,
|
||||||
syntax::{latex, BuildLog},
|
syntax::{bibtex, latex, BuildLog},
|
||||||
Db,
|
Db,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,6 +9,12 @@ pub struct TexDocumentData {
|
||||||
pub green: rowan::GreenNode,
|
pub green: rowan::GreenNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl TexDocumentData {
|
||||||
|
pub fn root(self, db: &dyn Db) -> latex::SyntaxNode {
|
||||||
|
latex::SyntaxNode::new_root(self.green(db))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
impl TexDocumentData {
|
impl TexDocumentData {
|
||||||
#[salsa::tracked]
|
#[salsa::tracked]
|
||||||
|
@ -23,6 +29,12 @@ pub struct BibDocumentData {
|
||||||
pub green: rowan::GreenNode,
|
pub green: rowan::GreenNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BibDocumentData {
|
||||||
|
pub fn root(self, db: &dyn Db) -> bibtex::SyntaxNode {
|
||||||
|
bibtex::SyntaxNode::new_root(self.green(db))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[salsa::interned]
|
#[salsa::interned]
|
||||||
pub struct LogDocumentData {
|
pub struct LogDocumentData {
|
||||||
pub log: BuildLog,
|
pub log: BuildLog,
|
||||||
|
|
|
@ -41,6 +41,13 @@ impl Workspace {
|
||||||
.copied()
|
.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lookup_uri(self, db: &dyn Db, uri: &Url) -> Option<Document> {
|
||||||
|
self.documents(db)
|
||||||
|
.iter()
|
||||||
|
.find(|document| document.location(db).uri(db) == uri)
|
||||||
|
.copied()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lookup_path(self, db: &dyn Db, path: &Path) -> Option<Document> {
|
pub fn lookup_path(self, db: &dyn Db, path: &Path) -> Option<Document> {
|
||||||
self.documents(db)
|
self.documents(db)
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -3,7 +3,7 @@ mod completion;
|
||||||
mod cursor;
|
mod cursor;
|
||||||
mod definition;
|
mod definition;
|
||||||
mod execute_command;
|
mod execute_command;
|
||||||
mod folding;
|
pub mod folding;
|
||||||
mod formatting;
|
mod formatting;
|
||||||
mod forward_search;
|
mod forward_search;
|
||||||
mod highlight;
|
mod highlight;
|
||||||
|
@ -25,7 +25,6 @@ pub use self::{
|
||||||
completion::{complete, CompletionItemData, COMPLETION_LIMIT},
|
completion::{complete, CompletionItemData, COMPLETION_LIMIT},
|
||||||
definition::goto_definition,
|
definition::goto_definition,
|
||||||
execute_command::execute_command,
|
execute_command::execute_command,
|
||||||
folding::find_foldings,
|
|
||||||
formatting::format_source_code,
|
formatting::format_source_code,
|
||||||
forward_search::{ForwardSearch, ForwardSearchResult, ForwardSearchStatus},
|
forward_search::{ForwardSearch, ForwardSearchResult, ForwardSearchStatus},
|
||||||
highlight::find_document_highlights,
|
highlight::find_document_highlights,
|
||||||
|
|
|
@ -1,49 +1,51 @@
|
||||||
use lsp_types::{FoldingRange, FoldingRangeKind, FoldingRangeParams, Range};
|
use lsp_types::{FoldingRange, FoldingRangeKind, Range, Url};
|
||||||
use rowan::ast::AstNode;
|
use rowan::ast::AstNode;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
db::{parse::DocumentData, workspace::Workspace},
|
||||||
syntax::{bibtex, latex},
|
syntax::{bibtex, latex},
|
||||||
DocumentData, LineIndexExt,
|
Db, LineIndexExt,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::FeatureRequest;
|
pub fn find_all(db: &dyn Db, uri: &Url) -> Option<Vec<FoldingRange>> {
|
||||||
|
let document = Workspace::get(db).lookup_uri(db, uri)?;
|
||||||
pub fn find_foldings(request: FeatureRequest<FoldingRangeParams>) -> Vec<FoldingRange> {
|
let line_index = document.contents(db).line_index(db);
|
||||||
let mut foldings = Vec::new();
|
let foldings = match document.parse(db) {
|
||||||
let main_document = request.main_document();
|
DocumentData::Tex(data) => {
|
||||||
match main_document.data() {
|
let mut results = Vec::new();
|
||||||
DocumentData::Latex(data) => {
|
let root = data.root(db);
|
||||||
for node in latex::SyntaxNode::new_root(data.green.clone()).descendants() {
|
for node in root.descendants() {
|
||||||
if let Some(folding) = latex::Environment::cast(node.clone())
|
if let Some(folding) = latex::Environment::cast(node.clone())
|
||||||
.map(|node| latex::small_range(&node))
|
.map(|node| latex::small_range(&node))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
latex::Section::cast(node.clone()).map(|node| latex::small_range(&node))
|
latex::Section::cast(node.clone()).map(|node| latex::small_range(&node))
|
||||||
})
|
})
|
||||||
.or_else(|| latex::EnumItem::cast(node).map(|node| latex::small_range(&node)))
|
.or_else(|| latex::EnumItem::cast(node).map(|node| latex::small_range(&node)))
|
||||||
.map(|node| main_document.line_index().line_col_lsp_range(node))
|
.map(|node| line_index.line_col_lsp_range(node))
|
||||||
.map(create_range)
|
.map(create_range)
|
||||||
{
|
{
|
||||||
foldings.push(folding);
|
results.push(folding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
results
|
||||||
}
|
}
|
||||||
DocumentData::Bibtex(data) => {
|
DocumentData::Bib(data) => {
|
||||||
for node in bibtex::SyntaxNode::new_root(data.green.clone()).descendants() {
|
let root = data.root(db);
|
||||||
if matches!(
|
root.descendants()
|
||||||
node.kind(),
|
.filter(|node| {
|
||||||
bibtex::PREAMBLE | bibtex::STRING | bibtex::ENTRY
|
matches!(
|
||||||
) {
|
node.kind(),
|
||||||
foldings.push(create_range(
|
bibtex::PREAMBLE | bibtex::STRING | bibtex::ENTRY
|
||||||
main_document
|
)
|
||||||
.line_index()
|
})
|
||||||
.line_col_lsp_range(node.text_range()),
|
.map(|node| create_range(line_index.line_col_lsp_range(node.text_range())))
|
||||||
));
|
.collect()
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DocumentData::BuildLog(_) => {}
|
DocumentData::Log(_) => return None,
|
||||||
}
|
};
|
||||||
foldings
|
|
||||||
|
Some(foldings)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_range(range: Range) -> FoldingRange {
|
fn create_range(range: Range) -> FoldingRange {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use lsp_server::{Connection, Message, RequestId};
|
||||||
use lsp_types::{notification::*, request::*, *};
|
use lsp_types::{notification::*, request::*, *};
|
||||||
use rowan::{ast::AstNode, TextSize};
|
use rowan::{ast::AstNode, TextSize};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use salsa::ParallelDatabase;
|
use salsa::{DbWithJar, ParallelDatabase};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use threadpool::ThreadPool;
|
use threadpool::ThreadPool;
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@ use crate::{
|
||||||
client::LspClient,
|
client::LspClient,
|
||||||
component_db::COMPONENT_DATABASE,
|
component_db::COMPONENT_DATABASE,
|
||||||
db::{
|
db::{
|
||||||
self,
|
|
||||||
document::{Language, Owner},
|
document::{Language, Owner},
|
||||||
workspace::Workspace,
|
workspace::Workspace,
|
||||||
Distro,
|
Distro,
|
||||||
|
@ -31,7 +30,7 @@ use crate::{
|
||||||
features::{
|
features::{
|
||||||
building::{BuildParams, BuildResult, BuildStatus, TexCompiler},
|
building::{BuildParams, BuildResult, BuildStatus, TexCompiler},
|
||||||
execute_command, find_all_references, find_document_highlights, find_document_links,
|
execute_command, find_all_references, find_document_highlights, find_document_links,
|
||||||
find_document_symbols, find_foldings, find_hover, find_inlay_hints, find_workspace_symbols,
|
find_document_symbols, find_hover, find_inlay_hints, find_workspace_symbols, folding,
|
||||||
format_source_code, goto_definition, prepare_rename_all, rename_all, CompletionItemData,
|
format_source_code, goto_definition, prepare_rename_all, rename_all, CompletionItemData,
|
||||||
FeatureRequest, ForwardSearch, ForwardSearchResult, ForwardSearchStatus,
|
FeatureRequest, ForwardSearch, ForwardSearchResult, ForwardSearchStatus,
|
||||||
},
|
},
|
||||||
|
@ -52,7 +51,6 @@ enum InternalMessage {
|
||||||
struct ServerFork {
|
struct ServerFork {
|
||||||
connection: Arc<Connection>,
|
connection: Arc<Connection>,
|
||||||
internal_tx: Sender<InternalMessage>,
|
internal_tx: Sender<InternalMessage>,
|
||||||
db: salsa::Snapshot<Database>,
|
|
||||||
workspace: crate::Workspace,
|
workspace: crate::Workspace,
|
||||||
diagnostic_tx: debouncer::Sender<crate::Workspace>,
|
diagnostic_tx: debouncer::Sender<crate::Workspace>,
|
||||||
diagnostic_manager: DiagnosticManager,
|
diagnostic_manager: DiagnosticManager,
|
||||||
|
@ -107,6 +105,22 @@ impl Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_async_query<R, Q>(&self, id: RequestId, query: Q)
|
||||||
|
where
|
||||||
|
R: Serialize + Default,
|
||||||
|
Q: FnOnce(&dyn Db) -> Option<R> + Send + 'static,
|
||||||
|
{
|
||||||
|
let snapshot = self.db.snapshot();
|
||||||
|
let client = self.client.clone();
|
||||||
|
self.pool.execute(move || {
|
||||||
|
let db = snapshot.as_jar_db();
|
||||||
|
let result = query(db).unwrap_or_default();
|
||||||
|
client
|
||||||
|
.send_response(lsp_server::Response::new_ok(id, result))
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn spawn(&self, job: impl FnOnce(ServerFork) + Send + 'static) {
|
fn spawn(&self, job: impl FnOnce(ServerFork) + Send + 'static) {
|
||||||
let fork = self.fork();
|
let fork = self.fork();
|
||||||
self.pool.execute(move || job(fork));
|
self.pool.execute(move || job(fork));
|
||||||
|
@ -116,7 +130,6 @@ impl Server {
|
||||||
ServerFork {
|
ServerFork {
|
||||||
connection: self.connection.clone(),
|
connection: self.connection.clone(),
|
||||||
internal_tx: self.internal_tx.clone(),
|
internal_tx: self.internal_tx.clone(),
|
||||||
db: self.db.snapshot(),
|
|
||||||
workspace: self.workspace.clone(),
|
workspace: self.workspace.clone(),
|
||||||
diagnostic_tx: self.diagnostic_tx.clone(),
|
diagnostic_tx: self.diagnostic_tx.clone(),
|
||||||
diagnostic_manager: self.diagnostic_manager.clone(),
|
diagnostic_manager: self.diagnostic_manager.clone(),
|
||||||
|
@ -362,12 +375,12 @@ impl Server {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn did_change(&mut self, mut params: DidChangeTextDocumentParams) -> Result<()> {
|
fn did_change(&mut self, params: DidChangeTextDocumentParams) -> Result<()> {
|
||||||
normalize_uri(&mut params.text_document.uri);
|
let mut uri = params.text_document.uri;
|
||||||
|
normalize_uri(&mut uri);
|
||||||
|
|
||||||
let workspace = Workspace::get(&self.db);
|
let workspace = Workspace::get(&self.db);
|
||||||
let location = db::document::Location::new(&self.db, params.text_document.uri);
|
let document = match workspace.lookup_uri(&self.db, &uri) {
|
||||||
let document = match workspace.lookup(&self.db, location) {
|
|
||||||
Some(document) => document,
|
Some(document) => document,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
@ -430,8 +443,7 @@ impl Server {
|
||||||
let mut uri = params.text_document.uri;
|
let mut uri = params.text_document.uri;
|
||||||
normalize_uri(&mut uri);
|
normalize_uri(&mut uri);
|
||||||
|
|
||||||
let location = db::document::Location::new(&self.db, uri);
|
if let Some(document) = Workspace::get(&self.db).lookup_uri(&self.db, &uri) {
|
||||||
if let Some(document) = Workspace::get(&self.db).lookup(&self.db, location) {
|
|
||||||
document
|
document
|
||||||
.set_owner(&mut self.db)
|
.set_owner(&mut self.db)
|
||||||
.with_durability(salsa::Durability::LOW)
|
.with_durability(salsa::Durability::LOW)
|
||||||
|
@ -558,10 +570,10 @@ impl Server {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn folding_range(&self, id: RequestId, mut params: FoldingRangeParams) -> Result<()> {
|
fn folding_range(&self, id: RequestId, params: FoldingRangeParams) -> Result<()> {
|
||||||
normalize_uri(&mut params.text_document.uri);
|
let mut uri = params.text_document.uri;
|
||||||
let uri = Arc::new(params.text_document.uri.clone());
|
normalize_uri(&mut uri);
|
||||||
self.handle_feature_request(id, params, uri, find_foldings)?;
|
self.run_async_query(id, move |db| folding::find_all(db.as_jar_db(), &uri));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,8 +595,7 @@ impl Server {
|
||||||
);
|
);
|
||||||
|
|
||||||
let workspace = Workspace::get(&self.db);
|
let workspace = Workspace::get(&self.db);
|
||||||
let location = db::document::Location::new(&self.db, uri.as_ref().clone());
|
if let Some(document) = workspace.lookup_uri(&self.db, &uri) {
|
||||||
if let Some(document) = workspace.lookup(&self.db, location) {
|
|
||||||
let position = document
|
let position = document
|
||||||
.contents(&self.db)
|
.contents(&self.db)
|
||||||
.line_index(&self.db)
|
.line_index(&self.db)
|
||||||
|
@ -759,8 +770,7 @@ impl Server {
|
||||||
callback: impl FnOnce(ForwardSearchStatus) + Send + 'static,
|
callback: impl FnOnce(ForwardSearchStatus) + Send + 'static,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let workspace = Workspace::get(&self.db);
|
let workspace = Workspace::get(&self.db);
|
||||||
let location = db::document::Location::new(&self.db, uri.clone());
|
let document = match workspace.lookup_uri(&self.db, &uri) {
|
||||||
let document = match workspace.lookup(&self.db, location) {
|
|
||||||
Some(document) => document,
|
Some(document) => document,
|
||||||
None => {
|
None => {
|
||||||
callback(ForwardSearchStatus::FAILURE);
|
callback(ForwardSearchStatus::FAILURE);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue