mirror of
https://github.com/alexpasmantier/television.git
synced 2025-06-06 03:25:23 +00:00
fix(entry): always preserve raw input + match ranges conversions (#62)
* fix(entry): preserve raw input * chore(version): bump workspace crates and television * test: add tests for replace_non_printable and cleanup commented out code * chore(changelog): update changelog (auto) * chore(deps): update cargo dependencies --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
parent
b703e1b26c
commit
edd9df4e29
2
.github/workflows/changelog.yml
vendored
2
.github/workflows/changelog.yml
vendored
@ -36,5 +36,5 @@ jobs:
|
|||||||
git config user.email 'github-actions[bot]@users.noreply.github.com'
|
git config user.email 'github-actions[bot]@users.noreply.github.com'
|
||||||
set +e
|
set +e
|
||||||
git add CHANGELOG.md
|
git add CHANGELOG.md
|
||||||
git commit -m "Update changelog"
|
git commit -m "chore(changelog): update changelog (auto)"
|
||||||
git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git ${{ steps.extract_branch.outputs.branch }}
|
git push https://${{ secrets.GITHUB_TOKEN }}@github.com/${GITHUB_REPOSITORY}.git ${{ steps.extract_branch.outputs.branch }}
|
||||||
|
10
CHANGELOG.md
10
CHANGELOG.md
@ -7,6 +7,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
### 🐛 Bug Fixes
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
- Quote file names that contain spaces when printing them to stdout (#51)
|
- Quote file names that contain spaces when printing them to stdout (#51)
|
||||||
|
- *(entry)* Preserve raw input
|
||||||
|
|
||||||
### 🚜 Refactor
|
### 🚜 Refactor
|
||||||
|
|
||||||
@ -15,15 +16,20 @@ All notable changes to this project will be documented in this file.
|
|||||||
### 📚 Documentation
|
### 📚 Documentation
|
||||||
|
|
||||||
- Terminal emulators compatibility and good first issues (#56)
|
- Terminal emulators compatibility and good first issues (#56)
|
||||||
- *(contributing)* Add setup step
|
|
||||||
|
|
||||||
### 🎨 Styling
|
### 🎨 Styling
|
||||||
|
|
||||||
- *(git)* Enforce conventional commits on git push with a hook
|
- *(git)* Enforce conventional commits on git push with a hook (#61)
|
||||||
|
|
||||||
|
### 🧪 Testing
|
||||||
|
|
||||||
|
- Add tests for replace_non_printable and cleanup commented out code
|
||||||
|
|
||||||
### ⚙️ Miscellaneous Tasks
|
### ⚙️ Miscellaneous Tasks
|
||||||
|
|
||||||
- Add readme version update to github actions (#55)
|
- Add readme version update to github actions (#55)
|
||||||
|
- *(version)* Bump workspace crates and television
|
||||||
|
- *(changelog)* Update changelog (auto)
|
||||||
|
|
||||||
### Build
|
### Build
|
||||||
|
|
||||||
|
150
Cargo.lock
generated
150
Cargo.lock
generated
@ -249,20 +249,20 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.10.0"
|
version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c"
|
checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytemuck"
|
name = "bytemuck"
|
||||||
version = "1.19.0"
|
version = "1.20.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d"
|
checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
@ -351,9 +351,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.37"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf"
|
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
@ -366,9 +366,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.20"
|
version = "4.5.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
|
checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
@ -376,9 +376,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.20"
|
version = "4.5.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
|
checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
@ -400,9 +400,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_lex"
|
name = "clap_lex"
|
||||||
version = "0.7.2"
|
version = "0.7.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
|
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clipboard-win"
|
name = "clipboard-win"
|
||||||
@ -575,9 +575,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.14"
|
version = "0.2.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0"
|
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@ -749,6 +749,12 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diff"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
@ -905,9 +911,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.34"
|
version = "1.0.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
|
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"miniz_oxide 0.8.0",
|
"miniz_oxide 0.8.0",
|
||||||
@ -1484,7 +1490,7 @@ dependencies = [
|
|||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"bstr",
|
"bstr",
|
||||||
"log",
|
"log",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"regex-syntax 0.8.5",
|
"regex-syntax 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1716,7 +1722,7 @@ dependencies = [
|
|||||||
"globset",
|
"globset",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"same-file",
|
"same-file",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
@ -1746,10 +1752,14 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instability"
|
name = "instability"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c"
|
checksum = "b829f37dead9dc39df40c2d3376c179fdfd2ac771f53f55d3c30dc096a3c0c6e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"indoc",
|
||||||
|
"pretty_assertions",
|
||||||
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
@ -1771,9 +1781,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jiff"
|
name = "jiff"
|
||||||
@ -1825,9 +1835,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.162"
|
version = "0.2.164"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
@ -1864,9 +1874,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.7.3"
|
version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
|
checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
@ -2275,10 +2285,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "pretty_assertions"
|
||||||
version = "1.0.89"
|
version = "1.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
|
||||||
|
dependencies = [
|
||||||
|
"diff",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.92"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
@ -2386,7 +2406,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-automata 0.4.8",
|
"regex-automata 0.4.9",
|
||||||
"regex-syntax 0.8.5",
|
"regex-syntax 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2401,9 +2421,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-automata"
|
name = "regex-automata"
|
||||||
version = "0.4.8"
|
version = "0.4.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
|
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -2470,9 +2490,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.40"
|
version = "0.38.41"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0"
|
checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"errno",
|
"errno",
|
||||||
@ -2525,18 +2545,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.214"
|
version = "1.0.215"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5"
|
checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.214"
|
version = "1.0.215"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2545,9 +2565,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.132"
|
version = "1.0.133"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03"
|
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
@ -2748,9 +2768,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.87"
|
version = "2.0.89"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
|
checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2792,7 +2812,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "television"
|
name = "television"
|
||||||
version = "0.5.1"
|
version = "0.5.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"better-panic",
|
"better-panic",
|
||||||
"clap",
|
"clap",
|
||||||
@ -2823,7 +2843,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "television-channels"
|
name = "television-channels"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
@ -2842,7 +2862,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "television-derive"
|
name = "television-derive"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -2851,7 +2871,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "television-fuzzy"
|
name = "television-fuzzy"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nucleo",
|
"nucleo",
|
||||||
"parking_lot",
|
"parking_lot",
|
||||||
@ -2859,7 +2879,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "television-previewers"
|
name = "television-previewers"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"devicons",
|
"devicons",
|
||||||
@ -2874,7 +2894,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "television-utils"
|
name = "television-utils"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bat",
|
"bat",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
@ -3158,9 +3178,9 @@ checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.13"
|
version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-normalization"
|
name = "unicode-normalization"
|
||||||
@ -3208,9 +3228,9 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.3"
|
version = "2.5.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada"
|
checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
@ -3670,10 +3690,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yansi"
|
||||||
version = "0.7.4"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5"
|
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke"
|
||||||
|
version = "0.7.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"stable_deref_trait",
|
"stable_deref_trait",
|
||||||
@ -3683,9 +3709,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke-derive"
|
name = "yoke-derive"
|
||||||
version = "0.7.4"
|
version = "0.7.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -3715,18 +3741,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerofrom"
|
name = "zerofrom"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55"
|
checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zerofrom-derive",
|
"zerofrom-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerofrom-derive"
|
name = "zerofrom-derive"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
12
Cargo.toml
12
Cargo.toml
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "television"
|
name = "television"
|
||||||
version = "0.5.1"
|
version = "0.5.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "The revolution will be televised."
|
description = "The revolution will be televised."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -54,11 +54,11 @@ name = "tv"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# workspace dependencies
|
# workspace dependencies
|
||||||
television-fuzzy = { path = "crates/television-fuzzy", version = "0.0.5" }
|
television-fuzzy = { path = "crates/television-fuzzy", version = "0.0.6" }
|
||||||
television-derive = { path = "crates/television-derive", version = "0.0.5" }
|
television-derive = { path = "crates/television-derive", version = "0.0.6" }
|
||||||
television-channels = { path = "crates/television-channels", version = "0.0.5" }
|
television-channels = { path = "crates/television-channels", version = "0.0.6" }
|
||||||
television-previewers = { path = "crates/television-previewers", version = "0.0.5" }
|
television-previewers = { path = "crates/television-previewers", version = "0.0.6" }
|
||||||
television-utils = { path = "crates/television-utils", version = "0.0.5" }
|
television-utils = { path = "crates/television-utils", version = "0.0.6" }
|
||||||
|
|
||||||
# external dependencies
|
# external dependencies
|
||||||
better-panic = "0.3.0"
|
better-panic = "0.3.0"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "television-channels"
|
name = "television-channels"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@ -13,9 +13,9 @@ edition.workspace = true
|
|||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
television-fuzzy = { path = "../television-fuzzy", version = "0.0.5" }
|
television-fuzzy = { path = "../television-fuzzy", version = "0.0.6" }
|
||||||
television-utils = { path = "../television-utils", version = "0.0.5" }
|
television-utils = { path = "../television-utils", version = "0.0.6" }
|
||||||
television-derive = { path = "../television-derive", version = "0.0.5" }
|
television-derive = { path = "../television-derive", version = "0.0.6" }
|
||||||
devicons = "0.6.11"
|
devicons = "0.6.11"
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
eyre = "0.6.12"
|
eyre = "0.6.12"
|
||||||
|
@ -4,7 +4,6 @@ use crate::entry::PreviewType;
|
|||||||
use devicons::FileIcon;
|
use devicons::FileIcon;
|
||||||
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
||||||
use television_utils::indices::sep_name_and_value_indices;
|
use television_utils::indices::sep_name_and_value_indices;
|
||||||
use television_utils::strings::preprocess_line;
|
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -146,8 +145,8 @@ async fn load_aliases(injector: Injector<Alias>) {
|
|||||||
if let Some(name) = parts.next() {
|
if let Some(name) = parts.next() {
|
||||||
if let Some(value) = parts.next() {
|
if let Some(value) = parts.next() {
|
||||||
return Some(Alias::new(
|
return Some(Alias::new(
|
||||||
preprocess_line(name),
|
name.to_string(),
|
||||||
preprocess_line(value),
|
value.to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ use super::OnAir;
|
|||||||
use crate::entry::{Entry, PreviewType};
|
use crate::entry::{Entry, PreviewType};
|
||||||
use television_fuzzy::matcher::{config::Config, Matcher};
|
use television_fuzzy::matcher::{config::Config, Matcher};
|
||||||
use television_utils::indices::sep_name_and_value_indices;
|
use television_utils::indices::sep_name_and_value_indices;
|
||||||
use television_utils::strings::preprocess_line;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct EnvVar {
|
struct EnvVar {
|
||||||
@ -26,15 +25,9 @@ impl Channel {
|
|||||||
let matcher = Matcher::new(Config::default().n_threads(NUM_THREADS));
|
let matcher = Matcher::new(Config::default().n_threads(NUM_THREADS));
|
||||||
let injector = matcher.injector();
|
let injector = matcher.injector();
|
||||||
for (name, value) in std::env::vars() {
|
for (name, value) in std::env::vars() {
|
||||||
let () = injector.push(
|
let () = injector.push(EnvVar { name, value }, |e, cols| {
|
||||||
EnvVar {
|
cols[0] = (e.name.clone() + &e.value).into();
|
||||||
name: preprocess_line(&name),
|
});
|
||||||
value: preprocess_line(&value),
|
|
||||||
},
|
|
||||||
|e, cols| {
|
|
||||||
cols[0] = (e.name.clone() + &e.value).into();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Channel {
|
Channel {
|
||||||
matcher,
|
matcher,
|
||||||
|
@ -5,7 +5,6 @@ use std::collections::HashSet;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
||||||
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
|
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
|
||||||
use television_utils::strings::preprocess_line;
|
|
||||||
|
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
matcher: Matcher<String>,
|
matcher: Matcher<String>,
|
||||||
@ -58,7 +57,7 @@ impl From<&mut TelevisionChannel> for Channel {
|
|||||||
Self::new(
|
Self::new(
|
||||||
entries
|
entries
|
||||||
.iter()
|
.iter()
|
||||||
.map(|entry| PathBuf::from(entry.display_name()))
|
.map(|entry| PathBuf::from(&entry.name))
|
||||||
.collect::<HashSet<_>>()
|
.collect::<HashSet<_>>()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -132,16 +131,15 @@ async fn load_files(paths: Vec<PathBuf>, injector: Injector<String>) {
|
|||||||
Box::new(move |result| {
|
Box::new(move |result| {
|
||||||
if let Ok(entry) = result {
|
if let Ok(entry) = result {
|
||||||
if entry.file_type().unwrap().is_file() {
|
if entry.file_type().unwrap().is_file() {
|
||||||
let file_path = preprocess_line(
|
let file_path = &entry
|
||||||
&entry
|
.path()
|
||||||
.path()
|
.strip_prefix(¤t_dir)
|
||||||
.strip_prefix(¤t_dir)
|
.unwrap_or(entry.path())
|
||||||
.unwrap_or(entry.path())
|
.to_string_lossy();
|
||||||
.to_string_lossy(),
|
let () =
|
||||||
);
|
injector.push(file_path.to_string(), |e, cols| {
|
||||||
let () = injector.push(file_path, |e, cols| {
|
cols[0] = e.clone().into();
|
||||||
cols[0] = e.clone().into();
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ignore::WalkState::Continue
|
ignore::WalkState::Continue
|
||||||
|
@ -9,7 +9,6 @@ use crate::channels::OnAir;
|
|||||||
use crate::entry::{Entry, PreviewType};
|
use crate::entry::{Entry, PreviewType};
|
||||||
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
||||||
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
|
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
|
||||||
use television_utils::strings::preprocess_line;
|
|
||||||
|
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
matcher: Matcher<String>,
|
matcher: Matcher<String>,
|
||||||
@ -150,13 +149,15 @@ async fn crawl_for_repos(starting_point: PathBuf, injector: Injector<String>) {
|
|||||||
if entry.file_type().unwrap().is_dir() {
|
if entry.file_type().unwrap().is_dir() {
|
||||||
// if the entry is a .git directory, add its parent to the list of git repos
|
// if the entry is a .git directory, add its parent to the list of git repos
|
||||||
if entry.path().ends_with(".git") {
|
if entry.path().ends_with(".git") {
|
||||||
let parent_path = preprocess_line(
|
let parent_path =
|
||||||
&entry.path().parent().unwrap().to_string_lossy(),
|
&entry.path().parent().unwrap().to_string_lossy();
|
||||||
);
|
|
||||||
debug!("Found git repo: {:?}", parent_path);
|
debug!("Found git repo: {:?}", parent_path);
|
||||||
let () = injector.push(parent_path, |e, cols| {
|
let () = injector.push(
|
||||||
cols[0] = e.clone().into();
|
parent_path.to_string(),
|
||||||
});
|
|e, cols| {
|
||||||
|
cols[0] = e.clone().into();
|
||||||
|
},
|
||||||
|
);
|
||||||
return ignore::WalkState::Skip;
|
return ignore::WalkState::Skip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ use devicons::FileIcon;
|
|||||||
use super::OnAir;
|
use super::OnAir;
|
||||||
use crate::entry::{Entry, PreviewType};
|
use crate::entry::{Entry, PreviewType};
|
||||||
use television_fuzzy::matcher::{config::Config, Matcher};
|
use television_fuzzy::matcher::{config::Config, Matcher};
|
||||||
use television_utils::strings::preprocess_line;
|
|
||||||
|
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
matcher: Matcher<String>,
|
matcher: Matcher<String>,
|
||||||
@ -20,7 +19,7 @@ impl Channel {
|
|||||||
let mut lines = Vec::new();
|
let mut lines = Vec::new();
|
||||||
for line in std::io::stdin().lock().lines().map_while(Result::ok) {
|
for line in std::io::stdin().lock().lines().map_while(Result::ok) {
|
||||||
if !line.trim().is_empty() {
|
if !line.trim().is_empty() {
|
||||||
lines.push(preprocess_line(&line));
|
lines.push(line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let matcher = Matcher::new(Config::default().n_threads(NUM_THREADS));
|
let matcher = Matcher::new(Config::default().n_threads(NUM_THREADS));
|
||||||
|
@ -11,8 +11,7 @@ use std::{
|
|||||||
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
use television_fuzzy::matcher::{config::Config, injector::Injector, Matcher};
|
||||||
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
|
use television_utils::files::{walk_builder, DEFAULT_NUM_THREADS};
|
||||||
use television_utils::strings::{
|
use television_utils::strings::{
|
||||||
preprocess_line, proportion_of_printable_ascii_characters,
|
proportion_of_printable_ascii_characters, PRINTABLE_ASCII_THRESHOLD,
|
||||||
PRINTABLE_ASCII_THRESHOLD,
|
|
||||||
};
|
};
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
@ -84,7 +83,7 @@ impl Channel {
|
|||||||
for entry in entries.into_iter().take(MAX_LINES_IN_MEM) {
|
for entry in entries.into_iter().take(MAX_LINES_IN_MEM) {
|
||||||
injector.push(
|
injector.push(
|
||||||
CandidateLine::new(
|
CandidateLine::new(
|
||||||
entry.display_name().into(),
|
entry.name.into(),
|
||||||
entry.value.unwrap(),
|
entry.value.unwrap(),
|
||||||
entry.line_number.unwrap(),
|
entry.line_number.unwrap(),
|
||||||
),
|
),
|
||||||
@ -169,15 +168,11 @@ impl OnAir for Channel {
|
|||||||
let line = item.matched_string;
|
let line = item.matched_string;
|
||||||
let display_path =
|
let display_path =
|
||||||
item.inner.path.to_string_lossy().to_string();
|
item.inner.path.to_string_lossy().to_string();
|
||||||
Entry::new(
|
Entry::new(display_path.clone(), PreviewType::Files)
|
||||||
display_path.clone() + &item.inner.line_number.to_string(),
|
.with_value(line)
|
||||||
PreviewType::Files,
|
.with_value_match_ranges(item.match_indices)
|
||||||
)
|
.with_icon(FileIcon::from(item.inner.path.as_path()))
|
||||||
.with_display_name(display_path)
|
.with_line_number(item.inner.line_number)
|
||||||
.with_value(line)
|
|
||||||
.with_value_match_ranges(item.match_indices)
|
|
||||||
.with_icon(FileIcon::from(item.inner.path.as_path()))
|
|
||||||
.with_line_number(item.inner.line_number)
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@ -186,11 +181,6 @@ impl OnAir for Channel {
|
|||||||
self.matcher.get_result(index).map(|item| {
|
self.matcher.get_result(index).map(|item| {
|
||||||
let display_path = item.inner.path.to_string_lossy().to_string();
|
let display_path = item.inner.path.to_string_lossy().to_string();
|
||||||
Entry::new(display_path.clone(), PreviewType::Files)
|
Entry::new(display_path.clone(), PreviewType::Files)
|
||||||
.with_display_name(
|
|
||||||
display_path.clone()
|
|
||||||
+ ":"
|
|
||||||
+ &item.inner.line_number.to_string(),
|
|
||||||
)
|
|
||||||
.with_icon(FileIcon::from(item.inner.path.as_path()))
|
.with_icon(FileIcon::from(item.inner.path.as_path()))
|
||||||
.with_line_number(item.inner.line_number)
|
.with_line_number(item.inner.line_number)
|
||||||
})
|
})
|
||||||
@ -314,8 +304,7 @@ fn try_inject_lines(
|
|||||||
match maybe_line {
|
match maybe_line {
|
||||||
Ok(l) => {
|
Ok(l) => {
|
||||||
line_number += 1;
|
line_number += 1;
|
||||||
let line = preprocess_line(&l);
|
if l.is_empty() {
|
||||||
if line.is_empty() {
|
|
||||||
debug!("Empty line");
|
debug!("Empty line");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -323,7 +312,7 @@ fn try_inject_lines(
|
|||||||
path.strip_prefix(current_dir)
|
path.strip_prefix(current_dir)
|
||||||
.unwrap_or(path)
|
.unwrap_or(path)
|
||||||
.to_path_buf(),
|
.to_path_buf(),
|
||||||
line,
|
l,
|
||||||
line_number,
|
line_number,
|
||||||
);
|
);
|
||||||
let () = injector.push(candidate, |c, cols| {
|
let () = injector.push(candidate, |c, cols| {
|
||||||
|
@ -10,8 +10,6 @@ use devicons::FileIcon;
|
|||||||
pub struct Entry {
|
pub struct Entry {
|
||||||
/// The name of the entry.
|
/// The name of the entry.
|
||||||
pub name: String,
|
pub name: String,
|
||||||
/// The display name of the entry.
|
|
||||||
display_name: Option<String>,
|
|
||||||
/// An optional value associated with the entry.
|
/// An optional value associated with the entry.
|
||||||
pub value: Option<String>,
|
pub value: Option<String>,
|
||||||
/// The optional ranges for matching characters in the name.
|
/// The optional ranges for matching characters in the name.
|
||||||
@ -35,7 +33,6 @@ impl Entry {
|
|||||||
/// use devicons::FileIcon;
|
/// use devicons::FileIcon;
|
||||||
///
|
///
|
||||||
/// let entry = Entry::new("name".to_string(), PreviewType::EnvVar)
|
/// let entry = Entry::new("name".to_string(), PreviewType::EnvVar)
|
||||||
/// .with_display_name("display_name".to_string())
|
|
||||||
/// .with_value("value".to_string())
|
/// .with_value("value".to_string())
|
||||||
/// .with_name_match_ranges(vec![(0, 1)])
|
/// .with_name_match_ranges(vec![(0, 1)])
|
||||||
/// .with_value_match_ranges(vec![(0, 1)])
|
/// .with_value_match_ranges(vec![(0, 1)])
|
||||||
@ -53,7 +50,6 @@ impl Entry {
|
|||||||
pub fn new(name: String, preview_type: PreviewType) -> Self {
|
pub fn new(name: String, preview_type: PreviewType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
display_name: None,
|
|
||||||
value: None,
|
value: None,
|
||||||
name_match_ranges: None,
|
name_match_ranges: None,
|
||||||
value_match_ranges: None,
|
value_match_ranges: None,
|
||||||
@ -63,11 +59,6 @@ impl Entry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_display_name(mut self, display_name: String) -> Self {
|
|
||||||
self.display_name = Some(display_name);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_value(mut self, value: String) -> Self {
|
pub fn with_value(mut self, value: String) -> Self {
|
||||||
self.value = Some(value);
|
self.value = Some(value);
|
||||||
self
|
self
|
||||||
@ -99,10 +90,6 @@ impl Entry {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display_name(&self) -> &str {
|
|
||||||
self.display_name.as_ref().unwrap_or(&self.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stdout_repr(&self) -> String {
|
pub fn stdout_repr(&self) -> String {
|
||||||
let mut repr = self.name.clone();
|
let mut repr = self.name.clone();
|
||||||
if repr.contains(|c| char::is_ascii_whitespace(&c)) {
|
if repr.contains(|c| char::is_ascii_whitespace(&c)) {
|
||||||
@ -118,7 +105,6 @@ impl Entry {
|
|||||||
|
|
||||||
pub const ENTRY_PLACEHOLDER: Entry = Entry {
|
pub const ENTRY_PLACEHOLDER: Entry = Entry {
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
display_name: None,
|
|
||||||
value: None,
|
value: None,
|
||||||
name_match_ranges: None,
|
name_match_ranges: None,
|
||||||
value_match_ranges: None,
|
value_match_ranges: None,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "television-derive"
|
name = "television-derive"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "television-fuzzy"
|
name = "television-fuzzy"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "television-previewers"
|
name = "television-previewers"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@ -14,8 +14,8 @@ rust-version.workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
syntect = "5.2.0"
|
syntect = "5.2.0"
|
||||||
television-channels = { path = "../television-channels", version = "0.0.5" }
|
television-channels = { path = "../television-channels", version = "0.0.6" }
|
||||||
television-utils = { path = "../television-utils", version = "0.0.5" }
|
television-utils = { path = "../television-utils", version = "0.0.6" }
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
parking_lot = "0.12.3"
|
parking_lot = "0.12.3"
|
||||||
tokio = "1.41.1"
|
tokio = "1.41.1"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use devicons::FileIcon;
|
||||||
use television_channels::entry::{Entry, PreviewType};
|
use television_channels::entry::{Entry, PreviewType};
|
||||||
|
|
||||||
pub mod basic;
|
pub mod basic;
|
||||||
@ -46,6 +47,7 @@ pub const FILE_TOO_LARGE_MSG: &str = "File too large";
|
|||||||
pub struct Preview {
|
pub struct Preview {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub content: PreviewContent,
|
pub content: PreviewContent,
|
||||||
|
pub icon: Option<FileIcon>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Preview {
|
impl Default for Preview {
|
||||||
@ -53,13 +55,22 @@ impl Default for Preview {
|
|||||||
Preview {
|
Preview {
|
||||||
title: String::new(),
|
title: String::new(),
|
||||||
content: PreviewContent::Empty,
|
content: PreviewContent::Empty,
|
||||||
|
icon: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Preview {
|
impl Preview {
|
||||||
pub fn new(title: String, content: PreviewContent) -> Self {
|
pub fn new(
|
||||||
Preview { title, content }
|
title: String,
|
||||||
|
content: PreviewContent,
|
||||||
|
icon: Option<FileIcon>,
|
||||||
|
) -> Self {
|
||||||
|
Preview {
|
||||||
|
title,
|
||||||
|
content,
|
||||||
|
icon,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn total_lines(&self) -> u16 {
|
pub fn total_lines(&self) -> u16 {
|
||||||
|
@ -22,6 +22,7 @@ impl BasicPreviewer {
|
|||||||
Arc::new(Preview {
|
Arc::new(Preview {
|
||||||
title: entry.name.clone(),
|
title: entry.name.clone(),
|
||||||
content: PreviewContent::PlainTextWrapped(entry.name.clone()),
|
content: PreviewContent::PlainTextWrapped(entry.name.clone()),
|
||||||
|
icon: entry.icon,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ fn build_tree_preview(entry: &Entry) -> Preview {
|
|||||||
.map(std::borrow::ToOwned::to_owned)
|
.map(std::borrow::ToOwned::to_owned)
|
||||||
.collect(),
|
.collect(),
|
||||||
),
|
),
|
||||||
|
icon: entry.icon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ impl EnvVarPreviewer {
|
|||||||
} else {
|
} else {
|
||||||
PreviewContent::Empty
|
PreviewContent::Empty
|
||||||
},
|
},
|
||||||
|
icon: entry.icon,
|
||||||
});
|
});
|
||||||
self.cache.insert(entry.clone(), preview.clone());
|
self.cache.insert(entry.clone(), preview.clone());
|
||||||
preview
|
preview
|
||||||
|
@ -164,7 +164,7 @@ impl FilePreviewer {
|
|||||||
.map_while(Result::ok)
|
.map_while(Result::ok)
|
||||||
// we need to add a newline here because sublime syntaxes expect one
|
// we need to add a newline here because sublime syntaxes expect one
|
||||||
// to be present at the end of each line
|
// to be present at the end of each line
|
||||||
.map(|line| preprocess_line(&line) + "\n")
|
.map(|line| preprocess_line(&line).0 + "\n")
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match syntax::compute_highlights_for_path(
|
match syntax::compute_highlights_for_path(
|
||||||
@ -185,6 +185,7 @@ impl FilePreviewer {
|
|||||||
PreviewContent::SyntectHighlightedText(
|
PreviewContent::SyntectHighlightedText(
|
||||||
highlighted_lines,
|
highlighted_lines,
|
||||||
),
|
),
|
||||||
|
entry_c.icon,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
debug!("Inserted highlighted preview into cache");
|
debug!("Inserted highlighted preview into cache");
|
||||||
@ -224,7 +225,7 @@ fn plain_text_preview(title: &str, reader: BufReader<&File>) -> Arc<Preview> {
|
|||||||
// truncate accordingly (since this is just a temp preview)
|
// truncate accordingly (since this is just a temp preview)
|
||||||
for maybe_line in reader.lines() {
|
for maybe_line in reader.lines() {
|
||||||
match maybe_line {
|
match maybe_line {
|
||||||
Ok(line) => lines.push(preprocess_line(&line)),
|
Ok(line) => lines.push(preprocess_line(&line).0),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Error reading file: {:?}", e);
|
warn!("Error reading file: {:?}", e);
|
||||||
return meta::not_supported(title);
|
return meta::not_supported(title);
|
||||||
@ -237,5 +238,6 @@ fn plain_text_preview(title: &str, reader: BufReader<&File>) -> Arc<Preview> {
|
|||||||
Arc::new(Preview::new(
|
Arc::new(Preview::new(
|
||||||
title.to_string(),
|
title.to_string(),
|
||||||
PreviewContent::PlainText(lines),
|
PreviewContent::PlainText(lines),
|
||||||
|
None,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ pub fn not_supported(title: &str) -> Arc<Preview> {
|
|||||||
Arc::new(Preview::new(
|
Arc::new(Preview::new(
|
||||||
title.to_string(),
|
title.to_string(),
|
||||||
PreviewContent::NotSupported,
|
PreviewContent::NotSupported,
|
||||||
|
None,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12,10 +13,15 @@ pub fn file_too_large(title: &str) -> Arc<Preview> {
|
|||||||
Arc::new(Preview::new(
|
Arc::new(Preview::new(
|
||||||
title.to_string(),
|
title.to_string(),
|
||||||
PreviewContent::FileTooLarge,
|
PreviewContent::FileTooLarge,
|
||||||
|
None,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn loading(title: &str) -> Arc<Preview> {
|
pub fn loading(title: &str) -> Arc<Preview> {
|
||||||
Arc::new(Preview::new(title.to_string(), PreviewContent::Loading))
|
Arc::new(Preview::new(
|
||||||
|
title.to_string(),
|
||||||
|
PreviewContent::Loading,
|
||||||
|
None,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "television-utils"
|
name = "television-utils"
|
||||||
version = "0.0.5"
|
version = "0.0.6"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::fmt::Write;
|
|
||||||
|
|
||||||
/// Returns the index of the next character boundary in the given string.
|
/// Returns the index of the next character boundary in the given string.
|
||||||
///
|
///
|
||||||
@ -121,7 +120,24 @@ pub fn slice_up_to_char_boundary(s: &str, byte_index: usize) -> &str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to parse a UTF-8 character from the given byte slice.
|
/// Attempts to parse a UTF-8 character from the given byte slice.
|
||||||
fn try_parse_utf8_char(input: &[u8]) -> Option<(char, usize)> {
|
///
|
||||||
|
/// The function returns the parsed character and the number of bytes consumed.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use television_utils::strings::try_parse_utf8_char;
|
||||||
|
///
|
||||||
|
/// let input = b"Hello, World!";
|
||||||
|
/// let (chr, n) = try_parse_utf8_char(input).unwrap();
|
||||||
|
/// assert_eq!(chr, 'H');
|
||||||
|
/// assert_eq!(n, 1);
|
||||||
|
///
|
||||||
|
/// let input = b"\xF0\x9F\x91\x8B\xF0\x9F\x8C\x8D!";
|
||||||
|
/// let (chr, n) = try_parse_utf8_char(input).unwrap();
|
||||||
|
/// assert_eq!(chr, '👋');
|
||||||
|
/// assert_eq!(n, 4);
|
||||||
|
/// ```
|
||||||
|
pub fn try_parse_utf8_char(input: &[u8]) -> Option<(char, usize)> {
|
||||||
let str_from_utf8 = |seq| std::str::from_utf8(seq).ok();
|
let str_from_utf8 = |seq| std::str::from_utf8(seq).ok();
|
||||||
|
|
||||||
let decoded = input
|
let decoded = input
|
||||||
@ -143,7 +159,6 @@ lazy_static! {
|
|||||||
pub const EMPTY_STRING: &str = "";
|
pub const EMPTY_STRING: &str = "";
|
||||||
pub const TAB_WIDTH: usize = 4;
|
pub const TAB_WIDTH: usize = 4;
|
||||||
|
|
||||||
const SPACE_CHARACTER: char = ' ';
|
|
||||||
const TAB_CHARACTER: char = '\t';
|
const TAB_CHARACTER: char = '\t';
|
||||||
const LINE_FEED_CHARACTER: char = '\x0A';
|
const LINE_FEED_CHARACTER: char = '\x0A';
|
||||||
const DELETE_CHARACTER: char = '\x7F';
|
const DELETE_CHARACTER: char = '\x7F';
|
||||||
@ -152,62 +167,68 @@ const NULL_CHARACTER: char = '\x00';
|
|||||||
const UNIT_SEPARATOR_CHARACTER: char = '\u{001F}';
|
const UNIT_SEPARATOR_CHARACTER: char = '\u{001F}';
|
||||||
const APPLICATION_PROGRAM_COMMAND_CHARACTER: char = '\u{009F}';
|
const APPLICATION_PROGRAM_COMMAND_CHARACTER: char = '\u{009F}';
|
||||||
|
|
||||||
|
#[allow(clippy::missing_panics_doc)]
|
||||||
/// Replaces non-printable characters in the given byte slice with default printable characters.
|
/// Replaces non-printable characters in the given byte slice with default printable characters.
|
||||||
///
|
///
|
||||||
/// The tab width is used to determine how many spaces to replace a tab character with.
|
/// The tab width is used to determine how many spaces to replace a tab character with.
|
||||||
/// The default printable character for non-printable characters is the Unicode symbol for NULL.
|
/// The default printable character for non-printable characters is the Unicode symbol for NULL.
|
||||||
///
|
///
|
||||||
|
/// The function returns a tuple containing the processed string and a vector of offsets introduced
|
||||||
|
/// by the transformation.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
/// ```
|
/// ```
|
||||||
/// use television_utils::strings::replace_non_printable;
|
/// use television_utils::strings::replace_non_printable;
|
||||||
///
|
///
|
||||||
/// let input = b"Hello, World!";
|
/// let input = b"Hello, World!";
|
||||||
/// let output = replace_non_printable(input, 2);
|
/// let (output, offsets) = replace_non_printable(input, 2);
|
||||||
/// assert_eq!(output, "Hello, World!");
|
/// assert_eq!(output, "Hello, World!");
|
||||||
|
/// assert_eq!(offsets, vec![0,0,0,0,0,0,0,0,0,0,0,0,0]);
|
||||||
///
|
///
|
||||||
/// let input = b"Hello\tWorld!";
|
/// let input = b"Hello,\tWorld!";
|
||||||
/// let output = replace_non_printable(input, 2);
|
/// let (output, offsets) = replace_non_printable(input, 4);
|
||||||
/// assert_eq!(output, "Hello World!");
|
/// assert_eq!(output, "Hello, World!");
|
||||||
|
/// assert_eq!(offsets, vec![0,0,0,0,0,0,0,3,3,3,3,3,3]);
|
||||||
///
|
///
|
||||||
/// let input = b"Hello\nWorld!";
|
/// let input = b"Hello,\nWorld!";
|
||||||
/// let output = replace_non_printable(input, 2);
|
/// let (output, offsets) = replace_non_printable(input, 2);
|
||||||
/// assert_eq!(output, "HelloWorld!");
|
/// assert_eq!(output, "Hello,World!");
|
||||||
///
|
/// assert_eq!(offsets, vec![0,0,0,0,0,0,0,-1,-1,-1,-1,-1,-1]);
|
||||||
/// let input = b"Hello\x00World!";
|
|
||||||
/// let output = replace_non_printable(input, 2);
|
|
||||||
/// assert_eq!(output, "Hello␀World!");
|
|
||||||
///
|
|
||||||
/// let input = b"Hello\x7FWorld!";
|
|
||||||
/// let output = replace_non_printable(input, 2);
|
|
||||||
/// assert_eq!(output, "Hello␀World!");
|
|
||||||
/// ```
|
/// ```
|
||||||
pub fn replace_non_printable(input: &[u8], tab_width: usize) -> String {
|
pub fn replace_non_printable(
|
||||||
|
input: &[u8],
|
||||||
|
tab_width: usize,
|
||||||
|
) -> (String, Vec<i16>) {
|
||||||
let mut output = String::new();
|
let mut output = String::new();
|
||||||
|
let mut offsets = Vec::new();
|
||||||
|
let mut cumulative_offset: i16 = 0;
|
||||||
|
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
let len = input.len();
|
let len = input.len();
|
||||||
while idx < len {
|
while idx < len {
|
||||||
|
offsets.push(cumulative_offset);
|
||||||
if let Some((chr, skip_ahead)) = try_parse_utf8_char(&input[idx..]) {
|
if let Some((chr, skip_ahead)) = try_parse_utf8_char(&input[idx..]) {
|
||||||
idx += skip_ahead;
|
idx += skip_ahead;
|
||||||
|
|
||||||
match chr {
|
match chr {
|
||||||
// space
|
|
||||||
SPACE_CHARACTER => output.push(' '),
|
|
||||||
// tab
|
// tab
|
||||||
TAB_CHARACTER => {
|
TAB_CHARACTER => {
|
||||||
output.push_str(&" ".repeat(tab_width));
|
output.push_str(&" ".repeat(tab_width));
|
||||||
|
cumulative_offset += i16::try_from(tab_width).unwrap() - 1;
|
||||||
}
|
}
|
||||||
// line feed
|
// line feed
|
||||||
LINE_FEED_CHARACTER => {}
|
LINE_FEED_CHARACTER => {
|
||||||
|
cumulative_offset -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
// ASCII control characters from 0x00 to 0x1F
|
// ASCII control characters from 0x00 to 0x1F
|
||||||
// + control characters from \u{007F} to \u{009F}
|
// + control characters from \u{007F} to \u{009F}
|
||||||
|
// + BOM
|
||||||
NULL_CHARACTER..=UNIT_SEPARATOR_CHARACTER
|
NULL_CHARACTER..=UNIT_SEPARATOR_CHARACTER
|
||||||
| DELETE_CHARACTER..=APPLICATION_PROGRAM_COMMAND_CHARACTER => {
|
| DELETE_CHARACTER..=APPLICATION_PROGRAM_COMMAND_CHARACTER
|
||||||
|
| BOM_CHARACTER => {
|
||||||
output.push(*NULL_SYMBOL);
|
output.push(*NULL_SYMBOL);
|
||||||
}
|
}
|
||||||
// don't print BOMs
|
|
||||||
BOM_CHARACTER => {}
|
|
||||||
// Unicode characters above 0x0700 seem unstable with ratatui
|
// Unicode characters above 0x0700 seem unstable with ratatui
|
||||||
c if c > '\u{0700}' => {
|
c if c > '\u{0700}' => {
|
||||||
output.push(*NULL_SYMBOL);
|
output.push(*NULL_SYMBOL);
|
||||||
@ -216,12 +237,12 @@ pub fn replace_non_printable(input: &[u8], tab_width: usize) -> String {
|
|||||||
c => output.push(c),
|
c => output.push(c),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
write!(output, "\\x{:02X}", input[idx]).ok();
|
output.push(*NULL_SYMBOL);
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
(output, offsets)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The threshold for considering a buffer to be printable ASCII.
|
/// The threshold for considering a buffer to be printable ASCII.
|
||||||
@ -272,18 +293,21 @@ const MAX_LINE_LENGTH: usize = 300;
|
|||||||
/// use television_utils::strings::preprocess_line;
|
/// use television_utils::strings::preprocess_line;
|
||||||
///
|
///
|
||||||
/// let line = "Hello, World!";
|
/// let line = "Hello, World!";
|
||||||
/// let processed = preprocess_line(line);
|
/// let (processed, offsets) = preprocess_line(line);
|
||||||
/// assert_eq!(processed, "Hello, World!");
|
/// assert_eq!(processed, "Hello, World!");
|
||||||
|
/// assert_eq!(offsets, vec![0,0,0,0,0,0,0,0,0,0,0,0,0]);
|
||||||
///
|
///
|
||||||
/// let line = "\x00World\x7F!";
|
/// let line = "\x00World\x7F!";
|
||||||
/// let processed = preprocess_line(line);
|
/// let (processed, offsets) = preprocess_line(line);
|
||||||
/// assert_eq!(processed, "␀World␀!");
|
/// assert_eq!(processed, "␀World␀!");
|
||||||
|
/// assert_eq!(offsets, vec![0,0,0,0,0,0,0,0]);
|
||||||
///
|
///
|
||||||
/// let line = "a".repeat(400);
|
/// let line = "a".repeat(400);
|
||||||
/// let processed = preprocess_line(&line);
|
/// let (processed, offsets) = preprocess_line(&line);
|
||||||
/// assert_eq!(processed.len(), 300);
|
/// assert_eq!(processed.len(), 300);
|
||||||
|
/// assert_eq!(offsets, vec![0; 300]);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn preprocess_line(line: &str) -> String {
|
pub fn preprocess_line(line: &str) -> (String, Vec<i16>) {
|
||||||
replace_non_printable(
|
replace_non_printable(
|
||||||
{
|
{
|
||||||
if line.len() > MAX_LINE_LENGTH {
|
if line.len() > MAX_LINE_LENGTH {
|
||||||
@ -292,12 +316,101 @@ pub fn preprocess_line(line: &str) -> String {
|
|||||||
line
|
line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.trim_end_matches(['\r', '\n', '\0'])
|
|
||||||
.as_bytes(),
|
.as_bytes(),
|
||||||
TAB_WIDTH,
|
TAB_WIDTH,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Make a matched string printable while preserving match ranges in the process.
|
||||||
|
///
|
||||||
|
/// This function preprocesses the matched string and returns a printable version of it along with
|
||||||
|
/// the match ranges adjusted to the new string.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use television_utils::strings::make_matched_string_printable;
|
||||||
|
///
|
||||||
|
/// let matched_string = "Hello, World!";
|
||||||
|
/// let match_ranges = vec![(0, 1), (7, 8)];
|
||||||
|
/// let match_ranges = Some(match_ranges.as_slice());
|
||||||
|
/// let (printable, match_indices) = make_matched_string_printable(matched_string, match_ranges);
|
||||||
|
/// assert_eq!(printable, "Hello, World!");
|
||||||
|
/// assert_eq!(match_indices, vec![(0, 1), (7, 8)]);
|
||||||
|
///
|
||||||
|
/// let matched_string = "Hello,\tWorld!";
|
||||||
|
/// let match_ranges = vec![(0, 1), (7, 8)];
|
||||||
|
/// let match_ranges = Some(match_ranges.as_slice());
|
||||||
|
/// let (printable, match_indices) = make_matched_string_printable(matched_string, match_ranges);
|
||||||
|
/// assert_eq!(printable, "Hello, World!");
|
||||||
|
/// assert_eq!(match_indices, vec![(0, 1), (10, 11)]);
|
||||||
|
///
|
||||||
|
/// let matched_string = "Hello,\nWorld!";
|
||||||
|
/// let match_ranges = vec![(0, 1), (7, 8)];
|
||||||
|
/// let match_ranges = Some(match_ranges.as_slice());
|
||||||
|
/// let (printable, match_indices) = make_matched_string_printable(matched_string, match_ranges);
|
||||||
|
/// assert_eq!(printable, "Hello,World!");
|
||||||
|
/// assert_eq!(match_indices, vec![(0, 1), (6, 7)]);
|
||||||
|
///
|
||||||
|
/// let matched_string = "Hello, World!";
|
||||||
|
/// let (printable, match_indices) = make_matched_string_printable(matched_string, None);
|
||||||
|
/// assert_eq!(printable, "Hello, World!");
|
||||||
|
/// assert_eq!(match_indices, vec![]);
|
||||||
|
///
|
||||||
|
/// let matched_string = "build.rs";
|
||||||
|
/// let match_ranges = vec![(0, 1), (7, 8)];
|
||||||
|
/// let match_ranges = Some(match_ranges.as_slice());
|
||||||
|
/// let (printable, match_indices) = make_matched_string_printable(matched_string, match_ranges);
|
||||||
|
/// assert_eq!(printable, "build.rs");
|
||||||
|
/// assert_eq!(match_indices, vec![(0, 1), (7, 8)]);
|
||||||
|
///
|
||||||
|
/// let matched_string = "a\tb";
|
||||||
|
/// let match_ranges = vec![(0, 1), (2, 3)];
|
||||||
|
/// let match_ranges = Some(match_ranges.as_slice());
|
||||||
|
/// let (printable, match_indices) = make_matched_string_printable(matched_string, match_ranges);
|
||||||
|
/// assert_eq!(printable, "a b");
|
||||||
|
/// assert_eq!(match_indices, vec![(0, 1), (5, 6)]);
|
||||||
|
///
|
||||||
|
/// let matched_string = "a\tbcd".repeat(65);
|
||||||
|
/// let match_ranges = vec![(0, 1), (310, 311)];
|
||||||
|
/// let match_ranges = Some(match_ranges.as_slice());
|
||||||
|
/// let (printable, match_indices) = make_matched_string_printable(&matched_string, match_ranges);
|
||||||
|
/// assert_eq!(printable.len(), 480);
|
||||||
|
/// assert_eq!(match_indices, vec![(0, 1)]);
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// This will panic if the length of the printable string or the match indices don't fit into a
|
||||||
|
/// `u32`.
|
||||||
|
pub fn make_matched_string_printable(
|
||||||
|
matched_string: &str,
|
||||||
|
match_ranges: Option<&[(u32, u32)]>,
|
||||||
|
) -> (String, Vec<(u32, u32)>) {
|
||||||
|
let (printable, transformation_offsets) = preprocess_line(matched_string);
|
||||||
|
let mut match_indices = Vec::new();
|
||||||
|
|
||||||
|
if let Some(ranges) = match_ranges {
|
||||||
|
for (start, end) in ranges.iter().take_while(|(start, _)| {
|
||||||
|
*start < u32::try_from(transformation_offsets.len()).unwrap()
|
||||||
|
}) {
|
||||||
|
let new_start = i64::from(*start)
|
||||||
|
+ i64::from(transformation_offsets[*start as usize]);
|
||||||
|
let new_end = i64::from(*end)
|
||||||
|
+ i64::from(
|
||||||
|
// Use the last offset if the end index is out of bounds
|
||||||
|
// (this will be the case when the match range includes the last character)
|
||||||
|
transformation_offsets[(*end as usize)
|
||||||
|
.min(transformation_offsets.len() - 1)],
|
||||||
|
);
|
||||||
|
match_indices.push((
|
||||||
|
u32::try_from(new_start).unwrap(),
|
||||||
|
u32::try_from(new_end).unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(printable, match_indices)
|
||||||
|
}
|
||||||
|
|
||||||
/// Shrink a string to a maximum length, adding an ellipsis in the middle.
|
/// Shrink a string to a maximum length, adding an ellipsis in the middle.
|
||||||
///
|
///
|
||||||
/// If the string is shorter than the maximum length, it is returned as is.
|
/// If the string is shorter than the maximum length, it is returned as is.
|
||||||
@ -402,7 +515,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_replace_non_printable(input: &str, expected: &str) {
|
fn test_replace_non_printable(input: &str, expected: &str) {
|
||||||
let actual = replace_non_printable(input.as_bytes(), 2);
|
let (actual, _offset) = replace_non_printable(input.as_bytes(), 2);
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,7 +551,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_replace_non_printable_bom() {
|
fn test_replace_non_printable_bom() {
|
||||||
test_replace_non_printable("Hello\u{FEFF}World!", "HelloWorld!");
|
test_replace_non_printable("Hello\u{FEFF}World!", "Hello␀World!");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -446,6 +559,35 @@ mod tests {
|
|||||||
test_replace_non_printable("Àì", "Àì␀");
|
test_replace_non_printable("Àì", "Àì␀");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_replace_non_printable_range_tab() {
|
||||||
|
let input = b"Hello,\tWorld!";
|
||||||
|
let (output, offsets) = replace_non_printable(input, 4);
|
||||||
|
assert_eq!(output, "Hello, World!");
|
||||||
|
assert_eq!(offsets, vec![0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_replace_non_printable_range_line_feed() {
|
||||||
|
let input = b"Hello,\nWorld!";
|
||||||
|
let (output, offsets) = replace_non_printable(input, 2);
|
||||||
|
assert_eq!(output, "Hello,World!");
|
||||||
|
assert_eq!(offsets, vec![0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_replace_non_printable_no_range_changes() {
|
||||||
|
let input = b"Hello,\x00World!";
|
||||||
|
let (output, offsets) = replace_non_printable(input, 2);
|
||||||
|
assert_eq!(output, "Hello,␀World!");
|
||||||
|
assert_eq!(offsets, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
||||||
|
let input = b"Hello,\x7FWorld!";
|
||||||
|
let (output, offsets) = replace_non_printable(input, 2);
|
||||||
|
assert_eq!(output, "Hello,␀World!");
|
||||||
|
assert_eq!(offsets, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
}
|
||||||
|
|
||||||
fn test_proportion_of_printable_ascii_characters(
|
fn test_proportion_of_printable_ascii_characters(
|
||||||
input: &str,
|
input: &str,
|
||||||
expected: f32,
|
expected: f32,
|
||||||
@ -469,17 +611,17 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_preprocess_line(input: &str, expected: &str) {
|
fn test_preprocess_line(input: &str, expected: &str) {
|
||||||
let actual = preprocess_line(input);
|
let (actual, _offset) = preprocess_line(input);
|
||||||
assert_eq!(actual, expected);
|
assert_eq!(actual, expected, "input: {:?}", input);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_preprocess_line_cases() {
|
fn test_preprocess_line_cases() {
|
||||||
test_preprocess_line("Hello, World!", "Hello, World!");
|
test_preprocess_line("Hello, World!", "Hello, World!");
|
||||||
test_preprocess_line("Hello, World!\n", "Hello, World!");
|
test_preprocess_line("Hello, World!\n", "Hello, World!");
|
||||||
test_preprocess_line("Hello, World!\x00", "Hello, World!");
|
test_preprocess_line("Hello, World!\x00", "Hello, World!␀");
|
||||||
test_preprocess_line("Hello, World!\x7F", "Hello, World!␀");
|
test_preprocess_line("Hello, World!\x7F", "Hello, World!␀");
|
||||||
test_preprocess_line("Hello, World!\u{FEFF}", "Hello, World!");
|
test_preprocess_line("Hello, World!\u{FEFF}", "Hello, World!␀");
|
||||||
test_preprocess_line(&"a".repeat(400), &"a".repeat(300));
|
test_preprocess_line(&"a".repeat(400), &"a".repeat(300));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -399,15 +399,17 @@ impl Television {
|
|||||||
|
|
||||||
// top right block: preview title
|
// top right block: preview title
|
||||||
self.current_preview_total_lines = preview.total_lines();
|
self.current_preview_total_lines = preview.total_lines();
|
||||||
self.draw_preview_title_block(f, &layout, &selected_entry, &preview)?;
|
self.draw_preview_title_block(f, &layout, &preview)?;
|
||||||
|
|
||||||
// bottom right block: preview content
|
// bottom right block: preview content
|
||||||
self.draw_preview_content_block(
|
self.draw_preview_content_block(
|
||||||
f,
|
f,
|
||||||
&layout,
|
&layout,
|
||||||
&selected_entry,
|
selected_entry
|
||||||
|
.line_number
|
||||||
|
.map(|l| u16::try_from(l).unwrap_or(0)),
|
||||||
&preview,
|
&preview,
|
||||||
)?;
|
);
|
||||||
|
|
||||||
// remote control
|
// remote control
|
||||||
if matches!(self.mode, Mode::RemoteControl | Mode::SendToChannel) {
|
if matches!(self.mode, Mode::RemoteControl | Mode::SendToChannel) {
|
||||||
|
@ -10,7 +10,6 @@ use std::str::FromStr;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use syntect::highlighting::Color as SyntectColor;
|
use syntect::highlighting::Color as SyntectColor;
|
||||||
use television_channels::channels::OnAir;
|
use television_channels::channels::OnAir;
|
||||||
use television_channels::entry::Entry;
|
|
||||||
use television_previewers::previewers::{
|
use television_previewers::previewers::{
|
||||||
Preview, PreviewContent, FILE_TOO_LARGE_MSG, PREVIEW_NOT_SUPPORTED_MSG,
|
Preview, PreviewContent, FILE_TOO_LARGE_MSG, PREVIEW_NOT_SUPPORTED_MSG,
|
||||||
};
|
};
|
||||||
@ -28,13 +27,11 @@ impl Television {
|
|||||||
&self,
|
&self,
|
||||||
f: &mut Frame,
|
f: &mut Frame,
|
||||||
layout: &Layout,
|
layout: &Layout,
|
||||||
selected_entry: &Entry,
|
|
||||||
preview: &Arc<Preview>,
|
preview: &Arc<Preview>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mut preview_title_spans = Vec::new();
|
let mut preview_title_spans = Vec::new();
|
||||||
if selected_entry.icon.is_some() && self.config.ui.use_nerd_font_icons
|
if preview.icon.is_some() && self.config.ui.use_nerd_font_icons {
|
||||||
{
|
let icon = preview.icon.as_ref().unwrap();
|
||||||
let icon = selected_entry.icon.as_ref().unwrap();
|
|
||||||
preview_title_spans.push(Span::styled(
|
preview_title_spans.push(Span::styled(
|
||||||
{
|
{
|
||||||
let mut icon_str = String::from(icon.icon);
|
let mut icon_str = String::from(icon.icon);
|
||||||
@ -68,9 +65,9 @@ impl Television {
|
|||||||
&mut self,
|
&mut self,
|
||||||
f: &mut Frame,
|
f: &mut Frame,
|
||||||
layout: &Layout,
|
layout: &Layout,
|
||||||
selected_entry: &Entry,
|
target_line: Option<u16>,
|
||||||
preview: &Arc<Preview>,
|
preview: &Arc<Preview>,
|
||||||
) -> Result<()> {
|
) {
|
||||||
let preview_outer_block = Block::default()
|
let preview_outer_block = Block::default()
|
||||||
.title_top(Line::from(" Preview ").alignment(Alignment::Center))
|
.title_top(Line::from(" Preview ").alignment(Alignment::Center))
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
@ -101,13 +98,10 @@ impl Television {
|
|||||||
preview_inner_block,
|
preview_inner_block,
|
||||||
inner,
|
inner,
|
||||||
preview,
|
preview,
|
||||||
selected_entry
|
target_line,
|
||||||
.line_number
|
|
||||||
.map(|l| u16::try_from(l).unwrap_or(0)),
|
|
||||||
);
|
);
|
||||||
f.render_widget(preview_block, inner);
|
f.render_widget(preview_block, inner);
|
||||||
//}
|
//}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -209,7 +203,7 @@ impl Television {
|
|||||||
.block(preview_block)
|
.block(preview_block)
|
||||||
.alignment(Alignment::Left)
|
.alignment(Alignment::Left)
|
||||||
.style(Style::default().add_modifier(Modifier::ITALIC)),
|
.style(Style::default().add_modifier(Modifier::ITALIC)),
|
||||||
_ => Paragraph::new(Text::raw(EMPTY_STRING)),
|
PreviewContent::Empty => Paragraph::new(Text::raw(EMPTY_STRING)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +311,7 @@ fn compute_paragraph_from_highlighted_lines(
|
|||||||
let line_number =
|
let line_number =
|
||||||
build_line_number_span(i + 1).style(Style::default().fg(
|
build_line_number_span(i + 1).style(Style::default().fg(
|
||||||
if line_specifier.is_some()
|
if line_specifier.is_some()
|
||||||
&& i == line_specifier.unwrap() - 1
|
&& i == line_specifier.unwrap().saturating_sub(1)
|
||||||
{
|
{
|
||||||
DEFAULT_PREVIEW_GUTTER_SELECTED_FG
|
DEFAULT_PREVIEW_GUTTER_SELECTED_FG
|
||||||
} else {
|
} else {
|
||||||
@ -334,7 +328,9 @@ fn compute_paragraph_from_highlighted_lines(
|
|||||||
convert_syn_region_to_span(
|
convert_syn_region_to_span(
|
||||||
&(sr.0, sr.1),
|
&(sr.0, sr.1),
|
||||||
if line_specifier.is_some()
|
if line_specifier.is_some()
|
||||||
&& i == line_specifier.unwrap() - 1
|
&& i == line_specifier
|
||||||
|
.unwrap()
|
||||||
|
.saturating_sub(1)
|
||||||
{
|
{
|
||||||
Some(SyntectColor {
|
Some(SyntectColor {
|
||||||
r: 50,
|
r: 50,
|
||||||
|
@ -12,7 +12,8 @@ use std::str::FromStr;
|
|||||||
use television_channels::channels::OnAir;
|
use television_channels::channels::OnAir;
|
||||||
use television_channels::entry::Entry;
|
use television_channels::entry::Entry;
|
||||||
use television_utils::strings::{
|
use television_utils::strings::{
|
||||||
next_char_boundary, slice_at_char_boundaries,
|
make_matched_string_printable, next_char_boundary,
|
||||||
|
slice_at_char_boundaries,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
@ -76,45 +77,41 @@ where
|
|||||||
List::new(entries.iter().map(|entry| {
|
List::new(entries.iter().map(|entry| {
|
||||||
let mut spans = Vec::new();
|
let mut spans = Vec::new();
|
||||||
// optional icon
|
// optional icon
|
||||||
if entry.icon.is_some() && use_icons {
|
if let Some(icon) = entry.icon.as_ref() {
|
||||||
let icon = entry.icon.as_ref().unwrap();
|
if use_icons {
|
||||||
spans.push(Span::styled(
|
spans.push(Span::styled(
|
||||||
icon.to_string(),
|
icon.to_string(),
|
||||||
Style::default().fg(Color::from_str(icon.color).unwrap()),
|
Style::default().fg(Color::from_str(icon.color).unwrap()),
|
||||||
));
|
));
|
||||||
spans.push(Span::raw(" "));
|
spans.push(Span::raw(" "));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// entry name
|
// entry name
|
||||||
if let Some(name_match_ranges) = &entry.name_match_ranges {
|
let (entry_name, name_match_ranges) = make_matched_string_printable(
|
||||||
let mut last_match_end = 0;
|
&entry.name,
|
||||||
for (start, end) in name_match_ranges
|
entry.name_match_ranges.as_deref(),
|
||||||
.iter()
|
);
|
||||||
.map(|(s, e)| (*s as usize, *e as usize))
|
let mut last_match_end = 0;
|
||||||
{
|
for (start, end) in name_match_ranges
|
||||||
spans.push(Span::styled(
|
.iter()
|
||||||
slice_at_char_boundaries(
|
.map(|(s, e)| (*s as usize, *e as usize))
|
||||||
&entry.name,
|
{
|
||||||
last_match_end,
|
|
||||||
start,
|
|
||||||
),
|
|
||||||
Style::default().fg(results_list_colors.result_name_fg),
|
|
||||||
));
|
|
||||||
spans.push(Span::styled(
|
|
||||||
slice_at_char_boundaries(&entry.name, start, end),
|
|
||||||
Style::default().fg(Color::Red),
|
|
||||||
));
|
|
||||||
last_match_end = end;
|
|
||||||
}
|
|
||||||
spans.push(Span::styled(
|
spans.push(Span::styled(
|
||||||
&entry.name[next_char_boundary(&entry.name, last_match_end)..],
|
slice_at_char_boundaries(&entry_name, last_match_end, start)
|
||||||
|
.to_string(),
|
||||||
Style::default().fg(results_list_colors.result_name_fg),
|
Style::default().fg(results_list_colors.result_name_fg),
|
||||||
));
|
));
|
||||||
} else {
|
|
||||||
spans.push(Span::styled(
|
spans.push(Span::styled(
|
||||||
entry.display_name(),
|
slice_at_char_boundaries(&entry_name, start, end).to_string(),
|
||||||
Style::default().fg(results_list_colors.result_name_fg),
|
Style::default().fg(Color::Red),
|
||||||
));
|
));
|
||||||
|
last_match_end = end;
|
||||||
}
|
}
|
||||||
|
spans.push(Span::styled(
|
||||||
|
entry_name[next_char_boundary(&entry_name, last_match_end)..]
|
||||||
|
.to_string(),
|
||||||
|
Style::default().fg(results_list_colors.result_name_fg),
|
||||||
|
));
|
||||||
// optional line number
|
// optional line number
|
||||||
if let Some(line_number) = entry.line_number {
|
if let Some(line_number) = entry.line_number {
|
||||||
spans.push(Span::styled(
|
spans.push(Span::styled(
|
||||||
@ -126,43 +123,32 @@ where
|
|||||||
if let Some(preview) = &entry.value {
|
if let Some(preview) = &entry.value {
|
||||||
spans.push(Span::raw(": "));
|
spans.push(Span::raw(": "));
|
||||||
|
|
||||||
if let Some(preview_match_ranges) = &entry.value_match_ranges {
|
let (preview, preview_match_ranges) =
|
||||||
if !preview_match_ranges.is_empty() {
|
make_matched_string_printable(
|
||||||
let mut last_match_end = 0;
|
|
||||||
for (start, end) in preview_match_ranges
|
|
||||||
.iter()
|
|
||||||
.map(|(s, e)| (*s as usize, *e as usize))
|
|
||||||
{
|
|
||||||
spans.push(Span::styled(
|
|
||||||
slice_at_char_boundaries(
|
|
||||||
preview,
|
|
||||||
last_match_end,
|
|
||||||
start,
|
|
||||||
),
|
|
||||||
Style::default()
|
|
||||||
.fg(results_list_colors.result_preview_fg),
|
|
||||||
));
|
|
||||||
spans.push(Span::styled(
|
|
||||||
slice_at_char_boundaries(preview, start, end),
|
|
||||||
Style::default().fg(Color::Red),
|
|
||||||
));
|
|
||||||
last_match_end = end;
|
|
||||||
}
|
|
||||||
spans.push(Span::styled(
|
|
||||||
&preview[next_char_boundary(
|
|
||||||
preview,
|
|
||||||
preview_match_ranges.last().unwrap().1 as usize,
|
|
||||||
)..],
|
|
||||||
Style::default()
|
|
||||||
.fg(results_list_colors.result_preview_fg),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
spans.push(Span::styled(
|
|
||||||
preview,
|
preview,
|
||||||
|
entry.value_match_ranges.as_deref(),
|
||||||
|
);
|
||||||
|
let mut last_match_end = 0;
|
||||||
|
for (start, end) in preview_match_ranges
|
||||||
|
.iter()
|
||||||
|
.map(|(s, e)| (*s as usize, *e as usize))
|
||||||
|
{
|
||||||
|
spans.push(Span::styled(
|
||||||
|
slice_at_char_boundaries(&preview, last_match_end, start)
|
||||||
|
.to_string(),
|
||||||
Style::default().fg(results_list_colors.result_preview_fg),
|
Style::default().fg(results_list_colors.result_preview_fg),
|
||||||
));
|
));
|
||||||
|
spans.push(Span::styled(
|
||||||
|
slice_at_char_boundaries(&preview, start, end).to_string(),
|
||||||
|
Style::default().fg(Color::Red),
|
||||||
|
));
|
||||||
|
last_match_end = end;
|
||||||
}
|
}
|
||||||
|
spans.push(Span::styled(
|
||||||
|
preview[next_char_boundary(&preview, last_match_end)..]
|
||||||
|
.to_string(),
|
||||||
|
Style::default().fg(results_list_colors.result_preview_fg),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Line::from(spans)
|
Line::from(spans)
|
||||||
}))
|
}))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user