summaryrefslogtreecommitdiff
path: root/support/texlab/src/symbol/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/symbol/mod.rs')
-rw-r--r--support/texlab/src/symbol/mod.rs231
1 files changed, 74 insertions, 157 deletions
diff --git a/support/texlab/src/symbol/mod.rs b/support/texlab/src/symbol/mod.rs
index ec68d70c3e..b292f15bb2 100644
--- a/support/texlab/src/symbol/mod.rs
+++ b/support/texlab/src/symbol/mod.rs
@@ -2,122 +2,30 @@ mod bibtex_entry;
mod bibtex_string;
mod latex_section;
mod project_order;
-
-use self::bibtex_entry::BibtexEntrySymbolProvider;
-use self::bibtex_string::BibtexStringSymbolProvider;
-use self::latex_section::LatexSectionSymbolProvider;
-use self::project_order::ProjectOrdering;
-use crate::capabilities::ClientCapabilitiesExt;
-use crate::lsp_kind::Structure;
-use crate::syntax::*;
-use crate::workspace::*;
-use futures_boxed::boxed;
-use lsp_types::*;
-use serde::{Deserialize, Serialize};
-use std::cmp::Reverse;
-use std::sync::Arc;
+mod types;
pub use self::latex_section::{build_section_tree, LatexSectionNode, LatexSectionTree};
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
-pub enum LatexSymbolKind {
- Section,
- Figure,
- Algorithm,
- Table,
- Listing,
- Enumeration,
- EnumerationItem,
- Theorem,
- Equation,
- Entry(BibtexEntryTypeCategory),
- Field,
- String,
-}
-
-impl Into<SymbolKind> for LatexSymbolKind {
- fn into(self) -> SymbolKind {
- match self {
- Self::Section => Structure::Section.symbol_kind(),
- Self::Figure | Self::Algorithm | Self::Table | Self::Listing => {
- Structure::Float.symbol_kind()
- }
- Self::Enumeration => Structure::Environment.symbol_kind(),
- Self::EnumerationItem => Structure::Item.symbol_kind(),
- Self::Theorem => Structure::Theorem.symbol_kind(),
- Self::Equation => Structure::Equation.symbol_kind(),
- Self::Entry(category) => Structure::Entry(category).symbol_kind(),
- Self::Field => Structure::Field.symbol_kind(),
- Self::String => Structure::Entry(BibtexEntryTypeCategory::String).symbol_kind(),
- }
- }
-}
-
-#[derive(Debug, PartialEq, Eq, Clone)]
-pub struct LatexSymbol {
- pub name: String,
- pub label: Option<String>,
- pub kind: LatexSymbolKind,
- pub deprecated: bool,
- pub full_range: Range,
- pub selection_range: Range,
- pub children: Vec<LatexSymbol>,
-}
-
-impl LatexSymbol {
- pub fn search_text(&self) -> String {
- let kind = match self.kind {
- LatexSymbolKind::Section => "latex section",
- LatexSymbolKind::Figure => "latex float figure",
- LatexSymbolKind::Algorithm => "latex float algorithm",
- LatexSymbolKind::Table => "latex float table",
- LatexSymbolKind::Listing => "latex float listing",
- LatexSymbolKind::Enumeration => "latex enumeration",
- LatexSymbolKind::EnumerationItem => "latex enumeration item",
- LatexSymbolKind::Theorem => "latex math",
- LatexSymbolKind::Equation => "latex math equation",
- LatexSymbolKind::Entry(_) => "bibtex entry",
- LatexSymbolKind::Field => "bibtex field",
- LatexSymbolKind::String => "bibtex string",
- };
- format!("{} {}", kind, self.name).to_lowercase()
- }
-
- pub fn flatten(mut self, buffer: &mut Vec<Self>) {
- if self.kind == LatexSymbolKind::Field {
- return;
- }
- for symbol in self.children.drain(..) {
- symbol.flatten(buffer);
- }
- buffer.push(self);
- }
-
- pub fn into_symbol_info(self, uri: Uri) -> SymbolInformation {
- SymbolInformation {
- name: self.name,
- deprecated: Some(self.deprecated),
- kind: self.kind.into(),
- container_name: None,
- location: Location::new(uri.clone().into(), self.full_range),
- }
- }
-}
-
-impl Into<DocumentSymbol> for LatexSymbol {
- fn into(self) -> DocumentSymbol {
- let children = self.children.into_iter().map(Into::into).collect();
- DocumentSymbol {
- name: self.name,
- deprecated: Some(self.deprecated),
- detail: self.label,
- kind: self.kind.into(),
- selection_range: self.selection_range,
- range: self.full_range,
- children: Some(children),
- }
- }
-}
+use self::{
+ bibtex_entry::BibtexEntrySymbolProvider, bibtex_string::BibtexStringSymbolProvider,
+ latex_section::LatexSectionSymbolProvider, project_order::ProjectOrdering, types::LatexSymbol,
+};
+use crate::{
+ feature::{ConcatProvider, DocumentView, FeatureProvider, FeatureRequest},
+ protocol::{
+ ClientCapabilities, ClientCapabilitiesExt, DocumentSymbolParams, DocumentSymbolResponse,
+ Options, PartialResultParams, SymbolInformation, TextDocumentIdentifier, Uri,
+ WorkDoneProgressParams, WorkspaceSymbolParams,
+ },
+ tex::Distribution,
+ workspace::Snapshot,
+};
+use async_trait::async_trait;
+use std::{
+ cmp::Reverse,
+ path::{Path, PathBuf},
+ sync::Arc,
+};
pub struct SymbolProvider {
provider: ConcatProvider<DocumentSymbolParams, LatexSymbol>,
@@ -141,44 +49,37 @@ impl Default for SymbolProvider {
}
}
+#[async_trait]
impl FeatureProvider for SymbolProvider {
type Params = DocumentSymbolParams;
type Output = Vec<LatexSymbol>;
- #[boxed]
- async fn execute<'a>(&'a self, request: &'a FeatureRequest<Self::Params>) -> Self::Output {
- self.provider.execute(request).await
+ async fn execute<'a>(&'a self, req: &'a FeatureRequest<Self::Params>) -> Self::Output {
+ self.provider.execute(req).await
}
}
-#[serde(untagged)]
-#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
-pub enum SymbolResponse {
- Flat(Vec<SymbolInformation>),
- Hierarchical(Vec<DocumentSymbol>),
-}
-
-impl SymbolResponse {
- pub fn new(
- client_capabilities: &ClientCapabilities,
- workspace: &Workspace,
- uri: &Uri,
- symbols: Vec<LatexSymbol>,
- ) -> Self {
- if client_capabilities.has_hierarchical_document_symbol_support() {
- Self::Hierarchical(symbols.into_iter().map(Into::into).collect())
- } else {
- let mut buffer = Vec::new();
- for symbol in symbols {
- symbol.flatten(&mut buffer);
- }
- let mut buffer = buffer
- .into_iter()
- .map(|symbol| symbol.into_symbol_info(uri.clone()))
- .collect();
- sort_symbols(workspace, &mut buffer);
- Self::Flat(buffer)
+pub fn document_symbols(
+ client_capabilities: &ClientCapabilities,
+ snapshot: &Snapshot,
+ uri: &Uri,
+ options: &Options,
+ current_dir: &Path,
+ symbols: Vec<LatexSymbol>,
+) -> DocumentSymbolResponse {
+ if client_capabilities.has_hierarchical_document_symbol_support() {
+ DocumentSymbolResponse::Nested(symbols.into_iter().map(Into::into).collect())
+ } else {
+ let mut buffer = Vec::new();
+ for symbol in symbols {
+ symbol.flatten(&mut buffer);
}
+ let mut buffer = buffer
+ .into_iter()
+ .map(|symbol| symbol.into_symbol_info(uri.clone()))
+ .collect();
+ sort_symbols(snapshot, options, &current_dir, &mut buffer);
+ DocumentSymbolResponse::Flat(buffer)
}
}
@@ -187,28 +88,39 @@ struct WorkspaceSymbol {
search_text: String,
}
-pub async fn workspace_symbols(
- distribution: Arc<Box<dyn tex::Distribution>>,
+pub async fn workspace_symbols<'a>(
+ distro: Arc<dyn Distribution>,
client_capabilities: Arc<ClientCapabilities>,
- workspace: Arc<Workspace>,
- params: &WorkspaceSymbolParams,
+ snapshot: Arc<Snapshot>,
+ options: &'a Options,
+ current_dir: Arc<PathBuf>,
+ params: &'a WorkspaceSymbolParams,
) -> Vec<SymbolInformation> {
let provider = SymbolProvider::new();
let mut 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)),
+ for doc in &snapshot.0 {
+ let uri: Uri = doc.uri.clone();
+ let req = FeatureRequest {
params: DocumentSymbolParams {
text_document: TextDocumentIdentifier::new(uri.clone().into()),
+ work_done_progress_params: WorkDoneProgressParams::default(),
+ partial_result_params: PartialResultParams::default(),
},
- distribution: Arc::clone(&distribution),
+ view: DocumentView::analyze(
+ Arc::clone(&snapshot),
+ Arc::clone(&doc),
+ &options,
+ &current_dir,
+ ),
+ distro: distro.clone(),
+ client_capabilities: Arc::clone(&client_capabilities),
+ options: options.clone(),
+ current_dir: Arc::clone(&current_dir),
};
let mut buffer = Vec::new();
- for symbol in provider.execute(&request).await {
+ for symbol in provider.execute(&req).await {
symbol.flatten(&mut buffer);
}
@@ -239,12 +151,17 @@ pub async fn workspace_symbols(
filtered.push(symbol.info);
}
}
- sort_symbols(&workspace, &mut filtered);
+ sort_symbols(&snapshot, options, &current_dir, &mut filtered);
filtered
}
-fn sort_symbols(workspace: &Workspace, symbols: &mut Vec<SymbolInformation>) {
- let ordering = ProjectOrdering::new(workspace);
+fn sort_symbols(
+ snapshot: &Snapshot,
+ options: &Options,
+ current_dir: &Path,
+ symbols: &mut Vec<SymbolInformation>,
+) {
+ let ordering = ProjectOrdering::analyze(snapshot, options, current_dir);
symbols.sort_by(|left, right| {
let left_key = (
ordering.get(&Uri::from(left.location.uri.clone())),