main.rs

 1// Allow binary to be called Zed for a nice application menu when running executable direcly
 2#![allow(non_snake_case)]
 3
 4use fs::OpenOptions;
 5use log::LevelFilter;
 6use simplelog::SimpleLogger;
 7use std::{fs, path::PathBuf};
 8use zed::{
 9    assets, editor, file_finder, menus, settings,
10    workspace::{self, OpenParams},
11};
12
13fn main() {
14    init_logger();
15
16    let app = gpui::App::new(assets::Assets).unwrap();
17    let (_, settings_rx) = settings::channel(&app.font_cache()).unwrap();
18    app.run(move |ctx| {
19        ctx.set_menus(menus::menus(settings_rx.clone()));
20        workspace::init(ctx);
21        editor::init(ctx);
22        file_finder::init(ctx);
23
24        if stdout_is_a_pty() {
25            ctx.platform().activate(true);
26        }
27
28        let paths = collect_path_args();
29        if !paths.is_empty() {
30            ctx.dispatch_global_action(
31                "workspace:open_paths",
32                OpenParams {
33                    paths,
34                    settings: settings_rx,
35                },
36            );
37        }
38    });
39}
40
41fn init_logger() {
42    let level = LevelFilter::Info;
43
44    if stdout_is_a_pty() {
45        SimpleLogger::init(level, Default::default()).expect("could not initialize logger");
46    } else {
47        let log_dir_path = dirs::home_dir()
48            .expect("could not locate home directory for logging")
49            .join("Library/Logs/");
50        let log_file_path = log_dir_path.join("Zed.log");
51        fs::create_dir_all(&log_dir_path).expect("could not create log directory");
52        let log_file = OpenOptions::new()
53            .create(true)
54            .append(true)
55            .open(log_file_path)
56            .expect("could not open logfile");
57        simplelog::WriteLogger::init(level, simplelog::Config::default(), log_file)
58            .expect("could not initialize logger");
59    }
60}
61
62fn stdout_is_a_pty() -> bool {
63    unsafe { libc::isatty(libc::STDOUT_FILENO as i32) != 0 }
64}
65
66fn collect_path_args() -> Vec<PathBuf> {
67    std::env::args()
68        .skip(1)
69        .filter_map(|arg| match fs::canonicalize(arg) {
70            Ok(path) => Some(path),
71            Err(error) => {
72                log::error!("error parsing path argument: {}", error);
73                None
74            }
75        })
76        .collect::<Vec<_>>()
77}