main.rs

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