Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Emit completion probes

Completion probes let an incomplete trailing dot produce rust-analyzer method completion inside an attribute token tree. Use them only when the macro emits the marker after a real typed receiver.

Handle a trailing dot

With the default options, Root::<_>.first(1). parses as a chain whose terminal marker is raCompletionMarker:

use attribute_dsl::AttributeChain;
use quote::quote;

let chain: AttributeChain = syn::parse_str("Root::<_>.first(1).")?;
assert!(chain.has_completion_probe());

let completion = chain
    .completion_marker()
    .map(|marker| quote! { .#marker })
    .unwrap_or_default();

Ok::<(), syn::Error>(())

Append completion after the application-owned constructor and parsed calls. At that position, the missing marker method gives rust-analyzer a typed receiver and allows it to offer the receiver’s methods at the original dot. The explicit terminal syntax Root::<_>.raCompletionMarker represents the same completion state.

Configure the marker

Use one stable Rust identifier when the consumer needs a custom marker:

use attribute_dsl::{AttributeChain, ChainParseOptions};
use quote::quote;

let options = ChainParseOptions::new().completion_marker("completeHere");
let chain = AttributeChain::parse_tokens_with_options(
    quote!(Root::<_>.first(1).),
    &options,
)?;

assert_eq!(
    chain
        .completion_marker()
        .expect("the input ends with a probe")
        .to_string(),
    "completeHere"
);

Ok::<(), syn::Error>(())

An invalid identifier produces a syn::Error when trailing-dot recovery needs to emit it. Custom ChainParseOptions apply to direct AttributeChain parsing; the Parse implementations for entries, lists, and groups use the defaults.

Reject probe syntax

Disable completion probes when the macro accepts only complete chains or cannot emit a typed receiver:

use attribute_dsl::{AttributeChain, ChainParseOptions, CompletionProbeParsing};
use quote::quote;

let options = ChainParseOptions::new()
    .allow_completion_probe(CompletionProbeParsing::Disabled);
let result = AttributeChain::parse_tokens_with_options(
    quote!(Root::<_>.first(1).),
    &options,
);

assert!(result.is_err());

Disabling probes rejects both trailing-dot recovery and an explicit terminal completion marker.

Preserve later list entries

Default completion recovery stops before a comma in ChainList, so later entries remain available while one entry is incomplete:

use attribute_dsl::ChainList;

let list: ChainList = syn::parse_str(
    "first = Root::<_>., second = Other::<String>",
)?;

assert!(list.entries()[0].chain().has_completion_probe());
assert_eq!(list.entries().len(), 2);

Ok::<(), syn::Error>(())

If parsing succeeds but rust-analyzer offers no methods, inspect the generated expression. The constructor and all preceding calls must resolve to the desired receiver type before the marker access.