oxwm

https://git.tonybtw.com/oxwm.git git://git.tonybtw.com/oxwm.git
4,890 bytes raw
1
use std::path::PathBuf;
2
3
fn main() -> Result<(), Box<dyn std::error::Error>> {
4
    let arguments: Vec<String> = std::env::args().collect();
5
6
    let mut custom_config_path: Option<PathBuf> = None;
7
8
    match arguments.get(1).map(|string| string.as_str()) {
9
        Some("--version") => {
10
            println!("oxwm {}", env!("CARGO_PKG_VERSION"));
11
            return Ok(());
12
        }
13
        Some("--help") => {
14
            print_help();
15
            return Ok(());
16
        }
17
        Some("--init") => {
18
            init_config()?;
19
            return Ok(());
20
        }
21
        Some("--config") => {
22
            if let Some(path) = arguments.get(2) {
23
                custom_config_path = Some(PathBuf::from(path));
24
            } else {
25
                eprintln!("Error: --config requires a path argument");
26
                std::process::exit(1);
27
            }
28
        }
29
        _ => {}
30
    }
31
32
    let (config, had_broken_config) = load_config(custom_config_path)?;
33
34
    let mut window_manager = oxwm::window_manager::WindowManager::new(config)?;
35
36
    if had_broken_config {
37
        window_manager.show_migration_overlay();
38
    }
39
40
    let should_restart = window_manager.run()?;
41
42
    drop(window_manager);
43
44
    if should_restart {
45
        use std::os::unix::process::CommandExt;
46
        let error = std::process::Command::new(&arguments[0])
47
            .args(&arguments[1..])
48
            .exec();
49
        eprintln!("Failed to restart: {}", error);
50
    }
51
52
    Ok(())
53
}
54
55
fn load_config(
56
    custom_path: Option<PathBuf>,
57
) -> Result<(oxwm::Config, bool), Box<dyn std::error::Error>> {
58
    let config_path = if let Some(path) = custom_path {
59
        path
60
    } else {
61
        let config_directory = get_config_path();
62
        let lua_path = config_directory.join("config.lua");
63
64
        if !lua_path.exists() {
65
            let ron_path = config_directory.join("config.ron");
66
            let had_ron_config = ron_path.exists();
67
68
            println!("No config found at {:?}", config_directory);
69
            println!("Creating default Lua config...");
70
            init_config()?;
71
72
            if had_ron_config {
73
                println!("\n NOTICE: OXWM has migrated to Lua configuration.");
74
                println!("   Your old config.ron has been preserved, but is no longer used.");
75
                println!("   Your settings have been reset to defaults.");
76
                println!("   Please manually port your configuration to the new Lua format.");
77
                println!("   See the new config.lua template for examples.\n");
78
            }
79
        }
80
81
        lua_path
82
    };
83
84
    let config_string = std::fs::read_to_string(&config_path)
85
        .map_err(|error| format!("Failed to read config file: {}", error))?;
86
87
    let config_directory = config_path.parent();
88
89
    match oxwm::config::parse_lua_config(&config_string, config_directory) {
90
        Ok(mut config) => {
91
            config.path = Some(config_path);
92
            Ok((config, false))
93
        }
94
        Err(_error) => {
95
            let template = include_str!("../../templates/config.lua");
96
            let config = oxwm::config::parse_lua_config(template, None)
97
                .map_err(|error| format!("Failed to parse default template config: {}", error))?;
98
            Ok((config, true))
99
        }
100
    }
101
}
102
103
fn init_config() -> Result<(), Box<dyn std::error::Error>> {
104
    let config_directory = get_config_path();
105
    std::fs::create_dir_all(&config_directory)?;
106
107
    let config_template = include_str!("../../templates/config.lua");
108
    let config_path = config_directory.join("config.lua");
109
    std::fs::write(&config_path, config_template)?;
110
111
    println!("✓ Config created at {:?}", config_path);
112
    println!("  Edit the file and reload with Mod+Shift+R");
113
    println!("  No compilation needed - changes take effect immediately!");
114
115
    Ok(())
116
}
117
118
fn get_config_path() -> PathBuf {
119
    dirs::config_dir()
120
        .expect("Could not find config directory")
121
        .join("oxwm")
122
}
123
124
fn print_help() {
125
    println!("OXWM - A dynamic window manager written in Rust\n");
126
    println!("USAGE:");
127
    println!("    oxwm [OPTIONS]\n");
128
    println!("OPTIONS:");
129
    println!("    --init              Create default config in ~/.config/oxwm/config.lua");
130
    println!("    --config <PATH>     Use custom config file");
131
    println!("    --version           Print version information");
132
    println!("    --help              Print this help message\n");
133
    println!("CONFIG:");
134
    println!("    Location: ~/.config/oxwm/config.lua");
135
    println!("    Edit the config file and use Mod+Shift+R to reload");
136
    println!("    No compilation needed - instant hot-reload!");
137
    println!("    LSP support included with oxwm.lua type definitions\n");
138
    println!("FIRST RUN:");
139
    println!("    Run 'oxwm --init' to create a config file");
140
    println!("    Or just start oxwm and it will create one automatically\n");
141
}