on master help sign in
Save command
3f707c1Blaž Hrastnik
Cargo.lock+1
@@ -523,6 +523,7 @@ dependencies = [
523 "crossterm",
523 "crossterm",
524 "helix-core",
524 "helix-core",
525 "once_cell",
525 "once_cell",
526+ "smol",
526 "tui",
527 "tui",
527 "url",
528 "url",
528]
529]
helix-term/src/main.rs+3−9
@@ -70,16 +70,10 @@ fn main() -> Result<(), Error> {
70 std::thread::spawn(move || smol::block_on(EX.run(smol::future::pending::<()>())));
70 std::thread::spawn(move || smol::block_on(EX.run(smol::future::pending::<()>())));
71 }
71 }
72
72
73− // let mut lsp = helix_lsp::Client::start(&EX, "rust-analyzer", &[]);
73+ let mut app = Application::new(args, &EX).unwrap();
74
74
75+ // we use the thread local executor to spawn the application task separately from the work pool
75− smol::block_on(async {
76+ smol::block_on(app.run());
76− // let res = lsp.initialize().await;
77− // let state = helix_core::State::load("test.rs".into(), &[]).unwrap();
78− // let res = lsp.text_document_did_open(&state).await;
79− // loop {}
80−
81− Application::new(args, &EX).unwrap().run().await;
82− });
83
77
84 Ok(())
78 Ok(())
85}
79}
helix-view/Cargo.toml+2
@@ -20,3 +20,5 @@ tui = { git = "https://github.com/fdehau/tui-rs", default-features = false, feat
20crossterm = { version = "0.18", features = ["event-stream"], optional = true}
20crossterm = { version = "0.18", features = ["event-stream"], optional = true}
21once_cell = "1.4"
21once_cell = "1.4"
22url = "2"
22url = "2"
23+
24+smol = "1"
helix-view/src/commands.rs+10−2
@@ -331,8 +331,7 @@ pub fn append_mode(cx: &mut Context) {
331}
331}
332
332
333// TODO: I, A, o and O can share a lot of the primitives.
333// TODO: I, A, o and O can share a lot of the primitives.
334−
335−pub fn command_mode(_view: &mut View, _count: usize) {
334+pub fn command_mode(_cx: &mut Context) {
336 unimplemented!()
335 unimplemented!()
337}
336}
338
337
@@ -670,3 +669,12 @@ pub fn indent_selection(_cx: &mut Context) {
670 // loop over each line and recompute proper indentation
669 // loop over each line and recompute proper indentation
671 unimplemented!()
670 unimplemented!()
672}
671}
672+
673+//
674+
675+pub fn save(cx: &mut Context) {
676+ // Spawns an async task to actually do the saving. This way we prevent blocking.
677+
678+ // TODO: handle save errors somehow?
679+ cx.executor.spawn(cx.view.doc.save()).detach();
680+}
helix-view/src/document.rs+25
@@ -1,4 +1,5 @@
1use anyhow::Error;
1use anyhow::Error;
2+use std::future::Future;
2use std::path::PathBuf;
3use std::path::PathBuf;
3
4
4use helix_core::{
5use helix_core::{
@@ -97,6 +98,30 @@ impl Document {
97 Ok(doc)
98 Ok(doc)
98 }
99 }
99
100
101+ pub fn save(&self) -> impl Future<Output = Result<(), anyhow::Error>> {
102+ // we clone and move text + path into the future so that we asynchronously save the current
103+ // state without blocking any further edits.
104+
105+ let text = self.text().clone();
106+ let path = self.path.clone().expect("Can't save with no path set!"); // TODO: handle no path
107+
108+ // TODO: mark changes up to now as saved
109+ // TODO: mark dirty false
110+
111+ async move {
112+ use smol::{fs::File, prelude::*};
113+ let mut file = File::create(path).await?;
114+
115+ // write all the rope chunks to file
116+ for chunk in text.chunks() {
117+ file.write_all(chunk.as_bytes()).await?;
118+ }
119+ // TODO: flush?
120+
121+ Ok(())
122+ } // and_then(// lsp.send_text_saved_notification())
123+ }
124+
100 pub fn set_language(&mut self, scope: &str, scopes: &[String]) {
125 pub fn set_language(&mut self, scope: &str, scopes: &[String]) {
101 if let Some(language_config) = LOADER.language_config_for_scope(scope) {
126 if let Some(language_config) = LOADER.language_config_for_scope(scope) {
102 let highlight_config = language_config.highlight_config(scopes).unwrap().unwrap();
127 let highlight_config = language_config.highlight_config(scopes).unwrap().unwrap();