sql-dialect-fmt-hover 1.18.0

LSP/editor-ready hover information for Snowflake SQL keywords, functions, types, procedures, and tasks.
Documentation
use std::ops::Range;

use sql_dialect_fmt_lexer::tokenize;
use sql_dialect_fmt_syntax::SyntaxKind;

#[derive(Clone, Debug)]
pub(crate) struct SpannedToken<'a> {
    pub(crate) kind: SyntaxKind,
    pub(crate) text: &'a str,
    pub(crate) range: Range<usize>,
}

pub(crate) fn spanned_tokens(source: &str) -> Vec<SpannedToken<'_>> {
    let mut offset = 0usize;
    tokenize(source)
        .tokens
        .into_iter()
        .filter_map(|token| {
            let start = offset;
            offset += token.text.len();
            (!token.kind.is_trivia()).then_some(SpannedToken {
                kind: token.kind,
                text: token.text,
                range: start..offset,
            })
        })
        .collect()
}

pub(crate) fn token_at(tokens: &[SpannedToken<'_>], offset: usize) -> Option<usize> {
    tokens
        .iter()
        .position(|token| token.range.start <= offset && offset < token.range.end)
        .or_else(|| {
            offset.checked_sub(1).and_then(|previous| {
                tokens
                    .iter()
                    .position(|token| token.range.start <= previous && previous < token.range.end)
            })
        })
}