use crate::server::{
lsp::{
CompletionItemBuilder, CompletionItemKind, CompletionList, InsertTextFormat, ItemDefaults,
},
message_handler::completion::CompletionError,
};
pub(crate) async fn completions() -> Result<CompletionList, CompletionError> {
Ok(CompletionList {
is_incomplete: false,
item_defaults: Some(ItemDefaults {
edit_range: None,
commit_characters: None,
data: None,
insert_text_format: Some(InsertTextFormat::Snippet),
insert_text_mode: None,
}),
items: vec![
CompletionItemBuilder::new()
.label("STR")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the string form of a literal or IRI. For a literal, returns the lexical form. For an IRI, returns the codepoint representation.")
.insert_text("STR(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("LANG")
.label_details(" (literal)")
.kind(CompletionItemKind::Function)
.documentation("Returns the language tag of a literal. Returns \"\" if the literal has no language tag.")
.insert_text("LANG(${0:literal})")
.build(),
CompletionItemBuilder::new()
.label("LANGDIR")
.label_details(" (literal)")
.kind(CompletionItemKind::Function)
.documentation("Returns the base direction of a directional language-tagged string (\"ltr\" or \"rtl\"). Returns \"\" if the literal has no base direction. (SPARQL 1.2)")
.insert_text("LANGDIR(${0:literal})")
.build(),
CompletionItemBuilder::new()
.label("LANGMATCHES")
.label_details(" (langTag, langRange)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the language tag matches the language range according to RFC 4647 ยง3.3.1. Use \"*\" to match any non-empty language tag.")
.insert_text("LANGMATCHES(${1:langTag}, ${0:langRange})")
.build(),
CompletionItemBuilder::new()
.label("DATATYPE")
.label_details(" (literal)")
.kind(CompletionItemKind::Function)
.documentation("Returns the datatype IRI of a literal. For language-tagged strings, returns rdf:langString. For simple literals, returns xsd:string.")
.insert_text("DATATYPE(${0:literal})")
.build(),
CompletionItemBuilder::new()
.label("STRLEN")
.label_details(" (string)")
.kind(CompletionItemKind::Function)
.documentation("Returns the number of characters in the string. The length is measured in Unicode codepoints.")
.insert_text("STRLEN(${0:string})")
.build(),
CompletionItemBuilder::new()
.label("SUBSTR")
.label_details(" (source, startingLoc [, length])")
.kind(CompletionItemKind::Function)
.documentation("Returns a substring of the source string, starting at the given position (1-based). If length is given, at most that many characters are returned.")
.insert_text("SUBSTR(${1:source}, ${0:startingLoc})")
.build(),
CompletionItemBuilder::new()
.label("UCASE")
.label_details(" (string)")
.kind(CompletionItemKind::Function)
.documentation("Returns the string converted to uppercase. The language tag, if any, is preserved.")
.insert_text("UCASE(${0:string})")
.build(),
CompletionItemBuilder::new()
.label("LCASE")
.label_details(" (string)")
.kind(CompletionItemKind::Function)
.documentation("Returns the string converted to lowercase. The language tag, if any, is preserved.")
.insert_text("LCASE(${0:string})")
.build(),
CompletionItemBuilder::new()
.label("STRSTARTS")
.label_details(" (string, prefix)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the string starts with the given prefix. Argument compatibility follows the invocation rules (e.g. matching language tags).")
.insert_text("STRSTARTS(${1:string}, ${0:prefix})")
.build(),
CompletionItemBuilder::new()
.label("STRENDS")
.label_details(" (string, suffix)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the string ends with the given suffix. Argument compatibility follows the invocation rules (e.g. matching language tags).")
.insert_text("STRENDS(${1:string}, ${0:suffix})")
.build(),
CompletionItemBuilder::new()
.label("CONTAINS")
.label_details(" (string, pattern)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the string contains the given pattern as a substring. Argument compatibility follows the invocation rules.")
.insert_text("CONTAINS(${1:string}, ${0:pattern})")
.build(),
CompletionItemBuilder::new()
.label("STRBEFORE")
.label_details(" (string, separator)")
.kind(CompletionItemKind::Function)
.documentation("Returns the part of the string that precedes the first occurrence of the separator. Returns \"\" if the separator is not found or is at the start.")
.insert_text("STRBEFORE(${1:string}, ${0:separator})")
.build(),
CompletionItemBuilder::new()
.label("STRAFTER")
.label_details(" (string, separator)")
.kind(CompletionItemKind::Function)
.documentation("Returns the part of the string that follows the first occurrence of the separator. Returns \"\" if the separator is not found or is at the end.")
.insert_text("STRAFTER(${1:string}, ${0:separator})")
.build(),
CompletionItemBuilder::new()
.label("ENCODE_FOR_URI")
.label_details(" (string)")
.kind(CompletionItemKind::Function)
.documentation("Percent-encodes a string for use in a URI. Encodes all characters except unreserved characters (letters, digits, '-', '.', '_', '~').")
.insert_text("ENCODE_FOR_URI(${0:string})")
.build(),
CompletionItemBuilder::new()
.label("CONCAT")
.label_details(" (expr, ...)")
.kind(CompletionItemKind::Function)
.documentation("Concatenates the lexical forms of its string arguments. If all arguments have the same language tag, the result preserves it.")
.insert_text("CONCAT(${1:expr}, ${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("REGEX")
.label_details(" (text, pattern [, flags])")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the text matches the regular expression pattern. Optional flags include: 's' (dot matches newline), 'm' (multiline), 'i' (case-insensitive), 'x' (extended).")
.insert_text("REGEX(${1:text}, ${0:pattern})")
.build(),
CompletionItemBuilder::new()
.label("REPLACE")
.label_details(" (text, pattern, replacement [, flags])")
.kind(CompletionItemKind::Function)
.documentation("Replaces all occurrences of the regular expression pattern in the text with the replacement string. Supports the same flags as REGEX.")
.insert_text("REPLACE(${1:text}, ${2:pattern}, ${0:replacement})")
.build(),
CompletionItemBuilder::new()
.label("STRLANG")
.label_details(" (lexicalForm, langTag)")
.kind(CompletionItemKind::Function)
.documentation("Constructs a language-tagged literal from the given lexical form and language tag.")
.insert_text("STRLANG(${1:lexicalForm}, ${0:langTag})")
.build(),
CompletionItemBuilder::new()
.label("STRLANGDIR")
.label_details(" (lexicalForm, langTag, direction)")
.kind(CompletionItemKind::Function)
.documentation("Constructs a directional language-tagged literal from the given lexical form, language tag, and base direction (\"ltr\" or \"rtl\"). (SPARQL 1.2)")
.insert_text("STRLANGDIR(${1:lexicalForm}, ${2:langTag}, ${0:direction})")
.build(),
CompletionItemBuilder::new()
.label("STRDT")
.label_details(" (lexicalForm, datatypeIRI)")
.kind(CompletionItemKind::Function)
.documentation("Constructs a typed literal from the given lexical form and datatype IRI.")
.insert_text("STRDT(${1:lexicalForm}, ${0:datatypeIRI})")
.build(),
CompletionItemBuilder::new()
.label("ABS")
.label_details(" (numeric)")
.kind(CompletionItemKind::Function)
.documentation("Returns the absolute value of a numeric expression.")
.insert_text("ABS(${0:numeric})")
.build(),
CompletionItemBuilder::new()
.label("CEIL")
.label_details(" (numeric)")
.kind(CompletionItemKind::Function)
.documentation("Returns the smallest integer value that is greater than or equal to the argument (rounds up).")
.insert_text("CEIL(${0:numeric})")
.build(),
CompletionItemBuilder::new()
.label("FLOOR")
.label_details(" (numeric)")
.kind(CompletionItemKind::Function)
.documentation("Returns the largest integer value that is less than or equal to the argument (rounds down).")
.insert_text("FLOOR(${0:numeric})")
.build(),
CompletionItemBuilder::new()
.label("ROUND")
.label_details(" (numeric)")
.kind(CompletionItemKind::Function)
.documentation("Returns the number rounded to the nearest integer. Values of x.5 are rounded towards positive infinity.")
.insert_text("ROUND(${0:numeric})")
.build(),
CompletionItemBuilder::new()
.label("RAND")
.label_details(" ()")
.kind(CompletionItemKind::Function)
.documentation("Returns a pseudo-random number between 0 (inclusive) and 1 (exclusive). Each call may return a different value.")
.insert_text("RAND()")
.build(),
CompletionItemBuilder::new()
.label("NOW")
.label_details(" ()")
.kind(CompletionItemKind::Function)
.documentation("Returns the current date and time as an xsd:dateTime literal. All calls within a single query return the same value.")
.insert_text("NOW()")
.build(),
CompletionItemBuilder::new()
.label("YEAR")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the year component of an xsd:dateTime or xsd:date value as an integer.")
.insert_text("YEAR(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("MONTH")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the month component of an xsd:dateTime or xsd:date value as an integer (1-12).")
.insert_text("MONTH(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("DAY")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the day component of an xsd:dateTime or xsd:date value as an integer.")
.insert_text("DAY(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("HOURS")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the hours component of an xsd:dateTime or xsd:time value as an integer (0-23).")
.insert_text("HOURS(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("MINUTES")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the minutes component of an xsd:dateTime or xsd:time value as an integer (0-59).")
.insert_text("MINUTES(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("SECONDS")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the seconds component of an xsd:dateTime or xsd:time value as a decimal.")
.insert_text("SECONDS(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("TIMEZONE")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the timezone of an xsd:dateTime value as an xsd:dayTimeDuration. Raises an error if the value has no timezone.")
.insert_text("TIMEZONE(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("TZ")
.label_details(" (datetime)")
.kind(CompletionItemKind::Function)
.documentation("Returns the timezone of an xsd:dateTime value as a string (e.g. \"-05:00\", \"Z\"). Returns \"\" if the value has no timezone.")
.insert_text("TZ(${0:datetime})")
.build(),
CompletionItemBuilder::new()
.label("MD5")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the MD5 hash of the string form of the argument as a hex string.")
.insert_text("MD5(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("SHA1")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the SHA-1 hash of the string form of the argument as a hex string.")
.insert_text("SHA1(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("SHA256")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the SHA-256 hash of the string form of the argument as a hex string.")
.insert_text("SHA256(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("SHA384")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the SHA-384 hash of the string form of the argument as a hex string.")
.insert_text("SHA384(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("SHA512")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the SHA-512 hash of the string form of the argument as a hex string.")
.insert_text("SHA512(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("BOUND")
.label_details(" (var)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the given variable is bound to a value in the current solution mapping. Commonly used in FILTER to test for optional values.")
.insert_text("BOUND(${0:?var})")
.build(),
CompletionItemBuilder::new()
.label("isIRI")
.label_details(" (term)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the term is an IRI.")
.insert_text("isIRI(${0:term})")
.build(),
CompletionItemBuilder::new()
.label("isURI")
.label_details(" (term)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the term is a URI. This is an alternative spelling of isIRI.")
.insert_text("isURI(${0:term})")
.build(),
CompletionItemBuilder::new()
.label("isBLANK")
.label_details(" (term)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the term is a blank node.")
.insert_text("isBLANK(${0:term})")
.build(),
CompletionItemBuilder::new()
.label("isLITERAL")
.label_details(" (term)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the term is a literal (string, number, date, etc.).")
.insert_text("isLITERAL(${0:term})")
.build(),
CompletionItemBuilder::new()
.label("isNUMERIC")
.label_details(" (term)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the term is a numeric literal (integer, decimal, or double).")
.insert_text("isNUMERIC(${0:term})")
.build(),
CompletionItemBuilder::new()
.label("isTRIPLE")
.label_details(" (term)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the term is a triple term (an RDF 1.2 quoted triple). (SPARQL 1.2)")
.insert_text("isTRIPLE(${0:term})")
.build(),
CompletionItemBuilder::new()
.label("hasLANG")
.label_details(" (literal)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the literal has a language tag. (SPARQL 1.2)")
.insert_text("hasLANG(${0:literal})")
.build(),
CompletionItemBuilder::new()
.label("hasLANGDIR")
.label_details(" (literal)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the literal has a base direction (\"ltr\" or \"rtl\"). (SPARQL 1.2)")
.insert_text("hasLANGDIR(${0:literal})")
.build(),
CompletionItemBuilder::new()
.label("sameTerm")
.label_details(" (term1, term2)")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the two arguments are the same RDF term. Unlike '=', this does not perform value-based comparison โ it compares term identity.")
.insert_text("sameTerm(${1:term1}, ${0:term2})")
.build(),
CompletionItemBuilder::new()
.label("IRI")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Constructs an IRI from a string or resolves a relative IRI against the base IRI.")
.insert_text("IRI(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("URI")
.label_details(" (expr)")
.kind(CompletionItemKind::Function)
.documentation("Constructs a URI from a string or resolves a relative URI against the base URI. This is an alternative spelling of IRI.")
.insert_text("URI(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("BNODE")
.label_details(" ([id])")
.kind(CompletionItemKind::Function)
.documentation("Constructs a blank node. With an argument, produces a blank node deterministic for that input within a single query. Without an argument, creates a fresh blank node each time.")
.insert_text("BNODE(${0:id})")
.build(),
CompletionItemBuilder::new()
.label("UUID")
.label_details(" ()")
.kind(CompletionItemKind::Function)
.documentation("Returns a fresh IRI from the UUID URN scheme (urn:uuid:...). Each call returns a different UUID.")
.insert_text("UUID()")
.build(),
CompletionItemBuilder::new()
.label("STRUUID")
.label_details(" ()")
.kind(CompletionItemKind::Function)
.documentation("Returns a string that is the UUID portion of a UUID IRI (without the urn:uuid: prefix). Each call returns a different UUID.")
.insert_text("STRUUID()")
.build(),
CompletionItemBuilder::new()
.label("TRIPLE")
.label_details(" (subject, predicate, object)")
.kind(CompletionItemKind::Function)
.documentation("Constructs a triple term from the given subject, predicate, and object. (SPARQL 1.2)")
.insert_text("TRIPLE(${1:subject}, ${2:predicate}, ${0:object})")
.build(),
CompletionItemBuilder::new()
.label("SUBJECT")
.label_details(" (tripleTerm)")
.kind(CompletionItemKind::Function)
.documentation("Returns the subject of a triple term. (SPARQL 1.2)")
.insert_text("SUBJECT(${0:tripleTerm})")
.build(),
CompletionItemBuilder::new()
.label("PREDICATE")
.label_details(" (tripleTerm)")
.kind(CompletionItemKind::Function)
.documentation("Returns the predicate of a triple term. (SPARQL 1.2)")
.insert_text("PREDICATE(${0:tripleTerm})")
.build(),
CompletionItemBuilder::new()
.label("OBJECT")
.label_details(" (tripleTerm)")
.kind(CompletionItemKind::Function)
.documentation("Returns the object of a triple term. (SPARQL 1.2)")
.insert_text("OBJECT(${0:tripleTerm})")
.build(),
CompletionItemBuilder::new()
.label("IF")
.label_details(" (condition, thenExpr, elseExpr)")
.kind(CompletionItemKind::Function)
.documentation("Evaluates the condition. If true, returns thenExpr; otherwise returns elseExpr. Only the selected branch is evaluated.")
.insert_text("IF(${1:condition}, ${2:thenExpr}, ${0:elseExpr})")
.build(),
CompletionItemBuilder::new()
.label("COALESCE")
.label_details(" (expr, ...)")
.kind(CompletionItemKind::Function)
.documentation("Returns the first argument that evaluates without error. Useful for providing fallback values when variables may be unbound.")
.insert_text("COALESCE(${1:expr}, ${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("EXISTS")
.label_details(" { pattern }")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the graph pattern matches the dataset. Variables already bound in the outer query are substituted into the pattern.")
.insert_text("EXISTS {\n\t$0\n}")
.build(),
CompletionItemBuilder::new()
.label("NOT EXISTS")
.label_details(" { pattern }")
.kind(CompletionItemKind::Function)
.documentation("Returns true if the graph pattern does NOT match the dataset. The negation of EXISTS.")
.insert_text("NOT EXISTS {\n\t$0\n}")
.build(),
CompletionItemBuilder::new()
.label("COUNT")
.label_details(" ([DISTINCT] expr | *)")
.kind(CompletionItemKind::Function)
.documentation("Counts the number of solutions. COUNT(*) counts all rows; COUNT(expr) counts non-error values; COUNT(DISTINCT expr) counts unique values.")
.insert_text("COUNT(${0:*})")
.build(),
CompletionItemBuilder::new()
.label("SUM")
.label_details(" ([DISTINCT] expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the sum of numeric values across all solutions in a group. Non-numeric values cause a type error.")
.insert_text("SUM(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("MIN")
.label_details(" ([DISTINCT] expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the minimum value across all solutions in a group, using SPARQL's ORDER BY ordering.")
.insert_text("MIN(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("MAX")
.label_details(" ([DISTINCT] expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the maximum value across all solutions in a group, using SPARQL's ORDER BY ordering.")
.insert_text("MAX(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("AVG")
.label_details(" ([DISTINCT] expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns the arithmetic mean of numeric values across all solutions in a group.")
.insert_text("AVG(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("SAMPLE")
.label_details(" ([DISTINCT] expr)")
.kind(CompletionItemKind::Function)
.documentation("Returns an arbitrary value from the solutions in a group. The choice is non-deterministic.")
.insert_text("SAMPLE(${0:expr})")
.build(),
CompletionItemBuilder::new()
.label("GROUP_CONCAT")
.label_details(" ([DISTINCT] expr [; SEPARATOR = str])")
.kind(CompletionItemKind::Function)
.documentation("Concatenates the string values of an expression across a group. The default separator is a space. Use SEPARATOR = \"...\" to specify a custom delimiter.")
.insert_text("GROUP_CONCAT(${1:expr}; SEPARATOR = \"${0:,}\")")
.build(),
],
})
}