From 4724ae60b2bf012d4e5db0d4d09a9e6ccecc3441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9ana=20=E6=B1=9F?= Date: Sat, 14 Jun 2025 14:19:33 +0200 Subject: [PATCH] better ast traversal it works! --- crates/ide/src/ide/inlay_hints.rs | 45 +++++++++++++++---------------- crates/nil/src/convert.rs | 4 +-- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/crates/ide/src/ide/inlay_hints.rs b/crates/ide/src/ide/inlay_hints.rs index e06877f..b03ef27 100644 --- a/crates/ide/src/ide/inlay_hints.rs +++ b/crates/ide/src/ide/inlay_hints.rs @@ -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 `{ ... = ; }` let hint_kind = |tok: &SyntaxToken| -> Option { - 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"], + ); } } diff --git a/crates/nil/src/convert.rs b/crates/nil/src/convert.rs index e5a5289..9d408b2 100644 --- a/crates/nil/src/convert.rs +++ b/crates/nil/src/convert.rs @@ -396,7 +396,7 @@ pub(crate) fn to_inlay_hints(line_map: &LineMap, hints: Vec) -> 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) -> text_edits: None, tooltip: None, padding_left: None, - padding_right: None, + padding_right: Some(true), data: None, }, }