@@ -949,11 +949,11 @@ impl Workspace {
&mut self,
cx: &mut ViewContext<Self>,
app_state: Arc<AppState>,
- mut callback: F,
+ callback: F,
) -> T
where
T: 'static,
- F: FnMut(&mut Workspace, &mut ViewContext<Workspace>) -> T,
+ F: FnOnce(&mut Workspace, &mut ViewContext<Workspace>) -> T,
{
if self.project.read(cx).is_local() {
callback(self, cx)
@@ -57,6 +57,7 @@ fn main() {
fs::create_dir_all(&logs_dir_path).expect("could not create logs path");
init_logger(&logs_dir_path);
+ log::info!("========== starting zed ==========");
let mut app = gpui::App::new(Assets).unwrap();
let app_version = ZED_APP_VERSION
.or_else(|| app.platform().app_version().ok())
@@ -210,6 +211,13 @@ fn init_logger(logs_dir_path: &Path) {
} else {
let level = LevelFilter::Info;
let log_file_path = logs_dir_path.join("Zed.log");
+
+ // Prevent log file from becoming too large.
+ const MAX_LOG_BYTES: u64 = 1 * 1024 * 1024;
+ if fs::metadata(&log_file_path).map_or(false, |metadata| metadata.len() > MAX_LOG_BYTES) {
+ let _ = fs::rename(&log_file_path, logs_dir_path.join("Zed.log.old"));
+ }
+
let log_file = OpenOptions::new()
.create(true)
.append(true)
@@ -9,6 +9,7 @@ use anyhow::{anyhow, Context, Result};
use assets::Assets;
use breadcrumbs::Breadcrumbs;
pub use client;
+use collections::VecDeque;
pub use contacts_panel;
use contacts_panel::ContactsPanel;
pub use editor;
@@ -52,6 +53,7 @@ actions!(
Quit,
DebugElements,
OpenSettings,
+ OpenLog,
OpenKeymap,
OpenDefaultSettings,
OpenDefaultKeymap,
@@ -65,9 +67,11 @@ actions!(
const MIN_FONT_SIZE: f32 = 6.0;
lazy_static! {
- pub static ref ROOT_PATH: PathBuf = dirs::home_dir()
- .expect("failed to determine home directory")
- .join(".zed");
+ pub static ref HOME_PATH: PathBuf =
+ dirs::home_dir().expect("failed to determine home directory");
+ pub static ref LOG_PATH: PathBuf = HOME_PATH.join("Library/Logs/Zed/Zed.log");
+ pub static ref OLD_LOG_PATH: PathBuf = HOME_PATH.join("Library/Logs/Zed/Zed.log.old");
+ pub static ref ROOT_PATH: PathBuf = HOME_PATH.join(".zed");
pub static ref SETTINGS_PATH: PathBuf = ROOT_PATH.join("settings.json");
pub static ref KEYMAP_PATH: PathBuf = ROOT_PATH.join("keymap.json");
}
@@ -120,6 +124,12 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
});
}
});
+ cx.add_action({
+ let app_state = app_state.clone();
+ move |workspace: &mut Workspace, _: &OpenLog, cx: &mut ViewContext<Workspace>| {
+ open_log_file(workspace, app_state.clone(), cx);
+ }
+ });
cx.add_action({
let app_state = app_state.clone();
move |_: &mut Workspace, _: &OpenKeymap, cx: &mut ViewContext<Workspace>| {
@@ -407,6 +417,60 @@ fn open_config_file(
.detach_and_log_err(cx)
}
+fn open_log_file(
+ workspace: &mut Workspace,
+ app_state: Arc<AppState>,
+ cx: &mut ViewContext<Workspace>,
+) {
+ const MAX_LINES: usize = 1000;
+
+ workspace.with_local_workspace(cx, app_state.clone(), |_, cx| {
+ cx.spawn_weak(|workspace, mut cx| async move {
+ let (old_log, new_log) = futures::join!(
+ app_state.fs.load(&OLD_LOG_PATH),
+ app_state.fs.load(&LOG_PATH)
+ );
+
+ if let Some(workspace) = workspace.upgrade(&cx) {
+ let mut lines = VecDeque::with_capacity(MAX_LINES);
+ for line in old_log
+ .iter()
+ .flat_map(|log| log.lines())
+ .chain(new_log.iter().flat_map(|log| log.lines()))
+ {
+ if lines.len() == MAX_LINES {
+ lines.pop_front();
+ }
+ lines.push_back(line);
+ }
+ let log = lines
+ .into_iter()
+ .flat_map(|line| [line, "\n"])
+ .collect::<String>();
+
+ workspace.update(&mut cx, |workspace, cx| {
+ let project = workspace.project().clone();
+ let buffer = project
+ .update(cx, |project, cx| project.create_buffer("", None, cx))
+ .expect("creating buffers on a local workspace always succeeds");
+ buffer.update(cx, |buffer, cx| buffer.edit([(0..0, log)], cx));
+
+ let buffer = cx.add_model(|cx| {
+ MultiBuffer::singleton(buffer, cx).with_title("Log".into())
+ });
+ workspace.add_item(
+ Box::new(
+ cx.add_view(|cx| Editor::for_multibuffer(buffer, Some(project), cx)),
+ ),
+ cx,
+ );
+ });
+ }
+ })
+ .detach();
+ });
+}
+
fn open_bundled_config_file(
workspace: &mut Workspace,
app_state: Arc<AppState>,