Autocomplete rsx (#2421)
* autocomplete rsx * hide the completions module * fix autocomplete for identifiers that start with a raw identifier * add field completion hints for props * remove extra import * Revert "add field completion hints for props" This reverts commit 194899c73783e0f9b5d601d53365746d838f2048. * fix autocomplete inside raw expressions * fix autofmt * feat: just use regular ifmt if it's compatible reuses the tokens for ifmt so RA provides its HIR lowering on simple formatted strings * fix merging ifmt strings * add a better error message for components called like functions --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
245003a5d4
commit
2523581cf4
21 files changed
+788
-217
No files matched your search
+50
-4
@@ -13,6 +13,41 @@
|
||||
//! - [x] Good errors if parsing fails
|
||||
//!
|
||||
//! Any errors in using rsx! will likely occur when people start using it, so the first errors must be really helpful.
|
||||
//!
|
||||
//! # Completions
|
||||
//! Rust analyzer completes macros by looking at the expansion of the macro and trying to match the start of identifiers in the macro to identifiers in the current scope
|
||||
//!
|
||||
//! Eg, if a macro expands to this:
|
||||
//! ```rust, ignore
|
||||
//! struct MyStruct;
|
||||
//!
|
||||
//! // macro expansion
|
||||
//! My
|
||||
//! ```
|
||||
//! Then the analyzer will try to match the start of the identifier "My" to an identifier in the current scope (MyStruct in this case).
|
||||
//!
|
||||
//! In dioxus, our macros expand to the completions module if we know the identifier is incomplete:
|
||||
//! ```rust, ignore
|
||||
//! // In the root of the macro, identifiers must be elements
|
||||
//! // rsx! { di }
|
||||
//! dioxus_elements::elements::di
|
||||
//!
|
||||
//! // Before the first child element, every following identifier is either an attribute or an element
|
||||
//! // rsx! { div { ta } }
|
||||
//! // Isolate completions scope
|
||||
//! mod completions__ {
|
||||
//! // import both the attributes and elements this could complete to
|
||||
//! use dioxus_elements::elements::div::*;
|
||||
//! use dioxus_elements::elements::*;
|
||||
//! fn complete() {
|
||||
//! ta;
|
||||
//! }
|
||||
//! }
|
||||
//!
|
||||
//! // After the first child element, every following identifier is another element
|
||||
//! // rsx! { div { attribute: value, child {} di } }
|
||||
//! dioxus_elements::elements::di
|
||||
//! ```
|
||||
|
||||
#[macro_use]
|
||||
mod errors;
|
||||
@@ -145,14 +180,19 @@ impl CallBody {
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for CallBody {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
/// Parse a stream into a CallBody. Return all error immediately instead of trying to partially expand the macro
|
||||
///
|
||||
/// This should be preferred over `parse` if you are outside of a macro
|
||||
pub fn parse_strict(input: ParseStream) -> Result<Self> {
|
||||
Self::parse_with_options(input, false)
|
||||
}
|
||||
|
||||
fn parse_with_options(input: ParseStream, partial_completions: bool) -> Result<Self> {
|
||||
let mut roots = Vec::new();
|
||||
|
||||
while !input.is_empty() {
|
||||
let node = input.parse::<BodyNode>()?;
|
||||
let node = BodyNode::parse_with_options(input, partial_completions)?;
|
||||
|
||||
if input.peek(Token![,]) {
|
||||
let _ = input.parse::<Token![,]>();
|
||||
@@ -165,6 +205,12 @@ impl Parse for CallBody {
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for CallBody {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
Self::parse_with_options(input, true)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToTokens for CallBody {
|
||||
fn to_tokens(&self, out_tokens: &mut TokenStream2) {
|
||||
// Empty templates just are placeholders for "none"
|
||||
|
||||
Reference in new issue
Block a user