Skip to main content

cargo_snippet_more/
lib.rs

1pub use cargo_snippet_more_macros::*;
2
3#[macro_export]
4macro_rules! snippet_start {
5    ($($tt:tt)*) => {};
6}
7
8#[macro_export]
9macro_rules! snippet_end {
10    ($name:literal) => {};
11}
12
13#[macro_export]
14macro_rules! expanded {
15    ($name:literal) => {};
16}
17
18/// Placeholder macro for defining interactive placeholders in snippets.
19///
20/// This macro creates placeholders that will be converted to editor-specific
21/// placeholder syntax in the generated snippets. It's the recommended way to
22/// specify placeholders in cargo-snippet-more as it's syntactically valid Rust
23/// and works in any expression or statement position.
24///
25/// # Why Macro-Based Placeholders?
26///
27/// Unlike comment-based approaches, the `p!` macro:
28/// - ✅ Is syntactically valid Rust that compiles and runs
29/// - ✅ Works with rustfmt and rust-analyzer
30/// - ✅ Can be placed in any expression/statement position
31/// - ✅ Provides type safety and IDE support
32///
33/// # Variants
34///
35/// - `p!(0)` - Final cursor position (converts to `$0`)
36/// - `p!(n)` - Placeholder without default value (converts to `${n}`)
37/// - `p!(n, |a, b, c|)` - Choice placeholder (converts to `${n|a,b,c|}`)
38/// - `p!(n, content)` - Placeholder with default value (converts to `${n:content}`)
39///
40/// # Examples
41///
42/// ## Basic Usage
43/// ```
44/// use cargo_snippet_more::p;
45///
46/// let p!(1, variable) = p!(2, 10);
47/// let mode = p!(3, |"read", "write"|);
48/// p!(0);
49/// ```
50///
51/// This generates:
52/// ```text
53/// let ${1:variable} = ${2:10};
54/// let mode = ${3|"read","write"|};
55/// $0
56/// ```
57///
58/// ## Advanced Example
59/// ```
60/// use cargo_snippet_more::p;
61///
62/// fn binary_search<T: Ord>(arr: &[T], target: &T) -> Option<usize> {
63///     let p!(1, mut low) = 0;
64///     let p!(2, mut high) = arr.len();
65///     while low < high {
66///         let p!(3, mid) = low + (high - low) / 2;
67///         match arr[mid].cmp(target) {
68///             std::cmp::Ordering::Less => low = mid + 1,
69///             std::cmp::Ordering::Equal => return Some(mid),
70///             std::cmp::Ordering::Greater => high = mid,
71///         }
72///     }
73///     p!(0);
74///     None
75/// }
76/// ```
77#[macro_export]
78macro_rules! p {
79    // p!(0) → $0 (final cursor position)
80    (0) => {};
81    // p!(n) → ${n} (no default value)
82    ($n:literal) => {};
83    // p!(n, |a, b, c|) → ${n|a,b,c|} (choices, expands to first choice at runtime)
84    ($n:literal, |$first:tt $(,$rest:tt)*|) => { $first };
85    // p!(n, content) → ${n:content}
86    ($n:literal, $($t:tt)*) => { $($t)* };
87}