qlue-ls 3.0.1

A language server for SPARQL
Documentation
use ll_sparql_parser::{SyntaxElement, syntax_kind::SyntaxKind};
use unicode_width::UnicodeWidthStr;

pub const KEYWORDS: [SyntaxKind; 109] = [
    SyntaxKind::BASE,
    SyntaxKind::PREFIX,
    SyntaxKind::SELECT,
    SyntaxKind::DISTINCT,
    SyntaxKind::REDUCED,
    SyntaxKind::FROM,
    SyntaxKind::NAMED,
    SyntaxKind::WHERE,
    SyntaxKind::UNION,
    SyntaxKind::OPTIONAL,
    SyntaxKind::MINUS,
    SyntaxKind::GRAPH,
    SyntaxKind::SERVICE,
    SyntaxKind::SILENT,
    SyntaxKind::FILTER,
    SyntaxKind::BIND,
    SyntaxKind::VALUES,
    SyntaxKind::AS,
    SyntaxKind::GROUP,
    SyntaxKind::BY,
    SyntaxKind::HAVING,
    SyntaxKind::ORDER,
    SyntaxKind::DESC,
    SyntaxKind::ASC,
    SyntaxKind::LIMIT,
    SyntaxKind::OFFSET,
    SyntaxKind::CONSTRUCT,
    SyntaxKind::DESCRIBE,
    SyntaxKind::ASK,
    SyntaxKind::STR,
    SyntaxKind::LANG,
    SyntaxKind::STR,
    SyntaxKind::LANG,
    SyntaxKind::LANGMATCHES,
    SyntaxKind::DATATYPE,
    SyntaxKind::BOUND,
    SyntaxKind::IRI,
    SyntaxKind::URI,
    SyntaxKind::BNODE,
    SyntaxKind::RAND,
    SyntaxKind::ABS,
    SyntaxKind::CEIL,
    SyntaxKind::FLOOR,
    SyntaxKind::ROUND,
    SyntaxKind::CONCAT,
    SyntaxKind::STRLEN,
    SyntaxKind::UCASE,
    SyntaxKind::LCASE,
    SyntaxKind::ENCODE_FOR_URI,
    SyntaxKind::CONTAINS,
    SyntaxKind::STRSTARTS,
    SyntaxKind::STRENDS,
    SyntaxKind::STRBEFORE,
    SyntaxKind::STRAFTER,
    SyntaxKind::YEAR,
    SyntaxKind::MONTH,
    SyntaxKind::DAY,
    SyntaxKind::HOURS,
    SyntaxKind::MINUTES,
    SyntaxKind::SECONDS,
    SyntaxKind::TIMEZONE,
    SyntaxKind::TZ,
    SyntaxKind::NOW,
    SyntaxKind::UUID,
    SyntaxKind::STRUUID,
    SyntaxKind::MD5,
    SyntaxKind::SHA1,
    SyntaxKind::SHA256,
    SyntaxKind::SHA384,
    SyntaxKind::SHA512,
    SyntaxKind::COALESCE,
    SyntaxKind::IF,
    SyntaxKind::STRLANG,
    SyntaxKind::STRDT,
    SyntaxKind::sameTerm,
    SyntaxKind::isIRI,
    SyntaxKind::isURI,
    SyntaxKind::isBLANK,
    SyntaxKind::isLITERAL,
    SyntaxKind::isNUMERIC,
    SyntaxKind::COUNT,
    SyntaxKind::SUM,
    SyntaxKind::MIN,
    SyntaxKind::MAX,
    SyntaxKind::AVG,
    SyntaxKind::SAMPLE,
    SyntaxKind::GROUP_CONCAT,
    SyntaxKind::SEPARATOR,
    SyntaxKind::SUBSTR,
    SyntaxKind::REGEX,
    SyntaxKind::EXISTS,
    SyntaxKind::IN,
    SyntaxKind::NOT,
    SyntaxKind::LOAD,
    SyntaxKind::INTO,
    SyntaxKind::CLEAR,
    SyntaxKind::ALL,
    SyntaxKind::NAMED,
    SyntaxKind::DEFAULT,
    SyntaxKind::DROP,
    SyntaxKind::ADD,
    SyntaxKind::TO,
    SyntaxKind::MOVE,
    SyntaxKind::COPY,
    SyntaxKind::INSERT,
    SyntaxKind::DATA,
    SyntaxKind::WITH,
    SyntaxKind::USING,
    SyntaxKind::CREATE,
];

pub(super) fn subtree_width(element: &SyntaxElement) -> usize {
    if let Some(node) = element.as_node() {
        node.descendants_with_tokens()
            .filter_map(|node| {
                (node.as_token().is_some() && !node.kind().is_trivia())
                    .then_some(node.to_string().width())
            })
            .sum::<usize>()
            + node.children().count().saturating_sub(1)
    } else {
        element.to_string().width()
    }
}