From 240fd5fe8af67337e240c10434af4834fc86278f Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 6 Nov 2023 03:03:43 +0000 Subject: CTAN sync 202311060303 --- support/texlab/CHANGELOG.md | 12 +++ support/texlab/Cargo.lock | 14 ++- support/texlab/crates/base-db/src/config.rs | 17 ++++ support/texlab/crates/inlay-hints/Cargo.toml | 19 ++++ support/texlab/crates/inlay-hints/src/label.rs | 59 +++++++++++++ support/texlab/crates/inlay-hints/src/lib.rs | 36 ++++++++ support/texlab/crates/parser/src/bibtex.rs | 4 +- ...parser__bibtex__tests__parse@issue_945.txt.snap | 27 ++++++ .../parser/src/test_data/bibtex/issue_945.txt | 1 + support/texlab/crates/texlab/Cargo.toml | 3 +- .../crates/texlab/src/features/inlay_hint.rs | 97 ++++++++++++--------- support/texlab/crates/texlab/src/server.rs | 23 ++--- support/texlab/crates/texlab/src/server/options.rs | 12 +++ support/texlab/texlab.1 | 4 +- support/texlab/texlab.pdf | Bin 26352 -> 26718 bytes 15 files changed, 273 insertions(+), 55 deletions(-) create mode 100644 support/texlab/crates/inlay-hints/Cargo.toml create mode 100644 support/texlab/crates/inlay-hints/src/label.rs create mode 100644 support/texlab/crates/inlay-hints/src/lib.rs create mode 100644 support/texlab/crates/parser/src/snapshots/parser__bibtex__tests__parse@issue_945.txt.snap create mode 100644 support/texlab/crates/parser/src/test_data/bibtex/issue_945.txt (limited to 'support/texlab') diff --git a/support/texlab/CHANGELOG.md b/support/texlab/CHANGELOG.md index 752480b13e..f36aed1950 100644 --- a/support/texlab/CHANGELOG.md +++ b/support/texlab/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [5.11.0] - 2023-11-05 + +### Added + +- Add `texlab.inlayHints.labelDefinitions` and `texlab.inlayHints.labelReferences` options ([#753](https://github.com/latex-lsp/texlab/issues/753)) +- Display inlay hints for label references by default ([#753](https://github.com/latex-lsp/texlab/issues/753)) + +### Fixed + +- Moving the build logs to the recycle bin will now clear the diagnostics ([texlab-vscode/#825](https://github.com/latex-lsp/texlab-vscode/issues/825)) +- Fix false positive when reporting syntax errors for BibTeX accents ([#945](https://github.com/latex-lsp/texlab/issues/945)) + ## [5.10.1] - 2023-10-10 ### Fixed diff --git a/support/texlab/Cargo.lock b/support/texlab/Cargo.lock index 83f8a78e08..1b4136224c 100644 --- a/support/texlab/Cargo.lock +++ b/support/texlab/Cargo.lock @@ -800,6 +800,17 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "inlay-hints" +version = "0.0.0" +dependencies = [ + "base-db", + "rowan", + "rustc-hash", + "syntax", + "test-utils", +] + [[package]] name = "inotify" version = "0.9.6" @@ -1630,7 +1641,7 @@ dependencies = [ [[package]] name = "texlab" -version = "5.10.1" +version = "5.11.0" dependencies = [ "anyhow", "assert_unordered", @@ -1651,6 +1662,7 @@ dependencies = [ "folding", "fuzzy-matcher", "hover", + "inlay-hints", "insta", "itertools 0.11.0", "log", diff --git a/support/texlab/crates/base-db/src/config.rs b/support/texlab/crates/base-db/src/config.rs index 65728e08c2..7c4187f7d2 100644 --- a/support/texlab/crates/base-db/src/config.rs +++ b/support/texlab/crates/base-db/src/config.rs @@ -14,6 +14,7 @@ pub struct Config { pub symbols: SymbolConfig, pub syntax: SyntaxConfig, pub completion: CompletionConfig, + pub inlay_hints: InlayHintConfig, } #[derive(Debug)] @@ -77,6 +78,12 @@ pub struct SymbolConfig { pub ignored_patterns: Vec, } +#[derive(Debug)] +pub struct InlayHintConfig { + pub label_definitions: bool, + pub label_references: bool, +} + #[derive(Debug)] pub struct CompletionConfig { pub matcher: MatchingAlgo, @@ -101,6 +108,7 @@ impl Default for Config { symbols: SymbolConfig::default(), syntax: SyntaxConfig::default(), completion: CompletionConfig::default(), + inlay_hints: InlayHintConfig::default(), } } } @@ -174,6 +182,15 @@ impl Default for SymbolConfig { } } +impl Default for InlayHintConfig { + fn default() -> Self { + Self { + label_definitions: true, + label_references: true, + } + } +} + impl Default for CompletionConfig { fn default() -> Self { Self { diff --git a/support/texlab/crates/inlay-hints/Cargo.toml b/support/texlab/crates/inlay-hints/Cargo.toml new file mode 100644 index 0000000000..82b1c729b9 --- /dev/null +++ b/support/texlab/crates/inlay-hints/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "inlay-hints" +version = "0.0.0" +license.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true + +[dependencies] +base-db = { path = "../base-db" } +rowan = "0.15.11" +rustc-hash = "1.1.0" +syntax = { path = "../syntax" } + +[dev-dependencies] +test-utils = { path = "../test-utils" } + +[lib] +doctest = false diff --git a/support/texlab/crates/inlay-hints/src/label.rs b/support/texlab/crates/inlay-hints/src/label.rs new file mode 100644 index 0000000000..8db852752e --- /dev/null +++ b/support/texlab/crates/inlay-hints/src/label.rs @@ -0,0 +1,59 @@ +use base_db::{ + semantics::tex::{Label, LabelKind}, + util::{queries::Object, render_label}, + FeatureParams, +}; +use rustc_hash::FxHashMap; + +use crate::{InlayHint, InlayHintBuilder, InlayHintData}; + +pub(super) fn find_hints(builder: &mut InlayHintBuilder) -> Option<()> { + let definitions = base_db::semantics::tex::Label::find_all(&builder.params.feature.project) + .into_iter() + .filter(|(_, label)| label.kind == LabelKind::Definition) + .map(|(_, label)| (label.name_text(), label)) + .collect::>(); + + let params = &builder.params.feature; + let data = params.document.data.as_tex()?; + let range = builder.params.range; + for label in data + .semantics + .labels + .iter() + .filter(|label| label.name.range.intersect(range).is_some()) + { + if let Some(hint) = process_label(params, &definitions, label) { + builder.hints.push(hint); + } + } + + Some(()) +} + +fn process_label<'a>( + params: &FeatureParams<'a>, + definitions: &FxHashMap<&str, &'a Label>, + label: &'a Label, +) -> Option> { + let config = ¶ms.workspace.config().inlay_hints; + let offset = label.full_range.end(); + let data = if label.kind == LabelKind::Definition { + if !config.label_definitions { + return None; + } + + let label = render_label(params.workspace, ¶ms.project, label)?; + InlayHintData::LabelDefinition(label) + } else { + if !config.label_references { + return None; + } + + let label = definitions.get(label.name.text.as_str())?; + let label = render_label(params.workspace, ¶ms.project, label)?; + InlayHintData::LabelReference(label) + }; + + Some(InlayHint { offset, data }) +} diff --git a/support/texlab/crates/inlay-hints/src/lib.rs b/support/texlab/crates/inlay-hints/src/lib.rs new file mode 100644 index 0000000000..48373d305b --- /dev/null +++ b/support/texlab/crates/inlay-hints/src/lib.rs @@ -0,0 +1,36 @@ +mod label; + +use base_db::{util::RenderedLabel, FeatureParams}; +use rowan::{TextRange, TextSize}; + +pub struct InlayHintParams<'a> { + pub range: TextRange, + pub feature: FeatureParams<'a>, +} + +#[derive(Debug, PartialEq, Eq)] +pub struct InlayHint<'a> { + pub offset: TextSize, + pub data: InlayHintData<'a>, +} + +#[derive(Debug, PartialEq, Eq)] +pub enum InlayHintData<'a> { + LabelDefinition(RenderedLabel<'a>), + LabelReference(RenderedLabel<'a>), +} + +pub fn find_all<'a>(params: InlayHintParams<'a>) -> Option> { + let mut builder = InlayHintBuilder { + params, + hints: Vec::new(), + }; + + label::find_hints(&mut builder); + Some(builder.hints) +} + +struct InlayHintBuilder<'a> { + params: InlayHintParams<'a>, + hints: Vec>, +} diff --git a/support/texlab/crates/parser/src/bibtex.rs b/support/texlab/crates/parser/src/bibtex.rs index 193203016e..d74254b2c5 100644 --- a/support/texlab/crates/parser/src/bibtex.rs +++ b/support/texlab/crates/parser/src/bibtex.rs @@ -181,7 +181,9 @@ fn accent(mut ptr: TokenPtr) -> TokenPtr { ptr.expect(ContentToken::Whitespace); } - ptr.expect(ContentToken::Word); + if ptr.at(ContentToken::Word) || ptr.at(ContentToken::CommandName) { + ptr.bump(); + } if group { ptr.expect(ContentToken::Whitespace); diff --git a/support/texlab/crates/parser/src/snapshots/parser__bibtex__tests__parse@issue_945.txt.snap b/support/texlab/crates/parser/src/snapshots/parser__bibtex__tests__parse@issue_945.txt.snap new file mode 100644 index 0000000000..11a2955b1c --- /dev/null +++ b/support/texlab/crates/parser/src/snapshots/parser__bibtex__tests__parse@issue_945.txt.snap @@ -0,0 +1,27 @@ +--- +source: crates/parser/src/bibtex.rs +expression: root +input_file: crates/parser/src/test_data/bibtex/issue_945.txt +--- +ROOT@0..33 + ENTRY@0..33 + TYPE@0..8 "@article" + L_DELIM@8..9 "{" + NAME@9..13 "test" + COMMA@13..14 "," + WHITESPACE@14..15 " " + FIELD@15..32 + NAME@15..21 "author" + WHITESPACE@21..22 " " + EQ@22..23 "=" + WHITESPACE@23..24 " " + CURLY_GROUP@24..32 + L_CURLY@24..25 "{" + ACCENT@25..31 + ACCENT_NAME@25..27 "\\\"" + L_CURLY@27..28 "{" + COMMAND_NAME@28..30 "\\i" + R_CURLY@30..31 "}" + R_CURLY@31..32 "}" + R_DELIM@32..33 "}" + diff --git a/support/texlab/crates/parser/src/test_data/bibtex/issue_945.txt b/support/texlab/crates/parser/src/test_data/bibtex/issue_945.txt new file mode 100644 index 0000000000..e50835d51f --- /dev/null +++ b/support/texlab/crates/parser/src/test_data/bibtex/issue_945.txt @@ -0,0 +1 @@ +@article{test, author = {\"{\i}}} \ No newline at end of file diff --git a/support/texlab/crates/texlab/Cargo.toml b/support/texlab/crates/texlab/Cargo.toml index e2ca8b443f..9b120d7884 100644 --- a/support/texlab/crates/texlab/Cargo.toml +++ b/support/texlab/crates/texlab/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "texlab" description = "LaTeX Language Server" -version = "5.10.1" +version = "5.11.0" license.workspace = true readme = "README.md" authors.workspace = true @@ -39,6 +39,7 @@ fern = "0.6.2" folding = { path = "../folding" } fuzzy-matcher = { version = "0.3.7", features = ["compact"] } hover = { path = "../hover" } +inlay-hints = { path = "../inlay-hints" } itertools = "0.11.0" log = "0.4.19" lsp-server = "0.7.4" diff --git a/support/texlab/crates/texlab/src/features/inlay_hint.rs b/support/texlab/crates/texlab/src/features/inlay_hint.rs index 14a53ae21d..cb4056f922 100644 --- a/support/texlab/crates/texlab/src/features/inlay_hint.rs +++ b/support/texlab/crates/texlab/src/features/inlay_hint.rs @@ -1,48 +1,67 @@ -mod label; - -use base_db::{Document, Project, Workspace}; -use lsp_types::{InlayHint, InlayHintLabel, Range, Url}; -use rowan::{TextRange, TextSize}; +use base_db::{util::RenderedObject, FeatureParams, Workspace}; +use inlay_hints::{InlayHintData, InlayHintParams}; use crate::util::line_index_ext::LineIndexExt; -pub fn find_all(workspace: &Workspace, uri: &Url, range: Range) -> Option> { +pub fn find_all( + workspace: &Workspace, + uri: &lsp_types::Url, + range: lsp_types::Range, +) -> Option> { let document = workspace.lookup(uri)?; - let range = document.line_index.offset_lsp_range(range); - let project = workspace.project(document); + let line_index = &document.line_index; + let range = line_index.offset_lsp_range(range); - let mut builder = InlayHintBuilder { - workspace, - document, - project, - range, - hints: Vec::new(), - }; + let feature = FeatureParams::new(workspace, document); + let params = InlayHintParams { range, feature }; + let hints = inlay_hints::find_all(params)?; + let hints = hints.into_iter().filter_map(|hint| { + let position = line_index.line_col_lsp(hint.offset); + Some(match hint.data { + InlayHintData::LabelDefinition(label) => { + let number = label.number?; - label::find_hints(&mut builder); - Some(builder.hints) -} + let text = match &label.object { + RenderedObject::Section { prefix, .. } => { + format!("{} {}", prefix, number) + } + RenderedObject::Float { kind, .. } => { + format!("{} {}", kind.as_str(), number) + } + RenderedObject::Theorem { kind, .. } => { + format!("{} {}", kind, number) + } + RenderedObject::Equation => format!("Equation ({})", number), + RenderedObject::EnumItem => format!("Item {}", number), + }; -struct InlayHintBuilder<'a> { - workspace: &'a Workspace, - document: &'a Document, - project: Project<'a>, - range: TextRange, - hints: Vec, -} + lsp_types::InlayHint { + position, + label: lsp_types::InlayHintLabel::String(format!(" {text} ")), + kind: None, + text_edits: None, + tooltip: None, + padding_left: Some(true), + padding_right: None, + data: None, + } + } + InlayHintData::LabelReference(label) => { + let text = label.reference(); + + lsp_types::InlayHint { + position, + label: lsp_types::InlayHintLabel::String(format!(" {text} ")), + kind: None, + text_edits: None, + tooltip: None, + padding_left: Some(true), + padding_right: None, + data: None, + } + } + }) + }); -impl<'db> InlayHintBuilder<'db> { - pub fn push(&mut self, offset: TextSize, text: String) { - let position = self.document.line_index.line_col_lsp(offset); - self.hints.push(InlayHint { - position, - label: InlayHintLabel::String(format!(" {text} ")), - kind: None, - text_edits: None, - tooltip: None, - padding_left: Some(true), - padding_right: None, - data: None, - }); - } + Some(hints.collect()) } diff --git a/support/texlab/crates/texlab/src/server.rs b/support/texlab/crates/texlab/src/server.rs index 5a0c48960e..7757bbb460 100644 --- a/support/texlab/crates/texlab/src/server.rs +++ b/support/texlab/crates/texlab/src/server.rs @@ -18,6 +18,7 @@ use diagnostics::{DiagnosticManager, DiagnosticSource}; use distro::{Distro, Language}; use lsp_server::{Connection, ErrorCode, Message, RequestId}; use lsp_types::{notification::*, request::*, *}; +use notify::event::ModifyKind; use notify_debouncer_full::{DebouncedEvent, Debouncer, FileIdMap}; use parking_lot::{Mutex, RwLock}; use rowan::ast::AstNode; @@ -878,6 +879,17 @@ impl Server { let mut workspace = self.workspace.write(); match event.kind { + notify::EventKind::Remove(_) | notify::EventKind::Modify(ModifyKind::Name(_)) => { + for path in event.paths { + if let Some(document) = workspace.lookup_path(&path) { + if document.owner == Owner::Server { + let uri = document.uri.clone(); + workspace.remove(&uri); + changed = true; + } + } + } + } notify::EventKind::Create(_) | notify::EventKind::Modify(_) => { for path in event.paths { if workspace @@ -894,17 +906,6 @@ impl Server { } } } - notify::EventKind::Remove(_) => { - for path in event.paths { - if let Some(document) = workspace.lookup_path(&path) { - if document.owner == Owner::Server { - let uri = document.uri.clone(); - workspace.remove(&uri); - changed = true; - } - } - } - } notify::EventKind::Any | notify::EventKind::Access(_) | notify::EventKind::Other => {} }; diff --git a/support/texlab/crates/texlab/src/server/options.rs b/support/texlab/crates/texlab/src/server/options.rs index 3a2bf1bb10..3828745257 100644 --- a/support/texlab/crates/texlab/src/server/options.rs +++ b/support/texlab/crates/texlab/src/server/options.rs @@ -22,6 +22,7 @@ pub struct Options { pub latexindent: LatexindentOptions, pub forward_search: ForwardSearchOptions, pub completion: CompletionOptions, + pub inlay_hints: InlayHintOptions, pub experimental: ExperimentalOptions, } @@ -100,6 +101,14 @@ pub struct DiagnosticsOptions { pub ignored_patterns: Vec, } +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +#[serde(default)] +pub struct InlayHintOptions { + pub label_definitions: Option, + pub label_references: Option, +} + #[derive(Debug, Clone, Default, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[serde(default)] @@ -243,6 +252,9 @@ impl From for Config { .map(|pattern| pattern.0) .collect(); + config.inlay_hints.label_definitions = value.inlay_hints.label_definitions.unwrap_or(true); + config.inlay_hints.label_references = value.inlay_hints.label_references.unwrap_or(true); + config.completion.matcher = match value.completion.matcher { CompletionMatcher::Fuzzy => base_db::MatchingAlgo::Skim, CompletionMatcher::FuzzyIgnoreCase => base_db::MatchingAlgo::SkimIgnoreCase, diff --git a/support/texlab/texlab.1 b/support/texlab/texlab.1 index 3dd21917a1..23418dce4c 100644 --- a/support/texlab/texlab.1 +++ b/support/texlab/texlab.1 @@ -1,7 +1,7 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. -.TH TEXLAB "1" "October 2023" "texlab 5.10.1" "User Commands" +.TH TEXLAB "1" "November 2023" "texlab 5.11.0" "User Commands" .SH NAME -texlab \- manual page for texlab 5.10.1 +texlab \- manual page for texlab 5.11.0 .SH SYNOPSIS .B texlab [\fI\,OPTIONS\/\fR] diff --git a/support/texlab/texlab.pdf b/support/texlab/texlab.pdf index 5964aac90a..d989a13e2e 100644 Binary files a/support/texlab/texlab.pdf and b/support/texlab/texlab.pdf differ -- cgit v1.2.3