summaryrefslogtreecommitdiff
path: root/support/texlab/src/features/completion
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/features/completion')
-rw-r--r--support/texlab/src/features/completion/acronym_ref.rs16
-rw-r--r--support/texlab/src/features/completion/citation.rs74
-rw-r--r--support/texlab/src/features/completion/color.rs11
-rw-r--r--support/texlab/src/features/completion/color_model.rs31
-rw-r--r--support/texlab/src/features/completion/component_environment.rs20
-rw-r--r--support/texlab/src/features/completion/field.rs2
-rw-r--r--support/texlab/src/features/completion/glossary_ref.rs18
-rw-r--r--support/texlab/src/features/completion/import.rs13
-rw-r--r--support/texlab/src/features/completion/include.rs11
-rw-r--r--support/texlab/src/features/completion/label.rs60
-rw-r--r--support/texlab/src/features/completion/theorem.rs21
-rw-r--r--support/texlab/src/features/completion/tikz_library.rs12
-rw-r--r--support/texlab/src/features/completion/types.rs8
-rw-r--r--support/texlab/src/features/completion/user_environment.rs21
14 files changed, 137 insertions, 181 deletions
diff --git a/support/texlab/src/features/completion/acronym_ref.rs b/support/texlab/src/features/completion/acronym_ref.rs
index 9d8bcc6c5f..db3e34f9eb 100644
--- a/support/texlab/src/features/completion/acronym_ref.rs
+++ b/support/texlab/src/features/completion/acronym_ref.rs
@@ -1,5 +1,4 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
use crate::{
@@ -16,18 +15,9 @@ pub fn complete_acronyms<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let group = latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
-
+ let (_, range, group) = context.find_curly_group_word()?;
latex::AcronymReference::cast(group.syntax().parent()?)?;
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
-
for document in &context.request.subset.documents {
if let Some(data) = document.data.as_latex() {
for name in data
@@ -35,8 +25,8 @@ pub fn complete_acronyms<'a>(
.descendants()
.filter_map(latex::AcronymDefinition::cast)
.filter_map(|node| node.name())
- .filter_map(|name| name.word())
- .map(|name| name.text())
+ .filter_map(|name| name.key())
+ .map(|name| name.to_string())
{
items.push(InternalCompletionItem::new(
range,
diff --git a/support/texlab/src/features/completion/citation.rs b/support/texlab/src/features/completion/citation.rs
index 6df3364099..0a7cc26b10 100644
--- a/support/texlab/src/features/completion/citation.rs
+++ b/support/texlab/src/features/completion/citation.rs
@@ -26,12 +26,14 @@ pub fn complete_citations<'a>(
let token = context.cursor.as_latex()?;
let range = if token.kind() == latex::WORD {
- token.text_range()
+ latex::Key::cast(token.parent())
+ .map(|key| key.small_range())
+ .or_else(|| latex::Text::cast(token.parent()).map(|text| text.small_range()))?
} else {
TextRange::empty(context.offset)
};
- check_citation(context, token).or_else(|| check_acronym(token))?;
+ check_citation(context).or_else(|| check_acronym(context))?;
for document in &context.request.subset.documents {
if let Some(data) = document.data.as_bibtex() {
for entry in data.root.children().filter_map(bibtex::Entry::cast) {
@@ -46,20 +48,17 @@ pub fn complete_citations<'a>(
Some(())
}
-fn check_citation(
- context: &CursorContext<CompletionParams>,
- token: &latex::SyntaxToken,
-) -> Option<()> {
- let group = latex::CurlyGroupWordList::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
+fn check_citation(context: &CursorContext<CompletionParams>) -> Option<()> {
+ let (_, _, group) = context.find_curly_group_word_list()?;
latex::Citation::cast(group.syntax().parent()?)?;
Some(())
}
-fn check_acronym(token: &latex::SyntaxToken) -> Option<()> {
+fn check_acronym(context: &CursorContext<CompletionParams>) -> Option<()> {
+ let token = context.cursor.as_latex()?;
+
let pair = token.ancestors().find_map(latex::KeyValuePair::cast)?;
- let mut key_words = pair.key()?.words();
- if key_words.next()?.text() != "cite" || key_words.next().is_some() {
+ if pair.key()?.to_string() != "cite" {
return None;
}
@@ -72,7 +71,7 @@ fn make_item<'a>(
entry: bibtex::Entry<'a>,
range: TextRange,
) -> Option<InternalCompletionItem<'a>> {
- let key = entry.key()?.text();
+ let key = entry.key()?.to_string();
let ty = LANGUAGE_DATA
.find_entry_type(&entry.ty()?.text()[1..])
.map(|ty| Structure::Entry(ty.category))
@@ -98,7 +97,7 @@ fn make_item<'a>(
range,
InternalCompletionItemData::Citation {
uri: Arc::clone(&document.uri),
- key: key.into(),
+ key,
text,
ty,
},
@@ -171,6 +170,29 @@ mod tests {
}
#[test]
+ fn test_latex_two_words() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ ("main.tex", "\\addbibresource{main.bib}\n\\cite{foo}"),
+ ("main.bib", "@article{foo bar,}"),
+ ])
+ .main("main.tex")
+ .line(1)
+ .character(6)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(32.into(), 35.into()));
+ }
+ }
+
+ #[test]
fn test_latex_open_brace() {
let request = FeatureTester::builder()
.files(vec![
@@ -241,4 +263,30 @@ mod tests {
assert_eq!(item.range, TextRange::new(54.into(), 54.into()));
}
}
+
+ #[test]
+ fn test_latex_acronym_two_words() {
+ let request = FeatureTester::builder()
+ .files(vec![
+ (
+ "main.tex",
+ "\\addbibresource{main.bib}\n\\DeclareAcronym{foo}{cite={\na b}}",
+ ),
+ ("main.bib", "@article{foo,}"),
+ ])
+ .main("main.tex")
+ .line(2)
+ .character(0)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_citations(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(54.into(), 57.into()));
+ }
+ }
}
diff --git a/support/texlab/src/features/completion/color.rs b/support/texlab/src/features/completion/color.rs
index 0e94af15fe..15a7c341f5 100644
--- a/support/texlab/src/features/completion/color.rs
+++ b/support/texlab/src/features/completion/color.rs
@@ -1,5 +1,4 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
use crate::{
@@ -17,15 +16,7 @@ pub fn complete_colors<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
-
- let group = latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
+ let (_, range, group) = context.find_curly_group_word()?;
latex::ColorReference::cast(group.syntax().parent()?)?;
for name in &LANGUAGE_DATA.colors {
diff --git a/support/texlab/src/features/completion/color_model.rs b/support/texlab/src/features/completion/color_model.rs
index f7f09b6367..a24953caa5 100644
--- a/support/texlab/src/features/completion/color_model.rs
+++ b/support/texlab/src/features/completion/color_model.rs
@@ -18,15 +18,7 @@ pub fn complete_color_models<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
-
- check_color_definition(context, token)
- .or_else(|| check_color_definition_set(context, token))?;
+ let range = check_color_definition(context).or_else(|| check_color_definition_set(context))?;
for name in MODEL_NAMES {
items.push(InternalCompletionItem::new(
@@ -38,30 +30,23 @@ pub fn complete_color_models<'a>(
Some(())
}
-fn check_color_definition(
- context: &CursorContext<CompletionParams>,
- token: &latex::SyntaxToken,
-) -> Option<()> {
- let group = latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
+fn check_color_definition(context: &CursorContext<CompletionParams>) -> Option<TextRange> {
+ let (_, range, group) = context.find_curly_group_word()?;
+
let definition = latex::ColorDefinition::cast(group.syntax().parent()?)?;
definition
.model()
.filter(|model| model.syntax().text_range() == group.syntax().text_range())?;
- Some(())
+ Some(range)
}
-fn check_color_definition_set(
- context: &CursorContext<CompletionParams>,
- token: &latex::SyntaxToken,
-) -> Option<()> {
- let group = latex::CurlyGroupWordList::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
+fn check_color_definition_set(context: &CursorContext<CompletionParams>) -> Option<TextRange> {
+ let (_, range, group) = context.find_curly_group_word_list()?;
let definition = latex::ColorSetDefinition::cast(group.syntax().parent()?)?;
definition
.model_list()
.filter(|model| model.syntax().text_range() == group.syntax().text_range())?;
- Some(())
+ Some(range)
}
#[cfg(test)]
diff --git a/support/texlab/src/features/completion/component_environment.rs b/support/texlab/src/features/completion/component_environment.rs
index fca9d03780..d4340a160a 100644
--- a/support/texlab/src/features/completion/component_environment.rs
+++ b/support/texlab/src/features/completion/component_environment.rs
@@ -1,12 +1,7 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
-use crate::{
- component_db::COMPONENT_DATABASE,
- features::cursor::CursorContext,
- syntax::{latex, CstNode},
-};
+use crate::{component_db::COMPONENT_DATABASE, features::cursor::CursorContext};
use super::types::{InternalCompletionItem, InternalCompletionItemData};
@@ -17,18 +12,7 @@ pub fn complete_component_environments<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let group = latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
- if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) {
- return None;
- }
-
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
+ let (_, range) = context.find_environment_name()?;
for component in COMPONENT_DATABASE.linked_components(&context.request.subset) {
cancellation_token.result().ok()?;
diff --git a/support/texlab/src/features/completion/field.rs b/support/texlab/src/features/completion/field.rs
index d7297b481b..ad1042b04d 100644
--- a/support/texlab/src/features/completion/field.rs
+++ b/support/texlab/src/features/completion/field.rs
@@ -26,7 +26,7 @@ pub fn complete_fields<'a>(
let parent = token.parent();
if let Some(entry) = bibtex::Entry::cast(parent) {
- if entry.key()?.text_range() == token.text_range() {
+ if entry.key()?.small_range() == token.text_range() {
return None;
}
} else {
diff --git a/support/texlab/src/features/completion/glossary_ref.rs b/support/texlab/src/features/completion/glossary_ref.rs
index 4529129fd7..66d20e46ff 100644
--- a/support/texlab/src/features/completion/glossary_ref.rs
+++ b/support/texlab/src/features/completion/glossary_ref.rs
@@ -1,5 +1,4 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
use crate::{
@@ -16,15 +15,8 @@ pub fn complete_glossary_entries<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let group = latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
+ let (_, range, group) = context.find_curly_group_word()?;
latex::GlossaryEntryReference::cast(group.syntax().parent()?)?;
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
for document in &context.request.subset.documents {
if let Some(data) = document.data.as_latex() {
@@ -33,8 +25,8 @@ pub fn complete_glossary_entries<'a>(
if let Some(name) = latex::GlossaryEntryDefinition::cast(node)
.and_then(|entry| entry.name())
- .and_then(|name| name.word())
- .map(|name| name.text())
+ .and_then(|name| name.key())
+ .map(|name| name.to_string())
{
items.push(InternalCompletionItem::new(
range,
@@ -42,8 +34,8 @@ pub fn complete_glossary_entries<'a>(
));
} else if let Some(name) = latex::AcronymDefinition::cast(node)
.and_then(|entry| entry.name())
- .and_then(|name| name.word())
- .map(|name| name.text())
+ .and_then(|name| name.key())
+ .map(|name| name.to_string())
{
items.push(InternalCompletionItem::new(
range,
diff --git a/support/texlab/src/features/completion/import.rs b/support/texlab/src/features/completion/import.rs
index ac5f2e6e40..da4c12c02b 100644
--- a/support/texlab/src/features/completion/import.rs
+++ b/support/texlab/src/features/completion/import.rs
@@ -1,5 +1,4 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
use rustc_hash::FxHashSet;
use smol_str::SmolStr;
@@ -17,15 +16,7 @@ pub fn complete_imports<'a>(
items: &mut Vec<InternalCompletionItem<'a>>,
cancellation_token: &CancellationToken,
) -> Option<()> {
- let token = context.cursor.as_latex()?;
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
-
- let group = latex::CurlyGroupWordList::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
+ let (_, range, group) = context.find_curly_group_word_list()?;
let (extension, mut factory): (
&str,
@@ -76,6 +67,8 @@ pub fn complete_imports<'a>(
#[cfg(test)]
mod tests {
+ use cstree::TextRange;
+
use crate::features::testing::FeatureTester;
use super::*;
diff --git a/support/texlab/src/features/completion/include.rs b/support/texlab/src/features/completion/include.rs
index c711ea5ce7..4a8e561866 100644
--- a/support/texlab/src/features/completion/include.rs
+++ b/support/texlab/src/features/completion/include.rs
@@ -25,15 +25,8 @@ pub fn complete_includes<'a>(
return None;
}
- let token = context.cursor.as_latex()?;
- let (path_text, path_range) = if token.kind() == latex::WORD {
- (token.text(), token.text_range())
- } else {
- ("", TextRange::empty(context.offset))
- };
+ let (path_text, path_range, group) = context.find_curly_group_word_list()?;
- let group = latex::CurlyGroupWordList::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
let include = group.syntax().parent()?;
let (include_extension, extensions): (bool, &[&str]) = match include.kind() {
latex::PACKAGE_INCLUDE => (false, &["sty"]),
@@ -62,7 +55,7 @@ pub fn complete_includes<'a>(
TextRange::new(start, path_range.end())
};
- let current_dir = current_dir(context, path_text)?;
+ let current_dir = current_dir(context, &path_text)?;
for entry in fs::read_dir(current_dir).ok()?.filter_map(Result::ok) {
let mut path = entry.path();
diff --git a/support/texlab/src/features/completion/label.rs b/support/texlab/src/features/completion/label.rs
index 2f7e2d8f77..3efb168d0d 100644
--- a/support/texlab/src/features/completion/label.rs
+++ b/support/texlab/src/features/completion/label.rs
@@ -18,26 +18,7 @@ pub fn complete_labels<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let is_math = latex::CurlyGroupWordList::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))
- .and_then(|group| group.syntax().parent())
- .and_then(|reference| latex::LabelReference::cast(reference))
- .and_then(|refernce| refernce.command())
- .map(|reference| reference.text() == "\\eqref")
- .or_else(|| {
- latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))
- .and_then(|group| group.syntax().parent())
- .and_then(|reference| latex::LabelReferenceRange::cast(reference))
- .map(|_| false)
- })?;
-
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
+ let (range, is_math) = find_reference(context).or_else(|| find_reference_range(context))?;
for document in &context.request.subset.documents {
if let Some(data) = document.data.as_latex() {
@@ -49,10 +30,10 @@ pub fn complete_labels<'a>(
{
if let Some(name) = label
.name()
- .and_then(|name| name.word())
- .map(|name| name.text())
+ .and_then(|name| name.key())
+ .map(|name| name.to_string())
{
- match render_label(&context.request.subset, name, Some(label)) {
+ match render_label(&context.request.subset, &name, Some(label)) {
Some(rendered_label) => {
let kind = match &rendered_label.object {
LabelledObject::Section { .. } => Structure::Section,
@@ -112,6 +93,19 @@ pub fn complete_labels<'a>(
Some(())
}
+fn find_reference(context: &CursorContext<CompletionParams>) -> Option<(TextRange, bool)> {
+ let (_, range, group) = context.find_curly_group_word_list()?;
+ let reference = latex::LabelReference::cast(group.syntax().parent()?)?;
+ let is_math = reference.command()?.text() == "\\eqref";
+ Some((range, is_math))
+}
+
+fn find_reference_range(context: &CursorContext<CompletionParams>) -> Option<(TextRange, bool)> {
+ let (_, range, group) = context.find_curly_group_word()?;
+ latex::LabelReferenceRange::cast(group.syntax().parent()?)?;
+ Some((range, false))
+}
+
#[cfg(test)]
mod tests {
use cstree::TextRange;
@@ -193,4 +187,24 @@ mod tests {
assert_eq!(item.range, TextRange::new(11.into(), 11.into()));
}
}
+
+ #[test]
+ fn test_multi_word() {
+ let request = FeatureTester::builder()
+ .files(vec![("main.tex", "\\ref{foo}\\label{foo bar}")])
+ .main("main.tex")
+ .line(0)
+ .character(8)
+ .build()
+ .completion();
+
+ let context = CursorContext::new(request);
+ let mut actual_items = Vec::new();
+ complete_labels(&context, &mut actual_items, CancellationToken::none());
+
+ assert!(!actual_items.is_empty());
+ for item in actual_items {
+ assert_eq!(item.range, TextRange::new(5.into(), 8.into()));
+ }
+ }
}
diff --git a/support/texlab/src/features/completion/theorem.rs b/support/texlab/src/features/completion/theorem.rs
index 54db031a4b..25eea87ab7 100644
--- a/support/texlab/src/features/completion/theorem.rs
+++ b/support/texlab/src/features/completion/theorem.rs
@@ -1,11 +1,7 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
-use crate::{
- features::cursor::CursorContext,
- syntax::{latex, CstNode},
-};
+use crate::features::cursor::CursorContext;
use super::types::{InternalCompletionItem, InternalCompletionItemData};
@@ -18,18 +14,7 @@ pub fn complete_theorem_environments<'a>(
return None;
}
- let token = context.cursor.as_latex()?;
- let group = latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
- if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) {
- return None;
- }
-
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
+ let (_, range) = context.find_environment_name()?;
for document in &context.request.subset.documents {
if let Some(data) = document.data.as_latex() {
@@ -49,6 +34,8 @@ pub fn complete_theorem_environments<'a>(
#[cfg(test)]
mod tests {
+ use cstree::TextRange;
+
use crate::features::testing::FeatureTester;
use super::*;
diff --git a/support/texlab/src/features/completion/tikz_library.rs b/support/texlab/src/features/completion/tikz_library.rs
index da2a26cc9b..b9c5e3ec7a 100644
--- a/support/texlab/src/features/completion/tikz_library.rs
+++ b/support/texlab/src/features/completion/tikz_library.rs
@@ -1,5 +1,4 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
use crate::{
@@ -17,15 +16,8 @@ pub fn complete_tikz_libraries<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
+ let (_, range, group) = context.find_curly_group_word_list()?;
- let group = latex::CurlyGroupWordList::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
let import = latex::TikzLibraryImport::cast(group.syntax().parent()?)?;
if import.command()?.text() == "\\usepgflibrary" {
@@ -49,6 +41,8 @@ pub fn complete_tikz_libraries<'a>(
#[cfg(test)]
mod tests {
+ use cstree::TextRange;
+
use crate::features::testing::FeatureTester;
use super::*;
diff --git a/support/texlab/src/features/completion/types.rs b/support/texlab/src/features/completion/types.rs
index b58a155fc4..b7e5c09592 100644
--- a/support/texlab/src/features/completion/types.rs
+++ b/support/texlab/src/features/completion/types.rs
@@ -40,7 +40,7 @@ pub enum InternalCompletionItemData<'a> {
BeginCommand,
Citation {
uri: Arc<Uri>,
- key: &'a str,
+ key: String,
text: String,
ty: Structure,
},
@@ -67,10 +67,10 @@ pub enum InternalCompletionItemData<'a> {
name: &'a str,
},
Acronym {
- name: &'a str,
+ name: String,
},
GlossaryEntry {
- name: &'a str,
+ name: String,
},
File {
name: SmolStr,
@@ -79,7 +79,7 @@ pub enum InternalCompletionItemData<'a> {
name: SmolStr,
},
Label {
- name: &'a str,
+ name: String,
kind: Structure,
header: Option<String>,
footer: Option<String>,
diff --git a/support/texlab/src/features/completion/user_environment.rs b/support/texlab/src/features/completion/user_environment.rs
index a1a5701fac..5529143adc 100644
--- a/support/texlab/src/features/completion/user_environment.rs
+++ b/support/texlab/src/features/completion/user_environment.rs
@@ -1,11 +1,7 @@
use cancellation::CancellationToken;
-use cstree::TextRange;
use lsp_types::CompletionParams;
-use crate::{
- features::cursor::CursorContext,
- syntax::{latex, CstNode},
-};
+use crate::features::cursor::CursorContext;
use super::types::{InternalCompletionItem, InternalCompletionItemData};
@@ -16,18 +12,7 @@ pub fn complete_user_environments<'a>(
) -> Option<()> {
cancellation_token.result().ok()?;
- let token = context.cursor.as_latex()?;
- let group = latex::CurlyGroupWord::cast(token.parent())
- .filter(|group| context.is_inside_latex_curly(group))?;
- if !matches!(group.syntax().parent()?.kind(), latex::BEGIN | latex::END) {
- return None;
- }
-
- let range = if token.kind() == latex::WORD {
- token.text_range()
- } else {
- TextRange::empty(context.offset)
- };
+ let (name, range) = context.find_environment_name()?;
for document in &context.request.subset.documents {
if let Some(data) = document.data.as_latex() {
@@ -35,7 +20,7 @@ pub fn complete_user_environments<'a>(
.extras
.environment_names
.iter()
- .filter(|name| name.as_str() != token.text())
+ .filter(|n| n.as_str() != name)
{
cancellation_token.result().ok()?;
items.push(InternalCompletionItem::new(