Upload local patches I've been running for jisho-cli.
This commit is contained in:
parent
128c0a6e9b
commit
139f3b17ab
7 changed files with 482 additions and 195 deletions
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
Binary file not shown.
Before Width: | Height: | Size: 100 KiB |
230
Cargo.lock
generated
230
Cargo.lock
generated
|
@ -2,21 +2,18 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ansi_term"
|
|
||||||
version = "0.12.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
|
|
||||||
dependencies = [
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argparse"
|
name = "argparse"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f8ebf5827e4ac4fd5946560e6a99776ea73b596d80898f357007317a7141e47"
|
checksum = "3f8ebf5827e4ac4fd5946560e6a99776ea73b596d80898f357007317a7141e47"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "arrayvec"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -34,6 +31,24 @@ version = "0.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "1.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitvec"
|
||||||
|
version = "0.19.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33"
|
||||||
|
dependencies = [
|
||||||
|
"funty",
|
||||||
|
"radium",
|
||||||
|
"tap",
|
||||||
|
"wyz",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.6.1"
|
version = "3.6.1"
|
||||||
|
@ -69,6 +84,70 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding"
|
||||||
|
version = "0.2.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec"
|
||||||
|
dependencies = [
|
||||||
|
"encoding-index-japanese",
|
||||||
|
"encoding-index-korean",
|
||||||
|
"encoding-index-simpchinese",
|
||||||
|
"encoding-index-singlebyte",
|
||||||
|
"encoding-index-tradchinese",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding-index-japanese"
|
||||||
|
version = "1.20141219.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_index_tests",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding-index-korean"
|
||||||
|
version = "1.20141219.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_index_tests",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding-index-simpchinese"
|
||||||
|
version = "1.20141219.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_index_tests",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding-index-singlebyte"
|
||||||
|
version = "1.20141219.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_index_tests",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding-index-tradchinese"
|
||||||
|
version = "1.20141219.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_index_tests",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "encoding_index_tests"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "form_urlencoded"
|
name = "form_urlencoded"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -79,6 +158,12 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "funty"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.18"
|
version = "0.1.18"
|
||||||
|
@ -109,14 +194,13 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||||
name = "jisho-cli"
|
name = "jisho-cli"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
|
||||||
"argparse",
|
"argparse",
|
||||||
"atty",
|
"atty",
|
||||||
"colored",
|
"colored",
|
||||||
|
"kradical_parsing",
|
||||||
"libc",
|
"libc",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"ureq",
|
"ureq",
|
||||||
"webbrowser",
|
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -129,12 +213,44 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kradical_jis"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02e3de4d97ae2ae659371d11e7181b2498efe5ef6211f7103aa37f58e5408c19"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "kradical_parsing"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7e62dbe571a488fae4ba0f5056224e56a00c58fd7c6583ca92720d1236b0087"
|
||||||
|
dependencies = [
|
||||||
|
"encoding",
|
||||||
|
"kradical_jis",
|
||||||
|
"nom",
|
||||||
|
"thiserror",
|
||||||
|
"unicode-segmentation",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lexical-core"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
|
||||||
|
dependencies = [
|
||||||
|
"arrayvec",
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"ryu",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.139"
|
version = "0.2.139"
|
||||||
|
@ -156,6 +272,25 @@ version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "6.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6a7a9657c84d5814c6196b68bb4429df09c18b1573806259fba397ea4ad0d44"
|
||||||
|
dependencies = [
|
||||||
|
"bitvec",
|
||||||
|
"funty",
|
||||||
|
"lexical-core",
|
||||||
|
"memchr",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.7.2"
|
version = "1.7.2"
|
||||||
|
@ -186,6 +321,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "radium"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.16.20"
|
version = "0.16.20"
|
||||||
|
@ -253,6 +394,12 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.68"
|
version = "1.0.68"
|
||||||
|
@ -264,6 +411,32 @@ dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tap"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -297,6 +470,12 @@ dependencies = [
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-segmentation"
|
||||||
|
version = "1.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -339,6 +518,12 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.73"
|
version = "0.2.73"
|
||||||
|
@ -403,17 +588,6 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "webbrowser"
|
|
||||||
version = "0.5.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ecad156490d6b620308ed411cfee90d280b3cbd13e189ea0d3fada8acc89158a"
|
|
||||||
dependencies = [
|
|
||||||
"web-sys",
|
|
||||||
"widestring",
|
|
||||||
"winapi",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "webpki"
|
name = "webpki"
|
||||||
version = "0.21.4"
|
version = "0.21.4"
|
||||||
|
@ -433,12 +607,6 @@ dependencies = [
|
||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "widestring"
|
|
||||||
version = "0.4.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -526,3 +694,9 @@ name = "windows_x86_64_msvc"
|
||||||
version = "0.42.1"
|
version = "0.42.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wyz"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214"
|
||||||
|
|
22
Cargo.toml
22
Cargo.toml
|
@ -1,24 +1,32 @@
|
||||||
[package]
|
[package]
|
||||||
name = "jisho-cli"
|
name = "jisho-cli"
|
||||||
description = "A very simple cli tool to lookup Japanese words using jisho.org"
|
description = "A simple cli tool to lookup Japanese words using jisho.org"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
authors = ["jojii <jojii@gmx.net>"]
|
authors = ["jojii <jojii@gmx.net>", "Hiers <dvmap@protonmail.com"]
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
repository = "https://github.com/JojiiOfficial/jisho-cli"
|
repository = "https://github.com/Hiers/jisho-cli"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
windows-sys = { version = "0.45.0", features = ["Win32_Foundation", "Win32_System_Console"] }
|
windows-sys = { version = "0.45.0", features = ["Win32_Foundation", "Win32_System_Console", "Win32_UI_Shell"] }
|
||||||
|
|
||||||
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
libc = "0.2.139"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ureq = { version = "2.1.0", features = ["json"] }
|
ureq = { version = "2.1.0", features = ["json"] }
|
||||||
libc = "0.2.139"
|
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
ansi_term = "0.12.1"
|
|
||||||
colored = "2.0.0"
|
colored = "2.0.0"
|
||||||
argparse = "0.2.2"
|
argparse = "0.2.2"
|
||||||
webbrowser = "0.5.5"
|
|
||||||
atty = "0.2"
|
atty = "0.2"
|
||||||
|
kradical_parsing = "0.1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = 'z'
|
||||||
|
lto = true
|
||||||
|
codegen-units = 1
|
||||||
|
panic = 'abort'
|
||||||
|
strip = true
|
||||||
|
|
34
README.md
34
README.md
|
@ -1,37 +1,27 @@
|
||||||
# Jisho (cli)
|
# Jisho (cli)
|
||||||
A very simple cli tool to look up Japanese words using jisho.org's API
|
A very simple cli tool to look up Japanese words using jisho.org's API.
|
||||||
|
Searching for kanji by radicals is also available.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<img src=".img/hV3BeXWDTmREm8ujOkR3v6903.png"/>
|
<img src=".img/dab0ab082751a1b17271309c2ffc3c16d53c8498513619e50235e8157bab01fa.png">
|
||||||
|
<img src=".img/16adb8274ff5e12b13545df2996dbdc3be149b9cd5575ceb38e2d9e031117ab9.png">
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
Binaries are directly available from the release tab.
|
||||||
|
|
||||||
From [Release tab](https://github.com/JojiiOfficial/jisho-cli/releases)
|
# Compilation
|
||||||
<br>
|
|
||||||
> Simply download the binary
|
|
||||||
<br>
|
|
||||||
|
|
||||||
From my [Arch repository](https://repo.jojii.de)
|
Download source and run
|
||||||
```
|
```
|
||||||
sudo pacman -S jisho
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
From crates.io:
|
|
||||||
```
|
|
||||||
cargo install jisho-cli
|
|
||||||
```
|
|
||||||
|
|
||||||
From AUR:
|
|
||||||
```
|
|
||||||
yay -S jisho
|
|
||||||
```
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
```
|
```
|
||||||
jisho [<words to look up>]
|
jisho [<words to look up>]
|
||||||
|
jisho :[<radicals in kanji>]
|
||||||
```
|
```
|
||||||
|
When looking up radicals, * (or *) can be used to add a radical that can't be easily typed, e.g. 气.
|
||||||
|
|
||||||
> Note: The binary from crates.io is called `jisho-cli`, not `jisho` <br>
|
# Note
|
||||||
> Note: You can use spaces
|
To search kanji by radicals, the [radkfile](https://www.edrdg.org/krad/kradinf.html) needs to be installed in either `~/.local/share/` on Linux or `~\AppData\Local\` on Windows.
|
||||||
|
|
357
src/main.rs
357
src/main.rs
|
@ -1,7 +1,9 @@
|
||||||
use std::{
|
use std::{
|
||||||
io::{stdin, stdout, Write},
|
io::{stdin, stdout, Write},
|
||||||
process::{Command, Stdio},
|
process::{Command, Stdio},
|
||||||
thread::{self, JoinHandle},
|
path::PathBuf,
|
||||||
|
collections::HashSet,
|
||||||
|
error::Error,
|
||||||
env,
|
env,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -9,6 +11,7 @@ use argparse::{ArgumentParser, List, Print, Store, StoreTrue};
|
||||||
use colored::*;
|
use colored::*;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use atty::Stream;
|
use atty::Stream;
|
||||||
|
use kradical_parsing::radk;
|
||||||
|
|
||||||
macro_rules! JISHO_URL {
|
macro_rules! JISHO_URL {
|
||||||
() => {
|
() => {
|
||||||
|
@ -16,73 +19,110 @@ macro_rules! JISHO_URL {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
struct Options {
|
struct Options {
|
||||||
limit: usize,
|
limit: usize,
|
||||||
query: String,
|
query: String,
|
||||||
kanji: bool, // Sadly not (yet) supported by jisho.org's API
|
|
||||||
interactive: bool,
|
interactive: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Options {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
limit: 0,
|
|
||||||
query: String::default(),
|
|
||||||
kanji: false,
|
|
||||||
interactive: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), ureq::Error> {
|
let term_size = if atty::is(Stream::Stdout) {
|
||||||
let term_size;
|
terminal_size().unwrap_or(0)
|
||||||
|
|
||||||
if atty::is(Stream::Stdout) {
|
|
||||||
term_size = terminal_size().unwrap_or(0);
|
|
||||||
} else {
|
} else {
|
||||||
term_size = 0;
|
0
|
||||||
}
|
};
|
||||||
|
|
||||||
let options = parse_args();
|
let options = parse_args();
|
||||||
|
|
||||||
let mut query = {
|
let mut query = String::new();
|
||||||
|
loop {
|
||||||
|
|
||||||
|
query.clear();
|
||||||
if options.interactive {
|
if options.interactive {
|
||||||
let mut o = String::new();
|
while query.trim().is_empty() || query.trim() == ":" || query.trim() == ":" {
|
||||||
while o.trim().is_empty() {
|
query.clear();
|
||||||
print!("=> ");
|
print!("=> ");
|
||||||
stdout().flush().unwrap();
|
stdout().flush().unwrap();
|
||||||
if (stdin().read_line(&mut o).expect("Can't read from stdin")) == 0 {
|
if (stdin().read_line(&mut query).expect("Can't read from stdin")) == 0 {
|
||||||
// Exit on EOF
|
/* Exit on EOF */
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
o
|
|
||||||
} else {
|
} else {
|
||||||
options.query.clone()
|
query = options.query.clone();
|
||||||
|
if query.trim().is_empty() || query.trim() == ":" || query.trim() == ":" {
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
query = query.trim().to_string();
|
||||||
|
|
||||||
loop {
|
|
||||||
let mut lines_output = 0;
|
let mut lines_output = 0;
|
||||||
let mut output = String::new();
|
let mut output = String::with_capacity(5242880); /* Give output 5MB of buffer; Should be enough to avoid reallocs*/
|
||||||
|
|
||||||
if options.kanji {
|
/* for kanji radical search */
|
||||||
// Open kanji page here
|
let mut result: HashSet<_> = HashSet::new();
|
||||||
let threads = query
|
let mut aux: HashSet<_> = HashSet::new();
|
||||||
.chars()
|
|
||||||
.into_iter()
|
|
||||||
.map(|kanji| {
|
|
||||||
let kanji = kanji.clone();
|
|
||||||
thread::spawn(move || {
|
|
||||||
webbrowser::open(&format!("https://jisho.org/search/{}%23kanji", kanji))
|
|
||||||
.expect("Couldn't open browser");
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<Vec<JoinHandle<()>>>();
|
|
||||||
|
|
||||||
for thread in threads {
|
if query.starts_with(':') || query.starts_with(':') {
|
||||||
thread.join().unwrap();
|
|
||||||
|
let path = get_radkfile_path();
|
||||||
|
|
||||||
|
match radk::parse_file(path.unwrap()) { /* if it doesn't exist, just panic */
|
||||||
|
Ok(radk_list) => {
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
/* First iteration: get the baseline for the results */
|
||||||
|
let mut rad = query.char_indices().nth(1).unwrap().1;
|
||||||
|
if rad == '*' || rad == '*' {
|
||||||
|
let a = search_by_strokes(&mut query, &radk_list, 1);
|
||||||
|
if a.is_err() {
|
||||||
|
/* if search_by_radical returned an error then something is very wrong */
|
||||||
|
panic!("Couldn't parse input: {}", a.err().unwrap());
|
||||||
|
}
|
||||||
|
rad = a.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for k in radk_list.iter() {
|
||||||
|
if k.radical.glyph.contains(rad) {
|
||||||
|
for input in &k.kanji {
|
||||||
|
result.insert(input);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate until you've exhausted user input: refine the baseline to get final output */
|
||||||
|
for (i, mut rad) in query.clone().chars().skip(2).enumerate() {
|
||||||
|
if rad == '*' || rad == '*' {
|
||||||
|
let a = search_by_strokes(&mut query, &radk_list, i+2);
|
||||||
|
if a.is_err() {
|
||||||
|
/* if search_by_radical returned an error then something is very wrong */
|
||||||
|
panic!("Couldn't parse input: {}", a.err().unwrap());
|
||||||
|
}
|
||||||
|
rad = a.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for k in radk_list.iter() {
|
||||||
|
if k.radical.glyph.contains(rad) {
|
||||||
|
for input in &k.kanji {
|
||||||
|
aux.insert(input);
|
||||||
|
}
|
||||||
|
result = &result & &aux;
|
||||||
|
aux.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for r in result {
|
||||||
|
print!("{r} ");
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
Err(_e) => eprintln!("Error while reading radkfile\nIf you don't have the radkfile, download it from \
|
||||||
|
https://www.edrdg.org/krad/kradinf.html and place it in \"~/.local/share/\" on Linux or \"~\\AppData\\Local\\\" on Windows. \
|
||||||
|
This file is needed to search radicals by strokes."),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Do API request
|
// Do API request
|
||||||
|
@ -106,49 +146,35 @@ fn main() -> Result<(), ureq::Error> {
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over meanings and print them
|
/* Iterate over meanings and print them */
|
||||||
for (i, entry) in body.iter().enumerate() {
|
for (i, entry) in body.iter().enumerate() {
|
||||||
if i >= options.limit && options.limit != 0 {
|
if i >= options.limit && options.limit != 0 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
match print_item(&query, entry, &mut output) {
|
if let Some(r) = print_item(&query, entry, &mut output) {
|
||||||
Some(r) => lines_output += r,
|
lines_output += r;
|
||||||
None => continue,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
lines_output += 1;
|
lines_output += 1;
|
||||||
}
|
}
|
||||||
output.pop();
|
output.pop();
|
||||||
if lines_output > 0 {
|
lines_output = lines_output.saturating_sub(1);
|
||||||
lines_output -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if lines_output >= term_size - 1 && term_size != 0 {
|
if lines_output >= term_size - 1 && term_size != 0 {
|
||||||
// Output is a different process that is not a tty (i.e. less), but we want to keep colour
|
/* Output is a different process that is not a tty (i.e. less), but we want to keep colour */
|
||||||
env::set_var("CLICOLOR_FORCE", "1");
|
env::set_var("CLICOLOR_FORCE", "1");
|
||||||
pipe_to_less(output);
|
pipe_to_less(output);
|
||||||
} else {
|
} else {
|
||||||
print!("{}", output);
|
print!("{}", output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
if !options.interactive {
|
if !options.interactive {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
query.clear();
|
|
||||||
while query.trim().is_empty() {
|
|
||||||
print!("=> ");
|
|
||||||
stdout().flush().unwrap();
|
|
||||||
if (stdin().read_line(&mut query).expect("Can't read from stdin")) == 0 {
|
|
||||||
// Exit on EOF
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,26 +185,28 @@ fn print_item(query: &str, value: &Value, output: &mut String) -> Option<usize>
|
||||||
|
|
||||||
*output += &format!("{} {}\n", format_form(query, main_form)?, format_result_tags(value));
|
*output += &format!("{} {}\n", format_form(query, main_form)?, format_result_tags(value));
|
||||||
|
|
||||||
// Print senses
|
/* Print senses */
|
||||||
let senses = value_to_arr(value.get("senses")?);
|
let senses = value_to_arr(value.get("senses")?);
|
||||||
let mut prev_parts_of_speech = String::new();
|
let mut prev_parts_of_speech = String::new();
|
||||||
|
|
||||||
for (i, sense) in senses.iter().enumerate() {
|
for (i, sense) in senses.iter().enumerate() {
|
||||||
let (sense_str, bump) = format_sense(&sense, i, &mut prev_parts_of_speech);
|
let (sense_str, new_part_of_speech) = format_sense(sense, i, &mut prev_parts_of_speech);
|
||||||
if sense_str.is_empty() {
|
if !sense_str.is_empty() {
|
||||||
continue;
|
/*
|
||||||
}
|
* If the current meaning of our word is a different part of speech
|
||||||
// This bump is to keep count of lines that may or may not be printed (like noun, adverb)
|
* (e.g. previous meaning was 'Noun' and the current is 'Adverb'), an extra line will be
|
||||||
if bump {
|
* printed with this information
|
||||||
|
*/
|
||||||
|
if new_part_of_speech {
|
||||||
num_of_lines += 1;
|
num_of_lines += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*output += &format!(" {}\n", sense_str);
|
*output += &format!(" {}\n", sense_str);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Print alternative readings and kanji usage
|
/* Print alternative readings and kanji usage */
|
||||||
match japanese.get(1) {
|
if let Some(form) = japanese.get(1) {
|
||||||
Some (form) => {
|
|
||||||
num_of_lines += 2;
|
num_of_lines += 2;
|
||||||
|
|
||||||
*output += &format!(" {}", "Other forms\n".bright_blue());
|
*output += &format!(" {}", "Other forms\n".bright_blue());
|
||||||
|
@ -189,17 +217,15 @@ fn print_item(query: &str, value: &Value, output: &mut String) -> Option<usize>
|
||||||
}
|
}
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
num_of_lines += senses.iter().count() + 1;
|
num_of_lines += senses.len() + 1;
|
||||||
Some(num_of_lines)
|
Some(num_of_lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format_form(query: &str, form: &Value) -> Option<String> {
|
fn format_form(query: &str, form: &Value) -> Option<String> {
|
||||||
let reading = form
|
let reading = form
|
||||||
.get("reading")
|
.get("reading")
|
||||||
.map(|i| value_to_str(i))
|
.map(value_to_str)
|
||||||
.unwrap_or(query);
|
.unwrap_or(query);
|
||||||
|
|
||||||
let word = value_to_str(form.get("word").unwrap_or(form.get("reading")?));
|
let word = value_to_str(form.get("word").unwrap_or(form.get("reading")?));
|
||||||
|
@ -218,25 +244,14 @@ fn format_sense(value: &Value, index: usize, prev_parts_of_speech: &mut String)
|
||||||
|
|
||||||
let parts_of_speech = if let Some(parts_of_speech) = parts_of_speech {
|
let parts_of_speech = if let Some(parts_of_speech) = parts_of_speech {
|
||||||
let parts = value_to_arr(parts_of_speech)
|
let parts = value_to_arr(parts_of_speech)
|
||||||
.to_owned()
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| {
|
.map(|i| {
|
||||||
let s = value_to_str(i);
|
value_to_str(i)
|
||||||
match s {
|
|
||||||
"Suru verb - irregular" => "Irregular verb",
|
|
||||||
_ => {
|
|
||||||
if s.contains("Godan verb") {
|
|
||||||
"Godan verb"
|
|
||||||
} else {
|
|
||||||
s
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<&str>>()
|
.collect::<Vec<&str>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
|
|
||||||
// Do not repeat a meaning's part of speech if it is the same as the previous meaning
|
/* Do not repeat a meaning's part of speech if it is the same as the previous meaning */
|
||||||
if !parts.is_empty() && parts != *prev_parts_of_speech {
|
if !parts.is_empty() && parts != *prev_parts_of_speech {
|
||||||
*prev_parts_of_speech = parts.clone();
|
*prev_parts_of_speech = parts.clone();
|
||||||
format!("{}\n ", parts.bright_blue())
|
format!("{}\n ", parts.bright_blue())
|
||||||
|
@ -247,11 +262,7 @@ fn format_sense(value: &Value, index: usize, prev_parts_of_speech: &mut String)
|
||||||
String::new()
|
String::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let bump = if parts_of_speech.is_empty() {
|
let new_part_of_speech = !parts_of_speech.is_empty();
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
let index_str = format!("{}.",(index + 1));
|
let index_str = format!("{}.",(index + 1));
|
||||||
let mut tags = format_sense_tags(value);
|
let mut tags = format_sense_tags(value);
|
||||||
|
@ -267,12 +278,12 @@ fn format_sense(value: &Value, index: usize, prev_parts_of_speech: &mut String)
|
||||||
index_str.bright_black(),
|
index_str.bright_black(),
|
||||||
english_definiton
|
english_definiton
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| value_to_str(i))
|
.map(value_to_str)
|
||||||
.collect::<Vec<&str>>()
|
.collect::<Vec<&str>>()
|
||||||
.join(", "),
|
.join(", "),
|
||||||
tags.bright_black(),
|
tags.bright_black(),
|
||||||
info.bright_black(),
|
info.bright_black(),
|
||||||
), bump)
|
), new_part_of_speech)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format tags from a whole meaning
|
/// Format tags from a whole meaning
|
||||||
|
@ -285,12 +296,16 @@ fn format_result_tags(value: &Value) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(jlpt) = value.get("jlpt") {
|
if let Some(jlpt) = value.get("jlpt") {
|
||||||
let jlpt = value_to_arr(&jlpt);
|
/*
|
||||||
|
* The jisho API actually returns an array of all of JLTP levels for each alternative of a word
|
||||||
|
* Since the main one is always at index 0, we take that for formatting
|
||||||
|
*/
|
||||||
|
let jlpt = value_to_arr(jlpt);
|
||||||
if !jlpt.is_empty() {
|
if !jlpt.is_empty() {
|
||||||
let jlpt = value_to_str(jlpt.get(0).unwrap())
|
let jlpt = value_to_str(jlpt.get(0).unwrap())
|
||||||
.replace("jlpt-", "")
|
.replace("jlpt-", "")
|
||||||
.to_uppercase();
|
.to_uppercase();
|
||||||
builder.push_str(&format!("({}) ", jlpt.bright_blue().to_string()));
|
builder.push_str(&format!("({}) ", jlpt.bright_blue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +329,6 @@ fn format_sense_tags(value: &Value) -> String {
|
||||||
builder += &format!(", {}", t.as_str());
|
builder += &format!(", {}", t.as_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder
|
builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +352,7 @@ fn format_sense_info(value: &Value) -> String {
|
||||||
builder += &format!(", {}", value_to_str(info));
|
builder += &format!(", {}", value_to_str(info));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder;
|
builder
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -371,7 +385,9 @@ fn parse_args() -> Options {
|
||||||
let mut query_vec: Vec<String> = Vec::new();
|
let mut query_vec: Vec<String> = Vec::new();
|
||||||
{
|
{
|
||||||
let mut ap = ArgumentParser::new();
|
let mut ap = ArgumentParser::new();
|
||||||
ap.set_description("Use jisho.org from cli");
|
ap.set_description("Use jisho.org from cli. \
|
||||||
|
Searching for kanji by radicals is also available if the radkfile file is installed in \"~/.local/share\" \
|
||||||
|
or \"~\\AppData\\Local\\\" if you're on Windows.");
|
||||||
ap.add_option(
|
ap.add_option(
|
||||||
&["-V", "--version"],
|
&["-V", "--version"],
|
||||||
Print(env!("CARGO_PKG_VERSION").to_string()),
|
Print(env!("CARGO_PKG_VERSION").to_string()),
|
||||||
|
@ -383,7 +399,9 @@ fn parse_args() -> Options {
|
||||||
"Limit the amount of results",
|
"Limit the amount of results",
|
||||||
);
|
);
|
||||||
ap.refer(&mut query_vec)
|
ap.refer(&mut query_vec)
|
||||||
.add_argument("Query", List, "The query to search for");
|
.add_argument("Query", List, "Search terms using jisho.org;
|
||||||
|
Prepend it with ':' to search a kanji by radicals instead \
|
||||||
|
and ':*' to search a radical by strokes (e.g. ':口*').");
|
||||||
|
|
||||||
ap.refer(&mut options.interactive).add_option(
|
ap.refer(&mut options.interactive).add_option(
|
||||||
&["-i", "--interactive"],
|
&["-i", "--interactive"],
|
||||||
|
@ -391,13 +409,6 @@ fn parse_args() -> Options {
|
||||||
"Don't exit after running a query",
|
"Don't exit after running a query",
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Uncomment when supported by jisho.org */
|
|
||||||
ap.refer(&mut options.kanji).add_option(
|
|
||||||
&["--kanji", "-k"],
|
|
||||||
StoreTrue,
|
|
||||||
"Look up a certain kanji",
|
|
||||||
);
|
|
||||||
|
|
||||||
ap.parse_args_or_exit();
|
ap.parse_args_or_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +416,64 @@ fn parse_args() -> Options {
|
||||||
options
|
options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn search_by_strokes(query: &mut String, radk_list: &[radk::Membership], n: usize) -> Result<char, std::io::Error> {
|
||||||
|
|
||||||
|
let mut strokes = String::new();
|
||||||
|
let mut radicals: Vec<char> = Vec::new();
|
||||||
|
let rad;
|
||||||
|
loop{
|
||||||
|
print!("How many strokes does your radical have? ");
|
||||||
|
stdout().flush()?;
|
||||||
|
strokes.clear();
|
||||||
|
if (stdin().read_line(&mut strokes).expect("Can't read from stdin")) == 0 {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
match strokes.trim().parse::<u8>() {
|
||||||
|
Ok(strk) => {
|
||||||
|
let mut i = 1;
|
||||||
|
for k in radk_list.iter() {
|
||||||
|
if k.radical.strokes == strk {
|
||||||
|
print!("{}{} ", i, k.radical.glyph);
|
||||||
|
radicals.push(k.radical.glyph.chars().next().unwrap());
|
||||||
|
i += 1;
|
||||||
|
} else if k.radical.strokes > strk {
|
||||||
|
println!();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
print!("Choose the radical to use for your search: ");
|
||||||
|
stdout().flush()?;
|
||||||
|
strokes.clear();
|
||||||
|
if (stdin().read_line(&mut strokes).expect("Can't read from stdin")) == 0 {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
match strokes.trim().parse::<usize>() {
|
||||||
|
Ok(strk) => {
|
||||||
|
if strk < 1 || strk > i-1 {
|
||||||
|
eprintln!("Couldn't parse input: number not in range");
|
||||||
|
} else {
|
||||||
|
rad = radicals.get(strk-1).unwrap();
|
||||||
|
/* UTF-8 is not fun */
|
||||||
|
query.replace_range(query.char_indices().nth(n).unwrap().0..
|
||||||
|
query.char_indices().nth(n).unwrap().0 +
|
||||||
|
query.char_indices().nth(n).unwrap().1.len_utf8(),
|
||||||
|
rad.to_string().as_str());
|
||||||
|
println!("{}", query.as_str().bright_black());
|
||||||
|
return Ok(*rad);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => { eprintln!("{e}"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => { eprintln!("{e}") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn pipe_to_less(output: String) {
|
fn pipe_to_less(output: String) {
|
||||||
|
|
||||||
let command = Command::new("less")
|
let command = Command::new("less")
|
||||||
|
@ -418,28 +487,34 @@ fn pipe_to_less(output: String) {
|
||||||
panic!("couldn't pipe to less: {}", e);
|
panic!("couldn't pipe to less: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't care about the return value, only whether wait failed or not
|
/* We don't care about the return value, only whether wait failed or not */
|
||||||
if process.wait().is_err() {
|
if process.wait().is_err() {
|
||||||
panic!("wait() was called on non-existent child process\
|
panic!("wait() was called on non-existent child process\
|
||||||
- this should not be possible");
|
- this should not be possible");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// less not found in PATH; print normally
|
/* less not found in PATH; print normally */
|
||||||
Err(_e) => print!("{}", output)
|
Err(_e) => print!("{}", output)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* OS specific part of the program */
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn terminal_size() -> Result<usize, i16> {
|
fn terminal_size() -> Result<usize, i16> {
|
||||||
use libc::{c_ushort, ioctl, STDOUT_FILENO, TIOCGWINSZ};
|
use libc::{ioctl, STDOUT_FILENO, TIOCGWINSZ, winsize};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut size: c_ushort = 0;
|
let mut size = winsize {
|
||||||
if ioctl(STDOUT_FILENO, TIOCGWINSZ.into(), &mut size as *mut _) != 0 {
|
ws_row: 0,
|
||||||
Err(-1)
|
ws_col: 0,
|
||||||
|
ws_xpixel: 0,
|
||||||
|
ws_ypixel: 0,
|
||||||
|
};
|
||||||
|
if ioctl(STDOUT_FILENO, TIOCGWINSZ, &mut size as *mut _) == 0 {
|
||||||
|
Ok(size.ws_row as usize)
|
||||||
} else {
|
} else {
|
||||||
Ok(size as usize)
|
Err(-1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,7 +526,7 @@ fn terminal_size() -> Result<usize, i16> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let handle = GetStdHandle(STD_OUTPUT_HANDLE) as windows_sys::Win32::Foundation::HANDLE;
|
let handle = GetStdHandle(STD_OUTPUT_HANDLE) as windows_sys::Win32::Foundation::HANDLE;
|
||||||
|
|
||||||
// Unlike the linux function, rust will complain if only part of the struct is sent
|
/* Unlike the linux function, rust will complain if only part of the struct is sent */
|
||||||
let mut window = CONSOLE_SCREEN_BUFFER_INFO {
|
let mut window = CONSOLE_SCREEN_BUFFER_INFO {
|
||||||
dwSize: COORD { X: 0, Y: 0},
|
dwSize: COORD { X: 0, Y: 0},
|
||||||
dwCursorPosition: COORD { X: 0, Y: 0},
|
dwCursorPosition: COORD { X: 0, Y: 0},
|
||||||
|
@ -471,3 +546,43 @@ fn terminal_size() -> Result<usize, i16> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
fn get_radkfile_path() -> Option<PathBuf> {
|
||||||
|
#[allow(deprecated)] /* obviously no windows problem here */
|
||||||
|
std::env::home_dir()
|
||||||
|
.map(|path| path.join(".local/share/radkfile"))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
/* Nicked this section straight from https://github.com/rust-lang/cargo/blob/master/crates/home/src/windows.rs */
|
||||||
|
extern "C" {
|
||||||
|
fn wcslen(buf: *const u16) -> usize;
|
||||||
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
fn get_radkfile_path() -> Option<PathBuf> {
|
||||||
|
use std::ffi::OsString;
|
||||||
|
use std::os::windows::ffi::OsStringExt;
|
||||||
|
use windows_sys::Win32::Foundation::{MAX_PATH, S_OK};
|
||||||
|
use windows_sys::Win32::UI::Shell::{SHGetFolderPathW, CSIDL_PROFILE};
|
||||||
|
|
||||||
|
match env::var_os("USERPROFILE").filter(|s| !s.is_empty()).map(PathBuf::from) {
|
||||||
|
Some(path) => {
|
||||||
|
return Some(path.join("Appdata\\Local\\radkfile"));
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
unsafe {
|
||||||
|
let mut path: Vec<u16> = Vec::with_capacity(MAX_PATH as usize);
|
||||||
|
match SHGetFolderPathW(0, CSIDL_PROFILE as i32, 0, 0, path.as_mut_ptr()) {
|
||||||
|
S_OK => {
|
||||||
|
let len = wcslen(path.as_ptr());
|
||||||
|
path.set_len(len);
|
||||||
|
let s = OsString::from_wide(&path);
|
||||||
|
Some(PathBuf::from(s).join("Appdata\\Local\\radkfile"))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue