ZIm/crates/zed/src/main.rs
2021-12-21 12:05:38 +01:00

135 lines
4.5 KiB
Rust

// Allow binary to be called Zed for a nice application menu when running executable direcly
#![allow(non_snake_case)]
use client::{self, http, ChannelList, UserStore};
use fs::OpenOptions;
use gpui::AssetSource;
use log::LevelFilter;
use parking_lot::Mutex;
use simplelog::SimpleLogger;
use std::{fs, path::PathBuf, sync::Arc};
use theme::{ThemeRegistry, DEFAULT_THEME_NAME};
use workspace::{self, settings, AppState, OpenNew, OpenParams, OpenPaths, Settings};
use zed::{
self, assets::Assets, build_window_options, build_workspace, fs::RealFs, language, menus,
};
fn main() {
init_logger();
let app = gpui::App::new(Assets).unwrap();
let embedded_fonts = Assets
.list("fonts")
.into_iter()
.map(|f| Arc::new(Assets.load(&f).unwrap().to_vec()))
.collect::<Vec<_>>();
app.platform().fonts().add_fonts(&embedded_fonts).unwrap();
let themes = ThemeRegistry::new(Assets, app.font_cache());
let theme = themes.get(DEFAULT_THEME_NAME).unwrap();
let settings = Settings::new("Inconsolata", &app.font_cache(), theme)
.unwrap()
.with_overrides(
language::PLAIN_TEXT.name(),
settings::Override {
soft_wrap: Some(settings::SoftWrap::PreferredLineLength),
..Default::default()
},
)
.with_overrides(
"Markdown",
settings::Override {
soft_wrap: Some(settings::SoftWrap::PreferredLineLength),
..Default::default()
},
);
let (settings_tx, settings) = postage::watch::channel_with(settings);
let languages = Arc::new(language::build_language_registry());
languages.set_theme(&settings.borrow().theme.editor.syntax);
app.run(move |cx| {
let client = client::Client::new();
let http = http::client();
let user_store = cx.add_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
let mut entry_openers = Vec::new();
client::init(client.clone(), cx);
workspace::init(cx);
editor::init(cx, &mut entry_openers);
go_to_line::init(cx);
file_finder::init(cx);
chat_panel::init(cx);
project_panel::init(cx);
diagnostics::init(cx);
let app_state = Arc::new(AppState {
languages: languages.clone(),
settings_tx: Arc::new(Mutex::new(settings_tx)),
settings,
themes,
channel_list: cx
.add_model(|cx| ChannelList::new(user_store.clone(), client.clone(), cx)),
client,
user_store,
fs: Arc::new(RealFs),
entry_openers: Arc::from(entry_openers),
build_window_options: &build_window_options,
build_workspace: &build_workspace,
});
journal::init(app_state.clone(), cx);
zed::init(&app_state, cx);
theme_selector::init(app_state.as_ref().into(), cx);
cx.set_menus(menus::menus(&app_state.clone()));
if stdout_is_a_pty() {
cx.platform().activate(true);
}
let paths = collect_path_args();
if paths.is_empty() {
cx.dispatch_global_action(OpenNew(app_state.clone()));
} else {
cx.dispatch_global_action(OpenPaths(OpenParams { paths, app_state }));
}
});
}
fn init_logger() {
let level = LevelFilter::Info;
if stdout_is_a_pty() {
SimpleLogger::init(level, Default::default()).expect("could not initialize logger");
} else {
let log_dir_path = dirs::home_dir()
.expect("could not locate home directory for logging")
.join("Library/Logs/");
let log_file_path = log_dir_path.join("Zed.log");
fs::create_dir_all(&log_dir_path).expect("could not create log directory");
let log_file = OpenOptions::new()
.create(true)
.append(true)
.open(log_file_path)
.expect("could not open logfile");
simplelog::WriteLogger::init(level, simplelog::Config::default(), log_file)
.expect("could not initialize logger");
log_panics::init();
}
}
fn stdout_is_a_pty() -> bool {
unsafe { libc::isatty(libc::STDOUT_FILENO as i32) != 0 }
}
fn collect_path_args() -> Vec<PathBuf> {
std::env::args()
.skip(1)
.filter_map(|arg| match fs::canonicalize(arg) {
Ok(path) => Some(path),
Err(error) => {
log::error!("error parsing path argument: {}", error);
None
}
})
.collect::<Vec<_>>()
}