save on proxy

This commit is contained in:
Dongdong Zhou 2020-11-23 18:08:06 +00:00
parent 37dcf757c2
commit 6c0084e164
6 changed files with 104 additions and 1 deletions

View File

@ -1,7 +1,9 @@
use std::collections::HashMap;
use anyhow::Result;
use druid::{Rect, Selector, Size, WidgetId};
use lsp_types::{Location, TextEdit};
use serde_json::Value;
use strum;
use strum_macros::{Display, EnumProperty, EnumString};
use tree_sitter_highlight::Highlight;
@ -186,6 +188,7 @@ pub enum LapceUICommand {
CloseBuffers(Vec<BufferId>),
RequestPaintRect(Rect),
ApplyEdits(usize, u64, Vec<TextEdit>),
ApplyEditsAndSave(usize, u64, Result<Value>),
UpdateHighlights(BufferId, u64, Vec<(usize, usize, Highlight)>),
CenterOfWindow,
UpdateLineChanges(BufferId),

View File

@ -50,6 +50,7 @@
};
use serde_json::Value;
use std::str::FromStr;
use std::sync::mpsc::channel;
use std::thread;
use std::{cmp::Ordering, iter::Iterator, path::PathBuf};
use std::{collections::HashMap, sync::Arc};
@ -1598,6 +1599,26 @@ pub fn request_layout(&self) {
);
}
pub fn apply_edits_and_save(
&mut self,
ctx: &mut EventCtx,
ui_state: &mut LapceUIState,
offset: usize,
rev: u64,
result: &Result<Value>,
) -> Option<()> {
if let Ok(res) = result {
let edits: Result<Vec<TextEdit>, serde_json::Error> =
serde_json::from_value(res.clone());
if let Ok(edits) = edits {
if edits.len() > 0 {
self.apply_edits(ctx, ui_state, rev, &edits);
}
}
}
None
}
pub fn apply_edits(
&mut self,
ctx: &mut EventCtx,
@ -2323,7 +2344,33 @@ pub fn run_command(
let editor = self.editors.get_mut(&self.active)?;
let buffer_id = editor.buffer_id.clone()?;
let buffer = self.buffers.get_mut(&buffer_id)?;
let window_id = self.window_id;
let tab_id = self.tab_id;
let rev = buffer.rev;
let offset = editor.selection.get_cursor_offset();
let state =
LAPCE_APP_STATE.get_tab_state(&self.window_id, &self.tab_id);
state
.clone()
.proxy
.lock()
.as_ref()
.unwrap()
.get_document_formatting(
buffer.id,
Box::new(move |result| {
let result = match result {
Ok(r) => Ok(r),
Err(e) => Err(anyhow!("{:?}", e)),
};
LAPCE_APP_STATE.submit_ui_command(
LapceUICommand::ApplyEditsAndSave(
offset, rev, result,
),
state.editor_split.lock().widget_id,
);
}),
);
// if let Some(edits) = {
// let state =

View File

@ -66,6 +66,16 @@ pub fn update(&self, buffer_id: BufferId, delta: &RopeDelta, rev: u64) {
)
}
pub fn save(&self, rev: u64, buffer_id: BufferId, f: Box<dyn Callback>) {
self.peer.send_rpc_request_async(
"save",
&json!({
"buffer_id": buffer_id,
}),
f,
);
}
pub fn get_completion(
&self,
request_id: usize,

View File

@ -205,6 +205,15 @@ fn event(
}
editor_split.apply_edits(ctx, data, *rev, edits);
}
LapceUICommand::ApplyEditsAndSave(offset, rev, result) => {
LAPCE_APP_STATE
.get_tab_state(&self.window_id, &self.tab_id)
.editor_split
.lock()
.apply_edits_and_save(
ctx, data, *offset, *rev, result,
);
}
LapceUICommand::GotoLocation(location) => {
let state = LAPCE_APP_STATE
.get_tab_state(&self.window_id, &self.tab_id);

View File

@ -1,9 +1,12 @@
use anyhow::Result;
use anyhow::{anyhow, Result};
use crossbeam_channel::Sender;
use std::borrow::Cow;
use std::ffi::OsString;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
use std::{fs, str::FromStr};
use lsp_types::*;
use serde::{Deserialize, Deserializer, Serialize};
@ -46,6 +49,28 @@ pub fn new(
}
}
pub fn save(&self, rev: u64) -> Result<()> {
if self.rev != rev {
return Err(anyhow!("not the right rev"));
}
let tmp_extension = self.path.extension().map_or_else(
|| OsString::from("swp"),
|ext| {
let mut ext = ext.to_os_string();
ext.push(".swp");
ext
},
);
let tmp_path = &self.path.with_extension(tmp_extension);
let mut f = File::create(tmp_path)?;
for chunk in self.rope.iter_chunks(..self.rope.len()) {
f.write_all(chunk.as_bytes())?;
}
fs::rename(tmp_path, &self.path)?;
Ok(())
}
pub fn update(
&mut self,
delta: &RopeDelta,

View File

@ -61,6 +61,10 @@ pub enum Request {
GetDocumentFormatting {
buffer_id: BufferId,
},
Save {
rev: u64,
buffer_id: BufferId,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -235,6 +239,11 @@ fn handle_request(&self, id: RequestId, rpc: Request) {
let buffer = buffers.get(&buffer_id).unwrap();
self.lsp.lock().get_document_formatting(id, buffer);
}
Request::Save { rev, buffer_id } => {
let buffers = self.buffers.lock();
let buffer = buffers.get(&buffer_id).unwrap();
self.respond(id, buffer.save(rev).map(|r| json!({})));
}
}
}
}