diff --git a/derive-ahk/src/lib.rs b/derive-ahk/src/lib.rs index 51f1dfcf..2780b9d3 100644 --- a/derive-ahk/src/lib.rs +++ b/derive-ahk/src/lib.rs @@ -1,19 +1,28 @@ #![warn(clippy::all, clippy::nursery, clippy::pedantic)] #![allow(clippy::missing_errors_doc)] +#![no_implicit_prelude] -use std::stringify; +use ::std::clone::Clone; +use ::std::convert::From; +use ::std::convert::Into; +use ::std::iter::Extend; +use ::std::iter::Iterator; +use ::std::matches; +use ::std::string::ToString; +use ::std::unreachable; -use quote::quote; -use syn::parse_macro_input; -use syn::Data; -use syn::DataEnum; -use syn::DeriveInput; -use syn::Fields; -use syn::FieldsNamed; -use syn::FieldsUnnamed; +use ::quote::quote; +use ::std::option::Option::Some; +use ::syn::parse_macro_input; +use ::syn::Data; +use ::syn::DataEnum; +use ::syn::DeriveInput; +use ::syn::Fields; +use ::syn::FieldsNamed; +use ::syn::FieldsUnnamed; -#[proc_macro_derive(Ahk)] -pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream { +#[proc_macro_derive(AhkFunction)] +pub fn ahk_function(input: ::proc_macro::TokenStream) -> ::proc_macro::TokenStream { let input = parse_macro_input!(input as DeriveInput); let name = input.ident; @@ -21,22 +30,23 @@ pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream { Data::Struct(s) => match s.fields { Fields::Named(FieldsNamed { named, .. }) => { let idents = named.iter().map(|f| &f.ident); - let arguments = format!("{}", quote! {#(#idents), *}); + let arguments = quote! {#(#idents), *}.to_string(); let idents = named.iter().map(|f| &f.ident); - let called_arguments = format!("{}", quote! {#(%#idents%) *}) + let called_arguments = quote! {#(%#idents%) *} + .to_string() .replace(" %", "%") .replace("% ", "%") .replace("%%", "% %"); quote! { - impl #name { - fn ahk_function() -> String { - format!(r#" + impl AhkFunction for #name { + fn generate_ahk_function() -> String { + ::std::format!(r#" {}({}) {{ Run, komorebic.exe {} {}, , Hide }}"#, - stringify!(#name), + ::std::stringify!(#name), #arguments, stringify!(#name).to_kebab_case(), #called_arguments @@ -47,31 +57,42 @@ pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream { } _ => unreachable!("only to be used on structs with named fields"), }, + _ => unreachable!("only to be used on structs"), + } + .into() +} + +#[proc_macro_derive(AhkLibrary)] +pub fn ahk_library(input: ::proc_macro::TokenStream) -> ::proc_macro::TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let name = input.ident; + + match input.data { Data::Enum(DataEnum { variants, .. }) => { let enums = variants.iter().filter(|&v| { matches!(v.fields, Fields::Unit) || matches!(v.fields, Fields::Unnamed(..)) }); - let mut stream = proc_macro2::TokenStream::new(); + let mut stream = ::proc_macro2::TokenStream::new(); for variant in enums.clone() { match &variant.fields { Fields::Unnamed(FieldsUnnamed { unnamed, .. }) => { for field in unnamed { stream.extend(quote! { - v.push(#field::ahk_function()); + v.push(#field::generate_ahk_function()); }); } } Fields::Unit => { let name = &variant.ident; stream.extend(quote! { - v.push(format!(r#" + v.push(::std::format!(r#" {}() {{ Run, komorebic.exe {}, , Hide }}"#, - stringify!(#name), - stringify!(#name).to_kebab_case() + ::std::stringify!(#name), + ::std::stringify!(#name).to_kebab_case() )); }); } @@ -93,7 +114,7 @@ pub fn ahk(input: proc_macro::TokenStream) -> proc_macro::TokenStream { } } } - Data::Union(_) => unreachable!("only to be used on enums and structs"), + _ => unreachable!("only to be used on enums"), } .into() } diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 1a9dad53..37936368 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -26,7 +26,8 @@ use bindings::Windows::Win32::Foundation::HWND; use bindings::Windows::Win32::UI::WindowsAndMessaging::ShowWindow; use bindings::Windows::Win32::UI::WindowsAndMessaging::SHOW_WINDOW_CMD; use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_RESTORE; -use derive_ahk::Ahk; +use derive_ahk::AhkFunction; +use derive_ahk::AhkLibrary; use komorebi_core::ApplicationIdentifier; use komorebi_core::CycleDirection; use komorebi_core::Flip; @@ -35,6 +36,14 @@ use komorebi_core::OperationDirection; use komorebi_core::Sizing; use komorebi_core::SocketMessage; +trait AhkLibrary { + fn generate_ahk_library() -> String; +} + +trait AhkFunction { + fn generate_ahk_function() -> String; +} + #[derive(ArgEnum)] enum BooleanState { Enable, @@ -55,7 +64,7 @@ macro_rules! gen_enum_subcommand_args { ( $( $name:ident: $element:ty ),+ ) => { $( paste! { - #[derive(clap::Clap, derive_ahk::Ahk)] + #[derive(clap::Clap, derive_ahk::AhkFunction)] pub struct $name { #[clap(arg_enum)] [<$element:snake>]: $element @@ -80,7 +89,7 @@ macro_rules! gen_target_subcommand_args { // SubCommand Pattern ( $( $name:ident ),+ ) => { $( - #[derive(clap::Clap, derive_ahk::Ahk)] + #[derive(clap::Clap, derive_ahk::AhkFunction)] pub struct $name { /// Target index (zero-indexed) target: usize, @@ -104,7 +113,7 @@ macro_rules! gen_workspace_subcommand_args { ( $( $name:ident: $(#[enum] $(@$arg_enum:tt)?)? $value:ty ),+ ) => ( paste! { $( - #[derive(clap::Clap, derive_ahk::Ahk)] + #[derive(clap::Clap, derive_ahk::AhkFunction)] pub struct [] { /// Monitor index (zero-indexed) monitor: usize, @@ -130,7 +139,7 @@ gen_workspace_subcommand_args! { Tiling: #[enum] BooleanState } -#[derive(Clap, Ahk)] +#[derive(Clap, AhkFunction)] struct Resize { #[clap(arg_enum)] edge: OperationDirection, @@ -138,7 +147,7 @@ struct Resize { sizing: Sizing, } -#[derive(Clap, Ahk)] +#[derive(Clap, AhkFunction)] struct EnsureWorkspaces { /// Monitor index (zero-indexed) monitor: usize, @@ -150,7 +159,7 @@ macro_rules! gen_padding_subcommand_args { // SubCommand Pattern ( $( $name:ident ),+ ) => { $( - #[derive(clap::Clap, derive_ahk::Ahk)] + #[derive(clap::Clap, derive_ahk::AhkFunction)] pub struct $name { /// Monitor index (zero-indexed) monitor: usize, @@ -172,7 +181,7 @@ macro_rules! gen_padding_adjustment_subcommand_args { // SubCommand Pattern ( $( $name:ident ),+ ) => { $( - #[derive(clap::Clap, derive_ahk::Ahk)] + #[derive(clap::Clap, derive_ahk::AhkFunction)] pub struct $name { #[clap(arg_enum)] sizing: Sizing, @@ -192,7 +201,7 @@ macro_rules! gen_application_target_subcommand_args { // SubCommand Pattern ( $( $name:ident ),+ ) => { $( - #[derive(clap::Clap, derive_ahk::Ahk)] + #[derive(clap::Clap, derive_ahk::AhkFunction)] pub struct $name { #[clap(arg_enum)] identifier: ApplicationIdentifier, @@ -209,7 +218,7 @@ gen_application_target_subcommand_args! { IdentifyTrayApplication } -#[derive(Clap, Ahk)] +#[derive(Clap, AhkFunction)] struct WorkspaceRule { #[clap(arg_enum)] identifier: ApplicationIdentifier, @@ -228,7 +237,7 @@ struct Opts { subcmd: SubCommand, } -#[derive(Clap, Ahk)] +#[derive(Clap, AhkLibrary)] enum SubCommand { /// Start komorebi.exe as a background process Start,