better ast traversal

it works!
This commit is contained in:
Léana 江 2025-06-14 14:19:33 +02:00
parent b614382e36
commit 4724ae60b2
No known key found for this signature in database
GPG key ID: 4E887A4CA9714ADA
2 changed files with 24 additions and 25 deletions

View file

@ -1,6 +1,8 @@
use itertools::Itertools;
use syntax::{ast, match_ast, SyntaxKind, SyntaxToken, TextRange};
use syntax::ast::{self, AstNode};
use syntax::{match_ast, NixLanguage, SyntaxKind, SyntaxToken, TextRange};
use crate::ide::expand_selection::expand_selection;
use crate::{DefDatabase, FileId};
#[derive(Debug, Clone)]
@ -29,29 +31,21 @@ pub(crate) fn inlay_hints(
),
};
// TODO:
// What is the best way to match ast?
// It would be nice to match on the shape `{ ... = <expr> ; }`
let hint_kind = |tok: &SyntaxToken| -> Option<InlayHintKind> {
let prev_token = {
let mut iter = std::iter::successors(Some(tok.clone()), |tok| tok.prev_token());
iter.next();
iter.find_or_first(|tok| !tok.kind().is_trivia())
};
let next_token = {
let mut iter = std::iter::successors(Some(tok.clone()), |tok| tok.next_token());
iter.next();
iter.find_or_first(|tok| !tok.kind().is_trivia())
};
if tok.kind() == SyntaxKind::SEMICOLON {
let attribute_node = tok
// Grab the attrset
.prev_sibling_or_token()?
.parent()?
// Grab the attrpath part, without space
.first_child_by_kind(&|u: SyntaxKind| u == SyntaxKind::ATTR_PATH)?
.children()
.filter(|node| !node.kind().is_trivia());
match (prev_token, next_token) {
(Some(prev), Some(next))
if prev.kind() == SyntaxKind::EQ && next.kind() == SyntaxKind::SEMICOLON =>
{
// TODO: inlay hint label
Some(InlayHintKind::AttrsetAttribute("text".into()))
}
_ => None,
let attr_name = attribute_node.map(|node| node.to_string()).join(".");
Some(InlayHintKind::AttrsetAttribute(attr_name))
} else {
None
}
};
@ -86,6 +80,11 @@ mod tests {
#[test]
fn hint() {
check("$0{ foo = true; }", expect!["fail"]);
// check("$0{ foo = true; }", expect!["fail"]);
// check("$0{ foo = [true true true]; }", expect!["fail"]);
check(
"$0{ foo.bar = { baz = [true true true]; }; }",
expect!["fail"],
);
}
}

View file

@ -396,7 +396,7 @@ pub(crate) fn to_inlay_hints(line_map: &LineMap, hints: Vec<InlayHintResult>) ->
match kind {
InlayHintKind::AttrsetAttribute(s) => InlayHint {
position: {
let (line, character) = line_map.line_col_for_pos(range.start());
let (line, character) = line_map.line_col_for_pos(range.end());
Position { line, character }
},
label: InlayHintLabel::String(s.clone()),
@ -404,7 +404,7 @@ pub(crate) fn to_inlay_hints(line_map: &LineMap, hints: Vec<InlayHintResult>) ->
text_edits: None,
tooltip: None,
padding_left: None,
padding_right: None,
padding_right: Some(true),
data: None,
},
}