summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqkzk <qkzk@users.noreply.github.com>2023-02-17 20:41:52 +0100
committerGitHub <noreply@github.com>2023-02-17 20:41:52 +0100
commit4d3093c4c7c7751fc78ab78f00b6db138e2fe292 (patch)
treefc64b7c963f4f9238d7bb329b81da19f1594a214
parent494cd8494fbdf6d89043933ec5cbfd78b5c848b4 (diff)
parentee10361122bb1c75ba978a04f7a2c401beae8eae (diff)
Merge pull request #71 from qkzk/better-tree-explorationv0.1.17
Better tree exploration
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock256
-rw-r--r--Cargo.toml8
-rw-r--r--development.md40
-rw-r--r--src/action_map.rs18
-rw-r--r--src/completion.rs18
-rw-r--r--src/compress.rs178
-rw-r--r--src/decompress.rs65
-rw-r--r--src/event_dispatch.rs12
-rw-r--r--src/event_exec.rs205
-rw-r--r--src/fm_error.rs21
-rw-r--r--src/git.rs18
-rw-r--r--src/help.rs4
-rw-r--r--src/keybindings.rs4
-rw-r--r--src/lib.rs1
-rw-r--r--src/marks.rs61
-rw-r--r--src/mode.rs16
-rw-r--r--src/opener.rs33
-rw-r--r--src/preview.rs4
-rw-r--r--src/status.rs6
-rw-r--r--src/tab.rs3
-rw-r--r--src/term_manager.rs43
-rw-r--r--src/tree.rs52
23 files changed, 908 insertions, 159 deletions
diff --git a/.gitignore b/.gitignore
index b8d5b8f..5ebe603 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/target
*.log
*.vimspector*
+*compress_example
diff --git a/Cargo.lock b/Cargo.lock
index 1b83a2a..aa31c46 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,6 +18,18 @@ dependencies = [
]
[[package]]
+name = "aes"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+ "opaque-debug",
+]
+
+[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -186,6 +198,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
+name = "base64ct"
+version = "1.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
+
+[[package]]
name = "beef"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -246,10 +264,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
+name = "bzip2"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
+dependencies = [
+ "bzip2-sys",
+ "libc",
+]
+
+[[package]]
+name = "bzip2-sys"
+version = "0.1.11+1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
name = "cc"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+dependencies = [
+ "jobserver",
+]
[[package]]
name = "cfg-if"
@@ -273,6 +315,15 @@ dependencies = [
]
[[package]]
+name = "cipher"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -351,18 +402,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
-name = "compress-tools"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a3b1511783270e75d95749c851008a01fba662a8136e488d29d2b3a51a56e08"
-dependencies = [
- "derive_more",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
name = "concurrent-queue"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -391,6 +430,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935"
[[package]]
+name = "constant_time_eq"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
+
+[[package]]
name = "content_inspector"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -646,17 +691,6 @@ dependencies = [
]
[[package]]
-name = "derive_more"
-version = "0.99.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "destructure_traitobject"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -670,6 +704,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
dependencies = [
"block-buffer",
"crypto-common",
+ "subtle",
]
[[package]]
@@ -911,6 +946,18 @@ dependencies = [
]
[[package]]
+name = "filetime"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "windows-sys",
+]
+
+[[package]]
name = "flate2"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -935,13 +982,13 @@ dependencies = [
[[package]]
name = "fm-tui"
-version = "0.1.16"
+version = "0.1.17"
dependencies = [
"chrono",
"clap 4.0.32",
- "compress-tools",
"content_inspector",
"copypasta",
+ "flate2",
"fs_extra",
"image",
"indicatif",
@@ -949,9 +996,11 @@ dependencies = [
"log",
"log4rs",
"notify-rust",
+ "pathdiff",
"pdf-extract",
"rand",
"regex",
+ "rust-lzma",
"sanitize-filename",
"serde_yaml 0.9.16",
"shellexpand",
@@ -961,9 +1010,11 @@ dependencies = [
"strum_macros 0.24.3",
"syntect",
"sysinfo",
+ "tar",
"tuikit",
"url-escape",
"users",
+ "zip",
]
[[package]]
@@ -1128,6 +1179,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
+name = "hmac"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+dependencies = [
+ "digest",
+]
+
+[[package]]
name = "humantime"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1249,6 +1309,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
[[package]]
+name = "jobserver"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "jpeg-decoder"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1675,6 +1744,12 @@ dependencies = [
]
[[package]]
+name = "opaque-debug"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
+
+[[package]]
name = "ordered-float"
version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1729,6 +1804,35 @@ dependencies = [
]
[[package]]
+name = "password-hash"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
+dependencies = [
+ "base64ct",
+ "rand_core",
+ "subtle",
+]
+
+[[package]]
+name = "pathdiff"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+
+[[package]]
+name = "pbkdf2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
+dependencies = [
+ "digest",
+ "hmac",
+ "password-hash",
+ "sha2",
+]
+
+[[package]]
name = "pdf-extract"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2034,6 +2138,15 @@ dependencies = [
]
[[package]]
+name = "rust-lzma"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "895dc04daeaeee338bb96e229797902ed3f0675bfc59d5b42e0f0b0c13ac54da"
+dependencies = [
+ "pkg-config",
+]
+
+[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2236,6 +2349,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012"
[[package]]
+name = "sha2"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
name = "shellexpand"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2473,6 +2597,12 @@ dependencies = [
]
[[package]]
+name = "subtle"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
+
+[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2522,6 +2652,17 @@ dependencies = [
]
[[package]]
+name = "tar"
+version = "0.4.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6"
+dependencies = [
+ "filetime",
+ "libc",
+ "xattr",
+]
+
+[[package]]
name = "tauri-winrt-notification"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2892,12 +3033,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
[[package]]
-name = "vcpkg"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
-
-[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3265,6 +3400,15 @@ dependencies = [
]
[[package]]
+name = "xattr"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "xcb"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3363,6 +3507,56 @@ dependencies = [
]
[[package]]
+name = "zip"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0445d0fbc924bb93539b4316c11afb121ea39296f99a3c4c9edad09e3658cdef"
+dependencies = [
+ "aes",
+ "byteorder",
+ "bzip2",
+ "constant_time_eq",
+ "crc32fast",
+ "crossbeam-utils",
+ "flate2",
+ "hmac",
+ "pbkdf2",
+ "sha1 0.10.5",
+ "time 0.3.17",
+ "zstd",
+]
+
+[[package]]
+name = "zstd"
+version = "0.11.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "5.0.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.7+zstd.1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
name = "zvariant"
version = "3.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 54ac5c4..7281912 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "fm-tui"
-version = "0.1.16"
+version = "0.1.17"
authors = ["Quentin Konieczko <qu3nt1n@gmail.com>"]
edition = "2021"
license-file = "LICENSE.txt"
@@ -31,9 +31,9 @@ fs_extra = "1.2.0"
[dependencies]
chrono = "0.4.22"
clap = { version = "4.0.2", features = ["derive"] }
-compress-tools = "0.14.0"
content_inspector = "0.2.4"
copypasta = "0.8.1"
+flate2 = "1.0"
fs_extra = "1.2.0"
image = "0.24.5"
indicatif = { version = "0.17.1", features= ["in_memory"] }
@@ -41,9 +41,11 @@ kamadak-exif = "0.5.5"
log = { version = "0.4.0", features = ["std"] }
log4rs = {version = "1.2.0", features = ["rolling_file_appender", "compound_policy", "size_trigger", "fixed_window_roller"] }
notify-rust = "4.5.10"
+pathdiff = "0.2.1"
pdf-extract = "0.6.4"
rand = "0.8.5"
regex = "1.6.0"
+rust-lzma = "0.5.1"
sanitize-filename = "0.4.0"
serde_yaml = "0.9.13"
shellexpand = "2.1.2"
@@ -53,6 +55,8 @@ strum = {version = "0.24.1", features = ["derive"]}
strum_macros = "0.24.3"
syntect = "5.0.0"
sysinfo = "0.26.7"
+tar = "0.4.38"
tuikit = "0.5.0"
url-escape = "0.1.1"
users = "0.11.0"
+zip = "0.6.4"
diff --git a/development.md b/development.md
index f1ce896..bd6eb03 100644
--- a/development.md
+++ b/development.md
@@ -340,6 +340,29 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
- [x] Add a shortcut to the config folder
- [x] use g to go to the mounted encrypted drive
+### Version 0.1.16 : fix completion & filter in tree
+
+- [x] FIX: can't parse uid gid if they only exists on a remote machine. See https://serverfault.com/questions/514118/mapping-uid-and-gid-of-local-user-to-the-mounted-nfs-share
+ for a fix.
+- [x] FIX: truncate file size in preview mode.
+- [x] FIX: in tree mode search is backward
+- [x] FIX: when searching from tree mode, it only completes with level 1 elements, not nested ones.
+- [x] FIX: when exiting search in tree mode, second line isn't updated
+- [x] FIX: when filtering in tree mode, only the level 1 matching elements are displayed
+ Decided to keep directories when filtering in tree mode. Those are excluded when filtering in normal mode.
+- [x] Tree: move 10 rows at a time
+
+### Version 0.1.17 : git root, navigable marks, compression/decompression, command mode, lazygit
+
+- [x] git root: cd to git root
+- [x] tree: use the length of the screen to avoid parsing non displayed lines
+- [x] navigate in marks: pick a mark and jump to it with enter
+- [x] compress flagged files: pick a compression algorithm from a list.
+- [x] decompress any archive we can create
+- [x] command mode with ":" and a command. (ie `:ClearFlags`). Command are completed.
+ some commands does nothing :(
+- [x] lazygit integration: open a terminal with lazygit in current path. Obviously (lazygit)[https://github.com/jesseduffield/lazygit] should be installed.
+
## TODO
- [ ] remote control
@@ -361,20 +384,9 @@ New view: Tree ! Toggle with 't', fold with 'z'. Navigate normally.
- [ ] vim keys, harmonize keybinds with ranger
- [ ] zoxide support
-
-- [ ] scrollable shortcuts, marks & history
-
-- [ ] Version 0.1.16 : fix completion & filter in tree
-
- - [x] FIX: can't parse uid gid if they only exists on a remote machine. See https://serverfault.com/questions/514118/mapping-uid-and-gid-of-local-user-to-the-mounted-nfs-share
- for a fix.
- - [x] FIX: truncate file size in preview mode.
- - [x] FIX: in tree mode search is backward
- - [x] FIX: when searching from tree mode, it only completes with level 1 elements, not nested ones.
- - [x] FIX: when exiting search in tree mode, second line isn't updated
- - [x] FIX: when filtering in tree mode, only the level 1 matching elements are displayed
- Decided to keep directories when filtering in tree mode. Those are excluded when filtering in normal mode.
- - [x] Tree: move 10 rows at a time
+- [ ] make navigable content scrollable
+- [ ] temporary marks
+- [ ] context switch
- [ ] Version 0.1.50 : safety & memory usage
diff --git a/src/action_map.rs b/src/action_map.rs
index f84d60b..d3fef16 100644
--- a/src/action_map.rs
+++ b/src/action_map.rs
@@ -1,4 +1,4 @@
-use strum_macros::{Display, EnumString};
+use strum_macros::{Display, EnumIter, EnumString};
use crate::config::Colors;
use crate::event_exec::EventExec;
@@ -9,7 +9,7 @@ use crate::status::Status;
/// All those actions are mapped to a key and this enum
/// makes the junction between received Key events and
/// actions in the application.
-#[derive(Clone, Debug, Display, EnumString)]
+#[derive(Clone, Debug, Display, EnumString, EnumIter)]
pub enum ActionMap {
Back,
BackTab,
@@ -17,6 +17,8 @@ pub enum ActionMap {
Bulkrename,
Chmod,
ClearFlags,
+ Command,
+ Compress,
CopyFilename,
CopyFilepath,
CopyPaste,
@@ -32,12 +34,14 @@ pub enum ActionMap {
Filter,
FlagAll,
FuzzyFind,
+ GitRoot,
Goto,
Help,
History,
Home,
Jump,
KeyHome,
+ Lazygit,
MarksJump,
MarksNew,
ModeNormal,
@@ -49,6 +53,7 @@ pub enum ActionMap {
NewFile,
Nothing,
NvimFilepicker,
+ OpenConfig,
OpenFile,
PageDown,
PageUp,
@@ -77,7 +82,6 @@ pub enum ActionMap {
TreeFold,
TreeUnFoldAll,
TreeFoldAll,
- OpenConfig,
}
impl ActionMap {
@@ -92,6 +96,8 @@ impl ActionMap {
ActionMap::Bulkrename => EventExec::event_bulkrename(status),
ActionMap::Chmod => EventExec::event_chmod(status),
ActionMap::ClearFlags => EventExec::event_clear_flags(status),
+ ActionMap::Command => EventExec::event_command(current_tab),
+ ActionMap::Compress => EventExec::event_compress(status),
ActionMap::CopyFilename => EventExec::event_copy_filename(status),
ActionMap::CopyFilepath => EventExec::event_copy_filepath(status),
ActionMap::CopyPaste => EventExec::event_copy_paste(status),
@@ -107,10 +113,12 @@ impl ActionMap {
ActionMap::Filter => EventExec::event_filter(current_tab),
ActionMap::FlagAll => EventExec::event_flag_all(status),
ActionMap::FuzzyFind => EventExec::event_fuzzyfind(status),
+ ActionMap::GitRoot => EventExec::event_git_root(current_tab),
ActionMap::Goto => EventExec::event_goto(current_tab),
ActionMap::Help => EventExec::event_help(status),
ActionMap::History => EventExec::event_history(current_tab),
ActionMap::Home => EventExec::event_home(current_tab),
+ ActionMap::Lazygit => EventExec::event_lazygit(status),
ActionMap::Jump => EventExec::event_jump(status),
ActionMap::KeyHome => EventExec::event_key_home(status, colors),
ActionMap::MarksJump => EventExec::event_marks_jump(status),
@@ -149,8 +157,8 @@ impl ActionMap {
ActionMap::TrashOpen => EventExec::event_trash_open(status),
ActionMap::Tree => EventExec::event_tree(status, colors),
ActionMap::TreeFold => EventExec::event_tree_fold(current_tab, colors),
- ActionMap::TreeFoldAll => EventExec::event_tree_fold_all(status, colors),
- ActionMap::TreeUnFoldAll => EventExec::event_tree_unfold_all(status, colors),
+ ActionMap::TreeFoldAll => EventExec::event_tree_fold_all(current_tab, colors),
+ ActionMap::TreeUnFoldAll => EventExec::event_tree_unfold_all(current_tab, colors),
ActionMap::OpenConfig => EventExec::event_open_config(status),
ActionMap::Nothing => Ok(()),
diff --git a/src/completion.rs b/src/completion.rs
index 6894bb8..a4733ae 100644
--- a/src/completion.rs
+++ b/src/completion.rs
@@ -1,5 +1,7 @@
use std::fs::{self, ReadDir};
+use strum::IntoEnumIterator;
+
use crate::fileinfo::PathContent;
use crate::fm_error::FmResult;
use crate::mode::Mode;
@@ -17,6 +19,8 @@ pub enum InputCompleted {
Search,
/// Complete an executable name from $PATH
Exec,
+ /// Command
+ Command,
}
/// Holds a `Vec<String>` of possible completions and an `usize` index
@@ -158,6 +162,20 @@ impl Completion {
Ok(())
}
+ pub fn command(&mut self, input_string: &str) -> FmResult<()> {
+ let proposals = crate::action_map::ActionMap::iter()
+ .filter(|command| {
+ command
+ .to_string()
+ .to_lowercase()
+ .contains(&input_string.to_lowercase())
+ })
+ .map(|command| command.to_string())
+ .collect();
+ self.update(proposals);
+ Ok(())
+ }
+
fn find_completion_in_path(
path: std::path::PathBuf,
input_string: &str,
diff --git a/src/compress.rs b/src/compress.rs
index 7ba8559..ac3ca50 100644
--- a/src/compress.rs
+++ b/src/compress.rs
@@ -1,29 +1,155 @@
-use std::fs::File;
-use std::path::Path;
-
-use compress_tools::*;
-
-use crate::fm_error::{FmError, FmResult};
-
-/// Decompress a compressed file into its parent directory.
-/// It may fail an return a `FmError` if the file has no parent,
-/// which should be impossible.
-/// It used `compress_tools` which is a wrapper around `libarchive`.
-pub fn decompress(source: &Path) -> FmResult<()> {
- let parent = source
- .parent()
- .ok_or_else(|| FmError::custom("decompress", "source should have a parent"))?;
- let file = File::open(source)?;
- Ok(uncompress_archive(&file, parent, Ownership::Preserve)?)
+use std::fmt::Display;
+use std::io::prelude::*;
+use std::io::Write;
+
+use crate::fm_error::FmResult;
+use crate::impl_selectable_content;
+use flate2::write::{DeflateEncoder, GzEncoder, ZlibEncoder};
+use flate2::Compression;
+use lzma::LzmaWriter;
+use zip::write::FileOptions;
+
+/// Different kind of compression methods
+#[derive(Debug)]
+pub enum CompressionMethod {
+ ZIP,
+ DEFLATE,
+ GZ,
+ ZLIB,
+ LZMA,
}
-/// Returns a list of compressed files within the archive.
-/// it may fail if the file can't be opened or if libarchive
-/// can't read it.
-pub fn list_files<P>(source: P) -> FmResult<Vec<String>>
-where
- P: AsRef<Path>,
-{
- let file = File::open(source)?;
- Ok(list_archive_files(file)?)
+impl Display for CompressionMethod {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ match self {
+ Self::ZIP => write!(f, "ZIP: archive.zip"),
+ Self::DEFLATE => write!(f, "DEFLATE: archive.tar.gz"),
+ Self::LZMA => write!(f, "LZMA: archive.tar.xz"),
+ Self::GZ => write!(f, "GZ: archive.tar.gz"),
+ Self::ZLIB => write!(f, "ZLIB: archive.tar.xz"),
+ }
+ }
}
+/// Holds a vector of CompressionMethod and a few methods to compress some files.
+#[derive(Debug)]
+pub struct Compresser {
+ content: Vec<CompressionMethod>,
+ pub index: usize,
+}
+
+impl Default for Compresser {
+ fn default() -> Self {
+ Self {
+ content: vec![
+ CompressionMethod::ZIP,
+ CompressionMethod::LZMA,
+ CompressionMethod::ZLIB,
+ CompressionMethod::GZ,
+ CompressionMethod::DEFLATE,
+ ],
+ index: 0,
+ }
+ }
+}
+
+impl Compresser {
+ /// Archive the files with tar and compress them with the selected method.
+ /// The compression method is chosen by the user.
+ pub fn compress(&self, files: Vec<std::path::PathBuf>) -> FmResult<()> {
+ let Some(selected) = self.selected() else { return Ok(()) };
+ match selected {
+ CompressionMethod::DEFLATE => Self::compress_deflate("archive.tar.gz", files),
+ CompressionMethod::GZ => Self::compress_gzip("archive.tar.gz", files),
+ CompressionMethod::ZLIB => Self::compress_zlib("archive.tar.xz", files),
+ CompressionMethod::ZIP => Self::compress_zip("archive.zip", files),
+ CompressionMethod::LZMA => Self::compress_lzma("archive.tar.xz", files),
+ }
+ }
+
+ fn make_tar<W>(files: Vec<std::path::PathBuf>, mut archive: tar::Builder<W>) -> FmResult<()>
+ where
+ W: Write,
+ {
+ for file in files.iter() {
+ if file.is_dir() {
+ archive.append_dir_all(file, file)?;
+ } else {
+ archive.append_path(file)?;
+ }
+ }
+ Ok(())
+ }
+
+ fn compress_gzip(archive_name: &str, files: Vec<std::path::PathBuf>) -> FmResult<()> {
+ let compressed_file = std::fs::File::create(archive_name)?;
+ let mut encoder = GzEncoder::new(compressed_file, Compression::default());
+
+ // Create tar archive and compress files
+ Self::make_tar(files, tar::Builder::new(&mut encoder))?;
+
+ // Finish Gzip file
+ encoder.finish()?;
+
+ Ok(())
+ }
+
+ fn compress_deflate(archive_name: &str, files: Vec<std::path::PathBuf>) -> FmResult<()> {
+ let compressed_file = std::fs::File::create(archive_name)?;
+ let mut encoder = DeflateEncoder::new(compressed_file, Compression::default());
+
+ // Create tar archive and compress files
+ Self::make_tar(files, tar::Builder::new(&mut encoder))?;
+
+ // Finish deflate file
+ encoder.finish()?;
+
+ Ok(())
+ }
+
+ fn compress_zlib(archive_name: &str, files: Vec<std::path::PathBuf>) -> FmResult<()> {
+ let compressed_file = std::fs::File::create(archive_name)?;
+ let mut encoder = ZlibEncoder::new(compressed_file, Compression::default());
+
+ // Create tar archive and compress files
+ Self::make_tar(files, tar::Builder::new(&mut encoder))?;
+
+ // Finish zlib file
+ encoder.finish()?;
+
+ Ok(())
+ }
+
+ fn compress_lzma(archive_name: &str, files: Vec<std::path::PathBuf>) -> FmResult<()> {
+ let compressed_file = std::fs::File::create(archive_name)?;
+ let mut encoder = LzmaWriter::new_compressor(compressed_file, 6)?;
+
+ // Create tar archive and compress files
+ Self::make_tar(files, tar::Builder::new(&mut encoder))?;
+
+ // Finish lzma file
+ encoder.finish()?;
+
+ Ok(())
+ }
+
+ fn compress_zip(archive_name: &str, files: Vec<std::path::PathBuf>) -> FmResult<()> {
+ let archive = std::fs::File::create(archive_name).unwrap();
+ let mut zip = zip::ZipWriter::new(archive);
+ for file in files.iter() {
+ zip.start_file(
+ file.to_st