mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-08-04 10:49:55 +00:00
Implement workspace/symbol request
This commit is contained in:
parent
6689c59fe8
commit
9de957f5bf
2 changed files with 80 additions and 23 deletions
|
@ -14,7 +14,7 @@ use crate::hover::HoverProvider;
|
|||
use crate::link::LinkProvider;
|
||||
use crate::reference::ReferenceProvider;
|
||||
use crate::rename::{PrepareRenameProvider, RenameProvider};
|
||||
use crate::symbol::{SymbolProvider, SymbolResponse};
|
||||
use crate::symbol::{self, SymbolProvider, SymbolResponse};
|
||||
use crate::syntax::*;
|
||||
use crate::workspace::*;
|
||||
use futures::lock::Mutex;
|
||||
|
@ -109,7 +109,7 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
references_provider: Some(true),
|
||||
document_highlight_provider: Some(true),
|
||||
document_symbol_provider: Some(true),
|
||||
workspace_symbol_provider: None,
|
||||
workspace_symbol_provider: Some(true),
|
||||
code_action_provider: None,
|
||||
code_lens_provider: None,
|
||||
document_formatting_provider: Some(true),
|
||||
|
@ -295,6 +295,17 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
Ok(results)
|
||||
}
|
||||
|
||||
#[jsonrpc_method("workspace/symbol", kind = "request")]
|
||||
pub async fn workspace_symbol(
|
||||
&self,
|
||||
params: WorkspaceSymbolParams,
|
||||
) -> Result<Vec<SymbolInformation>> {
|
||||
let client_capabilities = Arc::clone(&self.client_capabilities.get().unwrap());
|
||||
let workspace = self.workspace_manager.get();
|
||||
let symbols = symbol::workspace_symbols(client_capabilities, workspace, ¶ms).await;
|
||||
Ok(symbols)
|
||||
}
|
||||
|
||||
#[jsonrpc_method("textDocument/documentSymbol", kind = "request")]
|
||||
pub async fn document_symbol(&self, params: DocumentSymbolParams) -> Result<SymbolResponse> {
|
||||
let request = self.make_feature_request(params.text_document.as_uri(), params)?;
|
||||
|
|
|
@ -10,6 +10,7 @@ use crate::workspace::*;
|
|||
use futures_boxed::boxed;
|
||||
use lsp_types::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct SymbolProvider {
|
||||
provider: ConcatProvider<DocumentSymbolParams, DocumentSymbol>,
|
||||
|
@ -59,31 +60,76 @@ impl SymbolResponse {
|
|||
if client_capabilities.has_hierarchical_document_symbol_support() {
|
||||
Self::Hierarchical(symbols)
|
||||
} else {
|
||||
fn flatten(results: &mut Vec<SymbolInformation>, uri: &Uri, symbol: DocumentSymbol) {
|
||||
if symbol.kind == SymbolKind::Field {
|
||||
return;
|
||||
}
|
||||
|
||||
let info = SymbolInformation {
|
||||
name: symbol.name,
|
||||
deprecated: Some(false),
|
||||
kind: symbol.kind,
|
||||
container_name: None,
|
||||
location: Location::new(uri.clone().into(), symbol.range),
|
||||
};
|
||||
results.push(info);
|
||||
if let Some(children) = symbol.children {
|
||||
for child in children {
|
||||
flatten(results, uri, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut results = Vec::new();
|
||||
for symbol in symbols {
|
||||
flatten(&mut results, uri, symbol);
|
||||
Self::flatten(&mut results, uri, symbol);
|
||||
}
|
||||
Self::Flat(results)
|
||||
}
|
||||
}
|
||||
|
||||
fn flatten(results: &mut Vec<SymbolInformation>, uri: &Uri, symbol: DocumentSymbol) {
|
||||
if symbol.kind == SymbolKind::Field {
|
||||
return;
|
||||
}
|
||||
|
||||
let info = SymbolInformation {
|
||||
name: symbol.name,
|
||||
deprecated: Some(false),
|
||||
kind: symbol.kind,
|
||||
container_name: None,
|
||||
location: Location::new(uri.clone().into(), symbol.range),
|
||||
};
|
||||
results.push(info);
|
||||
if let Some(children) = symbol.children {
|
||||
for child in children {
|
||||
Self::flatten(results, uri, child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn workspace_symbols(
|
||||
client_capabilities: Arc<ClientCapabilities>,
|
||||
workspace: Arc<Workspace>,
|
||||
params: &WorkspaceSymbolParams,
|
||||
) -> Vec<SymbolInformation> {
|
||||
let provider = SymbolProvider::new();
|
||||
let mut all_symbols = Vec::new();
|
||||
|
||||
for document in &workspace.documents {
|
||||
let uri: Uri = document.uri.clone();
|
||||
let request = FeatureRequest {
|
||||
client_capabilities: Arc::clone(&client_capabilities),
|
||||
view: DocumentView::new(Arc::clone(&workspace), Arc::clone(&document)),
|
||||
params: DocumentSymbolParams {
|
||||
text_document: TextDocumentIdentifier::new(uri.clone().into()),
|
||||
},
|
||||
};
|
||||
for symbol in provider.execute(&request).await {
|
||||
SymbolResponse::flatten(&mut all_symbols, &uri, symbol);
|
||||
}
|
||||
}
|
||||
|
||||
let query_words: Vec<String> = params
|
||||
.query
|
||||
.split_whitespace()
|
||||
.map(str::to_lowercase)
|
||||
.collect();
|
||||
let mut filtered_symbols = Vec::new();
|
||||
for symbol in all_symbols {
|
||||
let name = symbol.name.to_lowercase();
|
||||
let mut included = true;
|
||||
for word in &query_words {
|
||||
if !name.contains(word) {
|
||||
included = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if included {
|
||||
filtered_symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
filtered_symbols
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue