mirror of https://github.com/lapce/lapce.git
cleanup when tab is closed
This commit is contained in:
parent
b6a3c25529
commit
71cb0cd0af
|
@ -77,8 +77,6 @@ pub struct Buffer {
|
|||
highlight_names: Vec<String>,
|
||||
pub highlights: Vec<(usize, usize, Highlight)>,
|
||||
pub line_highlights: HashMap<usize, Vec<(usize, usize, String)>>,
|
||||
// pub highlight_version: String,
|
||||
// event_sink: ExtEventSink,
|
||||
undos: Vec<Vec<(RopeDelta, RopeDelta)>>,
|
||||
current_undo: usize,
|
||||
pub path: String,
|
||||
|
|
|
@ -165,6 +165,7 @@ pub enum LapceUICommand {
|
|||
NewTab,
|
||||
NextTab,
|
||||
PreviousTab,
|
||||
CloseBuffers(Vec<BufferId>),
|
||||
RequestPaintRect(Rect),
|
||||
ApplyEdits(u64, Vec<TextEdit>),
|
||||
UpdateHighlights(BufferId, u64, Vec<(usize, usize, Highlight)>),
|
||||
|
|
|
@ -756,6 +756,22 @@ pub struct EditorSplitState {
|
|||
pub diagnostics: HashMap<String, Vec<Diagnostic>>,
|
||||
}
|
||||
|
||||
impl Drop for EditorSplitState {
|
||||
fn drop(&mut self) {
|
||||
LAPCE_APP_STATE
|
||||
.ui_sink
|
||||
.lock()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::CloseBuffers(self.buffers.keys().cloned().collect()),
|
||||
Target::Window(self.window_id),
|
||||
);
|
||||
println!("now drop editor split state");
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorSplitState {
|
||||
pub fn new(window_id: WindowId, tab_id: WidgetId) -> EditorSplitState {
|
||||
let editor_split_id = WidgetId::next();
|
||||
|
@ -2154,6 +2170,12 @@ pub struct EditorView {
|
|||
header: WidgetPod<LapceUIState, Box<dyn Widget<LapceUIState>>>,
|
||||
}
|
||||
|
||||
impl Drop for EditorView {
|
||||
fn drop(&mut self) {
|
||||
println!("now drop editor view");
|
||||
}
|
||||
}
|
||||
|
||||
impl EditorView {
|
||||
pub fn new(
|
||||
window_id: WindowId,
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
io::BufWriter,
|
||||
io::Write,
|
||||
process::Command,
|
||||
process::{self, Stdio},
|
||||
process::{self, Child, Stdio},
|
||||
sync::mpsc::{channel, Receiver},
|
||||
sync::Arc,
|
||||
thread,
|
||||
|
@ -48,12 +48,23 @@ pub enum LspHeader {
|
|||
ContentLength(usize),
|
||||
}
|
||||
|
||||
pub enum LspProcess {
|
||||
Child(Child),
|
||||
SshSession(SshSession),
|
||||
}
|
||||
|
||||
pub struct LspCatalog {
|
||||
window_id: WindowId,
|
||||
tab_id: WidgetId,
|
||||
clients: HashMap<String, Arc<Mutex<LspClient>>>,
|
||||
}
|
||||
|
||||
impl Drop for LspCatalog {
|
||||
fn drop(&mut self) {
|
||||
println!("now drop lsp catalog");
|
||||
}
|
||||
}
|
||||
|
||||
impl LspCatalog {
|
||||
pub fn new(window_id: WindowId, tab_id: WidgetId) -> LspCatalog {
|
||||
LspCatalog {
|
||||
|
@ -63,6 +74,19 @@ pub fn new(window_id: WindowId, tab_id: WidgetId) -> LspCatalog {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn stop(&self) {
|
||||
for (_, client) in self.clients.iter() {
|
||||
match &mut client.lock().process {
|
||||
LspProcess::Child(child) => {
|
||||
child.kill();
|
||||
}
|
||||
LspProcess::SshSession(ssh_session) => {
|
||||
ssh_session.session.disconnect(None, "closing down", None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_server(
|
||||
&mut self,
|
||||
exec_path: &str,
|
||||
|
@ -203,6 +227,7 @@ pub struct LspClient {
|
|||
next_id: u64,
|
||||
pending: HashMap<u64, Callback>,
|
||||
options: Option<Value>,
|
||||
process: LspProcess,
|
||||
pub server_capabilities: Option<ServerCapabilities>,
|
||||
pub opened_documents: HashMap<BufferId, Url>,
|
||||
pub is_initialized: bool,
|
||||
|
@ -222,12 +247,14 @@ pub fn new(
|
|||
.expect("Error Occurred");
|
||||
|
||||
let writer = Box::new(BufWriter::new(process.stdin.take().unwrap()));
|
||||
let stdout = process.stdout.take().unwrap();
|
||||
|
||||
let lsp_client = Arc::new(Mutex::new(LspClient {
|
||||
window_id,
|
||||
tab_id,
|
||||
writer,
|
||||
next_id: 0,
|
||||
process: LspProcess::Child(process),
|
||||
pending: HashMap::new(),
|
||||
server_capabilities: None,
|
||||
opened_documents: HashMap::new(),
|
||||
|
@ -236,16 +263,16 @@ pub fn new(
|
|||
}));
|
||||
|
||||
let local_lsp_client = lsp_client.clone();
|
||||
let mut stdout = process.stdout;
|
||||
thread::spawn(move || {
|
||||
let mut reader = Box::new(BufReader::new(stdout.take().unwrap()));
|
||||
let mut reader = Box::new(BufReader::new(stdout));
|
||||
loop {
|
||||
match read_message(&mut reader) {
|
||||
Ok(message_str) => {
|
||||
local_lsp_client.lock().handle_message(message_str.as_ref());
|
||||
}
|
||||
Err(err) => {
|
||||
// eprintln!("Error occurred {:?}", err);
|
||||
eprintln!("lsp read Error occurred {:?}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -266,6 +293,7 @@ pub fn new_ssh(
|
|||
ssh_session.channel_exec(&mut channel, exec_path)?;
|
||||
println!("lsp {}", exec_path);
|
||||
let writer = Box::new(ssh_session.get_stream(&channel));
|
||||
let reader = ssh_session.get_stream(&channel);
|
||||
let lsp_client = Arc::new(Mutex::new(LspClient {
|
||||
window_id,
|
||||
tab_id,
|
||||
|
@ -273,6 +301,7 @@ pub fn new_ssh(
|
|||
next_id: 0,
|
||||
pending: HashMap::new(),
|
||||
server_capabilities: None,
|
||||
process: LspProcess::SshSession(ssh_session),
|
||||
opened_documents: HashMap::new(),
|
||||
is_initialized: false,
|
||||
options,
|
||||
|
@ -281,8 +310,7 @@ pub fn new_ssh(
|
|||
let local_lsp_client = lsp_client.clone();
|
||||
// let reader = ssh_session.get_async_stream(channel.stream(0))?;
|
||||
thread::spawn(move || {
|
||||
let mut reader =
|
||||
Box::new(BufReader::new(ssh_session.get_stream(&channel)));
|
||||
let mut reader = Box::new(BufReader::new(reader));
|
||||
loop {
|
||||
match read_message(&mut reader) {
|
||||
Ok(message_str) => {
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
#[derive(Eq, PartialEq, Hash, Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct PluginId(pub usize);
|
||||
|
||||
pub enum PluginProcess {
|
||||
Child(Child),
|
||||
SshSession(SshSession),
|
||||
}
|
||||
|
||||
pub struct PluginCatalog {
|
||||
window_id: WindowId,
|
||||
tab_id: WidgetId,
|
||||
|
@ -42,6 +47,12 @@ pub struct PluginCatalog {
|
|||
running: Vec<Plugin>,
|
||||
}
|
||||
|
||||
impl Drop for PluginCatalog {
|
||||
fn drop(&mut self) {
|
||||
println!("now drop plugin catalog");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PluginHandler {
|
||||
window_id: WindowId,
|
||||
tab_id: WidgetId,
|
||||
|
@ -59,7 +70,7 @@ pub struct Plugin {
|
|||
peer: RpcPeer,
|
||||
id: PluginId,
|
||||
name: String,
|
||||
// process: Child,
|
||||
process: PluginProcess,
|
||||
}
|
||||
|
||||
impl Drop for Plugin {
|
||||
|
@ -160,6 +171,19 @@ pub fn load_from_paths(&mut self, paths: &[PathBuf]) -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn stop(&mut self) {
|
||||
for plugin in self.running.iter_mut() {
|
||||
match &mut plugin.process {
|
||||
PluginProcess::Child(child) => {
|
||||
child.kill();
|
||||
}
|
||||
PluginProcess::SshSession(ssh) => {
|
||||
ssh.session.disconnect(None, "closing down", None);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_all(&mut self) -> Result<()> {
|
||||
let state = LAPCE_APP_STATE.get_tab_state(&self.window_id, &self.tab_id);
|
||||
let workspace_type = state.workspace.lock().kind.clone();
|
||||
|
@ -299,9 +323,10 @@ fn start_plugin_ssh(
|
|||
let mut looper = RpcLoop::new(ssh_session.get_stream(&channel));
|
||||
let peer: RpcPeer = Box::new(looper.get_raw_peer());
|
||||
let name = plugin_desc.name.clone();
|
||||
let read_stream = ssh_session.get_stream(&channel);
|
||||
let plugin = Plugin {
|
||||
peer,
|
||||
//process: child,
|
||||
process: PluginProcess::SshSession(ssh_session),
|
||||
name,
|
||||
id,
|
||||
};
|
||||
|
@ -313,10 +338,7 @@ fn start_plugin_ssh(
|
|||
|
||||
// let reader = ssh_session.get_async_stream(channel.stream(0))?;
|
||||
let mut handler = PluginHandler { window_id, tab_id };
|
||||
if let Err(e) = looper.mainloop(
|
||||
|| BufReader::new(ssh_session.get_stream(&channel)),
|
||||
&mut handler,
|
||||
) {
|
||||
if let Err(e) = looper.mainloop(|| BufReader::new(read_stream), &mut handler) {
|
||||
println!("plugin main loop failed {} {:?}", e, plugin_desc.dir);
|
||||
}
|
||||
println!("plugin main loop exit {:?}", plugin_desc.dir);
|
||||
|
@ -355,7 +377,7 @@ fn start_plugin_process(
|
|||
let name = plugin_desc.name.clone();
|
||||
let plugin = Plugin {
|
||||
peer,
|
||||
//process: child,
|
||||
process: PluginProcess::Child(child),
|
||||
name,
|
||||
id,
|
||||
};
|
||||
|
|
|
@ -333,6 +333,11 @@ pub fn new(window_id: WindowId) -> LapceTabState {
|
|||
state
|
||||
}
|
||||
|
||||
pub fn stop(&self) {
|
||||
self.plugins.lock().stop();
|
||||
self.lsp.lock().stop();
|
||||
}
|
||||
|
||||
pub fn start_plugin(&self) {
|
||||
let mut plugins = self.plugins.lock();
|
||||
plugins.reload_from_paths(&[PathBuf::from_str("./lsp").unwrap()]);
|
||||
|
|
|
@ -45,6 +45,19 @@ pub fn new(window_id: WindowId, tab_id: WidgetId) -> LapceTab {
|
|||
}
|
||||
}
|
||||
|
||||
impl Drop for LapceTab {
|
||||
fn drop(&mut self) {
|
||||
println!("now drop tab");
|
||||
let state = LAPCE_APP_STATE.get_tab_state(&self.window_id, &self.tab_id);
|
||||
state.stop();
|
||||
LAPCE_APP_STATE
|
||||
.get_window_state(&self.window_id)
|
||||
.states
|
||||
.lock()
|
||||
.remove(&self.tab_id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget<LapceUIState> for LapceTab {
|
||||
fn event(
|
||||
&mut self,
|
||||
|
@ -184,6 +197,11 @@ fn event(
|
|||
_ if cmd.is(LAPCE_UI_COMMAND) => {
|
||||
let command = cmd.get_unchecked(LAPCE_UI_COMMAND);
|
||||
match command {
|
||||
LapceUICommand::CloseBuffers(buffer_ids) => {
|
||||
for buffer_id in buffer_ids {
|
||||
Arc::make_mut(&mut data.buffers).remove(buffer_id);
|
||||
}
|
||||
}
|
||||
LapceUICommand::NewTab => {
|
||||
let state = LapceTabState::new(self.window_id.clone());
|
||||
for (_, editor) in
|
||||
|
@ -229,7 +247,7 @@ fn event(
|
|||
};
|
||||
let new_active = self.tabs[new_index].widget().tab_id;
|
||||
self.tabs.remove(index);
|
||||
window_state.states.lock().remove(&active);
|
||||
//window_state.states.lock().remove(&active);
|
||||
*active = new_active;
|
||||
ctx.request_layout();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue