mirror of
https://github.com/sayanarijit/xplr.git
synced 2024-08-15 22:10:27 +03:00
Format & lint code
This commit is contained in:
parent
2d7158afc0
commit
a797d7b1c7
@ -14,12 +14,13 @@ const PWD: &str = "/tmp/xplr_bench";
|
||||
fn navigation_benchmark(c: &mut Criterion) {
|
||||
fs::create_dir_all(PWD).unwrap();
|
||||
(1..10000).for_each(|i| {
|
||||
fs::File::create(std::path::Path::new(PWD).join(i.to_string())).unwrap();
|
||||
fs::File::create(std::path::Path::new(PWD).join(i.to_string()))
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
let lua = mlua::Lua::new();
|
||||
let mut app =
|
||||
app::App::create(PWD.into(), &lua, None, [].into()).expect("failed to create app");
|
||||
let mut app = app::App::create(PWD.into(), &lua, None, [].into())
|
||||
.expect("failed to create app");
|
||||
|
||||
app = app
|
||||
.clone()
|
||||
@ -93,12 +94,13 @@ fn navigation_benchmark(c: &mut Criterion) {
|
||||
fn draw_benchmark(c: &mut Criterion) {
|
||||
fs::create_dir_all(PWD).unwrap();
|
||||
(1..10000).for_each(|i| {
|
||||
fs::File::create(std::path::Path::new(PWD).join(i.to_string())).unwrap();
|
||||
fs::File::create(std::path::Path::new(PWD).join(i.to_string()))
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
let lua = mlua::Lua::new();
|
||||
let mut app =
|
||||
app::App::create(PWD.into(), &lua, None, [].into()).expect("failed to create app");
|
||||
let mut app = app::App::create(PWD.into(), &lua, None, [].into())
|
||||
.expect("failed to create app");
|
||||
|
||||
app = app
|
||||
.clone()
|
||||
|
4
rustfmt.toml
Normal file
4
rustfmt.toml
Normal file
@ -0,0 +1,4 @@
|
||||
edition = "2021"
|
||||
max_width = 80
|
||||
tab_spaces = 4
|
||||
use_field_init_shorthand = true
|
303
src/app.rs
303
src/app.rs
@ -55,7 +55,8 @@ impl Pipe {
|
||||
|
||||
let msg_in = path.join("msg_in").to_string_lossy().to_string();
|
||||
|
||||
let selection_out = path.join("selection_out").to_string_lossy().to_string();
|
||||
let selection_out =
|
||||
path.join("selection_out").to_string_lossy().to_string();
|
||||
|
||||
let result_out = path.join("result_out").to_string_lossy().to_string();
|
||||
|
||||
@ -71,7 +72,8 @@ impl Pipe {
|
||||
|
||||
let logs_out = path.join("logs_out").to_string_lossy().to_string();
|
||||
|
||||
let history_out = path.join("history_out").to_string_lossy().to_string();
|
||||
let history_out =
|
||||
path.join("history_out").to_string_lossy().to_string();
|
||||
|
||||
Ok(Self {
|
||||
path: path.to_string_lossy().to_string(),
|
||||
@ -107,7 +109,9 @@ impl ResolvedNode {
|
||||
|
||||
let (is_dir, is_file, is_readonly, size) = path
|
||||
.metadata()
|
||||
.map(|m| (m.is_dir(), m.is_file(), m.permissions().readonly(), m.len()))
|
||||
.map(|m| {
|
||||
(m.is_dir(), m.is_file(), m.permissions().readonly(), m.len())
|
||||
})
|
||||
.unwrap_or((false, false, false, 0));
|
||||
|
||||
let mime_essence = mime_essence(&path, is_dir);
|
||||
@ -164,19 +168,21 @@ impl Node {
|
||||
.map(|p| (false, Some(ResolvedNode::from(p))))
|
||||
.unwrap_or_else(|_| (true, None));
|
||||
|
||||
let (is_symlink, is_dir, is_file, is_readonly, size, permissions) = path
|
||||
.symlink_metadata()
|
||||
.map(|m| {
|
||||
(
|
||||
m.file_type().is_symlink(),
|
||||
m.is_dir(),
|
||||
m.is_file(),
|
||||
m.permissions().readonly(),
|
||||
m.len(),
|
||||
Permissions::from(&m),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|_| (false, false, false, false, 0, Permissions::default()));
|
||||
let (is_symlink, is_dir, is_file, is_readonly, size, permissions) =
|
||||
path.symlink_metadata()
|
||||
.map(|m| {
|
||||
(
|
||||
m.file_type().is_symlink(),
|
||||
m.is_dir(),
|
||||
m.is_file(),
|
||||
m.permissions().readonly(),
|
||||
m.len(),
|
||||
Permissions::from(&m),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|_| {
|
||||
(false, false, false, false, 0, Permissions::default())
|
||||
});
|
||||
|
||||
let mime_essence = mime_essence(&path, is_dir);
|
||||
let human_size = to_humansize(size);
|
||||
@ -312,7 +318,9 @@ impl NodeSorterApplicable {
|
||||
|
||||
fn apply(&self, a: &Node, b: &Node) -> Ordering {
|
||||
let order = match self.sorter {
|
||||
NodeSorter::ByRelativePath => natord::compare(&a.relative_path, &b.relative_path),
|
||||
NodeSorter::ByRelativePath => {
|
||||
natord::compare(&a.relative_path, &b.relative_path)
|
||||
}
|
||||
NodeSorter::ByIRelativePath => {
|
||||
natord::compare_ignore_case(&a.relative_path, &b.relative_path)
|
||||
}
|
||||
@ -336,16 +344,18 @@ impl NodeSorterApplicable {
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
|
||||
NodeSorter::ByICanonicalAbsolutePath => natord::compare_ignore_case(
|
||||
&a.canonical
|
||||
.as_ref()
|
||||
.map(|s| s.absolute_path.clone())
|
||||
.unwrap_or_default(),
|
||||
&b.canonical
|
||||
.as_ref()
|
||||
.map(|s| s.absolute_path.clone())
|
||||
.unwrap_or_default(),
|
||||
),
|
||||
NodeSorter::ByICanonicalAbsolutePath => {
|
||||
natord::compare_ignore_case(
|
||||
&a.canonical
|
||||
.as_ref()
|
||||
.map(|s| s.absolute_path.clone())
|
||||
.unwrap_or_default(),
|
||||
&b.canonical
|
||||
.as_ref()
|
||||
.map(|s| s.absolute_path.clone())
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
}
|
||||
|
||||
NodeSorter::ByCanonicalExtension => a
|
||||
.canonical
|
||||
@ -505,18 +515,26 @@ impl NodeFilter {
|
||||
fn apply(&self, node: &Node, input: &str) -> bool {
|
||||
match self {
|
||||
Self::RelativePathIs => node.relative_path.eq(input),
|
||||
Self::IRelativePathIs => node.relative_path.eq_ignore_ascii_case(input),
|
||||
Self::IRelativePathIs => {
|
||||
node.relative_path.eq_ignore_ascii_case(input)
|
||||
}
|
||||
|
||||
Self::RelativePathIsNot => !node.relative_path.eq(input),
|
||||
Self::IRelativePathIsNot => !node.relative_path.eq_ignore_ascii_case(input),
|
||||
Self::IRelativePathIsNot => {
|
||||
!node.relative_path.eq_ignore_ascii_case(input)
|
||||
}
|
||||
|
||||
Self::RelativePathDoesStartWith => node.relative_path.starts_with(input),
|
||||
Self::RelativePathDoesStartWith => {
|
||||
node.relative_path.starts_with(input)
|
||||
}
|
||||
Self::IRelativePathDoesStartWith => node
|
||||
.relative_path
|
||||
.to_lowercase()
|
||||
.starts_with(&input.to_lowercase()),
|
||||
|
||||
Self::RelativePathDoesNotStartWith => !node.relative_path.starts_with(input),
|
||||
Self::RelativePathDoesNotStartWith => {
|
||||
!node.relative_path.starts_with(input)
|
||||
}
|
||||
|
||||
Self::IRelativePathDoesNotStartWith => !node
|
||||
.relative_path
|
||||
@ -529,37 +547,51 @@ impl NodeFilter {
|
||||
.to_lowercase()
|
||||
.contains(&input.to_lowercase()),
|
||||
|
||||
Self::RelativePathDoesNotContain => !node.relative_path.contains(input),
|
||||
Self::RelativePathDoesNotContain => {
|
||||
!node.relative_path.contains(input)
|
||||
}
|
||||
Self::IRelativePathDoesNotContain => !node
|
||||
.relative_path
|
||||
.to_lowercase()
|
||||
.contains(&input.to_lowercase()),
|
||||
|
||||
Self::RelativePathDoesEndWith => node.relative_path.ends_with(input),
|
||||
Self::RelativePathDoesEndWith => {
|
||||
node.relative_path.ends_with(input)
|
||||
}
|
||||
Self::IRelativePathDoesEndWith => node
|
||||
.relative_path
|
||||
.to_lowercase()
|
||||
.ends_with(&input.to_lowercase()),
|
||||
|
||||
Self::RelativePathDoesNotEndWith => !node.relative_path.ends_with(input),
|
||||
Self::RelativePathDoesNotEndWith => {
|
||||
!node.relative_path.ends_with(input)
|
||||
}
|
||||
Self::IRelativePathDoesNotEndWith => !node
|
||||
.relative_path
|
||||
.to_lowercase()
|
||||
.ends_with(&input.to_lowercase()),
|
||||
|
||||
Self::AbsolutePathIs => node.absolute_path.eq(input),
|
||||
Self::IAbsolutePathIs => node.absolute_path.eq_ignore_ascii_case(input),
|
||||
Self::IAbsolutePathIs => {
|
||||
node.absolute_path.eq_ignore_ascii_case(input)
|
||||
}
|
||||
|
||||
Self::AbsolutePathIsNot => !node.absolute_path.eq(input),
|
||||
Self::IAbsolutePathIsNot => !node.absolute_path.eq_ignore_ascii_case(input),
|
||||
Self::IAbsolutePathIsNot => {
|
||||
!node.absolute_path.eq_ignore_ascii_case(input)
|
||||
}
|
||||
|
||||
Self::AbsolutePathDoesStartWith => node.absolute_path.starts_with(input),
|
||||
Self::AbsolutePathDoesStartWith => {
|
||||
node.absolute_path.starts_with(input)
|
||||
}
|
||||
Self::IAbsolutePathDoesStartWith => node
|
||||
.absolute_path
|
||||
.to_lowercase()
|
||||
.starts_with(&input.to_lowercase()),
|
||||
|
||||
Self::AbsolutePathDoesNotStartWith => !node.absolute_path.starts_with(input),
|
||||
Self::AbsolutePathDoesNotStartWith => {
|
||||
!node.absolute_path.starts_with(input)
|
||||
}
|
||||
Self::IAbsolutePathDoesNotStartWith => !node
|
||||
.absolute_path
|
||||
.to_lowercase()
|
||||
@ -571,19 +603,25 @@ impl NodeFilter {
|
||||
.to_lowercase()
|
||||
.contains(&input.to_lowercase()),
|
||||
|
||||
Self::AbsolutePathDoesNotContain => !node.absolute_path.contains(input),
|
||||
Self::AbsolutePathDoesNotContain => {
|
||||
!node.absolute_path.contains(input)
|
||||
}
|
||||
Self::IAbsolutePathDoesNotContain => !node
|
||||
.absolute_path
|
||||
.to_lowercase()
|
||||
.contains(&input.to_lowercase()),
|
||||
|
||||
Self::AbsolutePathDoesEndWith => node.absolute_path.ends_with(input),
|
||||
Self::AbsolutePathDoesEndWith => {
|
||||
node.absolute_path.ends_with(input)
|
||||
}
|
||||
Self::IAbsolutePathDoesEndWith => node
|
||||
.absolute_path
|
||||
.to_lowercase()
|
||||
.ends_with(&input.to_lowercase()),
|
||||
|
||||
Self::AbsolutePathDoesNotEndWith => !node.absolute_path.ends_with(input),
|
||||
Self::AbsolutePathDoesNotEndWith => {
|
||||
!node.absolute_path.ends_with(input)
|
||||
}
|
||||
Self::IAbsolutePathDoesNotEndWith => !node
|
||||
.absolute_path
|
||||
.to_lowercase()
|
||||
@ -1045,7 +1083,10 @@ impl ExternalMsg {
|
||||
pub fn is_read_only(&self) -> bool {
|
||||
!matches!(
|
||||
self,
|
||||
Self::Call(_) | Self::CallSilently(_) | Self::BashExec(_) | Self::BashExecSilently(_)
|
||||
Self::Call(_)
|
||||
| Self::CallSilently(_)
|
||||
| Self::BashExec(_)
|
||||
| Self::BashExecSilently(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1236,7 +1277,8 @@ impl App {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
let path = PathBuf::from("/").join("etc").join("xplr").join("init.lua");
|
||||
let path =
|
||||
PathBuf::from("/").join("etc").join("xplr").join("init.lua");
|
||||
if path.exists() {
|
||||
Some(path)
|
||||
} else {
|
||||
@ -1383,13 +1425,21 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_external(self, msg: ExternalMsg, key: Option<Key>) -> Result<Self> {
|
||||
fn handle_external(
|
||||
self,
|
||||
msg: ExternalMsg,
|
||||
key: Option<Key>,
|
||||
) -> Result<Self> {
|
||||
if self.config.general.read_only && !msg.is_read_only() {
|
||||
self.log_error("Cannot call shell command in read-only mode.".into())
|
||||
self.log_error(
|
||||
"Cannot call shell command in read-only mode.".into(),
|
||||
)
|
||||
} else {
|
||||
match msg {
|
||||
ExternalMsg::ExplorePwd => self.explore_pwd(),
|
||||
ExternalMsg::ExploreParentsAsync => self.explore_parents_async(),
|
||||
ExternalMsg::ExploreParentsAsync => {
|
||||
self.explore_parents_async()
|
||||
}
|
||||
ExternalMsg::ExplorePwdAsync => self.explore_pwd_async(),
|
||||
ExternalMsg::Refresh => self.refresh(),
|
||||
ExternalMsg::ClearScreen => self.clear_screen(),
|
||||
@ -1404,52 +1454,80 @@ impl App {
|
||||
self.focus_previous_by_relative_index_from_input()
|
||||
}
|
||||
ExternalMsg::FocusNext => self.focus_next(),
|
||||
ExternalMsg::FocusNextByRelativeIndex(i) => self.focus_next_by_relative_index(i),
|
||||
ExternalMsg::FocusNextByRelativeIndex(i) => {
|
||||
self.focus_next_by_relative_index(i)
|
||||
}
|
||||
ExternalMsg::FocusNextByRelativeIndexFromInput => {
|
||||
self.focus_next_by_relative_index_from_input()
|
||||
}
|
||||
ExternalMsg::FocusPath(p) => self.focus_path(&p, true),
|
||||
ExternalMsg::FocusPathFromInput => self.focus_path_from_input(),
|
||||
ExternalMsg::FocusByIndex(i) => self.focus_by_index(i),
|
||||
ExternalMsg::FocusByIndexFromInput => self.focus_by_index_from_input(),
|
||||
ExternalMsg::FocusByFileName(n) => self.focus_by_file_name(&n, true),
|
||||
ExternalMsg::ChangeDirectory(dir) => self.change_directory(&dir, true),
|
||||
ExternalMsg::FocusByIndexFromInput => {
|
||||
self.focus_by_index_from_input()
|
||||
}
|
||||
ExternalMsg::FocusByFileName(n) => {
|
||||
self.focus_by_file_name(&n, true)
|
||||
}
|
||||
ExternalMsg::ChangeDirectory(dir) => {
|
||||
self.change_directory(&dir, true)
|
||||
}
|
||||
ExternalMsg::Enter => self.enter(),
|
||||
ExternalMsg::Back => self.back(),
|
||||
ExternalMsg::LastVisitedPath => self.last_visited_path(),
|
||||
ExternalMsg::NextVisitedPath => self.next_visited_path(),
|
||||
ExternalMsg::FollowSymlink => self.follow_symlink(),
|
||||
ExternalMsg::BufferInput(input) => self.buffer_input(&input),
|
||||
ExternalMsg::BufferInputFromKey => self.buffer_input_from_key(key),
|
||||
ExternalMsg::SetInputBuffer(input) => self.set_input_buffer(input),
|
||||
ExternalMsg::BufferInputFromKey => {
|
||||
self.buffer_input_from_key(key)
|
||||
}
|
||||
ExternalMsg::SetInputBuffer(input) => {
|
||||
self.set_input_buffer(input)
|
||||
}
|
||||
ExternalMsg::RemoveInputBufferLastCharacter => {
|
||||
self.remove_input_buffer_last_character()
|
||||
}
|
||||
ExternalMsg::RemoveInputBufferLastWord => self.remove_input_buffer_last_word(),
|
||||
ExternalMsg::RemoveInputBufferLastWord => {
|
||||
self.remove_input_buffer_last_word()
|
||||
}
|
||||
ExternalMsg::ResetInputBuffer => self.reset_input_buffer(),
|
||||
ExternalMsg::SwitchMode(mode) => self.switch_mode(&mode),
|
||||
ExternalMsg::SwitchModeKeepingInputBuffer(mode) => {
|
||||
self.switch_mode_keeping_input_buffer(&mode)
|
||||
}
|
||||
ExternalMsg::SwitchModeBuiltin(mode) => self.switch_mode_builtin(&mode),
|
||||
ExternalMsg::SwitchModeBuiltin(mode) => {
|
||||
self.switch_mode_builtin(&mode)
|
||||
}
|
||||
ExternalMsg::SwitchModeBuiltinKeepingInputBuffer(mode) => {
|
||||
self.switch_mode_builtin_keeping_input_buffer(&mode)
|
||||
}
|
||||
ExternalMsg::SwitchModeCustom(mode) => self.switch_mode_custom(&mode),
|
||||
ExternalMsg::SwitchModeCustom(mode) => {
|
||||
self.switch_mode_custom(&mode)
|
||||
}
|
||||
ExternalMsg::SwitchModeCustomKeepingInputBuffer(mode) => {
|
||||
self.switch_mode_custom_keeping_input_buffer(&mode)
|
||||
}
|
||||
ExternalMsg::PopMode => self.pop_mode(),
|
||||
ExternalMsg::PopModeKeepingInputBuffer => self.pop_mode_keeping_input_buffer(),
|
||||
ExternalMsg::PopModeKeepingInputBuffer => {
|
||||
self.pop_mode_keeping_input_buffer()
|
||||
}
|
||||
ExternalMsg::SwitchLayout(mode) => self.switch_layout(&mode),
|
||||
ExternalMsg::SwitchLayoutBuiltin(mode) => self.switch_layout_builtin(&mode),
|
||||
ExternalMsg::SwitchLayoutCustom(mode) => self.switch_layout_custom(&mode),
|
||||
ExternalMsg::SwitchLayoutBuiltin(mode) => {
|
||||
self.switch_layout_builtin(&mode)
|
||||
}
|
||||
ExternalMsg::SwitchLayoutCustom(mode) => {
|
||||
self.switch_layout_custom(&mode)
|
||||
}
|
||||
ExternalMsg::Call(cmd) => self.call(cmd),
|
||||
ExternalMsg::CallSilently(cmd) => self.call_silently(cmd),
|
||||
ExternalMsg::CallLua(func) => self.call_lua(func),
|
||||
ExternalMsg::CallLuaSilently(func) => self.call_lua_silently(func),
|
||||
ExternalMsg::CallLuaSilently(func) => {
|
||||
self.call_lua_silently(func)
|
||||
}
|
||||
ExternalMsg::BashExec(cmd) => self.bash_exec(cmd),
|
||||
ExternalMsg::BashExecSilently(cmd) => self.bash_exec_silently(cmd),
|
||||
ExternalMsg::BashExecSilently(cmd) => {
|
||||
self.bash_exec_silently(cmd)
|
||||
}
|
||||
ExternalMsg::Select => self.select(),
|
||||
ExternalMsg::SelectAll => self.select_all(),
|
||||
ExternalMsg::SelectPath(p) => self.select_path(p),
|
||||
@ -1458,21 +1536,33 @@ impl App {
|
||||
ExternalMsg::UnSelectPath(p) => self.un_select_path(p),
|
||||
ExternalMsg::ToggleSelection => self.toggle_selection(),
|
||||
ExternalMsg::ToggleSelectAll => self.toggle_select_all(),
|
||||
ExternalMsg::ToggleSelectionByPath(p) => self.toggle_selection_by_path(p),
|
||||
ExternalMsg::ToggleSelectionByPath(p) => {
|
||||
self.toggle_selection_by_path(p)
|
||||
}
|
||||
ExternalMsg::ClearSelection => self.clear_selection(),
|
||||
ExternalMsg::AddNodeFilter(f) => self.add_node_filter(f),
|
||||
ExternalMsg::AddNodeFilterFromInput(f) => self.add_node_filter_from_input(f),
|
||||
ExternalMsg::AddNodeFilterFromInput(f) => {
|
||||
self.add_node_filter_from_input(f)
|
||||
}
|
||||
ExternalMsg::RemoveNodeFilter(f) => self.remove_node_filter(f),
|
||||
ExternalMsg::RemoveNodeFilterFromInput(f) => self.remove_node_filter_from_input(f),
|
||||
ExternalMsg::RemoveNodeFilterFromInput(f) => {
|
||||
self.remove_node_filter_from_input(f)
|
||||
}
|
||||
ExternalMsg::ToggleNodeFilter(f) => self.toggle_node_filter(f),
|
||||
ExternalMsg::RemoveLastNodeFilter => self.remove_last_node_filter(),
|
||||
ExternalMsg::RemoveLastNodeFilter => {
|
||||
self.remove_last_node_filter()
|
||||
}
|
||||
ExternalMsg::ResetNodeFilters => self.reset_node_filters(),
|
||||
ExternalMsg::ClearNodeFilters => self.clear_node_filters(),
|
||||
ExternalMsg::AddNodeSorter(f) => self.add_node_sorter(f),
|
||||
ExternalMsg::RemoveNodeSorter(f) => self.remove_node_sorter(f),
|
||||
ExternalMsg::ReverseNodeSorter(f) => self.reverse_node_sorter(f),
|
||||
ExternalMsg::ReverseNodeSorter(f) => {
|
||||
self.reverse_node_sorter(f)
|
||||
}
|
||||
ExternalMsg::ToggleNodeSorter(f) => self.toggle_node_sorter(f),
|
||||
ExternalMsg::RemoveLastNodeSorter => self.remove_last_node_sorter(),
|
||||
ExternalMsg::RemoveLastNodeSorter => {
|
||||
self.remove_last_node_sorter()
|
||||
}
|
||||
ExternalMsg::ReverseNodeSorters => self.reverse_node_sorters(),
|
||||
ExternalMsg::ResetNodeSorters => self.reset_node_sorters(),
|
||||
ExternalMsg::ClearNodeSorters => self.clear_node_sorters(),
|
||||
@ -1488,10 +1578,16 @@ impl App {
|
||||
ExternalMsg::LogError(l) => self.log_error(l),
|
||||
ExternalMsg::Quit => self.quit(),
|
||||
ExternalMsg::PrintPwdAndQuit => self.print_pwd_and_quit(),
|
||||
ExternalMsg::PrintFocusPathAndQuit => self.print_focus_path_and_quit(),
|
||||
ExternalMsg::PrintSelectionAndQuit => self.print_selection_and_quit(),
|
||||
ExternalMsg::PrintFocusPathAndQuit => {
|
||||
self.print_focus_path_and_quit()
|
||||
}
|
||||
ExternalMsg::PrintSelectionAndQuit => {
|
||||
self.print_selection_and_quit()
|
||||
}
|
||||
ExternalMsg::PrintResultAndQuit => self.print_result_and_quit(),
|
||||
ExternalMsg::PrintAppStateAndQuit => self.print_app_state_and_quit(),
|
||||
ExternalMsg::PrintAppStateAndQuit => {
|
||||
self.print_app_state_and_quit()
|
||||
}
|
||||
ExternalMsg::Debug(path) => self.debug(path),
|
||||
ExternalMsg::Terminate => bail!(""),
|
||||
}
|
||||
@ -1615,7 +1711,10 @@ impl App {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn focus_previous_by_relative_index(mut self, index: usize) -> Result<Self> {
|
||||
fn focus_previous_by_relative_index(
|
||||
mut self,
|
||||
index: usize,
|
||||
) -> Result<Self> {
|
||||
let mut history = self.history.clone();
|
||||
if let Some(dir) = self.directory_buffer_mut() {
|
||||
if let Some(n) = dir.focused_node() {
|
||||
@ -1691,7 +1790,11 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
fn change_directory(mut self, dir: &str, save_history: bool) -> Result<Self> {
|
||||
fn change_directory(
|
||||
mut self,
|
||||
dir: &str,
|
||||
save_history: bool,
|
||||
) -> Result<Self> {
|
||||
let mut dir = PathBuf::from(dir);
|
||||
if dir.is_relative() {
|
||||
dir = PathBuf::from(self.pwd.clone()).join(dir);
|
||||
@ -1700,7 +1803,8 @@ impl App {
|
||||
match env::set_current_dir(&dir) {
|
||||
Ok(()) => {
|
||||
let pwd = self.pwd.clone();
|
||||
let focus = self.focused_node().map(|n| n.relative_path.clone());
|
||||
let focus =
|
||||
self.focused_node().map(|n| n.relative_path.clone());
|
||||
self = self.add_last_focus(pwd, focus)?;
|
||||
self.pwd = dir.to_string_lossy().to_string();
|
||||
if save_history {
|
||||
@ -1841,7 +1945,11 @@ impl App {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn focus_by_file_name(mut self, name: &str, save_history: bool) -> Result<Self> {
|
||||
pub fn focus_by_file_name(
|
||||
mut self,
|
||||
name: &str,
|
||||
save_history: bool,
|
||||
) -> Result<Self> {
|
||||
let mut history = self.history.clone();
|
||||
if let Some(dir_buf) = self.directory_buffer_mut() {
|
||||
if let Some(focus) = dir_buf
|
||||
@ -1879,8 +1987,14 @@ impl App {
|
||||
}
|
||||
if let Some(parent) = pathbuf.parent() {
|
||||
if let Some(filename) = pathbuf.file_name() {
|
||||
self.change_directory(&parent.to_string_lossy().to_string(), false)?
|
||||
.focus_by_file_name(&filename.to_string_lossy().to_string(), save_history)
|
||||
self.change_directory(
|
||||
&parent.to_string_lossy().to_string(),
|
||||
false,
|
||||
)?
|
||||
.focus_by_file_name(
|
||||
&filename.to_string_lossy().to_string(),
|
||||
save_history,
|
||||
)
|
||||
} else {
|
||||
self.log_error(format!("{} not found", path))
|
||||
}
|
||||
@ -1949,7 +2063,10 @@ impl App {
|
||||
})
|
||||
}
|
||||
|
||||
fn switch_mode_builtin_keeping_input_buffer(mut self, mode: &str) -> Result<Self> {
|
||||
fn switch_mode_builtin_keeping_input_buffer(
|
||||
mut self,
|
||||
mode: &str,
|
||||
) -> Result<Self> {
|
||||
if let Some(mode) = self.config.modes.builtin.get(mode).cloned() {
|
||||
self = self.push_mode();
|
||||
self.mode = mode.sanitized(self.config.general.read_only);
|
||||
@ -1967,7 +2084,10 @@ impl App {
|
||||
})
|
||||
}
|
||||
|
||||
fn switch_mode_custom_keeping_input_buffer(mut self, mode: &str) -> Result<Self> {
|
||||
fn switch_mode_custom_keeping_input_buffer(
|
||||
mut self,
|
||||
mode: &str,
|
||||
) -> Result<Self> {
|
||||
if let Some(mode) = self.config.modes.custom.get(mode).cloned() {
|
||||
self = self.push_mode();
|
||||
self.mode = mode.sanitized(self.config.general.read_only);
|
||||
@ -2053,7 +2173,11 @@ impl App {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
pub fn add_last_focus(mut self, parent: String, focused_path: Option<String>) -> Result<Self> {
|
||||
pub fn add_last_focus(
|
||||
mut self,
|
||||
parent: String,
|
||||
focused_path: Option<String>,
|
||||
) -> Result<Self> {
|
||||
self.last_focus.insert(parent, focused_path);
|
||||
Ok(self)
|
||||
}
|
||||
@ -2071,7 +2195,8 @@ impl App {
|
||||
path = PathBuf::from(self.pwd.clone()).join(path);
|
||||
}
|
||||
let parent = path.parent().map(|p| p.to_string_lossy().to_string());
|
||||
let filename = path.file_name().map(|p| p.to_string_lossy().to_string());
|
||||
let filename =
|
||||
path.file_name().map(|p| p.to_string_lossy().to_string());
|
||||
if let (Some(p), Some(n)) = (parent, filename) {
|
||||
self.selection.insert(Node::new(p, n));
|
||||
}
|
||||
@ -2161,7 +2286,10 @@ impl App {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn add_node_filter_from_input(mut self, filter: NodeFilter) -> Result<Self> {
|
||||
fn add_node_filter_from_input(
|
||||
mut self,
|
||||
filter: NodeFilter,
|
||||
) -> Result<Self> {
|
||||
if let Some(input) = self.input_buffer.clone() {
|
||||
self.explorer_config
|
||||
.filters
|
||||
@ -2170,12 +2298,18 @@ impl App {
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn remove_node_filter(mut self, filter: NodeFilterApplicable) -> Result<Self> {
|
||||
fn remove_node_filter(
|
||||
mut self,
|
||||
filter: NodeFilterApplicable,
|
||||
) -> Result<Self> {
|
||||
self.explorer_config.filters.retain(|f| f != &filter);
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn remove_node_filter_from_input(mut self, filter: NodeFilter) -> Result<Self> {
|
||||
fn remove_node_filter_from_input(
|
||||
mut self,
|
||||
filter: NodeFilter,
|
||||
) -> Result<Self> {
|
||||
if let Some(input) = self.input_buffer.clone() {
|
||||
let nfa = NodeFilterApplicable::new(filter, input);
|
||||
self.explorer_config.filters.retain(|f| f != &nfa);
|
||||
@ -2370,8 +2504,9 @@ impl App {
|
||||
|
||||
fn refresh_selection(mut self) -> Result<Self> {
|
||||
// Should be able to select broken symlink
|
||||
self.selection
|
||||
.retain(|n| PathBuf::from(&n.absolute_path).symlink_metadata().is_ok());
|
||||
self.selection.retain(|n| {
|
||||
PathBuf::from(&n.absolute_path).symlink_metadata().is_ok()
|
||||
});
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,9 @@ impl Cli {
|
||||
}
|
||||
|
||||
// Options
|
||||
"-c" | "--config" => cli.config = args.pop_front().map(PathBuf::from),
|
||||
"-c" | "--config" => {
|
||||
cli.config = args.pop_front().map(PathBuf::from)
|
||||
}
|
||||
|
||||
"-C" | "--extra-config" => {
|
||||
while let Some(path) = args.pop_front() {
|
||||
|
@ -298,8 +298,10 @@ impl KeyBindings {
|
||||
.filter_map(|(k, a)| a.sanitized(read_only).map(|a| (k, a)))
|
||||
.collect();
|
||||
|
||||
self.on_alphabet = self.on_alphabet.and_then(|a| a.sanitized(read_only));
|
||||
self.on_number = self.on_number.and_then(|a| a.sanitized(read_only));
|
||||
self.on_alphabet =
|
||||
self.on_alphabet.and_then(|a| a.sanitized(read_only));
|
||||
self.on_number =
|
||||
self.on_number.and_then(|a| a.sanitized(read_only));
|
||||
self.on_special_character = self
|
||||
.on_special_character
|
||||
.and_then(|a| a.sanitized(read_only));
|
||||
@ -353,32 +355,36 @@ impl Mode {
|
||||
let lines = extra_help_lines
|
||||
.unwrap_or_default()
|
||||
.into_iter()
|
||||
.chain(self.key_bindings.on_key.iter().filter_map(|(k, a)| {
|
||||
let remaps = self
|
||||
.key_bindings
|
||||
.on_key
|
||||
.iter()
|
||||
.filter_map(|(rk, ra)| {
|
||||
if rk == k {
|
||||
None
|
||||
} else if a == ra {
|
||||
Some(rk.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
.chain(self.key_bindings.on_key.iter().filter_map(
|
||||
|(k, a)| {
|
||||
let remaps = self
|
||||
.key_bindings
|
||||
.on_key
|
||||
.iter()
|
||||
.filter_map(|(rk, ra)| {
|
||||
if rk == k {
|
||||
None
|
||||
} else if a == ra {
|
||||
Some(rk.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
a.help.clone().map(|h| {
|
||||
HelpMenuLine::KeyMap(k.into(), remaps, h)
|
||||
})
|
||||
.collect::<Vec<String>>();
|
||||
a.help
|
||||
.clone()
|
||||
.map(|h| HelpMenuLine::KeyMap(k.into(), remaps, h))
|
||||
}))
|
||||
},
|
||||
))
|
||||
.chain(
|
||||
self.key_bindings
|
||||
.on_alphabet
|
||||
.iter()
|
||||
.map(|a| ("[a-Z]", a.help.clone()))
|
||||
.filter_map(|(k, mh)| {
|
||||
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
|
||||
mh.map(|h| {
|
||||
HelpMenuLine::KeyMap(k.into(), vec![], h)
|
||||
})
|
||||
}),
|
||||
)
|
||||
.chain(
|
||||
@ -387,7 +393,9 @@ impl Mode {
|
||||
.iter()
|
||||
.map(|a| ("[0-9]", a.help.clone()))
|
||||
.filter_map(|(k, mh)| {
|
||||
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
|
||||
mh.map(|h| {
|
||||
HelpMenuLine::KeyMap(k.into(), vec![], h)
|
||||
})
|
||||
}),
|
||||
)
|
||||
.chain(
|
||||
@ -396,7 +404,9 @@ impl Mode {
|
||||
.iter()
|
||||
.map(|a| ("[spcl chars]", a.help.clone()))
|
||||
.filter_map(|(k, mh)| {
|
||||
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
|
||||
mh.map(|h| {
|
||||
HelpMenuLine::KeyMap(k.into(), vec![], h)
|
||||
})
|
||||
}),
|
||||
)
|
||||
.chain(
|
||||
@ -405,7 +415,9 @@ impl Mode {
|
||||
.iter()
|
||||
.map(|a| ("[default]", a.help.clone()))
|
||||
.filter_map(|(k, mh)| {
|
||||
mh.map(|h| HelpMenuLine::KeyMap(k.into(), vec![], h))
|
||||
mh.map(|h| {
|
||||
HelpMenuLine::KeyMap(k.into(), vec![], h)
|
||||
})
|
||||
}),
|
||||
);
|
||||
|
||||
@ -414,7 +426,9 @@ impl Mode {
|
||||
|
||||
for line in lines {
|
||||
match line {
|
||||
HelpMenuLine::Paragraph(p) => result.push(HelpMenuLine::Paragraph(p)),
|
||||
HelpMenuLine::Paragraph(p) => {
|
||||
result.push(HelpMenuLine::Paragraph(p))
|
||||
}
|
||||
HelpMenuLine::KeyMap(k, r, d) => {
|
||||
if !remapped.contains(&k) {
|
||||
for k in r.iter() {
|
||||
@ -510,10 +524,18 @@ impl BuiltinModesConfig {
|
||||
"search" => Some(&self.search),
|
||||
"sort" => Some(&self.sort),
|
||||
"filter" => Some(&self.filter),
|
||||
"relative_path_does_contain" => Some(&self.relative_path_does_contain),
|
||||
"relative path does contain" => Some(&self.relative_path_does_contain),
|
||||
"relative_path_does_not_contain" => Some(&self.relative_path_does_not_contain),
|
||||
"relative path does not contain" => Some(&self.relative_path_does_not_contain),
|
||||
"relative_path_does_contain" => {
|
||||
Some(&self.relative_path_does_contain)
|
||||
}
|
||||
"relative path does contain" => {
|
||||
Some(&self.relative_path_does_contain)
|
||||
}
|
||||
"relative_path_does_not_contain" => {
|
||||
Some(&self.relative_path_does_not_contain)
|
||||
}
|
||||
"relative path does not contain" => {
|
||||
Some(&self.relative_path_does_not_contain)
|
||||
}
|
||||
"switch layout" => Some(&self.switch_layout),
|
||||
"switch_layout" => Some(&self.switch_layout),
|
||||
"quit" => Some(&self.quit),
|
||||
|
@ -40,12 +40,18 @@ impl EventReader {
|
||||
}
|
||||
}
|
||||
|
||||
fn keep_reading(tx_msg_in: Sender<Task>, rx_stopper: Receiver<bool>, tx_ack: Sender<()>) {
|
||||
fn keep_reading(
|
||||
tx_msg_in: Sender<Task>,
|
||||
rx_stopper: Receiver<bool>,
|
||||
tx_ack: Sender<()>,
|
||||
) {
|
||||
loop {
|
||||
if rx_stopper.try_recv().unwrap_or(false) {
|
||||
tx_ack.send(()).unwrap();
|
||||
break;
|
||||
} else if event::poll(std::time::Duration::from_millis(150)).unwrap_or_default() {
|
||||
} else if event::poll(std::time::Duration::from_millis(150))
|
||||
.unwrap_or_default()
|
||||
{
|
||||
// NOTE: The poll timeout need to stay low, else spawning sub subshell
|
||||
// and start typing immediately will cause panic.
|
||||
// To reproduce, press `:`, then press and hold `!`.
|
||||
|
@ -1,5 +1,8 @@
|
||||
use crate::app::{DirectoryBuffer, ExplorerConfig, ExternalMsg, InternalMsg, MsgIn, Node, Task};
|
||||
use anyhow::{Result, Error};
|
||||
use crate::app::{
|
||||
DirectoryBuffer, ExplorerConfig, ExternalMsg, InternalMsg, MsgIn, Node,
|
||||
Task,
|
||||
};
|
||||
use anyhow::{Error, Result};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
20
src/lua.rs
20
src/lua.rs
@ -32,7 +32,11 @@ pub fn check_version(version: &str, path: &str) -> Result<()> {
|
||||
let (rmajor, rminor, rbugfix, rbeta) = parse_version(VERSION)?;
|
||||
let (smajor, sminor, sbugfix, sbeta) = parse_version(version)?;
|
||||
|
||||
if rmajor == smajor && rminor == sminor && rbugfix >= sbugfix && rbeta == sbeta {
|
||||
if rmajor == smajor
|
||||
&& rminor == sminor
|
||||
&& rbugfix >= sbugfix
|
||||
&& rbeta == sbeta
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
bail!(
|
||||
@ -61,7 +65,10 @@ fn resolve_fn_recursive<'lua, 'a>(
|
||||
}
|
||||
|
||||
/// This function resolves paths like `builtin.func_foo`, `custom.func_bar` into lua functions.
|
||||
pub fn resolve_fn<'lua>(globals: &mlua::Table<'lua>, path: &str) -> Result<mlua::Function<'lua>> {
|
||||
pub fn resolve_fn<'lua>(
|
||||
globals: &mlua::Table<'lua>,
|
||||
path: &str,
|
||||
) -> Result<mlua::Function<'lua>> {
|
||||
let path = format!("xplr.fn.{}", path);
|
||||
resolve_fn_recursive(globals, path.split('.'))
|
||||
}
|
||||
@ -98,10 +105,11 @@ pub fn extend(lua: &Lua, path: &str) -> Result<Config> {
|
||||
|
||||
lua.load(&script).set_name("init")?.exec()?;
|
||||
|
||||
let version: String = match globals.get("version").and_then(|v| lua.from_value(v)) {
|
||||
Ok(v) => v,
|
||||
Err(_) => bail!("'version' must be defined globally in {}", path),
|
||||
};
|
||||
let version: String =
|
||||
match globals.get("version").and_then(|v| lua.from_value(v)) {
|
||||
Ok(v) => v,
|
||||
Err(_) => bail!("'version' must be defined globally in {}", path),
|
||||
};
|
||||
|
||||
check_version(&version, path)?;
|
||||
|
||||
|
@ -3,7 +3,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::Metadata;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize, Hash, Default)]
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Copy, Clone, Serialize, Deserialize, Hash, Default,
|
||||
)]
|
||||
pub struct Permissions {
|
||||
pub user_read: bool,
|
||||
pub user_write: bool,
|
||||
|
@ -17,27 +17,25 @@ pub fn keep_watching(
|
||||
thread::spawn(move || loop {
|
||||
if let Ok(new_pwd) = rx_pwd_watcher.try_recv() {
|
||||
pwd = PathBuf::from(new_pwd);
|
||||
} else {
|
||||
if let Err(e) = pwd
|
||||
.metadata()
|
||||
.map_err(Error::new)
|
||||
.and_then(|m| m.modified().map_err(Error::new))
|
||||
.and_then(|modified| {
|
||||
if modified != last_modified {
|
||||
let msg = MsgIn::External(ExternalMsg::ExplorePwdAsync);
|
||||
last_modified = modified;
|
||||
tx_msg_in.send(Task::new(msg, None)).map_err(Error::new)
|
||||
} else {
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
Result::Ok(())
|
||||
}
|
||||
})
|
||||
{
|
||||
let msg = MsgIn::External(ExternalMsg::LogError(e.to_string()));
|
||||
tx_msg_in.send(Task::new(msg, None)).unwrap_or_default();
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
};
|
||||
};
|
||||
} else if let Err(e) = pwd
|
||||
.metadata()
|
||||
.map_err(Error::new)
|
||||
.and_then(|m| m.modified().map_err(Error::new))
|
||||
.and_then(|modified| {
|
||||
if modified != last_modified {
|
||||
let msg = MsgIn::External(ExternalMsg::ExplorePwdAsync);
|
||||
last_modified = modified;
|
||||
tx_msg_in.send(Task::new(msg, None)).map_err(Error::new)
|
||||
} else {
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
Result::Ok(())
|
||||
}
|
||||
})
|
||||
{
|
||||
let msg = MsgIn::External(ExternalMsg::LogError(e.to_string()));
|
||||
tx_msg_in.send(Task::new(msg, None)).unwrap_or_default();
|
||||
thread::sleep(Duration::from_secs(1));
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
159
src/runner.rs
159
src/runner.rs
@ -151,7 +151,12 @@ impl Runner {
|
||||
pub fn run(self) -> Result<Option<String>> {
|
||||
// Why unsafe? See https://github.com/sayanarijit/xplr/issues/309
|
||||
let lua = unsafe { mlua::Lua::unsafe_new() };
|
||||
let mut app = app::App::create(self.pwd, &lua, self.config_file, self.extra_config_files)?;
|
||||
let mut app = app::App::create(
|
||||
self.pwd,
|
||||
&lua,
|
||||
self.config_file,
|
||||
self.extra_config_files,
|
||||
)?;
|
||||
app.config.general.read_only = self.read_only;
|
||||
|
||||
fs::create_dir_all(app.session_path.clone())?;
|
||||
@ -191,19 +196,19 @@ impl Runner {
|
||||
// let mut stdout = stdout.lock();
|
||||
execute!(stdout, term::EnterAlternateScreen)?;
|
||||
|
||||
let mut fifo: Option<fs::File> = if let Some(path) = app.config.general.start_fifo.as_ref()
|
||||
{
|
||||
// TODO remove duplicate segment
|
||||
match start_fifo(path, &app.focused_node_str()) {
|
||||
Ok(file) => Some(file),
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
None
|
||||
let mut fifo: Option<fs::File> =
|
||||
if let Some(path) = app.config.general.start_fifo.as_ref() {
|
||||
// TODO remove duplicate segment
|
||||
match start_fifo(path, &app.focused_node_str()) {
|
||||
Ok(file) => Some(file),
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut last_focus: Option<app::Node> = None;
|
||||
|
||||
@ -219,7 +224,11 @@ impl Runner {
|
||||
terminal.hide_cursor()?;
|
||||
|
||||
// Threads
|
||||
pwd_watcher::keep_watching(app.pwd.as_ref(), tx_msg_in.clone(), rx_pwd_watcher)?;
|
||||
pwd_watcher::keep_watching(
|
||||
app.pwd.as_ref(),
|
||||
tx_msg_in.clone(),
|
||||
rx_pwd_watcher,
|
||||
)?;
|
||||
let mut event_reader = EventReader::new(tx_msg_in.clone());
|
||||
event_reader.start();
|
||||
|
||||
@ -291,8 +300,13 @@ impl Runner {
|
||||
explorer::explore_async(
|
||||
app.explorer_config.clone(),
|
||||
app.pwd.clone().into(),
|
||||
app.focused_node().map(|n| n.relative_path.clone().into()),
|
||||
app.directory_buffer.as_ref().map(|d| d.focus).unwrap_or(0),
|
||||
app.focused_node().map(|n| {
|
||||
n.relative_path.clone().into()
|
||||
}),
|
||||
app.directory_buffer
|
||||
.as_ref()
|
||||
.map(|d| d.focus)
|
||||
.unwrap_or(0),
|
||||
tx_msg_in.clone(),
|
||||
);
|
||||
tx_pwd_watcher.send(app.pwd.clone())?;
|
||||
@ -302,8 +316,13 @@ impl Runner {
|
||||
explorer::explore_recursive_async(
|
||||
app.explorer_config.clone(),
|
||||
app.pwd.clone().into(),
|
||||
app.focused_node().map(|n| n.relative_path.clone().into()),
|
||||
app.directory_buffer.as_ref().map(|d| d.focus).unwrap_or(0),
|
||||
app.focused_node().map(|n| {
|
||||
n.relative_path.clone().into()
|
||||
}),
|
||||
app.directory_buffer
|
||||
.as_ref()
|
||||
.map(|d| d.focus)
|
||||
.unwrap_or(0),
|
||||
tx_msg_in.clone(),
|
||||
);
|
||||
tx_pwd_watcher.send(app.pwd.clone())?;
|
||||
@ -318,7 +337,11 @@ impl Runner {
|
||||
let focus = app.focused_node();
|
||||
if focus != last_focus.as_ref() {
|
||||
if let Some(ref mut file) = fifo {
|
||||
writeln!(file, "{}", app.focused_node_str())?;
|
||||
writeln!(
|
||||
file,
|
||||
"{}",
|
||||
app.focused_node_str()
|
||||
)?;
|
||||
};
|
||||
last_focus = focus.cloned();
|
||||
}
|
||||
@ -334,7 +357,8 @@ impl Runner {
|
||||
mouse_enabled = true;
|
||||
}
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
app =
|
||||
app.log_error(e.to_string())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -346,8 +370,10 @@ impl Runner {
|
||||
} else {
|
||||
app::ExternalMsg::EnableMouse
|
||||
};
|
||||
app = app
|
||||
.handle_task(app::Task::new(app::MsgIn::External(msg), None))?;
|
||||
app = app.handle_task(app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
))?;
|
||||
}
|
||||
|
||||
DisableMouse => {
|
||||
@ -360,14 +386,18 @@ impl Runner {
|
||||
mouse_enabled = false;
|
||||
}
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
app =
|
||||
app.log_error(e.to_string())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StartFifo(path) => {
|
||||
fifo = match start_fifo(&path, &app.focused_node_str()) {
|
||||
fifo = match start_fifo(
|
||||
&path,
|
||||
&app.focused_node_str(),
|
||||
) {
|
||||
Ok(file) => Some(file),
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
@ -388,10 +418,14 @@ impl Runner {
|
||||
fifo = None;
|
||||
std::mem::drop(file);
|
||||
} else {
|
||||
fifo = match start_fifo(&path, &app.focused_node_str()) {
|
||||
fifo = match start_fifo(
|
||||
&path,
|
||||
&app.focused_node_str(),
|
||||
) {
|
||||
Ok(file) => Some(file),
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
app =
|
||||
app.log_error(e.to_string())?;
|
||||
None
|
||||
}
|
||||
}
|
||||
@ -402,10 +436,12 @@ impl Runner {
|
||||
match call_lua(&app, &lua, &func, false) {
|
||||
Ok(Some(msgs)) => {
|
||||
for msg in msgs {
|
||||
app = app.handle_task(app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
))?;
|
||||
app = app.handle_task(
|
||||
app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(None) => {}
|
||||
@ -422,7 +458,10 @@ impl Runner {
|
||||
if s.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("process exited with code {}", &s))
|
||||
Err(format!(
|
||||
"process exited with code {}",
|
||||
&s
|
||||
))
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|e| Err(e.to_string()));
|
||||
@ -430,10 +469,12 @@ impl Runner {
|
||||
match pipe_reader::read_all(&app.pipe.msg_in) {
|
||||
Ok(msgs) => {
|
||||
for msg in msgs {
|
||||
app = app.handle_task(app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
))?;
|
||||
app = app.handle_task(
|
||||
app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@ -449,8 +490,11 @@ impl Runner {
|
||||
}
|
||||
|
||||
CallLua(func) => {
|
||||
execute!(terminal.backend_mut(), event::DisableMouseCapture)
|
||||
.unwrap_or_default();
|
||||
execute!(
|
||||
terminal.backend_mut(),
|
||||
event::DisableMouseCapture
|
||||
)
|
||||
.unwrap_or_default();
|
||||
|
||||
event_reader.stop();
|
||||
|
||||
@ -462,10 +506,12 @@ impl Runner {
|
||||
match call_lua(&app, &lua, &func, false) {
|
||||
Ok(Some(msgs)) => {
|
||||
for msg in msgs {
|
||||
app = app.handle_task(app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
))?;
|
||||
app = app.handle_task(
|
||||
app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Ok(None) => {}
|
||||
@ -488,15 +534,19 @@ impl Runner {
|
||||
mouse_enabled = true;
|
||||
}
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
app =
|
||||
app.log_error(e.to_string())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Call(cmd) => {
|
||||
execute!(terminal.backend_mut(), event::DisableMouseCapture)
|
||||
.unwrap_or_default();
|
||||
execute!(
|
||||
terminal.backend_mut(),
|
||||
event::DisableMouseCapture
|
||||
)
|
||||
.unwrap_or_default();
|
||||
|
||||
event_reader.stop();
|
||||
|
||||
@ -511,7 +561,10 @@ impl Runner {
|
||||
if s.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("process exited with code {}", &s))
|
||||
Err(format!(
|
||||
"process exited with code {}",
|
||||
&s
|
||||
))
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|e| Err(e.to_string()));
|
||||
@ -520,10 +573,12 @@ impl Runner {
|
||||
match pipe_reader::read_all(&app.pipe.msg_in) {
|
||||
Ok(msgs) => {
|
||||
for msg in msgs {
|
||||
app = app.handle_task(app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
))?;
|
||||
app = app.handle_task(
|
||||
app::Task::new(
|
||||
app::MsgIn::External(msg),
|
||||
None,
|
||||
),
|
||||
)?;
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
@ -551,7 +606,8 @@ impl Runner {
|
||||
mouse_enabled = true;
|
||||
}
|
||||
Err(e) => {
|
||||
app = app.log_error(e.to_string())?;
|
||||
app =
|
||||
app.log_error(e.to_string())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -570,7 +626,8 @@ impl Runner {
|
||||
terminal.clear()?;
|
||||
terminal.set_cursor(0, 0)?;
|
||||
execute!(terminal.backend_mut(), term::LeaveAlternateScreen)?;
|
||||
execute!(terminal.backend_mut(), event::DisableMouseCapture).unwrap_or_default();
|
||||
execute!(terminal.backend_mut(), event::DisableMouseCapture)
|
||||
.unwrap_or_default();
|
||||
term::disable_raw_mode()?;
|
||||
terminal.show_cursor()?;
|
||||
|
||||
|
246
src/ui.rs
246
src/ui.rs
@ -17,10 +17,14 @@ use std::env;
|
||||
use std::ops::BitXor;
|
||||
use tui::backend::Backend;
|
||||
use tui::layout::Rect as TuiRect;
|
||||
use tui::layout::{Constraint as TuiConstraint, Direction, Layout as TuiLayout};
|
||||
use tui::layout::{
|
||||
Constraint as TuiConstraint, Direction, Layout as TuiLayout,
|
||||
};
|
||||
use tui::style::{Color, Modifier as TuiModifier, Style as TuiStyle};
|
||||
use tui::text::{Span, Spans, Text};
|
||||
use tui::widgets::{Block, Borders as TuiBorders, Cell, List, ListItem, Paragraph, Row, Table};
|
||||
use tui::widgets::{
|
||||
Block, Borders as TuiBorders, Cell, List, ListItem, Paragraph, Row, Table,
|
||||
};
|
||||
use tui::Frame;
|
||||
|
||||
lazy_static! {
|
||||
@ -55,7 +59,8 @@ pub struct LayoutOptions {
|
||||
impl LayoutOptions {
|
||||
pub fn extend(mut self, other: &Self) -> Self {
|
||||
self.margin = other.margin.or(self.margin);
|
||||
self.horizontal_margin = other.horizontal_margin.or(self.horizontal_margin);
|
||||
self.horizontal_margin =
|
||||
other.horizontal_margin.or(self.horizontal_margin);
|
||||
self.vertical_margin = other.vertical_margin.or(self.vertical_margin);
|
||||
self.constraints = other.constraints.to_owned().or(self.constraints);
|
||||
self
|
||||
@ -157,7 +162,9 @@ impl Layout {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Serialize, Deserialize,
|
||||
)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub enum Border {
|
||||
Top,
|
||||
@ -177,7 +184,9 @@ impl Border {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Serialize, Deserialize)]
|
||||
#[derive(
|
||||
Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Serialize, Deserialize,
|
||||
)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub enum Modifier {
|
||||
Bold,
|
||||
@ -220,8 +229,10 @@ impl Style {
|
||||
pub fn extend(mut self, other: &Self) -> Self {
|
||||
self.fg = other.fg.or(self.fg);
|
||||
self.bg = other.bg.or(self.bg);
|
||||
self.add_modifiers = other.add_modifiers.to_owned().or(self.add_modifiers);
|
||||
self.sub_modifiers = other.sub_modifiers.to_owned().or(self.sub_modifiers);
|
||||
self.add_modifiers =
|
||||
other.add_modifiers.to_owned().or(self.add_modifiers);
|
||||
self.sub_modifiers =
|
||||
other.sub_modifiers.to_owned().or(self.sub_modifiers);
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -241,8 +252,12 @@ impl Into<TuiStyle> for Style {
|
||||
TuiStyle {
|
||||
fg: self.fg,
|
||||
bg: self.bg,
|
||||
add_modifier: TuiModifier::from_bits_truncate(xor(self.add_modifiers)),
|
||||
sub_modifier: TuiModifier::from_bits_truncate(xor(self.sub_modifiers)),
|
||||
add_modifier: TuiModifier::from_bits_truncate(xor(
|
||||
self.add_modifiers
|
||||
)),
|
||||
sub_modifier: TuiModifier::from_bits_truncate(xor(
|
||||
self.sub_modifiers
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -271,7 +286,11 @@ pub enum Constraint {
|
||||
}
|
||||
|
||||
impl Constraint {
|
||||
pub fn to_tui(self, screen_size: TuiRect, layout_size: TuiRect) -> TuiConstraint {
|
||||
pub fn to_tui(
|
||||
self,
|
||||
screen_size: TuiRect,
|
||||
layout_size: TuiRect,
|
||||
) -> TuiConstraint {
|
||||
match self {
|
||||
Self::Percentage(n) => TuiConstraint::Percentage(n),
|
||||
Self::Ratio(x, y) => TuiConstraint::Ratio(x, y),
|
||||
@ -289,15 +308,31 @@ impl Constraint {
|
||||
TuiConstraint::Length(layout_size.width.max(n) - n)
|
||||
}
|
||||
Self::Max(n) => TuiConstraint::Max(n),
|
||||
Self::MaxLessThanScreenHeight(n) => TuiConstraint::Max(screen_size.height.max(n) - n),
|
||||
Self::MaxLessThanScreenWidth(n) => TuiConstraint::Max(screen_size.width.max(n) - n),
|
||||
Self::MaxLessThanLayoutHeight(n) => TuiConstraint::Max(layout_size.height.max(n) - n),
|
||||
Self::MaxLessThanLayoutWidth(n) => TuiConstraint::Max(layout_size.width.max(n) - n),
|
||||
Self::MaxLessThanScreenHeight(n) => {
|
||||
TuiConstraint::Max(screen_size.height.max(n) - n)
|
||||
}
|
||||
Self::MaxLessThanScreenWidth(n) => {
|
||||
TuiConstraint::Max(screen_size.width.max(n) - n)
|
||||
}
|
||||
Self::MaxLessThanLayoutHeight(n) => {
|
||||
TuiConstraint::Max(layout_size.height.max(n) - n)
|
||||
}
|
||||
Self::MaxLessThanLayoutWidth(n) => {
|
||||
TuiConstraint::Max(layout_size.width.max(n) - n)
|
||||
}
|
||||
Self::Min(n) => TuiConstraint::Min(n),
|
||||
Self::MinLessThanScreenHeight(n) => TuiConstraint::Min(screen_size.height.max(n) - n),
|
||||
Self::MinLessThanScreenWidth(n) => TuiConstraint::Min(screen_size.width.max(n) - n),
|
||||
Self::MinLessThanLayoutHeight(n) => TuiConstraint::Min(layout_size.height.max(n) - n),
|
||||
Self::MinLessThanLayoutWidth(n) => TuiConstraint::Min(layout_size.width.max(n) - n),
|
||||
Self::MinLessThanScreenHeight(n) => {
|
||||
TuiConstraint::Min(screen_size.height.max(n) - n)
|
||||
}
|
||||
Self::MinLessThanScreenWidth(n) => {
|
||||
TuiConstraint::Min(screen_size.width.max(n) - n)
|
||||
}
|
||||
Self::MinLessThanLayoutHeight(n) => {
|
||||
TuiConstraint::Min(layout_size.height.max(n) - n)
|
||||
}
|
||||
Self::MinLessThanLayoutWidth(n) => {
|
||||
TuiConstraint::Min(layout_size.width.max(n) - n)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -437,7 +472,9 @@ fn draw_table<B: Backend>(
|
||||
let config = panel_config.default.to_owned().extend(&panel_config.table);
|
||||
let app_config = app.config.to_owned();
|
||||
let header_height = app_config.general.table.header.height.unwrap_or(1);
|
||||
let height: usize = (layout_size.height.max(header_height + 2) - (header_height + 2)).into();
|
||||
let height: usize = (layout_size.height.max(header_height + 2)
|
||||
- (header_height + 2))
|
||||
.into();
|
||||
|
||||
let rows = app
|
||||
.directory_buffer
|
||||
@ -476,8 +513,10 @@ fn draw_table<B: Backend>(
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut me = node.mime_essence.splitn(2, '/');
|
||||
let mimetype: String = me.next().map(|s| s.into()).unwrap_or_default();
|
||||
let mimesub: String = me.next().map(|s| s.into()).unwrap_or_default();
|
||||
let mimetype: String =
|
||||
me.next().map(|s| s.into()).unwrap_or_default();
|
||||
let mimesub: String =
|
||||
me.next().map(|s| s.into()).unwrap_or_default();
|
||||
|
||||
let mut node_type = if node.is_symlink {
|
||||
app_config.node_types.symlink.to_owned()
|
||||
@ -496,28 +535,39 @@ fn draw_table<B: Backend>(
|
||||
node_type = node_type.extend(conf);
|
||||
}
|
||||
|
||||
if let Some(conf) = app_config.node_types.extension.get(&node.extension) {
|
||||
if let Some(conf) =
|
||||
app_config.node_types.extension.get(&node.extension)
|
||||
{
|
||||
node_type = node_type.extend(conf);
|
||||
}
|
||||
|
||||
if let Some(conf) = app_config.node_types.special.get(&node.relative_path) {
|
||||
if let Some(conf) =
|
||||
app_config.node_types.special.get(&node.relative_path)
|
||||
{
|
||||
node_type = node_type.extend(conf);
|
||||
}
|
||||
|
||||
let (relative_index, is_before_focus, is_after_focus) =
|
||||
match dir.focus.cmp(&index) {
|
||||
Ordering::Greater => (dir.focus - index, true, false),
|
||||
Ordering::Greater => {
|
||||
(dir.focus - index, true, false)
|
||||
}
|
||||
Ordering::Less => (index - dir.focus, false, true),
|
||||
Ordering::Equal => (0, false, false),
|
||||
};
|
||||
|
||||
let (mut prefix, mut suffix, mut style) = {
|
||||
let ui = app_config.general.default_ui.to_owned();
|
||||
(ui.prefix, ui.suffix, ui.style.extend(&node_type.style))
|
||||
(
|
||||
ui.prefix,
|
||||
ui.suffix,
|
||||
ui.style.extend(&node_type.style),
|
||||
)
|
||||
};
|
||||
|
||||
if is_focused && is_selected {
|
||||
let ui = app_config.general.focus_selection_ui.to_owned();
|
||||
let ui =
|
||||
app_config.general.focus_selection_ui.to_owned();
|
||||
prefix = ui.prefix.to_owned().or(prefix);
|
||||
suffix = ui.suffix.to_owned().or(suffix);
|
||||
style = style.extend(&ui.style);
|
||||
@ -561,10 +611,16 @@ fn draw_table<B: Backend>(
|
||||
.iter()
|
||||
.filter_map(|c| {
|
||||
c.format.as_ref().map(|f| {
|
||||
let out: Result<String> = lua::call(lua, f, v.clone());
|
||||
let out: Result<String> =
|
||||
lua::call(lua, f, v.clone());
|
||||
match out {
|
||||
Ok(o) => ansi_to_text(o.bytes())
|
||||
.unwrap_or_else(|e| Text::raw(format!("{:?}", e))),
|
||||
.unwrap_or_else(|e| {
|
||||
Text::raw(format!(
|
||||
"{:?}",
|
||||
e
|
||||
))
|
||||
}),
|
||||
Err(e) => Text::raw(e.to_string()),
|
||||
}
|
||||
})
|
||||
@ -596,7 +652,9 @@ fn draw_table<B: Backend>(
|
||||
.widths(&table_constraints)
|
||||
.style(app_config.general.table.style.to_owned().into())
|
||||
.highlight_style(app_config.general.focus_ui.style.to_owned().into())
|
||||
.column_spacing(app_config.general.table.col_spacing.unwrap_or_default())
|
||||
.column_spacing(
|
||||
app_config.general.table.col_spacing.unwrap_or_default(),
|
||||
)
|
||||
.block(block(
|
||||
config,
|
||||
format!(
|
||||
@ -655,8 +713,8 @@ fn draw_selection<B: Backend>(
|
||||
.collect();
|
||||
|
||||
// Selected items
|
||||
let selection_list =
|
||||
List::new(selection).block(block(config, format!(" Selection ({}) ", selection_count)));
|
||||
let selection_list = List::new(selection)
|
||||
.block(block(config, format!(" Selection ({}) ", selection_count)));
|
||||
|
||||
f.render_widget(selection_list, layout_size);
|
||||
}
|
||||
@ -679,9 +737,10 @@ fn draw_help_menu<B: Backend>(
|
||||
.into_iter()
|
||||
.map(|l| match l {
|
||||
HelpMenuLine::Paragraph(p) => Row::new([Cell::from(p)].to_vec()),
|
||||
HelpMenuLine::KeyMap(k, remaps, h) => {
|
||||
Row::new([Cell::from(k), Cell::from(remaps.join("|")), Cell::from(h)].to_vec())
|
||||
}
|
||||
HelpMenuLine::KeyMap(k, remaps, h) => Row::new(
|
||||
[Cell::from(k), Cell::from(remaps.join("|")), Cell::from(h)]
|
||||
.to_vec(),
|
||||
),
|
||||
})
|
||||
.collect::<Vec<Row>>();
|
||||
|
||||
@ -751,7 +810,8 @@ fn draw_sort_n_filter<B: Backend>(
|
||||
.to_owned()
|
||||
.extend(&panel_config.sort_and_filter);
|
||||
let ui = app.config.general.sort_and_filter_ui.to_owned();
|
||||
let filter_by: &IndexSet<NodeFilterApplicable> = &app.explorer_config.filters;
|
||||
let filter_by: &IndexSet<NodeFilterApplicable> =
|
||||
&app.explorer_config.filters;
|
||||
let sort_by: &IndexSet<NodeSorterApplicable> = &app.explorer_config.sorters;
|
||||
let defaultui = &ui.default_identifier;
|
||||
let forwardui = defaultui
|
||||
@ -786,7 +846,10 @@ fn draw_sort_n_filter<B: Backend>(
|
||||
.map(|u| {
|
||||
let ui = defaultui.to_owned().extend(u);
|
||||
(
|
||||
Span::styled(ui.format.to_owned().unwrap_or_default(), ui.style.into()),
|
||||
Span::styled(
|
||||
ui.format.to_owned().unwrap_or_default(),
|
||||
ui.style.into(),
|
||||
),
|
||||
Span::styled(
|
||||
direction.format.to_owned().unwrap_or_default(),
|
||||
direction.style.to_owned().into(),
|
||||
@ -847,7 +910,11 @@ fn draw_logs<B: Backend>(
|
||||
app::LogLevel::Warning => ListItem::new(format!(
|
||||
"{} | {} | {}",
|
||||
&time,
|
||||
&logs_config.warning.format.to_owned().unwrap_or_default(),
|
||||
&logs_config
|
||||
.warning
|
||||
.format
|
||||
.to_owned()
|
||||
.unwrap_or_default(),
|
||||
l.message
|
||||
))
|
||||
.style(logs_config.warning.style.to_owned().into()),
|
||||
@ -855,7 +922,11 @@ fn draw_logs<B: Backend>(
|
||||
app::LogLevel::Success => ListItem::new(format!(
|
||||
"{} | {} | {}",
|
||||
&time,
|
||||
&logs_config.success.format.to_owned().unwrap_or_default(),
|
||||
&logs_config
|
||||
.success
|
||||
.format
|
||||
.to_owned()
|
||||
.unwrap_or_default(),
|
||||
l.message
|
||||
))
|
||||
.style(logs_config.success.style.to_owned().into()),
|
||||
@ -863,7 +934,11 @@ fn draw_logs<B: Backend>(
|
||||
app::LogLevel::Error => ListItem::new(format!(
|
||||
"{} | {} | {}",
|
||||
&time,
|
||||
&logs_config.error.format.to_owned().unwrap_or_default(),
|
||||
&logs_config
|
||||
.error
|
||||
.format
|
||||
.to_owned()
|
||||
.unwrap_or_default(),
|
||||
l.message
|
||||
))
|
||||
.style(logs_config.error.style.to_owned().into()),
|
||||
@ -911,7 +986,8 @@ pub fn draw_custom_content<B: Backend>(
|
||||
|
||||
match body {
|
||||
ContentBody::StaticParagraph { render } => {
|
||||
let render = ansi_to_text(render.bytes()).unwrap_or_else(|e| Text::raw(e.to_string()));
|
||||
let render = ansi_to_text(render.bytes())
|
||||
.unwrap_or_else(|e| Text::raw(e.to_string()));
|
||||
let content = Paragraph::new(render).block(block(
|
||||
config,
|
||||
title.map(|t| format!(" {} ", t)).unwrap_or_default(),
|
||||
@ -928,10 +1004,14 @@ pub fn draw_custom_content<B: Backend>(
|
||||
|
||||
let render = lua
|
||||
.to_value(&ctx)
|
||||
.map(|arg| lua::call(lua, &render, arg).unwrap_or_else(|e| format!("{:?}", e)))
|
||||
.map(|arg| {
|
||||
lua::call(lua, &render, arg)
|
||||
.unwrap_or_else(|e| format!("{:?}", e))
|
||||
})
|
||||
.unwrap_or_else(|e| e.to_string());
|
||||
|
||||
let render = ansi_to_text(render.bytes()).unwrap_or_else(|e| Text::raw(e.to_string()));
|
||||
let render = ansi_to_text(render.bytes())
|
||||
.unwrap_or_else(|e| Text::raw(e.to_string()));
|
||||
|
||||
let content = Paragraph::new(render).block(block(
|
||||
config,
|
||||
@ -943,7 +1023,10 @@ pub fn draw_custom_content<B: Backend>(
|
||||
ContentBody::StaticList { render } => {
|
||||
let items = render
|
||||
.into_iter()
|
||||
.map(|item| ansi_to_text(item.bytes()).unwrap_or_else(|e| Text::raw(e.to_string())))
|
||||
.map(|item| {
|
||||
ansi_to_text(item.bytes())
|
||||
.unwrap_or_else(|e| Text::raw(e.to_string()))
|
||||
})
|
||||
.map(ListItem::new)
|
||||
.collect::<Vec<ListItem>>();
|
||||
|
||||
@ -964,11 +1047,15 @@ pub fn draw_custom_content<B: Backend>(
|
||||
let items = lua
|
||||
.to_value(&ctx)
|
||||
.map(|arg| {
|
||||
lua::call(lua, &render, arg).unwrap_or_else(|e| vec![format!("{:?}", e)])
|
||||
lua::call(lua, &render, arg)
|
||||
.unwrap_or_else(|e| vec![format!("{:?}", e)])
|
||||
})
|
||||
.unwrap_or_else(|e| vec![e.to_string()])
|
||||
.into_iter()
|
||||
.map(|item| ansi_to_text(item.bytes()).unwrap_or_else(|e| Text::raw(e.to_string())))
|
||||
.map(|item| {
|
||||
ansi_to_text(item.bytes())
|
||||
.unwrap_or_else(|e| Text::raw(e.to_string()))
|
||||
})
|
||||
.map(ListItem::new)
|
||||
.collect::<Vec<ListItem>>();
|
||||
|
||||
@ -990,8 +1077,9 @@ pub fn draw_custom_content<B: Backend>(
|
||||
Row::new(
|
||||
cols.into_iter()
|
||||
.map(|item| {
|
||||
ansi_to_text(item.bytes())
|
||||
.unwrap_or_else(|e| Text::raw(e.to_string()))
|
||||
ansi_to_text(item.bytes()).unwrap_or_else(|e| {
|
||||
Text::raw(e.to_string())
|
||||
})
|
||||
})
|
||||
.map(Cell::from)
|
||||
.collect::<Vec<Cell>>(),
|
||||
@ -1029,7 +1117,8 @@ pub fn draw_custom_content<B: Backend>(
|
||||
let rows = lua
|
||||
.to_value(&ctx)
|
||||
.map(|arg| {
|
||||
lua::call(lua, &render, arg).unwrap_or_else(|e| vec![vec![format!("{:?}", e)]])
|
||||
lua::call(lua, &render, arg)
|
||||
.unwrap_or_else(|e| vec![vec![format!("{:?}", e)]])
|
||||
})
|
||||
.unwrap_or_else(|e| vec![vec![e.to_string()]])
|
||||
.into_iter()
|
||||
@ -1037,8 +1126,9 @@ pub fn draw_custom_content<B: Backend>(
|
||||
Row::new(
|
||||
cols.into_iter()
|
||||
.map(|item| {
|
||||
ansi_to_text(item.bytes())
|
||||
.unwrap_or_else(|e| Text::raw(e.to_string()))
|
||||
ansi_to_text(item.bytes()).unwrap_or_else(|e| {
|
||||
Text::raw(e.to_string())
|
||||
})
|
||||
})
|
||||
.map(Cell::from)
|
||||
.collect::<Vec<Cell>>(),
|
||||
@ -1102,9 +1192,15 @@ pub fn draw_layout<B: Backend>(
|
||||
match layout {
|
||||
Layout::Nothing => draw_nothing(f, screen_size, layout_size, app, lua),
|
||||
Layout::Table => draw_table(f, screen_size, layout_size, app, lua),
|
||||
Layout::SortAndFilter => draw_sort_n_filter(f, screen_size, layout_size, app, lua),
|
||||
Layout::HelpMenu => draw_help_menu(f, screen_size, layout_size, app, lua),
|
||||
Layout::Selection => draw_selection(f, screen_size, layout_size, app, lua),
|
||||
Layout::SortAndFilter => {
|
||||
draw_sort_n_filter(f, screen_size, layout_size, app, lua)
|
||||
}
|
||||
Layout::HelpMenu => {
|
||||
draw_help_menu(f, screen_size, layout_size, app, lua)
|
||||
}
|
||||
Layout::Selection => {
|
||||
draw_selection(f, screen_size, layout_size, app, lua)
|
||||
}
|
||||
Layout::InputAndLogs => {
|
||||
if app.input_buffer.is_some() {
|
||||
draw_input_buffer(f, screen_size, layout_size, app, lua);
|
||||
@ -1112,9 +1208,15 @@ pub fn draw_layout<B: Backend>(
|
||||
draw_logs(f, screen_size, layout_size, app, lua);
|
||||
};
|
||||
}
|
||||
Layout::CustomContent { title, body } => {
|
||||
draw_custom_content(f, screen_size, layout_size, app, title, body, lua)
|
||||
}
|
||||
Layout::CustomContent { title, body } => draw_custom_content(
|
||||
f,
|
||||
screen_size,
|
||||
layout_size,
|
||||
app,
|
||||
title,
|
||||
body,
|
||||
lua,
|
||||
),
|
||||
Layout::Horizontal { config, splits } => {
|
||||
let chunks = TuiLayout::default()
|
||||
.direction(Direction::Horizontal)
|
||||
@ -1133,13 +1235,19 @@ pub fn draw_layout<B: Backend>(
|
||||
.or(config.margin)
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.vertical_margin(config.vertical_margin.or(config.margin).unwrap_or_default())
|
||||
.vertical_margin(
|
||||
config
|
||||
.vertical_margin
|
||||
.or(config.margin)
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.split(layout_size);
|
||||
|
||||
splits
|
||||
.into_iter()
|
||||
.zip(chunks.into_iter())
|
||||
.for_each(|(split, chunk)| draw_layout(split, f, screen_size, chunk, app, lua));
|
||||
splits.into_iter().zip(chunks.into_iter()).for_each(
|
||||
|(split, chunk)| {
|
||||
draw_layout(split, f, screen_size, chunk, app, lua)
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Layout::Vertical { config, splits } => {
|
||||
@ -1160,13 +1268,19 @@ pub fn draw_layout<B: Backend>(
|
||||
.or(config.margin)
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.vertical_margin(config.vertical_margin.or(config.margin).unwrap_or_default())
|
||||
.vertical_margin(
|
||||
config
|
||||
.vertical_margin
|
||||
.or(config.margin)
|
||||
.unwrap_or_default(),
|
||||
)
|
||||
.split(layout_size);
|
||||
|
||||
splits
|
||||
.into_iter()
|
||||
.zip(chunks.into_iter())
|
||||
.for_each(|(split, chunk)| draw_layout(split, f, screen_size, chunk, app, lua));
|
||||
splits.into_iter().zip(chunks.into_iter()).for_each(
|
||||
|(split, chunk)| {
|
||||
draw_layout(split, f, screen_size, chunk, app, lua)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user