mirror of https://github.com/lapce/lapce.git
improve file explorer watch
This commit is contained in:
parent
510274f3a9
commit
6380a4dfa4
|
@ -383,7 +383,7 @@ pub enum LapceUICommand {
|
|||
FilterKeymaps(String, Arc<Vec<KeyMap>>, Arc<Vec<LapceCommand>>),
|
||||
UpdatePickerPwd(PathBuf),
|
||||
UpdatePickerItems(PathBuf, HashMap<PathBuf, FileNodeItem>),
|
||||
UpdateExplorerItems(usize, PathBuf, Vec<FileNodeItem>),
|
||||
UpdateExplorerItems(PathBuf, HashMap<PathBuf, FileNodeItem>, bool),
|
||||
UpdateInstalledPlugins(HashMap<String, PluginDescription>),
|
||||
UpdatePluginDescriptions(Vec<PluginDescription>),
|
||||
RequestLayout,
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
selection::Selection,
|
||||
};
|
||||
use lapce_rpc::{
|
||||
file::FileNodeItem, plugin::PluginDescription, source_control::FileDiff,
|
||||
terminal::TermId,
|
||||
plugin::PluginDescription, source_control::FileDiff, terminal::TermId,
|
||||
};
|
||||
use lsp_types::{
|
||||
CodeActionOrCommand, Diagnostic, Position, ProgressToken, TextEdit,
|
||||
|
@ -1039,37 +1038,12 @@ pub fn run_workbench_command(
|
|||
if let Some(node) = picker.root.get_file_node(&picker.pwd) {
|
||||
if !node.read {
|
||||
let tab_id = self.id;
|
||||
let path = node.path_buf.clone();
|
||||
let event_sink = ctx.get_external_handle();
|
||||
self.proxy.read_dir(
|
||||
FilePickerData::read_dir(
|
||||
&node.path_buf,
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let resp: Result<
|
||||
Vec<FileNodeItem>,
|
||||
serde_json::Error,
|
||||
> = serde_json::from_value(res);
|
||||
if let Ok(items) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdatePickerItems(
|
||||
path,
|
||||
items
|
||||
.iter()
|
||||
.map(|item| {
|
||||
(
|
||||
item.path_buf
|
||||
.clone(),
|
||||
item.clone(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
tab_id,
|
||||
&self.proxy,
|
||||
event_sink,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1110,37 +1084,12 @@ pub fn run_workbench_command(
|
|||
if let Some(node) = picker.root.get_file_node(&picker.pwd) {
|
||||
if !node.read {
|
||||
let tab_id = self.id;
|
||||
let path = node.path_buf.clone();
|
||||
let event_sink = ctx.get_external_handle();
|
||||
self.proxy.read_dir(
|
||||
FilePickerData::read_dir(
|
||||
&node.path_buf,
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let resp: Result<
|
||||
Vec<FileNodeItem>,
|
||||
serde_json::Error,
|
||||
> = serde_json::from_value(res);
|
||||
if let Ok(items) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdatePickerItems(
|
||||
path,
|
||||
items
|
||||
.iter()
|
||||
.map(|item| {
|
||||
(
|
||||
item.path_buf
|
||||
.clone(),
|
||||
item.clone(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
tab_id,
|
||||
&self.proxy,
|
||||
event_sink,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1668,30 +1617,7 @@ pub fn read_picker_pwd(&mut self, ctx: &mut EventCtx) {
|
|||
let path = self.picker.pwd.clone();
|
||||
let event_sink = ctx.get_external_handle();
|
||||
let tab_id = self.id;
|
||||
self.proxy.read_dir(
|
||||
&path.clone(),
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let resp: Result<Vec<FileNodeItem>, serde_json::Error> =
|
||||
serde_json::from_value(res);
|
||||
if let Ok(items) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdatePickerItems(
|
||||
path,
|
||||
items
|
||||
.iter()
|
||||
.map(|item| {
|
||||
(item.path_buf.clone(), item.clone())
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
FilePickerData::read_dir(&path, tab_id, &self.proxy, event_sink);
|
||||
}
|
||||
|
||||
pub fn set_picker_pwd(&mut self, pwd: PathBuf) {
|
||||
|
@ -1729,27 +1655,39 @@ pub fn set_picker_pwd(&mut self, pwd: PathBuf) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn handle_file_change(&mut self, event: ¬ify::Event) {
|
||||
if let Some(workspace) =
|
||||
Arc::make_mut(&mut self.file_explorer).workspace.as_mut()
|
||||
{
|
||||
pub fn handle_file_change(&mut self, ctx: &mut EventCtx, event: ¬ify::Event) {
|
||||
if self.file_explorer.workspace.is_some() {
|
||||
match &event.kind {
|
||||
notify::EventKind::Create(creat_kind) => {
|
||||
notify::EventKind::Create(_)
|
||||
| notify::EventKind::Modify(notify::event::ModifyKind::Name(_))
|
||||
| notify::EventKind::Remove(_) => {
|
||||
for path in event.paths.iter() {
|
||||
workspace.add_child(
|
||||
path,
|
||||
creat_kind == ¬ify::event::CreateKind::Folder,
|
||||
);
|
||||
}
|
||||
}
|
||||
notify::EventKind::Remove(_) => {
|
||||
for path in event.paths.iter() {
|
||||
workspace.remove_child(path);
|
||||
if let Some(path) = path.parent() {
|
||||
FileExplorerData::read_dir(
|
||||
path,
|
||||
false,
|
||||
self.id,
|
||||
&self.proxy,
|
||||
ctx.get_external_handle(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
// let doc = self
|
||||
// .main_split
|
||||
// .local_docs
|
||||
// .get_mut(&LocalBufferKind::Search)
|
||||
// .unwrap();
|
||||
// let pattern = doc.buffer().text().to_string();
|
||||
// ctx.submit_command(Command::new(
|
||||
// LAPCE_UI_COMMAND,
|
||||
// LapceUICommand::UpdateSearch(pattern),
|
||||
// Target::Widget(self.id),
|
||||
// ));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
use include_dir::{include_dir, Dir};
|
||||
use lapce_rpc::file::FileNodeItem;
|
||||
use lapce_rpc::proxy::ReadDirResponse;
|
||||
|
||||
use crate::data::LapceWorkspace;
|
||||
use crate::proxy::LapceProxy;
|
||||
|
@ -46,29 +47,9 @@ pub fn new(
|
|||
children: HashMap::new(),
|
||||
children_open_count: 0,
|
||||
});
|
||||
let index = 0;
|
||||
let path = path.clone();
|
||||
std::thread::spawn(move || {
|
||||
proxy.read_dir(
|
||||
&path.clone(),
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let resp: Result<Vec<FileNodeItem>, serde_json::Error> =
|
||||
serde_json::from_value(res);
|
||||
if let Ok(items) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdateExplorerItems(
|
||||
index,
|
||||
path.clone(),
|
||||
items,
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
Self::read_dir(&path, true, tab_id, &proxy, event_sink);
|
||||
});
|
||||
}
|
||||
Self {
|
||||
|
@ -133,6 +114,72 @@ pub fn get_node_mut(&mut self, path: &Path) -> Option<&mut FileNodeItem> {
|
|||
}
|
||||
Some(node)
|
||||
}
|
||||
|
||||
pub fn update_children(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
children: HashMap<PathBuf, FileNodeItem>,
|
||||
expand: bool,
|
||||
) -> Option<()> {
|
||||
let node = self.workspace.as_mut()?.get_file_node_mut(path)?;
|
||||
|
||||
let removed_paths: Vec<PathBuf> = node
|
||||
.children
|
||||
.keys()
|
||||
.filter(|p| !children.contains_key(*p))
|
||||
.map(PathBuf::from)
|
||||
.collect();
|
||||
for path in removed_paths {
|
||||
node.children.remove(&path);
|
||||
}
|
||||
|
||||
for (path, child) in children.into_iter() {
|
||||
if !node.children.contains_key(&path) {
|
||||
node.children.insert(child.path_buf.clone(), child);
|
||||
}
|
||||
}
|
||||
|
||||
node.read = true;
|
||||
if expand {
|
||||
node.open = true;
|
||||
}
|
||||
|
||||
for p in path.ancestors() {
|
||||
self.update_node_count(p);
|
||||
}
|
||||
|
||||
Some(())
|
||||
}
|
||||
|
||||
pub fn read_dir(
|
||||
path: &Path,
|
||||
expand: bool,
|
||||
tab_id: WidgetId,
|
||||
proxy: &LapceProxy,
|
||||
event_sink: ExtEventSink,
|
||||
) {
|
||||
let path = PathBuf::from(path);
|
||||
let local_path = path.clone();
|
||||
proxy.read_dir(
|
||||
&local_path,
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let path = path.clone();
|
||||
let resp: Result<ReadDirResponse, serde_json::Error> =
|
||||
serde_json::from_value(res);
|
||||
if let Ok(resp) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdateExplorerItems(
|
||||
path, resp.items, expand,
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_item_children(
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use druid::WidgetId;
|
||||
use lapce_rpc::file::FileNodeItem;
|
||||
use druid::{ExtEventSink, Target, WidgetId};
|
||||
use lapce_rpc::{file::FileNodeItem, proxy::ReadDirResponse};
|
||||
|
||||
use crate::{
|
||||
command::{LapceUICommand, LAPCE_UI_COMMAND},
|
||||
proxy::LapceProxy,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FilePickerData {
|
||||
|
@ -73,6 +78,33 @@ pub fn init_home(&mut self, home: &Path) {
|
|||
self.root = current_file_node;
|
||||
self.pwd = home.to_path_buf();
|
||||
}
|
||||
|
||||
pub fn read_dir(
|
||||
path: &Path,
|
||||
tab_id: WidgetId,
|
||||
proxy: &LapceProxy,
|
||||
event_sink: ExtEventSink,
|
||||
) {
|
||||
let path = PathBuf::from(path);
|
||||
let local_path = path.clone();
|
||||
proxy.read_dir(
|
||||
&local_path,
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let path = path.clone();
|
||||
let resp: Result<ReadDirResponse, serde_json::Error> =
|
||||
serde_json::from_value(res);
|
||||
if let Ok(resp) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdatePickerItems(path, resp.items),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FilePickerData {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
use lapce_rpc::buffer::{BufferHeadResponse, BufferId, NewBufferResponse};
|
||||
use lapce_rpc::core::CoreNotification;
|
||||
use lapce_rpc::file::FileNodeItem;
|
||||
use lapce_rpc::proxy::{ProxyNotification, ProxyRequest};
|
||||
use lapce_rpc::proxy::{ProxyNotification, ProxyRequest, ReadDirResponse};
|
||||
use lapce_rpc::source_control::{DiffInfo, FileDiff};
|
||||
use lapce_rpc::terminal::TermId;
|
||||
use lapce_rpc::{self, Call, RequestId, RpcObject};
|
||||
|
@ -95,12 +95,9 @@ fn handle_event(&mut self, event: notify::Result<notify::Event>) {
|
|||
notify::EventKind::Create(_)
|
||||
| notify::EventKind::Modify(_)
|
||||
| notify::EventKind::Remove(_) => {
|
||||
let notification =
|
||||
serde_json::to_value(&CoreNotification::FileChange {
|
||||
event,
|
||||
})
|
||||
.unwrap();
|
||||
self.send_rpc_notification(notification);
|
||||
self.send_rpc_notification(CoreNotification::FileChange {
|
||||
event,
|
||||
});
|
||||
|
||||
if let Some(workspace) = self.workspace.lock().clone() {
|
||||
if let Some(diff) = git_diff_new(&workspace) {
|
||||
|
@ -271,8 +268,28 @@ pub fn respond(&self, id: RequestId, result: Result<Value>) {
|
|||
let _ = self.sender.send(resp);
|
||||
}
|
||||
|
||||
pub fn send_rpc_notification(&self, notification: Value) {
|
||||
let _ = self.sender.send(notification);
|
||||
pub fn respond_rpc<T: serde::Serialize>(
|
||||
&self,
|
||||
id: RequestId,
|
||||
result: Result<T>,
|
||||
) {
|
||||
let mut resp = json!({ "id": id });
|
||||
match result {
|
||||
Ok(v) => resp["result"] = serde_json::to_value(v).unwrap(),
|
||||
Err(e) => {
|
||||
resp["error"] = json!({
|
||||
"code": 0,
|
||||
"message": format!("{}",e),
|
||||
})
|
||||
}
|
||||
}
|
||||
let _ = self.sender.send(resp);
|
||||
}
|
||||
|
||||
pub fn send_rpc_notification<T: serde::Serialize>(&self, notification: T) {
|
||||
let _ = self
|
||||
.sender
|
||||
.send(serde_json::to_value(notification).unwrap());
|
||||
}
|
||||
|
||||
pub fn send_notification(&self, method: &str, params: Value) {
|
||||
|
@ -510,21 +527,27 @@ fn handle_request(&self, id: RequestId, rpc: ProxyRequest) {
|
|||
.into_iter()
|
||||
.filter_map(|entry| {
|
||||
entry
|
||||
.map(|e| FileNodeItem {
|
||||
path_buf: e.path(),
|
||||
is_dir: e.path().is_dir(),
|
||||
open: false,
|
||||
read: false,
|
||||
children: HashMap::new(),
|
||||
children_open_count: 0,
|
||||
.map(|e| {
|
||||
(
|
||||
e.path(),
|
||||
FileNodeItem {
|
||||
path_buf: e.path(),
|
||||
is_dir: e.path().is_dir(),
|
||||
open: false,
|
||||
read: false,
|
||||
children: HashMap::new(),
|
||||
children_open_count: 0,
|
||||
},
|
||||
)
|
||||
})
|
||||
.ok()
|
||||
})
|
||||
.collect::<Vec<FileNodeItem>>();
|
||||
serde_json::to_value(items).unwrap()
|
||||
.collect::<HashMap<PathBuf, FileNodeItem>>();
|
||||
|
||||
ReadDirResponse { items }
|
||||
})
|
||||
.map_err(|e| anyhow!(e));
|
||||
local_dispatcher.respond(id, result);
|
||||
local_dispatcher.respond_rpc(id, result);
|
||||
});
|
||||
}
|
||||
GetFiles { .. } => {
|
||||
|
|
|
@ -110,15 +110,15 @@ pub fn get_file_node_mut(&mut self, path: &Path) -> Option<&mut FileNodeItem> {
|
|||
node
|
||||
}
|
||||
|
||||
pub fn remove_child(&mut self, path: &Path) -> Option<()> {
|
||||
pub fn remove_child(&mut self, path: &Path) -> Option<FileNodeItem> {
|
||||
let parent = path.parent()?;
|
||||
let node = self.get_file_node_mut(parent)?;
|
||||
node.children.remove(path)?;
|
||||
let node = node.children.remove(path)?;
|
||||
for p in path.ancestors() {
|
||||
self.update_node_count(p);
|
||||
}
|
||||
|
||||
Some(())
|
||||
Some(node)
|
||||
}
|
||||
|
||||
pub fn add_child(&mut self, path: &Path, is_dir: bool) -> Option<()> {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::path::PathBuf;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use lsp_types::{CompletionItem, Position};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use xi_rope::RopeDelta;
|
||||
|
||||
use crate::{
|
||||
buffer::BufferId, plugin::PluginDescription, source_control::FileDiff,
|
||||
terminal::TermId,
|
||||
buffer::BufferId, file::FileNodeItem, plugin::PluginDescription,
|
||||
source_control::FileDiff, terminal::TermId,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
@ -111,3 +111,8 @@ pub enum ProxyRequest {
|
|||
buffer_id: BufferId,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ReadDirResponse {
|
||||
pub items: HashMap<PathBuf, FileNodeItem>,
|
||||
}
|
||||
|
|
|
@ -411,27 +411,13 @@ fn event(
|
|||
node.open = !node.open;
|
||||
} else {
|
||||
let tab_id = data.id;
|
||||
let path = node.path_buf.clone();
|
||||
let event_sink = ctx.get_external_handle();
|
||||
data.proxy.read_dir(
|
||||
FileExplorerData::read_dir(
|
||||
&node.path_buf,
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let resp: Result<
|
||||
Vec<FileNodeItem>,
|
||||
serde_json::Error,
|
||||
> = serde_json::from_value(res);
|
||||
if let Ok(items) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdateExplorerItems(
|
||||
index, path, items,
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
true,
|
||||
tab_id,
|
||||
&data.proxy,
|
||||
event_sink,
|
||||
);
|
||||
}
|
||||
let path = node.path_buf.clone();
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
||||
|
||||
use druid::{
|
||||
kurbo::Line,
|
||||
|
@ -15,6 +11,7 @@
|
|||
command::{LapceUICommand, LAPCE_UI_COMMAND},
|
||||
config::{Config, LapceTheme},
|
||||
data::LapceTabData,
|
||||
picker::FilePickerData,
|
||||
};
|
||||
use lapce_rpc::file::FileNodeItem;
|
||||
|
||||
|
@ -26,131 +23,6 @@
|
|||
tab::LapceButton,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FilePickerData {
|
||||
pub widget_id: WidgetId,
|
||||
pub editor_view_id: WidgetId,
|
||||
pub active: bool,
|
||||
root: FileNodeItem,
|
||||
pub home: PathBuf,
|
||||
pub pwd: PathBuf,
|
||||
}
|
||||
|
||||
impl FilePickerData {
|
||||
pub fn new() -> Self {
|
||||
let root = FileNodeItem {
|
||||
path_buf: PathBuf::from("/"),
|
||||
is_dir: true,
|
||||
read: false,
|
||||
open: false,
|
||||
children: HashMap::new(),
|
||||
children_open_count: 0,
|
||||
};
|
||||
let home = PathBuf::from("/");
|
||||
let pwd = PathBuf::from("/");
|
||||
Self {
|
||||
widget_id: WidgetId::next(),
|
||||
editor_view_id: WidgetId::next(),
|
||||
active: false,
|
||||
root,
|
||||
home,
|
||||
pwd,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_item_children(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
children: HashMap<PathBuf, FileNodeItem>,
|
||||
) {
|
||||
if let Some(node) = self.get_file_node_mut(path) {
|
||||
node.open = true;
|
||||
node.read = true;
|
||||
node.children = children;
|
||||
}
|
||||
|
||||
for p in path.ancestors() {
|
||||
self.update_node_count(&PathBuf::from(p));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init_home(&mut self, home: &Path) {
|
||||
self.home = home.to_path_buf();
|
||||
let mut current_file_node = FileNodeItem {
|
||||
path_buf: home.to_path_buf(),
|
||||
is_dir: true,
|
||||
read: false,
|
||||
open: false,
|
||||
children: HashMap::new(),
|
||||
children_open_count: 0,
|
||||
};
|
||||
let mut current_path = home.to_path_buf();
|
||||
|
||||
let mut ancestors = home.ancestors();
|
||||
ancestors.next();
|
||||
|
||||
for p in ancestors {
|
||||
let mut file_node = FileNodeItem {
|
||||
path_buf: PathBuf::from(p),
|
||||
is_dir: true,
|
||||
read: false,
|
||||
open: true,
|
||||
children: HashMap::new(),
|
||||
children_open_count: 0,
|
||||
};
|
||||
file_node
|
||||
.children
|
||||
.insert(current_path.clone(), current_file_node.clone());
|
||||
current_file_node = file_node;
|
||||
current_path = PathBuf::from(p);
|
||||
}
|
||||
self.root = current_file_node;
|
||||
self.pwd = home.to_path_buf();
|
||||
}
|
||||
|
||||
pub fn get_file_node_mut(&mut self, path: &Path) -> Option<&mut FileNodeItem> {
|
||||
let mut node = Some(&mut self.root);
|
||||
|
||||
let ancestors = path.ancestors().collect::<Vec<&Path>>();
|
||||
for p in ancestors[..ancestors.len() - 1].iter().rev() {
|
||||
node = Some(node?.children.get_mut(&PathBuf::from(p))?);
|
||||
}
|
||||
node
|
||||
}
|
||||
|
||||
pub fn get_file_node(&self, path: &Path) -> Option<&FileNodeItem> {
|
||||
let mut node = Some(&self.root);
|
||||
|
||||
let ancestors = path.ancestors().collect::<Vec<&Path>>();
|
||||
for p in ancestors[..ancestors.len() - 1].iter().rev() {
|
||||
node = Some(node?.children.get(&PathBuf::from(p))?);
|
||||
}
|
||||
node
|
||||
}
|
||||
|
||||
pub fn update_node_count(&mut self, path: &Path) -> Option<()> {
|
||||
let node = self.get_file_node_mut(path)?;
|
||||
if node.is_dir {
|
||||
if node.open {
|
||||
node.children_open_count = node
|
||||
.children
|
||||
.iter()
|
||||
.map(|(_, item)| item.children_open_count + 1)
|
||||
.sum::<usize>();
|
||||
} else {
|
||||
node.children_open_count = 0;
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FilePickerData {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FilePicker {
|
||||
widget_id: WidgetId,
|
||||
pwd: WidgetPod<LapceTabData, Box<dyn Widget<LapceTabData>>>,
|
||||
|
@ -476,37 +348,12 @@ fn mouse_down(
|
|||
node.open = !node.open;
|
||||
} else {
|
||||
let tab_id = data.id;
|
||||
let path = node.path_buf.clone();
|
||||
let event_sink = ctx.get_external_handle();
|
||||
data.proxy.read_dir(
|
||||
FilePickerData::read_dir(
|
||||
&node.path_buf,
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let resp: Result<
|
||||
Vec<FileNodeItem>,
|
||||
serde_json::Error,
|
||||
> = serde_json::from_value(res);
|
||||
if let Ok(items) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdatePickerItems(
|
||||
path,
|
||||
items
|
||||
.iter()
|
||||
.map(|item| {
|
||||
(
|
||||
item.path_buf
|
||||
.clone(),
|
||||
item.clone(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
tab_id,
|
||||
&data.proxy,
|
||||
event_sink,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -519,37 +366,12 @@ fn mouse_down(
|
|||
// double click
|
||||
self.last_left_click = None;
|
||||
let tab_id = data.id;
|
||||
let path = node.path_buf.clone();
|
||||
let event_sink = ctx.get_external_handle();
|
||||
data.proxy.read_dir(
|
||||
FilePickerData::read_dir(
|
||||
&node.path_buf,
|
||||
Box::new(move |result| {
|
||||
if let Ok(res) = result {
|
||||
let resp: Result<
|
||||
Vec<FileNodeItem>,
|
||||
serde_json::Error,
|
||||
> = serde_json::from_value(res);
|
||||
if let Ok(items) = resp {
|
||||
let _ = event_sink.submit_command(
|
||||
LAPCE_UI_COMMAND,
|
||||
LapceUICommand::UpdatePickerItems(
|
||||
path,
|
||||
items
|
||||
.iter()
|
||||
.map(|item| {
|
||||
(
|
||||
item.path_buf
|
||||
.clone(),
|
||||
item.clone(),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
Target::Widget(tab_id),
|
||||
);
|
||||
}
|
||||
}
|
||||
}),
|
||||
tab_id,
|
||||
&data.proxy,
|
||||
event_sink,
|
||||
);
|
||||
let pwd = node.path_buf.clone();
|
||||
picker.index = 0;
|
||||
|
|
|
@ -457,7 +457,7 @@ fn event(
|
|||
ctx.set_handled();
|
||||
}
|
||||
LapceUICommand::FileChange(event) => {
|
||||
data.handle_file_change(event);
|
||||
data.handle_file_change(ctx, event);
|
||||
ctx.set_handled();
|
||||
}
|
||||
LapceUICommand::CloseTerminal(id) => {
|
||||
|
@ -957,22 +957,13 @@ fn event(
|
|||
.set_item_children(path, items.clone());
|
||||
ctx.set_handled();
|
||||
}
|
||||
LapceUICommand::UpdateExplorerItems(_index, path, items) => {
|
||||
LapceUICommand::UpdateExplorerItems(path, items, expand) => {
|
||||
let file_explorer = Arc::make_mut(&mut data.file_explorer);
|
||||
if let Some(node) = file_explorer.get_node_mut(path) {
|
||||
node.children = items
|
||||
.iter()
|
||||
.map(|item| (item.path_buf.clone(), item.clone()))
|
||||
.collect();
|
||||
node.read = true;
|
||||
node.open = true;
|
||||
node.children_open_count = node.children.len();
|
||||
}
|
||||
if let Some(paths) = file_explorer.node_tree(path) {
|
||||
for path in paths.iter() {
|
||||
file_explorer.update_node_count(path);
|
||||
}
|
||||
}
|
||||
file_explorer.update_children(
|
||||
path,
|
||||
items.to_owned(),
|
||||
*expand,
|
||||
);
|
||||
ctx.set_handled();
|
||||
}
|
||||
_ => (),
|
||||
|
|
Loading…
Reference in New Issue