diff --git a/defaults/settings.toml b/defaults/settings.toml index 9cc244a6..c3c895bf 100644 --- a/defaults/settings.toml +++ b/defaults/settings.toml @@ -19,6 +19,7 @@ auto-closing-matching-pairs = true hover-delay = 300 # ms modal-mode-relative-line-numbers = true format-on-save = true +autosave-interval = 0 enable-inlay-hints = true inlay-hint-font-family = "" inlay-hint-font-size = 0 diff --git a/lapce-data/src/config.rs b/lapce-data/src/config.rs index 0e4e4b22..22a7006e 100644 --- a/lapce-data/src/config.rs +++ b/lapce-data/src/config.rs @@ -236,6 +236,10 @@ pub struct EditorConfig { desc = "How the editor should render whitespace characters.\nOptions: none, all, boundary, trailing." )] pub render_whitespace: String, + #[field_names( + desc = "Set the auto save delay (in milliseconds), Set to 0 to completely disable" + )] + pub autosave_interval: u64, } impl EditorConfig { diff --git a/lapce-ui/src/editor/view.rs b/lapce-ui/src/editor/view.rs index 323e4303..f546448c 100644 --- a/lapce-ui/src/editor/view.rs +++ b/lapce-ui/src/editor/view.rs @@ -42,6 +42,7 @@ pub struct LapceEditorView { pub editor: WidgetPod, pub find: Option>>>, cursor_blink_timer: TimerToken, + autosave_timer: TimerToken, last_idle_timer: TimerToken, display_border: bool, background_color_name: &'static str, @@ -94,6 +95,7 @@ pub fn new( editor: WidgetPod::new(editor), find, cursor_blink_timer: TimerToken::INVALID, + autosave_timer: TimerToken::INVALID, last_idle_timer: TimerToken::INVALID, display_border: true, background_color_name: LapceTheme::EDITOR_BACKGROUND, @@ -636,6 +638,39 @@ fn event( } } } + Event::Timer(id) if self.autosave_timer == *id => { + ctx.set_handled(); + if let Some(editor) = data + .main_split + .active + .and_then(|active| data.main_split.editors.get(&active)) + .cloned() + { + if data.config.editor.autosave_interval > 0 { + if ctx.is_focused() { + let doc = data.main_split.editor_doc(self.view_id); + if !doc.buffer().is_pristine() { + ctx.submit_command(Command::new( + LAPCE_COMMAND, + LapceCommand { + kind: CommandKind::Focus(FocusCommand::Save), + data: None, + }, + Target::Widget(editor.view_id), + )); + } + self.autosave_timer = ctx.request_timer( + Duration::from_millis( + data.config.editor.autosave_interval, + ), + None, + ); + } else { + self.cursor_blink_timer = TimerToken::INVALID; + } + } + } + } _ => {} } @@ -862,6 +897,15 @@ fn update( } } + if data.config.editor.autosave_interval > 0 + && editor_data.doc.rev() != old_editor_data.doc.rev() + { + self.autosave_timer = ctx.request_timer( + Duration::from_millis(data.config.editor.autosave_interval), + None, + ); + } + if old_data.config.lapce.modal != data.config.lapce.modal && !editor_data.doc.content().is_input() {