Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ indexmap = { version = "2.14.0", default-features = false, features = ["std"] }
regex = { version = "1.12.4", default-features = false, features = ["std", "unicode-perl"] }
linearize = { version = "0.1.7", default-features = false, features = ["derive"] }
kbvm = { version = "0.1.7", default-features = false }
tempfile = { version = "3.27.0", default-features = false }
Comment thread
mahkoh marked this conversation as resolved.
1 change: 0 additions & 1 deletion codegen/codegen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ set -ex
cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.."

cargo run -p codegen
cargo +nightly fmt
124 changes: 47 additions & 77 deletions codegen/src/input_event_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,77 +74,61 @@ pub fn main() -> Result<()> {
}
let map = generate_map("KEYCODES", "str", "MappedKey", &keys, &mut values)?;
let mut out = String::new();
writeln!(out, "use super::MappedKey;")?;
writeln!(out, "use crate::phf_map::PhfMap;")?;
writeln!(out)?;
writeln!(out, "{}", map)?;
define_w!(out);
wl!("use super::MappedKey;");
wl!("use crate::phf_map::PhfMap;");
wl!();
wl!("{}", map);
let file = match ty {
MappingType::Keycode => {
concat!(
env!("CARGO_MANIFEST_DIR"),
"/../toml-config/src/config/keycodes/generated.rs",
)
}
MappingType::InputEventCode => {
concat!(
env!("CARGO_MANIFEST_DIR"),
"/../toml-config/src/config/input_event_codes/generated.rs",
)
}
MappingType::Keycode => "toml-config/src/config/keycodes/generated.rs",
MappingType::InputEventCode => "toml-config/src/config/input_event_codes/generated.rs",
};
update(file, &out)?;
}
{
let mut out = String::new();
writeln!(out, "pub const MAX_INPUT_EVENT_CODE: usize = {max};")?;
writeln!(out)?;
writeln!(
out,
"#[derive(Copy, Clone, Debug, Eq, PartialEq, linearize::Linearize)]"
)?;
writeln!(out, "#[expect(non_camel_case_types)]")?;
writeln!(out, "pub enum InputEventCode {{")?;
define_w!(out);
wl!("pub const MAX_INPUT_EVENT_CODE: usize = {max};");
wl!();
wl!("#[derive(Copy, Clone, Debug, Eq, PartialEq, linearize::Linearize)]");
wl!("#[expect(non_camel_case_types)]");
wl!("pub enum InputEventCode {{");
for names in by_value.values() {
writeln!(out, " {},", names[0])?;
wl!(" {},", names[0]);
}
writeln!(out, "}}")?;
writeln!(out)?;
writeln!(out, "impl InputEventCode {{")?;
writeln!(out, " pub fn raw(self) -> u32 {{")?;
writeln!(out, " match self {{")?;
wl!("}}");
wl!();
wl!("impl InputEventCode {{");
wl!(" pub fn raw(self) -> u32 {{");
wl!(" match self {{");
for (value, names) in by_value.iter() {
writeln!(out, " Self::{} => {value},", names[0])?;
wl!(" Self::{} => {value},", names[0]);
}
writeln!(out, " }}")?;
writeln!(out, " }}")?;
writeln!(out)?;
writeln!(out, " pub fn from_raw(raw: u32) -> Option<Self> {{")?;
writeln!(
out,
wl!(" }}");
wl!(" }}");
wl!();
wl!(" pub fn from_raw(raw: u32) -> Option<Self> {{");
wl!(
" static MAP: [Option<InputEventCode>; {}] = [",
max + 1
)?;
);
for i in 0..=max {
if let Some(value) = by_value.get(&i) {
writeln!(out, " Some(InputEventCode::{}),", value[0])?;
wl!(" Some(InputEventCode::{}),", value[0]);
} else {
writeln!(out, " None,")?;
wl!(" None,");
}
}
writeln!(out, " ];")?;
writeln!(out, " MAP.get(raw as usize).copied().flatten()")?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
writeln!(out)?;
writeln!(
out,
"impl crate::utils::static_text::StaticText for InputEventCode {{"
)?;
writeln!(out, " fn text(&self) -> &'static str {{")?;
writeln!(out, " match self {{")?;
wl!(" ];");
wl!(" MAP.get(raw as usize).copied().flatten()");
wl!(" }}");
wl!("}}");
wl!();
wl!("impl crate::utils::static_text::StaticText for InputEventCode {{");
wl!(" fn text(&self) -> &'static str {{");
wl!(" match self {{");
for names in by_value.values() {
writeln!(
out,
wl!(
" Self::{} => \"{}\",",
names[0],
fmt::from_fn(|f| {
Expand All @@ -156,36 +140,22 @@ pub fn main() -> Result<()> {
}
Ok(())
})
)?;
);
}
writeln!(out, " }}")?;
writeln!(out, " }}")?;
writeln!(out, "}}")?;
update(
concat!(
env!("CARGO_MANIFEST_DIR"),
"/../src/evdev/input_event_codes.rs",
),
&out,
)?;
wl!(" }}");
wl!(" }}");
wl!("}}");
update("src/evdev/input_event_codes.rs", &out)?;
}
{
let mut out = String::new();
writeln!(out, "use super::InputEventCode;")?;
writeln!(out)?;
define_w!(out);
wl!("use super::InputEventCode;");
wl!();
for (name, value) in &codes {
writeln!(
out,
"pub const {name}: InputEventCode = InputEventCode({value});"
)?;
wl!("pub const {name}: InputEventCode = InputEventCode({value});");
}
update(
concat!(
env!("CARGO_MANIFEST_DIR"),
"/../jay-config/src/input/input_event_codes.rs",
),
&out,
)?;
update("jay-config/src/input/input_event_codes.rs", &out)?;
}
Ok(())
}
19 changes: 5 additions & 14 deletions codegen/src/keysyms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,12 @@ pub fn main() -> Result<()> {
}
syms.sort_by_key(|s| s.0);
let mut res = String::new();
writeln!(res, r#"use super::KeySym;"#)?;
writeln!(res)?;
define_w!(res);
wl!(r#"use super::KeySym;"#);
wl!();
for (name, sym) in syms {
writeln!(
res,
r#"pub const SYM_{name}: KeySym = KeySym(0x{:x});"#,
sym.0
)?;
wl!(r#"pub const SYM_{name}: KeySym = KeySym(0x{:x});"#, sym.0);
}
update(
concat!(
env!("CARGO_MANIFEST_DIR"),
"/../jay-config/src/keyboard/syms/generated.rs",
),
&res,
)?;
update("jay-config/src/keyboard/syms/generated.rs", &res)?;
Ok(())
}
75 changes: 56 additions & 19 deletions codegen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,30 @@

use {
crate::phf::PhfHash,
anyhow::Result,
anyhow::{Context, Result, bail},
permutation::Permutation,
std::{fmt::Debug, io},
std::{fmt::Debug, io::Write, path::PathBuf, process::Command},
};

macro_rules! define_w {
($w:ident) => {
define_w!($w, $);
};
($w:ident, $dol:tt) => {
#[allow(unused_macros)]
macro_rules! w {
($dol($arg:tt)*) => {
write!($w, $dol($arg)*)?;
};
}
macro_rules! wl {
($dol($arg:tt)*) => {
writeln!($w, $dol($arg)*)?;
};
}
};
}

mod input_event_codes;
mod keysyms;
#[path = "../../toml-config/src/phf.rs"]
Expand All @@ -30,31 +49,49 @@ fn generate_map(
let state = phf_generator::generate_hash(keys);
Permutation::oneline(state.map).apply_inv_slice_in_place(values);
let mut res = String::new();
writeln!(
res,
"pub(super) static {name}: PhfMap<{key_type}, {value_type}> = PhfMap {{"
)?;
writeln!(res, " key: {},", state.key)?;
writeln!(res, " disps: &[")?;
define_w!(res);
wl!("pub(super) static {name}: PhfMap<{key_type}, {value_type}> = PhfMap {{");
wl!(" key: {},", state.key);
wl!(" disps: &[");
for disp in state.disps {
writeln!(res, " {disp:?},")?;
wl!(" {disp:?},");
}
writeln!(res, " ],")?;
writeln!(res, " map: &[")?;
wl!(" ],");
wl!(" map: &[");
for value in values {
writeln!(res, " {value:?},")?;
wl!(" {value:?},");
}
writeln!(res, " ],")?;
writeln!(res, " _phantom: core::marker::PhantomData,")?;
writeln!(res, "}};")?;
wl!(" ],");
wl!(" _phantom: core::marker::PhantomData,");
wl!("}};");
Ok(res)
}

fn update(file: &str, data: &str) -> io::Result<()> {
if let Ok(current) = std::fs::read_to_string(file)
&& current == data
fn update(relative: &str, raw: &str) -> Result<()> {
let mut absolute = PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/.."));
absolute.push(relative);

let formatted = {
let dir = absolute.parent().context("file path has no parent")?;
let mut tmp = tempfile::Builder::default().tempfile_in(dir)?;
tmp.write_all(raw.as_bytes())?;
let status = Command::new("rustfmt")
.arg("+nightly")
.arg("--edition=2024")
.arg(tmp.path())
.status()?;
if !status.success() {
bail!("rustfmt failed");
}
std::fs::read_to_string(&tmp)?
};

if let Ok(current) = std::fs::read_to_string(&absolute)
&& current == formatted
{
return Ok(());
}
std::fs::write(file, data)
std::fs::write(&absolute, formatted)?;

Ok(())
}
Loading
Loading